Skip to content

Commit e6ffd91

Browse files
committed
fixed
1 parent 321491a commit e6ffd91

File tree

6 files changed

+139
-63
lines changed

6 files changed

+139
-63
lines changed

elliptic/ed521/ed521_curves.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@ func initAll() {
1313
func initE521() {
1414
ed521 = &Ed521Curve{
1515
Name: "Ed521",
16-
P: bigFromHex("1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
17-
N: bigFromHex("7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd15b6c64746fc85f736b8af5e7ec53f04fbd8c4569a8f1f4540ea2435f5180d6b"),
18-
D: bigFromHex("1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa4331"),
19-
Gx: bigFromHex("752cb45c48648b189df90cb2296b2878a3bfd9f42fc6c818ec8bf3c9c0c6203913f6ecc5ccc72434b1ae949d568fc99c6059d0fb13364838aa302a940a2f19ba6c"),
20-
Gy: bigFromHex("0c"),
16+
P: bigFromDec("6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151"),
17+
N: bigFromDec("1716199415032652428745475199770348304317358825035826352348615864796385795849413675475876651663657849636693659065234142604319282948702542317993421293670108523"),
18+
D: bigFromDec("-376014"),
19+
Gx: bigFromDec("1571054894184995387535939749894317568645297350402905821437625181152304994381188529632591196067604100772673927915114267193389905003276673749012051148356041324"),
20+
Gy: bigFromDec("12"),
2121
BitSize: 521,
2222
}
2323
}
2424

25-
func bigFromHex(s string) (i *big.Int) {
25+
func bigFromDec(s string) (i *big.Int) {
2626
i = new(big.Int)
27-
i.SetString(s, 16)
27+
i.SetString(s, 10)
2828

2929
return
3030
}

elliptic/ed521/ed521_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,21 @@ func Test_MarshalCompressed(t *testing.T) {
144144
cryptobin_test.Equal(t, a1, x)
145145
cryptobin_test.Equal(t, b1, y)
146146
}
147+
148+
func Test_MarshalPoint(t *testing.T) {
149+
a1 := bigintFromHex("135e8ba63870ade80365ee6b6832d971a83c8519310bed795809637bd61e4d54676d0823d7a95d26291be2742994d833b16d306dcea0574b57924aac6b62552ef81")
150+
b1 := bigintFromHex("d6e622c17fb2723b47ef82f0a704694689c96c5cc12f24b42a735b89283c6bd47fe0596dff8841603414b8b3a5c681d72750e03a807f6668a008738876e2f1fcde")
151+
152+
m := MarshalPoint(ED521(), a1, b1)
153+
154+
m2 := fmt.Sprintf("%x", m)
155+
mcheck := "defcf1e276887308a068667f803ae05027d781c6a5b3b81434604188ff6d59e07fd46b3c28895b732ab4242fc15c6cc989466904a7f082ef473b72b27fc122e6d680"
156+
157+
cryptobin_test.Equal(t, mcheck, m2)
158+
159+
mcheck2 := bigintFromHex(mcheck).Bytes()
160+
161+
x, y := UnmarshalPoint(ED521(), mcheck2)
162+
cryptobin_test.Equal(t, a1, x)
163+
cryptobin_test.Equal(t, b1, y)
164+
}

elliptic/ed521/params.go

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,42 @@ func (curve *Ed521Curve) UnmarshalCompressed(data []byte) (x, y *big.Int) {
252252
return
253253
}
254254

255+
func (curve *Ed521Curve) UnmarshalPoint(data []byte) (x, y *big.Int) {
256+
byteLen := (curve.BitSize + 7) / 8
257+
if len(data) != byteLen {
258+
return
259+
}
260+
261+
size := len(data)
262+
eP := make([]byte, size)
263+
copy(eP, data)
264+
265+
sign := eP[size-1] & 0x80
266+
eP[size - 1] &= 0x7F // got 0x7F = ~0x80
267+
268+
eP = Reverse(eP)
269+
270+
p := curve.Params().P
271+
y = new(big.Int).SetBytes(eP)
272+
if y.Cmp(p) >= 0 {
273+
return
274+
}
275+
276+
// x² = (y² - 1) / (dy² - 1)
277+
x = curve.polynomial(y)
278+
x = x.ModSqrt(x, curve.P)
279+
if x == nil {
280+
return
281+
}
282+
283+
if byte(sign) != data[0]&1 {
284+
x.Sub(p, x)
285+
x.Mod(x, p)
286+
}
287+
288+
return
289+
}
290+
255291
func Marshal(curve elliptic.Curve, x, y *big.Int) []byte {
256292
panicIfNotOnCurve(curve, x, y)
257293

@@ -295,6 +331,34 @@ func UnmarshalCompressed(curve elliptic.Curve, data []byte) (*big.Int, *big.Int)
295331
return nil, nil
296332
}
297333

334+
func MarshalPoint(curve elliptic.Curve, x, y *big.Int) []byte {
335+
panicIfNotOnCurve(curve, x, y)
336+
337+
byteLen := (curve.Params().BitSize + 7) / 8
338+
339+
compressed := make([]byte, byteLen)
340+
y.FillBytes(compressed)
341+
342+
compressed = Reverse(compressed)
343+
344+
one := big.NewInt(1)
345+
346+
xx := new(big.Int).Set(x)
347+
if xx.And(xx, one).Cmp(one) == 0 {
348+
compressed[byteLen-1] |= 0x80
349+
}
350+
351+
return compressed
352+
}
353+
354+
func UnmarshalPoint(curve elliptic.Curve, data []byte) (*big.Int, *big.Int) {
355+
if c, ok := curve.(*Ed521Curve); ok {
356+
return c.UnmarshalPoint(data)
357+
}
358+
359+
return nil, nil
360+
}
361+
298362
func panicIfNotOnCurve(curve elliptic.Curve, x, y *big.Int) {
299363
// (0, 0) is the point at infinity by convention. It's ok to operate on it,
300364
// although IsOnCurve is documented to return false for it. See Issue 37294.

pubkey/ed521/ed521.go

Lines changed: 45 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -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
)
@@ -27,6 +25,12 @@ var (
2725
const (
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
182186
func 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.
335357
func 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-
408409
func randFieldElement(rand io.Reader, curve elliptic.Curve) (*big.Int, error) {
409410
N := curve.Params().N
410411

pubkey/ed521/ed521_test.go

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"fmt"
55
"bytes"
66
"testing"
7-
"math/big"
87
"crypto"
98
"crypto/rand"
109
"crypto/elliptic"
@@ -230,13 +229,7 @@ func Test_SignVerify_fail(t *testing.T) {
230229
t.Fatal(err)
231230
}
232231

233-
R, S, _ := parseSignature(sig)
234-
R.Add(R, big.NewInt(1))
235-
236-
sig, err = encodeSignature(R, S)
237-
if err != nil {
238-
t.Fatal(err)
239-
}
232+
sig[len(sig)-6] = sig[len(sig)-6] + 1
240233

241234
res, _ := Verify(pub, data, sig)
242235
cryptobin_test.False(t, res)
@@ -344,7 +337,7 @@ var testSigVec = []testVec{
344337
secretKey: fromHex("313e78bd2f5eb3f0a9ee0120496cb3c891a3d4f79d1b8c01f81cd7d70bcadefbb941a3058dabe6b5dbe559b6f5331cc0087af6a367d47555d5cb95a8dacea4d167"),
345338
publicKey: fromHex("03015c5b1c1dbdb4e81225cfd8bbfa14b01148b3d3741e9dc0d16c4d40ac8d72eb6752a9015c6aa5c87239491d1d49f292b67a78987283f430af271572e030f9d7f862"),
346339
message: fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
347-
signature: fromHex("3081870242018c284f975122ffb3cb1097b316bbd03f9e03c295d1344b08dc20bba159e7acc28a0048b222a4a39cdd8139ececa2ac7122c4fa8d234a90c4a3cb7f0dff87379d33024128cbc3c194aa653bd038e8a43ec4c9cd8ca293377596dc29c3c6105c5e0bc86cbc6e11949b8ab8ed9b7e65cd2780baaf098e57c73ef2b6ae85e970cd8795c573f8"),
340+
signature: fromHex("a6659ed7213f736f46c10c983329523cf246fd0126406bd533783f80b33893b52c899c37e5f8012b378214b983fad7cde1b1d528977a4892cb8abc4872a59d18c500782fdeafb0c93ea7a4f8b16028df15ff05644ede3698ca88c1602ede83c68342aaa013cec1ea2e8d65d4bed0764f8b42e9548a2e41d49786aa0ad2ed782d6c353200"),
348341
verification: true,
349342
},
350343

@@ -353,7 +346,7 @@ var testSigVec = []testVec{
353346
secretKey: fromHex("22713dc2f3d8a4611e9266d8a2a9e3d237505dc34c65d87d598b9a4e6c41b35e3d090458e66c8213a4af011e5614377960c99d9f84e379fdd1f1e168b163b5d930"),
354347
publicKey: fromHex("0300d4a01d6c5cd88d226e33ab966991d6939c72d7012f209a7fc7006d0b9f93df99e8ab5543cb5d27a2818f27cad1648bfecdd49e7772ded70ee7043444a518683019"),
355348
message: fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
356-
signature: fromHex("3081870242018c284f975122ffb3cb1097b316bbd03f9e03c295d1344b08dc20bba159e7acc28a0048b222a4a39cdd8139ececa2ac7122c4fa8d234a90c4a3cb7f0dff87379d33024128cbc3c194aa653bd038e8a43ec4c9cd8ca293377596dc29c3c6105c5e0bc86cbc6e11949b8ab8ed9b7e65cd2780baaf098e57c73ef2b6ae85e970cd8795c573f8"),
349+
signature: fromHex("a6659ed7213f736f46c10c983329523cf246fd0126406bd533783f80b33893b52c899c37e5f8012b378214b983fad7cde1b1d528977a4892cb8abc4872a59d18c500782fdeafb0c93ea7a4f8b16028df15ff05644ede3698ca88c1602ede83c68342aaa013cec1ea2e8d65d4bed0764f8b42e9548a2e41d49786aa0ad2ed782d6c353200"),
357350
verification: false,
358351
},
359352
}

pubkey/ed521/pkcs8_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ func Test_MarshalPKCS8(t *testing.T) {
4242
}
4343

4444
var privPEM = `-----BEGIN PRIVATE KEY-----
45-
MFYCAQAwDgYKKwYBBAGC3CwCAQYABEFn+ELryWPBgSXqTFTDWjkuJWzLBl88Muvr
46-
1+xy/LIGwSO2090Eo8LkEV57zYuG0Jjh81ZAuyNaqQ8tma1Wolq/JQ==
45+
MFcCAQAwDgYKKwYBBAGC3CwCAQYABEIAZ/hC68ljwYEl6kxUw1o5LiVsywZfPDLr
46+
69fscvyyBsEjttPdBKPC5BFee82LhtCY4fNWQLsjWqkPLZmtVqJavyU=
4747
-----END PRIVATE KEY-----
4848
`
4949

0 commit comments

Comments
 (0)