예제 #1
1
// Verify the given payload
func (ctx rsaEncrypterVerifier) verifyPayload(payload []byte, signature []byte, alg SignatureAlgorithm) error {
	var hash crypto.Hash

	switch alg {
	case RS256, PS256:
		hash = crypto.SHA256
	case RS384, PS384:
		hash = crypto.SHA384
	case RS512, PS512:
		hash = crypto.SHA512
	default:
		return ErrUnsupportedAlgorithm
	}

	hasher := hash.New()

	// According to documentation, Write() on hash never fails
	_, _ = hasher.Write(payload)
	hashed := hasher.Sum(nil)

	switch alg {
	case RS256, RS384, RS512:
		return rsa.VerifyPKCS1v15(ctx.publicKey, hash, hashed, signature)
	case PS256, PS384, PS512:
		return rsa.VerifyPSS(ctx.publicKey, hash, hashed, signature, nil)
	}

	return ErrUnsupportedAlgorithm
}
예제 #2
0
func generate_digest2(hash crypto.Hash, key, src []byte) ([]byte, error) {
	key1 := make([]byte, SNMP_EXTENDED_KEY_SIZ)
	key2 := make([]byte, SNMP_EXTENDED_KEY_SIZ)
	extkey := make([]byte, SNMP_EXTENDED_KEY_SIZ)
	copy(extkey, key)

	for i := 0; i < SNMP_EXTENDED_KEY_SIZ; i++ {
		key1[i] = extkey[i] ^ 0x36
		key2[i] = extkey[i] ^ 0x5c
	}

	calc := hash.New()
	_, err := calc.Write(key1)
	if nil != err {
		return nil, err
	}
	_, err = calc.Write(src)
	if nil != err {
		return nil, err
	}
	internal := calc.Sum(nil)

	calc = hash.New()
	_, err = calc.Write(key2)
	if nil != err {
		return nil, err
	}
	_, err = calc.Write(internal)
	if nil != err {
		return nil, err
	}
	return calc.Sum(nil)[0:SNMP_USM_AUTH_SIZE], nil
}
예제 #3
0
// kexDH performs Diffie-Hellman key agreement on a ServerConnection.
func (s *ServerConn) kexDH(group *dhGroup, hashFunc crypto.Hash, magics *handshakeMagics, priv Signer) (result *kexResult, err error) {
	packet, err := s.readPacket()
	if err != nil {
		return
	}
	var kexDHInit kexDHInitMsg
	if err = unmarshal(&kexDHInit, packet, msgKexDHInit); err != nil {
		return
	}

	y, err := rand.Int(s.config.rand(), group.p)
	if err != nil {
		return
	}

	Y := new(big.Int).Exp(group.g, y, group.p)
	kInt, err := group.diffieHellman(kexDHInit.X, y)
	if err != nil {
		return nil, err
	}

	hostKeyBytes := MarshalPublicKey(priv.PublicKey())

	h := hashFunc.New()
	writeString(h, magics.clientVersion)
	writeString(h, magics.serverVersion)
	writeString(h, magics.clientKexInit)
	writeString(h, magics.serverKexInit)
	writeString(h, hostKeyBytes)
	writeInt(h, kexDHInit.X)
	writeInt(h, Y)

	K := make([]byte, intLength(kInt))
	marshalInt(K, kInt)
	h.Write(K)

	H := h.Sum(nil)

	// H is already a hash, but the hostkey signing will apply its
	// own key specific hash algorithm.
	sig, err := signAndMarshal(priv, s.config.rand(), H)
	if err != nil {
		return nil, err
	}

	kexDHReply := kexDHReplyMsg{
		HostKey:   hostKeyBytes,
		Y:         Y,
		Signature: sig,
	}
	packet = marshal(msgKexDHReply, kexDHReply)

	err = s.writePacket(packet)
	return &kexResult{
		H:       H,
		K:       K,
		HostKey: hostKeyBytes,
		Hash:    hashFunc,
	}, nil
}
예제 #4
0
파일: ecdsa.go 프로젝트: lestrrat/go-jwx
// Thumbprint returns the JWK thumbprint using the indicated
// hashing algorithm, according to RFC 7638
func (k EcdsaPublicKey) Thumbprint(hash crypto.Hash) ([]byte, error) {
	const tmpl = `{"crv":"%s","kty":"EC","x":"%s","y":"%s"}`

	csize := k.Curve.Size()

	// We need to truncate the buffer at curve size
	xbuf := k.X.Bytes()
	if len(xbuf) > csize {
		xbuf = xbuf[:csize]
	}
	ybuf := k.Y.Bytes()
	if len(ybuf) > csize {
		ybuf = ybuf[:csize]
	}
	enc := base64.RawURLEncoding
	x64 := make([]byte, enc.EncodedLen(len(xbuf)))
	enc.Encode(x64, xbuf)
	y64 := make([]byte, enc.EncodedLen(len(ybuf)))
	enc.Encode(y64, ybuf)

	v := fmt.Sprintf(tmpl, k.Curve.String(), x64, y64)
	h := hash.New()
	h.Write([]byte(v))
	return h.Sum(nil), nil
}
예제 #5
0
파일: su3.go 프로젝트: MDrollette/i2p-tools
func (s *Su3File) Sign(privkey *rsa.PrivateKey) error {
	var hashType crypto.Hash
	switch s.SignatureType {
	case SIGTYPE_DSA:
		hashType = crypto.SHA1
	case SIGTYPE_ECDSA_SHA256, SIGTYPE_RSA_SHA256:
		hashType = crypto.SHA256
	case SIGTYPE_ECDSA_SHA384, SIGTYPE_RSA_SHA384:
		hashType = crypto.SHA384
	case SIGTYPE_ECDSA_SHA512, SIGTYPE_RSA_SHA512:
		hashType = crypto.SHA512
	default:
		return fmt.Errorf("Unknown signature type.")
	}

	h := hashType.New()
	h.Write(s.BodyBytes())
	digest := h.Sum(nil)

	sig, err := rsa.SignPKCS1v15(rand.Reader, privkey, 0, digest)
	if nil != err {
		return err
	}

	s.Signature = sig

	return nil
}
예제 #6
0
파일: transport.go 프로젝트: davecheney/ssh
// setupKeys sets the cipher and MAC keys from kex.K, kex.H and sessionId, as
// described in RFC 4253, section 6.4. direction should either be serverKeys
// (to setup server->client keys) or clientKeys (for client->server keys).
func (c *common) setupKeys(d direction, K, H, sessionId []byte, hashFunc crypto.Hash) error {
	cipherMode := cipherModes[c.cipherAlgo]

	macKeySize := 20

	iv := make([]byte, cipherMode.ivSize)
	key := make([]byte, cipherMode.keySize)
	macKey := make([]byte, macKeySize)

	h := hashFunc.New()
	generateKeyMaterial(iv, d.ivTag, K, H, sessionId, h)
	generateKeyMaterial(key, d.keyTag, K, H, sessionId, h)
	generateKeyMaterial(macKey, d.macKeyTag, K, H, sessionId, h)

	c.mac = truncatingMAC{12, hmac.NewSHA1(macKey)}

	cipher, err := cipherMode.createCipher(key, iv)
	if err != nil {
		return err
	}

	c.cipher = cipher

	return nil
}
예제 #7
0
파일: gpgv.go 프로젝트: u-root/u-root
func verifyDetachedSignature(key *packet.PublicKey, contentf, sigf io.Reader) error {
	var hashFunc crypto.Hash

	packets := packet.NewReader(sigf)
	p, err := packets.Next()
	if err != nil {
		return err
	}
	switch sig := p.(type) {
	case *packet.Signature:
		hashFunc = sig.Hash
	case *packet.SignatureV3:
		hashFunc = sig.Hash
	default:
		return errors.UnsupportedError("unrecognized signature")
	}

	h := hashFunc.New()
	if _, err := io.Copy(h, contentf); err != nil && err != io.EOF {
		return err
	}
	switch sig := p.(type) {
	case *packet.Signature:
		err = key.VerifySignature(h, sig)
	case *packet.SignatureV3:
		err = key.VerifySignatureV3(h, sig)
	default:
		panic("unreachable")
	}
	return err
}
예제 #8
0
func generateHash(algo HashAlgorithm, data []byte) ([]byte, crypto.Hash, error) {
	var hashType crypto.Hash
	switch algo {
	case MD5:
		hashType = crypto.MD5
	case SHA1:
		hashType = crypto.SHA1
	case SHA224:
		hashType = crypto.SHA224
	case SHA256:
		hashType = crypto.SHA256
	case SHA384:
		hashType = crypto.SHA384
	case SHA512:
		hashType = crypto.SHA512
	default:
		return nil, hashType, fmt.Errorf("unsupported Algorithm.Hash in signature: %v", algo)
	}

	hasher := hashType.New()
	if _, err := hasher.Write(data); err != nil {
		return nil, hashType, fmt.Errorf("failed to write to hasher: %v", err)
	}
	return hasher.Sum([]byte{}), hashType, nil
}
예제 #9
0
파일: rsa.go 프로젝트: keysonZZZ/kmg
//这个接口应该和php版的openssl_verify在使用rsa公钥的时候有完全相同的输入输出,加密的坑简直太多了..
//msg是需要验证签名的消息,sig是签名之后生成的
func RsaOpensslVerify(pub *rsa.PublicKey, h crypto.Hash, msg []byte, sig []byte) (err error) {
	h1 := h.New()
	h1.Write(msg)
	digest := h1.Sum(nil)
	err = rsa.VerifyPKCS1v15(pub, h, digest, sig)
	return
}
예제 #10
0
파일: pubkey.go 프로젝트: kisom/hockeypuck
// sigSerializeUserAttribute calculates the user attribute packet hash
// TODO: clean up & contribute this to go.crypto/openpgp
func (pubkey *Pubkey) sigSerializeUserAttribute(uat *UserAttribute, hashFunc crypto.Hash) (h hash.Hash, err error) {
	if !hashFunc.Available() {
		return nil, errors.UnsupportedError("hash function")
	}
	h = hashFunc.New()

	// Get user attribute opaque packet
	var uatOpaque *packet.OpaquePacket
	if uatOpaque, err = uat.GetOpaquePacket(); err != nil {
		return
	}
	// Get public key opaque packet.
	var pkOpaque *packet.OpaquePacket
	if pkOpaque, err = pubkey.GetOpaquePacket(); err != nil {
		return
	}
	// RFC 4880, section 5.2.4
	// Write the signature prefix and public key contents to hash
	pubkey.PublicKey.SerializeSignaturePrefix(h)
	h.Write(pkOpaque.Contents)
	// V4 certification hash
	var buf [5]byte
	// User attribute constant
	buf[0] = 0xd1
	// Big-endian length of user attribute contents
	l := len(uatOpaque.Contents)
	buf[1] = byte(l >> 24)
	buf[2] = byte(l >> 16)
	buf[3] = byte(l >> 8)
	buf[4] = byte(l)
	h.Write(buf[:])
	// User attribute contents
	h.Write(uatOpaque.Contents)
	return
}
예제 #11
0
파일: rsa.go 프로젝트: keysonZZZ/kmg
func RsaOpensslSign(pub *rsa.PrivateKey, h crypto.Hash, msg []byte) (s []byte, err error) {
	h1 := h.New()
	h1.Write(msg)
	digest := h1.Sum(nil)
	s, err = rsa.SignPKCS1v15(nil, pub, h, digest)
	return
}
예제 #12
0
func populateHash(hashFunc crypto.Hash, msg []byte) (hash.Hash, error) {
	h := hashFunc.New()
	if _, err := h.Write(msg); err != nil {
		return nil, err
	}
	return h, nil
}
예제 #13
0
파일: keys.go 프로젝트: naunga/vault
func (s *wrappedSigner) Sign(rand io.Reader, data []byte) (*Signature, error) {
	var hashFunc crypto.Hash

	switch key := s.pubKey.(type) {
	case *rsaPublicKey, *dsaPublicKey:
		hashFunc = crypto.SHA1
	case *ecdsaPublicKey:
		hashFunc = ecHash(key.Curve)
	case ed25519PublicKey:
	default:
		return nil, fmt.Errorf("ssh: unsupported key type %T", key)
	}

	var digest []byte
	if hashFunc != 0 {
		h := hashFunc.New()
		h.Write(data)
		digest = h.Sum(nil)
	} else {
		digest = data
	}

	signature, err := s.signer.Sign(rand, digest, hashFunc)
	if err != nil {
		return nil, err
	}

	// crypto.Signer.Sign is expected to return an ASN.1-encoded signature
	// for ECDSA and DSA, but that's not the encoding expected by SSH, so
	// re-encode.
	switch s.pubKey.(type) {
	case *ecdsaPublicKey, *dsaPublicKey:
		type asn1Signature struct {
			R, S *big.Int
		}
		asn1Sig := new(asn1Signature)
		_, err := asn1.Unmarshal(signature, asn1Sig)
		if err != nil {
			return nil, err
		}

		switch s.pubKey.(type) {
		case *ecdsaPublicKey:
			signature = Marshal(asn1Sig)

		case *dsaPublicKey:
			signature = make([]byte, 40)
			r := asn1Sig.R.Bytes()
			s := asn1Sig.S.Bytes()
			copy(signature[20-len(r):20], r)
			copy(signature[40-len(s):40], s)
		}
	}

	return &Signature{
		Format: s.pubKey.Type(),
		Blob:   signature,
	}, nil
}
예제 #14
0
// the core function of the Signer, generates the raw hmac of he bytes.
func (p *signer) SignBytes(h crypto.Hash, buf []byte) (signature []byte, err os.Error) {
	hasher := hmac.New(func() hash.Hash { return h.New() }, p.secretAccessKey)
	_, err = hasher.Write(buf)
	if err == nil {
		signature = hasher.Sum()
	}
	return
}
예제 #15
0
파일: apply.go 프로젝트: tjyang/go-update
func checksumFor(h crypto.Hash, payload []byte) ([]byte, error) {
	if !h.Available() {
		return nil, errors.New("requested hash function not available")
	}
	hash := h.New()
	hash.Write(payload) // guaranteed not to error
	return hash.Sum([]byte{}), nil
}
예제 #16
0
// ToDS converts a DNSKEY record to a DS record.
func (k *DNSKEY) ToDS(h uint8) *DS {
	if k == nil {
		return nil
	}
	ds := new(DS)
	ds.Hdr.Name = k.Hdr.Name
	ds.Hdr.Class = k.Hdr.Class
	ds.Hdr.Rrtype = TypeDS
	ds.Hdr.Ttl = k.Hdr.Ttl
	ds.Algorithm = k.Algorithm
	ds.DigestType = h
	ds.KeyTag = k.KeyTag()

	keywire := new(dnskeyWireFmt)
	keywire.Flags = k.Flags
	keywire.Protocol = k.Protocol
	keywire.Algorithm = k.Algorithm
	keywire.PublicKey = k.PublicKey
	wire := make([]byte, DefaultMsgSize)
	n, err := PackStruct(keywire, wire, 0)
	if err != nil {
		return nil
	}
	wire = wire[:n]

	owner := make([]byte, 255)
	off, err1 := PackDomainName(strings.ToLower(k.Hdr.Name), owner, 0, nil, false)
	if err1 != nil {
		return nil
	}
	owner = owner[:off]
	// RFC4034:
	// digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA);
	// "|" denotes concatenation
	// DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key.

	// digest buffer
	digest := append(owner, wire...) // another copy

	var hash crypto.Hash
	switch h {
	case SHA1:
		hash = crypto.SHA1
	case SHA256:
		hash = crypto.SHA256
	case SHA384:
		hash = crypto.SHA384
	case SHA512:
		hash = crypto.SHA512
	default:
		return nil
	}

	s := hash.New()
	s.Write(digest)
	ds.Digest = hex.EncodeToString(s.Sum(nil))
	return ds
}
예제 #17
0
파일: signer.go 프로젝트: ncw/GoAWS
// the core function of the Signer, generates the raw hmac of he bytes.
func (self *Signer) SignBytes(h crypto.Hash, buff []byte) (sig []byte, err error) {
	hh := hmac.New(func() hash.Hash {
		return h.New()
	}, self.secretAccessKey)
	_, err = hh.Write(buff)
	if err == nil {
		sig = hh.Sum(nil)
	}
	return
}
예제 #18
0
파일: public_key.go 프로젝트: qbit/client
// keySignatureHash returns a Hash of the message that needs to be signed for
// pk to assert a subkey relationship to signed.
func keySignatureHash(pk, signed signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
	if !hashFunc.Available() {
		return nil, errors.UnsupportedError("hash function")
	}
	h = hashFunc.New()

	updateKeySignatureHash(pk, signed, h)

	return
}
예제 #19
0
파일: mode.go 프로젝트: 89hmdys/toast
func (pkcs1v15 *pkcs1v15Sign) Sign(src []byte, hash crypto.Hash, prk *rsa.PrivateKey) ([]byte, error) {
	if !hash.Available() {
		return nil, errors.New("unsupport hash type")
	}

	h := hash.New()
	h.Write(src)
	hashed := h.Sum(nil)
	return rsa.SignPKCS1v15(rand.Reader, prk, hash, hashed)
}
예제 #20
0
파일: public_key.go 프로젝트: qbit/client
// userIdSignatureHash returns a Hash of the message that needs to be signed
// to assert that pk is a valid key for id.
func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
	if !hashFunc.Available() {
		return nil, errors.UnsupportedError("hash function")
	}
	h = hashFunc.New()

	updateUserIdSignatureHash(id, pk, h)

	return
}
예제 #21
0
func checkSignature(c *x509.Certificate, algo x509.SignatureAlgorithm, signed, signature []byte) (err error) {
	var hashType crypto.Hash

	switch algo {
	case x509.SHA1WithRSA, x509.DSAWithSHA1, x509.ECDSAWithSHA1:
		hashType = crypto.SHA1
	case x509.SHA256WithRSA, x509.DSAWithSHA256, x509.ECDSAWithSHA256:
		hashType = crypto.SHA256
	case x509.SHA384WithRSA, x509.ECDSAWithSHA384:
		hashType = crypto.SHA384
	case x509.SHA512WithRSA, x509.ECDSAWithSHA512:
		hashType = crypto.SHA512
	default:
		return x509.ErrUnsupportedAlgorithm
	}

	if !hashType.Available() {
		return x509.ErrUnsupportedAlgorithm
	}
	h := hashType.New()

	h.Write(signed)
	digest := h.Sum(nil)

	switch pub := c.PublicKey.(type) {
	case *rsa.PublicKey:
		// the digest is already hashed, so we force a 0 here
		return rsa.VerifyPKCS1v15(pub, 0, digest, signature)
	case *dsa.PublicKey:
		dsaSig := new(dsaSignature)
		if _, err := asn1.Unmarshal(signature, dsaSig); err != nil {
			return err
		}
		if dsaSig.R.Sign() <= 0 || dsaSig.S.Sign() <= 0 {
			return errors.New("x509: DSA signature contained zero or negative values")
		}
		if !dsa.Verify(pub, digest, dsaSig.R, dsaSig.S) {
			return errors.New("x509: DSA verification failure")
		}
		return
	case *ecdsa.PublicKey:
		ecdsaSig := new(ecdsaSignature)
		if _, err := asn1.Unmarshal(signature, ecdsaSig); err != nil {
			return err
		}
		if ecdsaSig.R.Sign() <= 0 || ecdsaSig.S.Sign() <= 0 {
			return errors.New("x509: ECDSA signature contained zero or negative values")
		}
		if !ecdsa.Verify(pub, digest, ecdsaSig.R, ecdsaSig.S) {
			return errors.New("x509: ECDSA verification failure")
		}
		return
	}
	return x509.ErrUnsupportedAlgorithm
}
예제 #22
0
// Sign the given payload
func (ctx ecDecrypterSigner) signPayload(payload []byte, alg SignatureAlgorithm) (Signature, error) {
	var expectedBitSize int
	var hash crypto.Hash

	switch alg {
	case ES256:
		expectedBitSize = 256
		hash = crypto.SHA256
	case ES384:
		expectedBitSize = 384
		hash = crypto.SHA384
	case ES512:
		expectedBitSize = 521
		hash = crypto.SHA512
	}

	curveBits := ctx.privateKey.Curve.Params().BitSize
	if expectedBitSize != curveBits {
		return Signature{}, fmt.Errorf("square/go-jose: expected %d bit key, got %d bits instead", expectedBitSize, curveBits)
	}

	hasher := hash.New()

	// According to documentation, Write() on hash never fails
	_, _ = hasher.Write(payload)
	hashed := hasher.Sum(nil)

	r, s, err := ecdsa.Sign(randReader, ctx.privateKey, hashed)
	if err != nil {
		return Signature{}, err
	}

	keyBytes := curveBits / 8
	if curveBits%8 > 0 {
		keyBytes += 1
	}

	// We serialize the outpus (r and s) into big-endian byte arrays and pad
	// them with zeros on the left to make sure the sizes work out. Both arrays
	// must be keyBytes long, and the output must be 2*keyBytes long.
	rBytes := r.Bytes()
	rBytesPadded := make([]byte, keyBytes)
	copy(rBytesPadded[keyBytes-len(rBytes):], rBytes)

	sBytes := s.Bytes()
	sBytesPadded := make([]byte, keyBytes)
	copy(sBytesPadded[keyBytes-len(sBytes):], sBytes)

	out := append(rBytesPadded, sBytesPadded...)

	return Signature{
		Signature: out,
		protected: &rawHeader{},
	}, nil
}
예제 #23
0
파일: mode.go 프로젝트: 89hmdys/toast
func (pkcs1v15 *pkcs1v15Sign) Verify(src []byte, sign []byte, hash crypto.Hash, puk *rsa.PublicKey) error {
	if !hash.Available() {
		return errors.New("unsupport hash type")
	}

	h := hash.New()
	h.Write(src)
	hashed := h.Sum(nil)

	return rsa.VerifyPKCS1v15(puk, hash, hashed, sign)
}
예제 #24
0
func pkcs1v15HashInfo(hash crypto.Hash, inLen int) (hashLen int, prefix []byte, err error) {
	hashLen = hash.Size()
	if inLen != hashLen {
		return 0, nil, errors.New("input must be hashed message")
	}
	prefix, ok := hashPrefixes[hash]
	if !ok {
		return 0, nil, errors.New("unsupported hash function")
	}
	return
}
예제 #25
0
// Thumbprint returns the JWK thumbprint using the indicated
// hashing algorithm, according to RFC 7638
func (s SymmetricKey) Thumbprint(hash crypto.Hash) ([]byte, error) {
	const tmpl = `{"k":"%s","kty":"oct"}`
	k64, err := s.Key.Base64Encode()
	if err != nil {
		return nil, err
	}

	v := fmt.Sprintf(tmpl, k64)
	h := hash.New()
	h.Write([]byte(v))
	return h.Sum(nil), nil
}
예제 #26
0
func keyRevocationHash(pk signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) {
	if !hashFunc.Available() {
		return nil, errors.UnsupportedError("hash function")
	}
	h = hashFunc.New()

	// RFC 4880, section 5.2.4
	pk.SerializeSignaturePrefix(h)
	pk.serializeWithoutHeaders(h)

	return
}
예제 #27
0
파일: contentcache.go 프로젝트: lht/termite
func NewHashWriter(dir string, hashfunc crypto.Hash) *HashWriter {
	me := &HashWriter{}
	tmp, err := ioutil.TempFile(dir, ".md5temp")
	if err != nil {
		panic(err)
		log.Fatal(err)
	}

	me.dest = tmp
	me.hasher = hashfunc.New()
	return me
}
예제 #28
0
func token(data string, hash crypto.Hash) string {
	var tokenKey [keySize]byte
	n, err := rand.Read(tokenKey[:])
	for n < keySize || err != nil {
		n, err = rand.Read(tokenKey[:])
	}
	h := hash.New()
	h.Write([]byte(data))
	h.Write(tokenKey[:])
	h.Write([]byte(time.Now().Format(time.RFC3339Nano)))
	return fmt.Sprintf("%x", h.Sum(nil))
}
예제 #29
0
파일: render.go 프로젝트: dolab/gogo
func NewHashRender(w Responser, hasher crypto.Hash) Render {
	if !hasher.Available() {
		panic(ErrHash.Error())
	}

	render := &HashRender{
		response: w,
		hash:     hasher.New(),
	}

	return render
}
예제 #30
0
// userIdSignatureV3Hash returns a Hash of the message that needs to be signed
// to assert that pk is a valid key for id.
func userIdSignatureV3Hash(id string, pk signingKey, hfn crypto.Hash) (h hash.Hash, err error) {
	if h = hfn.New(); h == nil {
		return nil, errors.UnsupportedError("hash function")
	}

	// RFC 4880, section 5.2.4
	pk.SerializeSignaturePrefix(h)
	pk.serializeWithoutHeaders(h)

	h.Write([]byte(id))

	return
}