Skip to content

Commit b2f1196

Browse files
committed
fixed
1 parent 6c87785 commit b2f1196

File tree

5 files changed

+132
-59
lines changed

5 files changed

+132
-59
lines changed

elliptic/ed521/params.go

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import (
55
"crypto/elliptic"
66
)
77

8+
var one = big.NewInt(1)
9+
810
// Ed521 curve
911
type Ed521Curve struct {
1012
Name string
@@ -280,7 +282,12 @@ func (curve *Ed521Curve) UnmarshalPoint(data []byte) (x, y *big.Int) {
280282
return
281283
}
282284

283-
if byte(sign) != data[0]&1 {
285+
if sign > 0 {
286+
sign = 1
287+
}
288+
289+
xx := new(big.Int).Set(x)
290+
if xx.And(xx, one).Cmp(big.NewInt(int64(sign))) != 0 {
284291
x.Sub(p, x)
285292
x.Mod(x, p)
286293
}
@@ -341,11 +348,9 @@ func MarshalPoint(curve elliptic.Curve, x, y *big.Int) []byte {
341348

342349
compressed = Reverse(compressed)
343350

344-
one := big.NewInt(1)
345-
346351
xx := new(big.Int).Set(x)
347352
if xx.And(xx, one).Cmp(one) == 0 {
348-
compressed[byteLen-1] |= 0x80
353+
compressed[len(compressed)-1] |= 0x80
349354
}
350355

351356
return compressed
@@ -371,6 +376,24 @@ func panicIfNotOnCurve(curve elliptic.Curve, x, y *big.Int) {
371376
}
372377
}
373378

379+
func GetPrivateScalar(buffer []byte) []byte {
380+
a := pruningBuffer(buffer)
381+
s := Reverse(a)
382+
383+
return s
384+
}
385+
386+
func pruningBuffer(b []byte) []byte {
387+
buffer := make([]byte, len(b))
388+
copy(buffer, b)
389+
390+
buffer[0] &= 0xFC
391+
buffer[len(buffer) - 1] = 0
392+
buffer[len(buffer) - 2] |= 0x80
393+
394+
return buffer
395+
}
396+
374397
// Reverse bytes
375398
func Reverse(b []byte) []byte {
376399
d := make([]byte, len(b))

pubkey/ed448/ed448_test.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@ package ed448
22

33
import (
44
"bytes"
5+
"testing"
56
"crypto"
67
"crypto/rand"
78
"encoding/hex"
8-
"testing"
9+
10+
cryptobin_test "github.com/deatil/go-cryptobin/tool/test"
911
)
1012

1113
type zeroReader struct{}
@@ -17,6 +19,11 @@ func (zeroReader) Read(buf []byte) (int, error) {
1719
return len(buf), nil
1820
}
1921

22+
func fromHex(s string) []byte {
23+
h, _ := hex.DecodeString(s)
24+
return h
25+
}
26+
2027
func decodeHex(t testing.TB, s string) []byte {
2128
t.Helper()
2229
data, err := hex.DecodeString(s)
@@ -326,6 +333,21 @@ func TestEqual(t *testing.T) {
326333
}
327334
}
328335

336+
var privBytes = "c4eab05d357007c632f3dbb48489924d552b08fe0c353a0d4a1f00acda2c463afbea67c5e8d2877c5e3bc397a659949ef8021e954e0a12274e"
337+
var pubBytes = "43ba28f430cdff456ae531545f7ecd0ac834a55d9358c0372bfa0c6c6798c0866aea01eb00742802b8438ea4cb82169c235160627b4c3a9480"
338+
339+
func Test_Key(t *testing.T) {
340+
privPlain := fromHex(privBytes)
341+
pubPlain := fromHex(pubBytes)
342+
343+
priv := NewKeyFromSeed(privPlain)
344+
pub0 := priv.Public()
345+
346+
pub1 := PublicKey(pubPlain)
347+
348+
cryptobin_test.Equal(t, pub0, pub1)
349+
}
350+
329351
func TestVerify(t *testing.T) {
330352
public, private, _ := GenerateKey(rand.Reader)
331353

pubkey/ed521/ed521.go

Lines changed: 48 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const (
2626
// ContextMaxSize is the maximum length (in bytes) allowed for context.
2727
ContextMaxSize = 255
2828
// PublicKeySize is the size, in bytes, of public keys as used in this package.
29-
PublicKeySize = 133
29+
PublicKeySize = 66
3030
// PrivateKeySize is the size, in bytes, of private keys as used in this package.
3131
PrivateKeySize = 66
3232
// SignatureSize is the size, in bytes, of signatures generated and verified by this package.
@@ -107,6 +107,11 @@ func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool {
107107
bigIntEqual(priv.D, xx.D)
108108
}
109109

110+
func (priv *PrivateKey) Seed() []byte {
111+
seed := make([]byte, SeedSize)
112+
return priv.D.FillBytes(seed)
113+
}
114+
110115
// Sign creates a signature for message
111116
func (priv *PrivateKey) Sign(rand io.Reader, message []byte, opts crypto.SignerOpts) ([]byte, error) {
112117
var context string
@@ -149,34 +154,37 @@ func GenerateKey(rand io.Reader) (*PrivateKey, error) {
149154
return nil, err
150155
}
151156

152-
return newKeyFromSeed(k.Bytes())
157+
bytes := make([]byte, SeedSize)
158+
return newKeyFromSeed(k.FillBytes(bytes))
153159
}
154160

155161
func newKeyFromSeed(seed []byte) (*PrivateKey, error) {
156-
if l := len(seed); l > SeedSize {
162+
if l := len(seed); l != SeedSize {
157163
panic("go-cryptobin/ed521: bad seed length: " + strconv.Itoa(l))
158164
}
159165

160166
curve := ed521.ED521()
161167

162-
k := new(big.Int).SetBytes(seed)
168+
h := make([]byte, 132)
169+
sha3.ShakeSum256(h, seed)
163170

164-
n := new(big.Int).Sub(curve.Params().N, one)
165-
if k.Cmp(n) >= 0 {
166-
return nil, errors.New("go-cryptobin/ed521: privateKey's seed is overflow")
167-
}
171+
k := new(big.Int).SetBytes(seed)
168172

169-
h := make([]byte, 132)
170-
sha3.ShakeSum256(h, k.Bytes())
173+
scalar := ed521.GetPrivateScalar(h[:66])
171174

172175
priv := new(PrivateKey)
173176
priv.PublicKey.Curve = curve
174177
priv.D = k
175-
priv.PublicKey.X, priv.PublicKey.Y = curve.ScalarBaseMult(h[:66])
178+
priv.PublicKey.X, priv.PublicKey.Y = curve.ScalarBaseMult(scalar)
176179

177180
return priv, nil
178181
}
179182

183+
// New a private key from seed bytes
184+
func NewKeyFromSeed(seed []byte) (*PrivateKey, error) {
185+
return newKeyFromSeed(seed)
186+
}
187+
180188
// New a private key from key data bytes
181189
func NewPrivateKey(d []byte) (*PrivateKey, error) {
182190
return newKeyFromSeed(d)
@@ -192,7 +200,7 @@ func PrivateKeyTo(key *PrivateKey) []byte {
192200
func NewPublicKey(data []byte) (*PublicKey, error) {
193201
curve := ed521.ED521()
194202

195-
x, y := elliptic.Unmarshal(curve, data)
203+
x, y := ed521.UnmarshalPoint(curve, data)
196204
if x == nil || y == nil {
197205
return nil, errors.New("go-cryptobin/ed521: incorrect public key")
198206
}
@@ -208,7 +216,7 @@ func NewPublicKey(data []byte) (*PublicKey, error) {
208216

209217
// return PublicKey data
210218
func PublicKeyTo(key *PublicKey) []byte {
211-
return ed521.Marshal(key.Curve, key.X, key.Y)
219+
return ed521.MarshalPoint(key.Curve, key.X, key.Y)
212220
}
213221

214222
// sign data and return marshal plain data
@@ -253,15 +261,14 @@ func sign(privateKey *PrivateKey, message []byte, domPre, context string) ([]byt
253261
n := params.N
254262
byteLen := (params.BitSize + 7) / 8
255263

256-
var tmpBuf []byte
257-
258-
seed := privateKey.D.Bytes()
264+
seed := privateKey.Seed()
259265
publicKeyBytes := ed521.MarshalPoint(privateKey.Curve, privateKey.X, privateKey.Y)
260266

261267
h := make([]byte, 132)
262268
sha3.ShakeSum256(h, seed)
263269

264-
s := new(big.Int).SetBytes(h[:66])
270+
scalar := ed521.GetPrivateScalar(h[:66])
271+
s := new(big.Int).SetBytes(scalar)
265272
s.Mod(s, n)
266273

267274
prefix := h[66:]
@@ -280,19 +287,14 @@ func sign(privateKey *PrivateKey, message []byte, domPre, context string) ([]byt
280287
r := new(big.Int).SetBytes(messageDigest)
281288
r.Mod(r, n)
282289

283-
_, R := privateKey.Curve.ScalarBaseMult(r.Bytes())
284-
285-
buf := make([]byte, 2*byteLen)
286-
R.FillBytes(buf[:byteLen])
287-
288-
tmpBuf = ed521.Reverse(buf[:byteLen])
289-
copy(buf[:byteLen], tmpBuf)
290+
Rx, Ry := privateKey.Curve.ScalarBaseMult(r.Bytes())
291+
R := ed521.MarshalPoint(privateKey.Curve, Rx, Ry)
290292

291293
kh := sha3.NewShake256()
292294
kh.Write([]byte(domPre))
293295
kh.Write([]byte{byte(len(context))})
294296
kh.Write([]byte(context))
295-
kh.Write(buf[:byteLen])
297+
kh.Write(R)
296298
kh.Write(publicKeyBytes)
297299
kh.Write(PHM)
298300
hramDigest := make([]byte, 132)
@@ -308,11 +310,13 @@ func sign(privateKey *PrivateKey, message []byte, domPre, context string) ([]byt
308310
S.Add(S, r)
309311
S.Mod(S, n)
310312

311-
S.FillBytes(buf[byteLen:])
312-
tmpBuf = ed521.Reverse(buf[byteLen:])
313-
copy(buf[byteLen:], tmpBuf)
313+
SBytes := ed521.Reverse(S.FillBytes(make([]byte, byteLen)))
314314

315-
return buf, nil
315+
sig := make([]byte, 2*byteLen)
316+
copy(sig[:byteLen], R)
317+
copy(sig[byteLen:], SBytes)
318+
319+
return sig, nil
316320
}
317321

318322
// VerifyWithOptions reports whether sig is a valid signature of message by
@@ -374,10 +378,14 @@ func verify(publicKey *PublicKey, message, sig []byte, domPre, context string) b
374378
return false
375379
}
376380

377-
RBytes := ed521.Reverse(sig[:byteLen])
378-
SBytes := ed521.Reverse(sig[byteLen:])
381+
R := sig[:byteLen]
379382

380-
R := new(big.Int).SetBytes(RBytes)
383+
Rx, Ry := ed521.UnmarshalPoint(curve, R)
384+
if Rx == nil && Ry == nil {
385+
return false
386+
}
387+
388+
SBytes := ed521.Reverse(sig[byteLen:])
381389
S := new(big.Int).SetBytes(SBytes)
382390

383391
publicKeyBytes := ed521.MarshalPoint(publicKey.Curve, publicKey.X, publicKey.Y)
@@ -386,7 +394,7 @@ func verify(publicKey *PublicKey, message, sig []byte, domPre, context string) b
386394
kh.Write([]byte(domPre))
387395
kh.Write([]byte{byte(len(context))})
388396
kh.Write([]byte(context))
389-
kh.Write(sig[:byteLen])
397+
kh.Write(R)
390398
kh.Write(publicKeyBytes)
391399
kh.Write(PHM)
392400
hramDigest := make([]byte, 132)
@@ -401,26 +409,26 @@ func verify(publicKey *PublicKey, message, sig []byte, domPre, context string) b
401409
// r = S - k * pub
402410
x21, y21 := curve.ScalarMult(publicKey.X, publicKey.Y, k.Bytes())
403411
x22, y22 := curve.ScalarBaseMult(S.Bytes())
404-
_, y2 := curve.Add(x21, y21, x22, y22)
412+
y1, y2 := curve.Add(x21, y21, x22, y22)
405413

406-
return bigIntEqual(R, y2)
414+
return bigIntEqual(Rx, y1) &&
415+
bigIntEqual(Ry, y2)
407416
}
408417

409418
func randFieldElement(rand io.Reader, curve elliptic.Curve) (*big.Int, error) {
410419
N := curve.Params().N
411420

412-
byteLen := (N.BitLen() + 7) / 8
413-
bytes := make([]byte, byteLen)
421+
bytes := make([]byte, SeedSize)
414422

415423
for {
416424
_, err := io.ReadFull(rand, bytes)
417425
if err != nil {
418426
return nil, err
419427
}
420428

421-
num := new(big.Int).SetBytes(bytes)
422-
if num.Cmp(N) < 0 {
423-
return num, nil
429+
k := new(big.Int).SetBytes(bytes)
430+
if k.Cmp(N) < 0 {
431+
return k, nil
424432
}
425433
}
426434
}

pubkey/ed521/ed521_test.go

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func Test_NewPrivateKey(t *testing.T) {
8484
}
8585
}
8686

87-
func aTest_Public(t *testing.T) {
87+
func Test_Public(t *testing.T) {
8888
priv, err := GenerateKey(rand.Reader)
8989
if err != nil {
9090
t.Fatal(err)
@@ -271,6 +271,28 @@ func Test_Marshal(t *testing.T) {
271271
cryptobin_test.Equal(t, pub, pub3)
272272
}
273273

274+
var privBytes = "2367b29bceaca04d6fe50d959dee3d706f3a5f605ce5aac0205c54cdda59145c573b932814c7405770cd46171a0eb44c911f8e851adeefcc77e5841bf86e0b6486dd"
275+
var pubBytes = "72c86f2d561e5d3db6e350a92b0287a2434207b3869cd013ccbf1034c82b647b7548bc927975da76e750c991a443a11d23a264888b36c73e6a48a2602f777d3ff081"
276+
277+
func Test_Key(t *testing.T) {
278+
privPlain := fromHex(privBytes)
279+
pubPlain := fromHex(pubBytes)
280+
281+
priv, err := NewKeyFromSeed(privPlain)
282+
if err != nil {
283+
t.Fatal(err)
284+
}
285+
286+
pub0 := &priv.PublicKey
287+
288+
pub1, err := NewPublicKey(pubPlain)
289+
if err != nil {
290+
t.Fatal(err)
291+
}
292+
293+
cryptobin_test.Equal(t, pub0, pub1)
294+
}
295+
274296
func Test_Vec_Check(t *testing.T) {
275297
for i, td := range testSigVec {
276298
t.Run(fmt.Sprintf("index %d", i), func(t *testing.T) {
@@ -316,7 +338,7 @@ func Test_Vec_Check(t *testing.T) {
316338

317339
veri := pubkey.Verify(td.message, td.signature)
318340
if veri != td.verification {
319-
t.Error("VerifyASN1 fail")
341+
t.Error("Verify fail")
320342
}
321343

322344
})
@@ -334,19 +356,19 @@ type testVec struct {
334356

335357
var testSigVec = []testVec{
336358
{
337-
secretKey: fromHex("313e78bd2f5eb3f0a9ee0120496cb3c891a3d4f79d1b8c01f81cd7d70bcadefbb941a3058dabe6b5dbe559b6f5331cc0087af6a367d47555d5cb95a8dacea4d167"),
338-
publicKey: fromHex("03015c5b1c1dbdb4e81225cfd8bbfa14b01148b3d3741e9dc0d16c4d40ac8d72eb6752a9015c6aa5c87239491d1d49f292b67a78987283f430af271572e030f9d7f862"),
359+
secretKey: fromHex("22713dc2f3d8a4611e9266d8a2a9e3d237505dc34c65d87d598b9a4e6c41b35e3d090458e66c8213a4af011e5614377960c99d9f84e379fdd1f1e168b163b5d93012"),
360+
publicKey: fromHex("020006be6a2ea17441c94e25799154b049ebae2fedcedfb27355ab03f9eb802d239677c340392fe113ffb18138b95dc8ba3efd766401cabfc4cc30d0ccdce7b178d954"),
339361
message: fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
340-
signature: fromHex("a6659ed7213f736f46c10c983329523cf246fd0126406bd533783f80b33893b52c899c37e5f8012b378214b983fad7cde1b1d528977a4892cb8abc4872a59d18c500782fdeafb0c93ea7a4f8b16028df15ff05644ede3698ca88c1602ede83c68342aaa013cec1ea2e8d65d4bed0764f8b42e9548a2e41d49786aa0ad2ed782d6c353200"),
362+
signature: fromHex("e6309d7d752de236179d694954f9345a73b1abcbe7ebde16e5e0fa1a4ed60003839a13f03fe1fccfecdac66614b8aff731e7956678be247b8f19795b20351a578301780dd7e6d41db086ef9bdc4658cbcc3d86d259b7e36ea399b075da86f2559489c64f59d196c5a439b3c5442609912dee28721d82dd08c71884b7f406961510110e00"),
341363
verification: true,
342364
},
343365

344366
// fail
345367
{
346-
secretKey: fromHex("22713dc2f3d8a4611e9266d8a2a9e3d237505dc34c65d87d598b9a4e6c41b35e3d090458e66c8213a4af011e5614377960c99d9f84e379fdd1f1e168b163b5d930"),
347-
publicKey: fromHex("0300d4a01d6c5cd88d226e33ab966991d6939c72d7012f209a7fc7006d0b9f93df99e8ab5543cb5d27a2818f27cad1648bfecdd49e7772ded70ee7043444a518683019"),
368+
secretKey: fromHex("22713dc2f3d8a4611e9266d8a2a9e3d237505dc34c65d87d598b9a4e6c41b35e3d090458e66c8213a4af011e5614377960c99d9f84e379fdd1f1e168b163b5d93012"),
369+
publicKey: fromHex("020006be6a2ea17441c94e25799154b049ebae2fedcedfb27355ab03f9eb802d239677c340392fe113ffb18138b95dc8ba3efd766401cabfc4cc30d0ccdce7b178d954"),
348370
message: fromHex("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"),
349-
signature: fromHex("a6659ed7213f736f46c10c983329523cf246fd0126406bd533783f80b33893b52c899c37e5f8012b378214b983fad7cde1b1d528977a4892cb8abc4872a59d18c500782fdeafb0c93ea7a4f8b16028df15ff05644ede3698ca88c1602ede83c68342aaa013cec1ea2e8d65d4bed0764f8b42e9548a2e41d49786aa0ad2ed782d6c353200"),
371+
signature: fromHex("3bd0454bd7a48f25fa40e0ebd76c1eb48e7fff63f606f35f9a8de9fc6d8fde0f75c10c0d97b7dc3001c5da6da681ff95d1a6ace65c19134ca727b99b1c349752ee01e8c9d1f325ab430511bcbf1e009d37418f56f132383ed55e43d97c04feff5a6f875fa64458ab73f9e4d1ad93cc978a7939a9afe532e8e6162b7bcb986f04a2282a00"),
350372
verification: false,
351373
},
352374
}

0 commit comments

Comments
 (0)