in sumdb/note/note.go [618:678]
func Sign(n *Note, signers ...Signer) ([]byte, error) {
var buf bytes.Buffer
if !strings.HasSuffix(n.Text, "\n") {
return nil, errMalformedNote
}
buf.WriteString(n.Text)
// Prepare signatures.
var sigs bytes.Buffer
have := make(map[nameHash]bool)
for _, s := range signers {
name := s.Name()
hash := s.KeyHash()
have[nameHash{name, hash}] = true
if !isValidName(name) {
return nil, errInvalidSigner
}
sig, err := s.Sign(buf.Bytes()) // buf holds n.Text
if err != nil {
return nil, err
}
var hbuf [4]byte
binary.BigEndian.PutUint32(hbuf[:], hash)
b64 := base64.StdEncoding.EncodeToString(append(hbuf[:], sig...))
sigs.WriteString("— ")
sigs.WriteString(name)
sigs.WriteString(" ")
sigs.WriteString(b64)
sigs.WriteString("\n")
}
buf.WriteString("\n")
// Emit existing signatures not replaced by new ones.
for _, list := range [][]Signature{n.Sigs, n.UnverifiedSigs} {
for _, sig := range list {
name, hash := sig.Name, sig.Hash
if !isValidName(name) {
return nil, errMalformedNote
}
if have[nameHash{name, hash}] {
continue
}
// Double-check hash against base64.
raw, err := base64.StdEncoding.DecodeString(sig.Base64)
if err != nil || len(raw) < 4 || binary.BigEndian.Uint32(raw) != hash {
return nil, errMalformedNote
}
buf.WriteString("— ")
buf.WriteString(sig.Name)
buf.WriteString(" ")
buf.WriteString(sig.Base64)
buf.WriteString("\n")
}
}
buf.Write(sigs.Bytes())
return buf.Bytes(), nil
}