@@ -6,6 +6,7 @@ package note
66
77import (
88 "bytes"
9+ "crypto"
910 "crypto/ed25519"
1011 "crypto/sha256"
1112 "encoding/base64"
@@ -58,27 +59,49 @@ func NewMLDSASigner(skey string) (SubtreeSigner, error) {
5859 if priv1 != "PRIVATE" || priv2 != "KEY" || len (hash16 ) != 8 || err != nil || ! isValidName (name ) || len (key ) == 0 {
5960 return nil , errSignerID
6061 }
62+ hash , err := strconv .ParseUint (hash16 , 16 , 32 )
63+ if err != nil {
64+ return nil , errInvalidHash
65+ }
66+
6167 alg , key := key [0 ], key [1 :]
6268 if alg != algMLDSA44 {
6369 return nil , errSignerID
6470 }
65- return newMLDSASigner (name , key )
66- }
67-
68- // newMLDSASigner returns a signer for MLDSA cosignature v1, with the provided
69- // name and key bytes in the format: algo || private key.
70- func newMLDSASigner (name string , keyBytes []byte ) (* subtreeSigner , error ) {
71- s := & subtreeSigner {name : name }
72- if len (keyBytes ) != mldsa .PrivateKeySize {
71+ if len (key ) != mldsa .PrivateKeySize {
7372 return nil , errSignerID
7473 }
75- key , err := mldsa .NewPrivateKey (mldsa .MLDSA44 (), keyBytes )
74+ priv , err := mldsa .NewPrivateKey (mldsa .MLDSA44 (), key )
75+ if err != nil {
76+ return nil , err
77+ }
78+ s , err := NewMLDSASignerFromCrypto (name , priv )
7679 if err != nil {
7780 return nil , err
7881 }
79- pubKey := key .PublicKey ()
82+ if s .KeyHash () != uint32 (hash ) {
83+ return nil , errInvalidHash
84+ }
85+ return s , nil
86+ }
87+
88+ // NewMLDSASignerFromCrypto returns a subtree signer for MLDSA cosignature v1 which uses an underlying crypto.Signer for cryptographic operations.
89+ func NewMLDSASignerFromCrypto (name string , signer crypto.Signer ) (SubtreeSigner , error ) {
90+ if ! isValidName (name ) {
91+ return nil , errSignerID
92+ }
93+ pubKey , ok := signer .Public ().(* mldsa.PublicKey )
94+ if ! ok {
95+ return nil , errSignerAlg
96+ }
8097 pubKeyBytes := append ([]byte {algMLDSA44 }, pubKey .Bytes ()... )
81- s .hash = keyHashMLDSA (name , pubKeyBytes )
98+
99+ h := keyHashMLDSA (name , pubKeyBytes )
100+ s := & subtreeSigner {
101+ name : name ,
102+ hash : h ,
103+ }
104+
82105 s .signNote = func (msg []byte ) ([]byte , error ) {
83106 t := uint64 (time .Now ().Unix ())
84107 c := & log.Checkpoint {}
@@ -92,7 +115,7 @@ func newMLDSASigner(name string, keyBytes []byte) (*subtreeSigner, error) {
92115 if err != nil {
93116 return nil , err
94117 }
95- sB , err := key .Sign (nil , m , nil )
118+ sB , err := signer .Sign (nil , m , nil )
96119 if err != nil {
97120 return nil , err
98121 }
@@ -192,13 +215,20 @@ func NewSignerForCosignatureV1(skey string) (Signer, error) {
192215 s .verify = verifyEd25519CosigV1 (pubkey [1 :])
193216
194217 case algMLDSA44 :
195- stSigner , err := newMLDSASigner (name , key )
218+ if len (key ) != mldsa .PrivateKeySize {
219+ return nil , errSignerID
220+ }
221+ priv , err := mldsa .NewPrivateKey (mldsa .MLDSA44 (), key )
222+ if err != nil {
223+ return nil , err
224+ }
225+ stSigner , err := NewMLDSASignerFromCrypto (name , priv )
196226 if err != nil {
197227 return nil , err
198228 }
199229 s .sign = stSigner .Sign
200- s .verify = stSigner .verifier . verifyNote
201- s .hash = stSigner .hash
230+ s .verify = stSigner .Verifier (). Verify
231+ s .hash = stSigner .KeyHash ()
202232 }
203233
204234 return s , nil
@@ -373,7 +403,7 @@ func formatEd25519CosignatureV1(t uint64, msg []byte) ([]byte, error) {
373403 if lines := bytes .Split (msg , []byte ("\n " )); len (lines ) < 3 {
374404 return nil , errors .New ("cosigned note format invalid" )
375405 }
376- return [] byte ( fmt .Sprintf ( "cosignature/v1\n time %d\n %s" , t , msg ) ), nil
406+ return fmt .Appendf ( nil , "cosignature/v1\n time %d\n %s" , t , msg ), nil
377407}
378408
379409func formatMLDSACosignatureV1 (cosignerName string , timestamp uint64 , logOrigin string , start , end uint64 , hash []byte ) ([]byte , error ) {
@@ -417,7 +447,6 @@ var (
417447 errInvalidTimestamp = errors .New ("invalid timestamp" )
418448)
419449
420-
421450// SubtreeSigner is a note.Signer that can additionally produce subtree signatures, and
422451// provide access to a similarly capable verifier.
423452type SubtreeSigner interface {
0 commit comments