@@ -10,8 +10,6 @@ import (
1010 "crypto/elliptic"
1111
1212 "golang.org/x/crypto/sha3"
13- "golang.org/x/crypto/cryptobyte"
14- "golang.org/x/crypto/cryptobyte/asn1"
1513
1614 "github.com/deatil/go-cryptobin/elliptic/ed521"
1715)
2725const (
2826 // ContextMaxSize is the maximum length (in bytes) allowed for context.
2927 ContextMaxSize = 255
28+ // PublicKeySize is the size, in bytes, of public keys as used in this package.
29+ PublicKeySize = 133
30+ // PrivateKeySize is the size, in bytes, of private keys as used in this package.
31+ PrivateKeySize = 66
32+ // SignatureSize is the size, in bytes, of signatures generated and verified by this package.
33+ SignatureSize = 132
3034 // SeedSize is the size, in bytes, of private key seeds.
3135 SeedSize = 66
3236)
@@ -180,7 +184,7 @@ func NewPrivateKey(d []byte) (*PrivateKey, error) {
180184
181185// return PrivateKey data
182186func PrivateKeyTo (key * PrivateKey ) []byte {
183- privateKey := make ([]byte , ( key . Curve . Params (). N . BitLen () + 7 ) / 8 )
187+ privateKey := make ([]byte , PrivateKeySize )
184188 return key .D .FillBytes (privateKey )
185189}
186190
@@ -245,10 +249,14 @@ func sign(privateKey *PrivateKey, message []byte, domPre, context string) ([]byt
245249 PHM = message
246250 }
247251
248- n := privateKey .Curve .Params ().N
252+ params := privateKey .Curve .Params ()
253+ n := params .N
254+ byteLen := (params .BitSize + 7 ) / 8
255+
256+ var tmpBuf []byte
249257
250258 seed := privateKey .D .Bytes ()
251- publicKeyBytes := ed521 .MarshalCompressed (privateKey .Curve , privateKey .X , privateKey .Y )
259+ publicKeyBytes := ed521 .MarshalPoint (privateKey .Curve , privateKey .X , privateKey .Y )
252260
253261 h := make ([]byte , 132 )
254262 sha3 .ShakeSum256 (h , seed )
@@ -267,21 +275,31 @@ func sign(privateKey *PrivateKey, message []byte, domPre, context string) ([]byt
267275 messageDigest := make ([]byte , 132 )
268276 mh .Read (messageDigest )
269277
278+ messageDigest = ed521 .Reverse (messageDigest )
279+
270280 r := new (big.Int ).SetBytes (messageDigest )
271281 r .Mod (r , n )
272282
273283 _ , R := privateKey .Curve .ScalarBaseMult (r .Bytes ())
274284
285+ buf := make ([]byte , 2 * byteLen )
286+ R .FillBytes (buf [:byteLen ])
287+
288+ tmpBuf = ed521 .Reverse (buf [:byteLen ])
289+ copy (buf [:byteLen ], tmpBuf )
290+
275291 kh := sha3 .NewShake256 ()
276292 kh .Write ([]byte (domPre ))
277293 kh .Write ([]byte {byte (len (context ))})
278294 kh .Write ([]byte (context ))
279- kh .Write (R . Bytes () )
295+ kh .Write (buf [: byteLen ] )
280296 kh .Write (publicKeyBytes )
281297 kh .Write (PHM )
282298 hramDigest := make ([]byte , 132 )
283299 kh .Read (hramDigest )
284300
301+ hramDigest = ed521 .Reverse (hramDigest )
302+
285303 k := new (big.Int ).SetBytes (hramDigest )
286304 k .Mod (k , n )
287305
@@ -290,7 +308,11 @@ func sign(privateKey *PrivateKey, message []byte, domPre, context string) ([]byt
290308 S .Add (S , r )
291309 S .Mod (S , n )
292310
293- return encodeSignature (R , S )
311+ S .FillBytes (buf [byteLen :])
312+ tmpBuf = ed521 .Reverse (buf [byteLen :])
313+ copy (buf [byteLen :], tmpBuf )
314+
315+ return buf , nil
294316}
295317
296318// VerifyWithOptions reports whether sig is a valid signature of message by
@@ -333,11 +355,6 @@ func VerifyWithOptions(publicKey *PublicKey, message, sig []byte, opts crypto.Si
333355
334356// Verify reports whether sig is a valid signature of message by publicKey.
335357func verify (publicKey * PublicKey , message , sig []byte , domPre , context string ) bool {
336- R , S , err := parseSignature (sig )
337- if err != nil {
338- return false
339- }
340-
341358 var PHM []byte
342359
343360 if domPre == domPrefixPh {
@@ -349,23 +366,36 @@ func verify(publicKey *PublicKey, message, sig []byte, domPre, context string) b
349366 }
350367
351368 curve := publicKey .Curve
369+ params := curve .Params ()
352370 n := curve .Params ().N
371+ byteLen := (params .BitSize + 7 ) / 8
372+
373+ if len (sig ) != 2 * byteLen {
374+ return false
375+ }
353376
354- publicKeyBytes := ed521 .MarshalCompressed (publicKey .Curve , publicKey .X , publicKey .Y )
377+ RBytes := ed521 .Reverse (sig [:byteLen ])
378+ SBytes := ed521 .Reverse (sig [byteLen :])
379+
380+ R := new (big.Int ).SetBytes (RBytes )
381+ S := new (big.Int ).SetBytes (SBytes )
382+
383+ publicKeyBytes := ed521 .MarshalPoint (publicKey .Curve , publicKey .X , publicKey .Y )
355384
356385 kh := sha3 .NewShake256 ()
357386 kh .Write ([]byte (domPre ))
358387 kh .Write ([]byte {byte (len (context ))})
359388 kh .Write ([]byte (context ))
360- kh .Write (R . Bytes () )
389+ kh .Write (sig [: byteLen ] )
361390 kh .Write (publicKeyBytes )
362391 kh .Write (PHM )
363392 hramDigest := make ([]byte , 132 )
364393 kh .Read (hramDigest )
365394
395+ hramDigest = ed521 .Reverse (hramDigest )
396+
366397 k := new (big.Int ).SetBytes (hramDigest )
367398 k .Mod (k , n )
368-
369399 k .Mod (k .Neg (k ), n )
370400
371401 // r = S - k * pub
@@ -376,35 +406,6 @@ func verify(publicKey *PublicKey, message, sig []byte, domPre, context string) b
376406 return bigIntEqual (R , y2 )
377407}
378408
379- func encodeSignature (r , s * big.Int ) ([]byte , error ) {
380- var b cryptobyte.Builder
381- b .AddASN1 (asn1 .SEQUENCE , func (b * cryptobyte.Builder ) {
382- b .AddASN1BigInt (r )
383- b .AddASN1BigInt (s )
384- })
385-
386- return b .Bytes ()
387- }
388-
389- func parseSignature (sig []byte ) (r , s * big.Int , err error ) {
390- var inner cryptobyte.String
391- input := cryptobyte .String (sig )
392-
393- r = new (big.Int )
394- s = new (big.Int )
395-
396- if ! input .ReadASN1 (& inner , asn1 .SEQUENCE ) ||
397- ! input .Empty () ||
398- ! inner .ReadASN1Integer (r ) ||
399- ! inner .ReadASN1Integer (s ) ||
400- ! inner .Empty () {
401- err = ErrInvalidASN1
402- return
403- }
404-
405- return
406- }
407-
408409func randFieldElement (rand io.Reader , curve elliptic.Curve ) (* big.Int , error ) {
409410 N := curve .Params ().N
410411
0 commit comments