@@ -35,20 +35,14 @@ const (
3535//
3636// Note that ML-DSA-44 cosigners reject checkpoints with extension lines.
3737func NewCosignatureSigner (name string , key crypto.Signer ) (* CosignatureSigner , error ) {
38- if ! isValidName (name ) {
39- return nil , errors .New ("invalid name" )
38+ pubKey := key .Public ()
39+ v , err := NewCosignatureVerifierFromKey (name , pubKey )
40+ if err != nil {
41+ return nil , err
4042 }
41-
42- s := & CosignatureSigner {}
43- s .v .name = name
44-
45- ed25519Key , isEd25519 := key .Public ().(ed25519.PublicKey )
46- mldsaKey , isMLDSA := key .Public ().(* mldsa.PublicKey )
47-
48- switch {
49- case isEd25519 :
50- s .v .hash = keyHash (name , append ([]byte {algCosignatureEd25519 }, ed25519Key ... ))
51- s .v .key = ed25519Key
43+ s := & CosignatureSigner {v : * v }
44+ switch pubKey .(type ) {
45+ case ed25519.PublicKey :
5246 s .sign = func (msg []byte ) ([]byte , error ) {
5347 t := uint64 (time .Now ().Unix ())
5448 m , err := formatCosignatureV1 (t , msg )
@@ -66,21 +60,7 @@ func NewCosignatureSigner(name string, key crypto.Signer) (*CosignatureSigner, e
6660 sig = append (sig , s ... )
6761 return sig , nil
6862 }
69- s .v .verify = func (msg , sig []byte ) bool {
70- if len (sig ) != 8 + ed25519 .SignatureSize {
71- return false
72- }
73- t := binary .BigEndian .Uint64 (sig )
74- sig = sig [8 :]
75- m , err := formatCosignatureV1 (t , msg )
76- if err != nil {
77- return false
78- }
79- return ed25519 .Verify (ed25519Key , m , sig )
80- }
81- case isMLDSA :
82- s .v .hash = keyHash (name , append ([]byte {algCosignatureMLDSA }, mldsaKey .Bytes ()... ))
83- s .v .key = mldsaKey
63+ case * mldsa.PublicKey :
8464 s .sign = func (msg []byte ) ([]byte , error ) {
8565 t := uint64 (time .Now ().Unix ())
8666 m , err := formatSubtreeV1 (name , t , msg )
@@ -98,22 +78,9 @@ func NewCosignatureSigner(name string, key crypto.Signer) (*CosignatureSigner, e
9878 sig = append (sig , s ... )
9979 return sig , nil
10080 }
101- s .v .verify = func (msg , sig []byte ) bool {
102- if len (sig ) != 8 + mldsa .MLDSA44SignatureSize {
103- return false
104- }
105- t := binary .BigEndian .Uint64 (sig )
106- sig = sig [8 :]
107- m , err := formatSubtreeV1 (name , t , msg )
108- if err != nil {
109- return false
110- }
111- return mldsa .Verify (mldsaKey , m , sig , nil ) == nil
112- }
11381 default :
11482 return nil , errors .New ("key type is not supported" )
11583 }
116-
11784 return s , nil
11885}
11986
@@ -206,23 +173,58 @@ func NewCosignatureVerifier(vkey string) (*CosignatureVerifier, error) {
206173 hash16 , key64 , _ := strings .Cut (vkey , "+" )
207174 hash , err1 := strconv .ParseUint (hash16 , 16 , 32 )
208175 key , err2 := base64 .StdEncoding .DecodeString (key64 )
209- if len (hash16 ) != 8 || err1 != nil || err2 != nil || ! isValidName ( name ) || len (key ) == 0 {
176+ if len (hash16 ) != 8 || err1 != nil || err2 != nil || len (key ) == 0 {
210177 return nil , errors .New ("malformed verifier id" )
211178 }
212- if uint32 (hash ) != keyHash (name , key ) {
213- return nil , errors .New ("invalid verifier hash" )
214- }
215179 alg , key := key [0 ], key [1 :]
180+ var verifier * CosignatureVerifier
216181 switch alg {
217182 case algCosignatureEd25519 :
218183 if len (key ) != ed25519 .PublicKeySize {
219184 return nil , errors .New ("malformed verifier public key" )
220185 }
221186 k := ed25519 .PublicKey (key )
187+ v , err := NewCosignatureVerifierFromKey (name , k )
188+ if err != nil {
189+ return nil , err
190+ }
191+ verifier = v
192+ case algCosignatureMLDSA :
193+ k , err := mldsa .NewPublicKey (mldsa .MLDSA44 (), key )
194+ if err != nil {
195+ return nil , fmt .Errorf ("malformed verifier public key: %w" , err )
196+ }
197+ v , err := NewCosignatureVerifierFromKey (name , k )
198+ if err != nil {
199+ return nil , err
200+ }
201+ verifier = v
202+ default :
203+ return nil , errors .New ("unknown verifier algorithm" )
204+ }
205+ if uint32 (hash ) != verifier .KeyHash () {
206+ return nil , errors .New ("invalid verifier hash" )
207+ }
208+ return verifier , nil
209+ }
210+
211+ // NewCosignatureVerifierFromKey constructs a new [CosignatureVerifier] from a
212+ // public key. It supports [ed25519.PublicKey] and [*mldsa.PublicKey].
213+ func NewCosignatureVerifierFromKey (name string , key crypto.PublicKey ) (* CosignatureVerifier , error ) {
214+ if ! isValidName (name ) {
215+ return nil , errors .New ("invalid name" )
216+ }
217+
218+ switch k := key .(type ) {
219+ case ed25519.PublicKey :
220+ if len (k ) != ed25519 .PublicKeySize {
221+ return nil , errors .New ("malformed Ed25519 public key" )
222+ }
223+ hash := keyHash (name , append ([]byte {algCosignatureEd25519 }, k ... ))
222224 return & CosignatureVerifier {
223225 verifier : verifier {
224226 name : name ,
225- hash : uint32 ( hash ) ,
227+ hash : hash ,
226228 verify : func (msg , sig []byte ) bool {
227229 if len (sig ) != 8 + ed25519 .SignatureSize {
228230 return false
@@ -239,17 +241,17 @@ func NewCosignatureVerifier(vkey string) (*CosignatureVerifier, error) {
239241 return ed25519 .Verify (k , m , sig )
240242 },
241243 },
242- key : ed25519 . PublicKey ( key ) ,
244+ key : k ,
243245 }, nil
244- case algCosignatureMLDSA :
245- k , err := mldsa .NewPublicKey (mldsa .MLDSA44 (), key )
246- if err != nil {
247- return nil , fmt .Errorf ("malformed verifier public key: %w" , err )
246+ case * mldsa.PublicKey :
247+ if k .Parameters () != mldsa .MLDSA44 () {
248+ return nil , errors .New ("ML-DSA parameters are not ML-DSA-44" )
248249 }
250+ hash := keyHash (name , append ([]byte {algCosignatureMLDSA }, k .Bytes ()... ))
249251 return & CosignatureVerifier {
250252 verifier : verifier {
251253 name : name ,
252- hash : uint32 ( hash ) ,
254+ hash : hash ,
253255 verify : func (msg , sig []byte ) bool {
254256 if len (sig ) != 8 + mldsa .MLDSA44SignatureSize {
255257 return false
@@ -269,7 +271,7 @@ func NewCosignatureVerifier(vkey string) (*CosignatureVerifier, error) {
269271 key : k ,
270272 }, nil
271273 default :
272- return nil , errors .New ("unknown verifier algorithm " )
274+ return nil , errors .New ("key type is not supported " )
273275 }
274276}
275277
0 commit comments