@@ -6,6 +6,7 @@ package note
66
77import (
88 "bytes"
9+ "crypto"
910 "crypto/ed25519"
1011 "crypto/sha256"
1112 "encoding/base64"
@@ -58,27 +59,48 @@ 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+ s := & subtreeSigner {
100+ name : name ,
101+ hash : keyHashMLDSA (name , pubKeyBytes ),
102+ }
103+
82104 s .signNote = func (msg []byte ) ([]byte , error ) {
83105 t := uint64 (time .Now ().Unix ())
84106 c := & log.Checkpoint {}
@@ -92,7 +114,7 @@ func newMLDSASigner(name string, keyBytes []byte) (*subtreeSigner, error) {
92114 if err != nil {
93115 return nil , err
94116 }
95- sB , err := key .Sign (nil , m , nil )
117+ sB , err := signer .Sign (nil , m , nil )
96118 if err != nil {
97119 return nil , err
98120 }
@@ -192,13 +214,20 @@ func NewSignerForCosignatureV1(skey string) (Signer, error) {
192214 s .verify = verifyEd25519CosigV1 (pubkey [1 :])
193215
194216 case algMLDSA44 :
195- stSigner , err := newMLDSASigner (name , key )
217+ if len (key ) != mldsa .PrivateKeySize {
218+ return nil , errSignerID
219+ }
220+ priv , err := mldsa .NewPrivateKey (mldsa .MLDSA44 (), key )
221+ if err != nil {
222+ return nil , err
223+ }
224+ stSigner , err := NewMLDSASignerFromCrypto (name , priv )
196225 if err != nil {
197226 return nil , err
198227 }
199228 s .sign = stSigner .Sign
200- s .verify = stSigner .verifier . verifyNote
201- s .hash = stSigner .hash
229+ s .verify = stSigner .Verifier (). Verify
230+ s .hash = stSigner .KeyHash ()
202231 }
203232
204233 return s , nil
@@ -373,7 +402,7 @@ func formatEd25519CosignatureV1(t uint64, msg []byte) ([]byte, error) {
373402 if lines := bytes .Split (msg , []byte ("\n " )); len (lines ) < 3 {
374403 return nil , errors .New ("cosigned note format invalid" )
375404 }
376- return [] byte ( fmt .Sprintf ( "cosignature/v1\n time %d\n %s" , t , msg ) ), nil
405+ return fmt .Appendf ( nil , "cosignature/v1\n time %d\n %s" , t , msg ), nil
377406}
378407
379408func formatMLDSACosignatureV1 (cosignerName string , timestamp uint64 , logOrigin string , start , end uint64 , hash []byte ) ([]byte , error ) {
@@ -417,7 +446,6 @@ var (
417446 errInvalidTimestamp = errors .New ("invalid timestamp" )
418447)
419448
420-
421449// SubtreeSigner is a note.Signer that can additionally produce subtree signatures, and
422450// provide access to a similarly capable verifier.
423451type SubtreeSigner interface {
0 commit comments