Skip to content

Commit 513114d

Browse files
authored
Merge pull request #398 from XinFinOrg/XDC-01
XDC-01 | Potential Missed Fixings in `crypto` Module
2 parents ddac0a6 + d4b9806 commit 513114d

File tree

10 files changed

+102
-88
lines changed

10 files changed

+102
-88
lines changed

crypto/bn256/bn256_fuzz.go

Lines changed: 52 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -20,42 +20,52 @@ package bn256
2020

2121
import (
2222
"bytes"
23+
"fmt"
24+
"io"
2325
"math/big"
2426

2527
cloudflare "github.com/XinFinOrg/XDPoSChain/crypto/bn256/cloudflare"
2628
google "github.com/XinFinOrg/XDPoSChain/crypto/bn256/google"
2729
)
2830

29-
// FuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries.
30-
func FuzzAdd(data []byte) int {
31-
// Ensure we have enough data in the first place
32-
if len(data) != 128 {
33-
return 0
31+
func getG1Points(input io.Reader) (*cloudflare.G1, *google.G1) {
32+
_, xc, err := cloudflare.RandomG1(input)
33+
if err != nil {
34+
// insufficient input
35+
return nil, nil
3436
}
35-
// Ensure both libs can parse the first curve point
36-
xc := new(cloudflare.G1)
37-
_, errc := xc.Unmarshal(data[:64])
38-
3937
xg := new(google.G1)
40-
_, errg := xg.Unmarshal(data[:64])
41-
42-
if (errc == nil) != (errg == nil) {
43-
panic("parse mismatch")
44-
} else if errc != nil {
45-
return 0
38+
if _, err := xg.Unmarshal(xc.Marshal()); err != nil {
39+
panic(fmt.Sprintf("Could not marshal cloudflare -> google:", err))
4640
}
47-
// Ensure both libs can parse the second curve point
48-
yc := new(cloudflare.G1)
49-
_, errc = yc.Unmarshal(data[64:])
41+
return xc, xg
42+
}
5043

51-
yg := new(google.G1)
52-
_, errg = yg.Unmarshal(data[64:])
44+
func getG2Points(input io.Reader) (*cloudflare.G2, *google.G2) {
45+
_, xc, err := cloudflare.RandomG2(input)
46+
if err != nil {
47+
// insufficient input
48+
return nil, nil
49+
}
50+
xg := new(google.G2)
51+
if _, err := xg.Unmarshal(xc.Marshal()); err != nil {
52+
panic(fmt.Sprintf("Could not marshal cloudflare -> google:", err))
53+
}
54+
return xc, xg
55+
}
5356

54-
if (errc == nil) != (errg == nil) {
55-
panic("parse mismatch")
56-
} else if errc != nil {
57+
// FuzzAdd fuzzez bn256 addition between the Google and Cloudflare libraries.
58+
func FuzzAdd(data []byte) int {
59+
input := bytes.NewReader(data)
60+
xc, xg := getG1Points(input)
61+
if xc == nil {
5762
return 0
5863
}
64+
yc, yg := getG1Points(input)
65+
if yc == nil {
66+
return 0
67+
}
68+
// Ensure both libs can parse the second curve point
5969
// Add the two points and ensure they result in the same output
6070
rc := new(cloudflare.G1)
6171
rc.Add(xc, yc)
@@ -66,73 +76,50 @@ func FuzzAdd(data []byte) int {
6676
if !bytes.Equal(rc.Marshal(), rg.Marshal()) {
6777
panic("add mismatch")
6878
}
69-
return 0
79+
return 1
7080
}
7181

7282
// FuzzMul fuzzez bn256 scalar multiplication between the Google and Cloudflare
7383
// libraries.
7484
func FuzzMul(data []byte) int {
75-
// Ensure we have enough data in the first place
76-
if len(data) != 96 {
85+
input := bytes.NewReader(data)
86+
pc, pg := getG1Points(input)
87+
if pc == nil {
7788
return 0
7889
}
79-
// Ensure both libs can parse the curve point
80-
pc := new(cloudflare.G1)
81-
_, errc := pc.Unmarshal(data[:64])
82-
83-
pg := new(google.G1)
84-
_, errg := pg.Unmarshal(data[:64])
85-
86-
if (errc == nil) != (errg == nil) {
87-
panic("parse mismatch")
88-
} else if errc != nil {
90+
// Add the two points and ensure they result in the same output
91+
remaining := input.Len()
92+
if remaining == 0 {
8993
return 0
9094
}
91-
// Add the two points and ensure they result in the same output
95+
buf := make([]byte, remaining)
96+
input.Read(buf)
97+
9298
rc := new(cloudflare.G1)
93-
rc.ScalarMult(pc, new(big.Int).SetBytes(data[64:]))
99+
rc.ScalarMult(pc, new(big.Int).SetBytes(buf))
94100

95101
rg := new(google.G1)
96-
rg.ScalarMult(pg, new(big.Int).SetBytes(data[64:]))
102+
rg.ScalarMult(pg, new(big.Int).SetBytes(buf))
97103

98104
if !bytes.Equal(rc.Marshal(), rg.Marshal()) {
99105
panic("scalar mul mismatch")
100106
}
101-
return 0
107+
return 1
102108
}
103109

104110
func FuzzPair(data []byte) int {
105-
// Ensure we have enough data in the first place
106-
if len(data) != 192 {
111+
input := bytes.NewReader(data)
112+
pc, pg := getG1Points(input)
113+
if pc == nil {
107114
return 0
108115
}
109-
// Ensure both libs can parse the curve point
110-
pc := new(cloudflare.G1)
111-
_, errc := pc.Unmarshal(data[:64])
112-
113-
pg := new(google.G1)
114-
_, errg := pg.Unmarshal(data[:64])
115-
116-
if (errc == nil) != (errg == nil) {
117-
panic("parse mismatch")
118-
} else if errc != nil {
119-
return 0
120-
}
121-
// Ensure both libs can parse the twist point
122-
tc := new(cloudflare.G2)
123-
_, errc = tc.Unmarshal(data[64:])
124-
125-
tg := new(google.G2)
126-
_, errg = tg.Unmarshal(data[64:])
127-
128-
if (errc == nil) != (errg == nil) {
129-
panic("parse mismatch")
130-
} else if errc != nil {
116+
tc, tg := getG2Points(input)
117+
if tc == nil {
131118
return 0
132119
}
133120
// Pair the two points and ensure thet result in the same output
134121
if cloudflare.PairingCheck([]*cloudflare.G1{pc}, []*cloudflare.G2{tc}) != google.PairingCheck([]*google.G1{pg}, []*google.G2{tg}) {
135122
panic("pair mismatch")
136123
}
137-
return 0
124+
return 1
138125
}

crypto/bn256/cloudflare/bn256.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323
func randomK(r io.Reader) (k *big.Int, err error) {
2424
for {
2525
k, err = rand.Int(r, Order)
26-
if k.Sign() > 0 || err != nil {
26+
if err != nil || k.Sign() > 0 {
2727
return
2828
}
2929
}
@@ -100,6 +100,10 @@ func (e *G1) Marshal() []byte {
100100
// Each value is a 256-bit number.
101101
const numBytes = 256 / 8
102102

103+
if e.p == nil {
104+
e.p = &curvePoint{}
105+
}
106+
103107
e.p.MakeAffine()
104108
ret := make([]byte, numBytes*2)
105109
if e.p.IsInfinity() {
@@ -382,6 +386,11 @@ func (e *GT) Marshal() []byte {
382386
// Each value is a 256-bit number.
383387
const numBytes = 256 / 8
384388

389+
if e.p == nil {
390+
e.p = &gfP12{}
391+
e.p.SetOne()
392+
}
393+
385394
ret := make([]byte, numBytes*12)
386395
temp := &gfP{}
387396

crypto/bn256/cloudflare/bn256_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,19 @@ func TestTripartiteDiffieHellman(t *testing.T) {
9292
}
9393
}
9494

95+
func TestG2SelfAddition(t *testing.T) {
96+
s, _ := rand.Int(rand.Reader, Order)
97+
p := new(G2).ScalarBaseMult(s)
98+
99+
if !p.p.IsOnCurve() {
100+
t.Fatal("p isn't on curve")
101+
}
102+
m := p.Add(p, p).Marshal()
103+
if _, err := p.Unmarshal(m); err != nil {
104+
t.Fatalf("p.Add(p, p) ∉ G₂: %v", err)
105+
}
106+
}
107+
95108
func BenchmarkG1(b *testing.B) {
96109
x, _ := rand.Int(rand.Reader, Order)
97110
b.ResetTimer()

crypto/bn256/cloudflare/curve.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,15 +171,15 @@ func (c *curvePoint) Double(a *curvePoint) {
171171
gfpAdd(t, d, d)
172172
gfpSub(&c.x, f, t)
173173

174+
gfpMul(&c.z, &a.y, &a.z)
175+
gfpAdd(&c.z, &c.z, &c.z)
176+
174177
gfpAdd(t, C, C)
175178
gfpAdd(t2, t, t)
176179
gfpAdd(t, t2, t2)
177180
gfpSub(&c.y, d, &c.x)
178181
gfpMul(t2, e, &c.y)
179182
gfpSub(&c.y, t2, t)
180-
181-
gfpMul(t, &a.y, &a.z)
182-
gfpAdd(&c.z, t, t)
183183
}
184184

185185
func (c *curvePoint) Mul(a *curvePoint, scalar *big.Int) {

crypto/bn256/cloudflare/gfp.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ func (e *gfP) Marshal(out []byte) {
6161
func (e *gfP) Unmarshal(in []byte) error {
6262
// Unmarshal the bytes into little endian form
6363
for w := uint(0); w < 4; w++ {
64+
e[3-w] = 0
6465
for b := uint(0); b < 8; b++ {
6566
e[3-w] += uint64(in[8*w+b]) << (56 - 8*b)
6667
}

crypto/bn256/cloudflare/gfp_amd64.s

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ TEXT ·gfpNeg(SB),0,$0-16
4949
SBBQ 24(DI), R11
5050

5151
MOVQ $0, AX
52-
gfpCarry(R8,R9,R10,R11,AX, R12,R13,R14,R15,BX)
52+
gfpCarry(R8,R9,R10,R11,AX, R12,R13,R14,CX,BX)
5353

5454
MOVQ c+0(FP), DI
5555
storeBlock(R8,R9,R10,R11, 0(DI))
@@ -68,7 +68,7 @@ TEXT ·gfpAdd(SB),0,$0-24
6868
ADCQ 24(SI), R11
6969
ADCQ $0, R12
7070

71-
gfpCarry(R8,R9,R10,R11,R12, R13,R14,R15,AX,BX)
71+
gfpCarry(R8,R9,R10,R11,R12, R13,R14,CX,AX,BX)
7272

7373
MOVQ c+0(FP), DI
7474
storeBlock(R8,R9,R10,R11, 0(DI))
@@ -83,7 +83,7 @@ TEXT ·gfpSub(SB),0,$0-24
8383
MOVQ ·p2+0(SB), R12
8484
MOVQ ·p2+8(SB), R13
8585
MOVQ ·p2+16(SB), R14
86-
MOVQ ·p2+24(SB), R15
86+
MOVQ ·p2+24(SB), CX
8787
MOVQ $0, AX
8888

8989
SUBQ 0(SI), R8
@@ -94,12 +94,12 @@ TEXT ·gfpSub(SB),0,$0-24
9494
CMOVQCC AX, R12
9595
CMOVQCC AX, R13
9696
CMOVQCC AX, R14
97-
CMOVQCC AX, R15
97+
CMOVQCC AX, CX
9898

9999
ADDQ R12, R8
100100
ADCQ R13, R9
101101
ADCQ R14, R10
102-
ADCQ R15, R11
102+
ADCQ CX, R11
103103

104104
MOVQ c+0(FP), DI
105105
storeBlock(R8,R9,R10,R11, 0(DI))
@@ -115,7 +115,7 @@ TEXT ·gfpMul(SB),0,$160-24
115115

116116
mulBMI2(0(DI),8(DI),16(DI),24(DI), 0(SI))
117117
storeBlock( R8, R9,R10,R11, 0(SP))
118-
storeBlock(R12,R13,R14,R15, 32(SP))
118+
storeBlock(R12,R13,R14,CX, 32(SP))
119119
gfpReduceBMI2()
120120
JMP end
121121

@@ -125,6 +125,6 @@ nobmi2Mul:
125125

126126
end:
127127
MOVQ c+0(FP), DI
128-
storeBlock(R12,R13,R14,R15, 0(DI))
128+
storeBlock(R12,R13,R14,CX, 0(DI))
129129
RET
130130

crypto/bn256/cloudflare/mul_amd64.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@
165165
\
166166
\ // Add the 512-bit intermediate to m*N
167167
loadBlock(96+stack, R8,R9,R10,R11) \
168-
loadBlock(128+stack, R12,R13,R14,R15) \
168+
loadBlock(128+stack, R12,R13,R14,CX) \
169169
\
170170
MOVQ $0, AX \
171171
ADDQ 0+stack, R8 \
@@ -175,7 +175,7 @@
175175
ADCQ 32+stack, R12 \
176176
ADCQ 40+stack, R13 \
177177
ADCQ 48+stack, R14 \
178-
ADCQ 56+stack, R15 \
178+
ADCQ 56+stack, CX \
179179
ADCQ $0, AX \
180180
\
181-
gfpCarry(R12,R13,R14,R15,AX, R8,R9,R10,R11,BX)
181+
gfpCarry(R12,R13,R14,CX,AX, R8,R9,R10,R11,BX)

crypto/bn256/cloudflare/mul_bmi2_amd64.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
ADCQ $0, R14 \
3030
\
3131
MOVQ a2, DX \
32-
MOVQ $0, R15 \
32+
MOVQ $0, CX \
3333
MULXQ 0+rb, AX, BX \
3434
ADDQ AX, R10 \
3535
ADCQ BX, R11 \
@@ -43,7 +43,7 @@
4343
MULXQ 24+rb, AX, BX \
4444
ADCQ AX, R13 \
4545
ADCQ BX, R14 \
46-
ADCQ $0, R15 \
46+
ADCQ $0, CX \
4747
\
4848
MOVQ a3, DX \
4949
MULXQ 0+rb, AX, BX \
@@ -52,13 +52,13 @@
5252
MULXQ 16+rb, AX, BX \
5353
ADCQ AX, R13 \
5454
ADCQ BX, R14 \
55-
ADCQ $0, R15 \
55+
ADCQ $0, CX \
5656
MULXQ 8+rb, AX, BX \
5757
ADDQ AX, R12 \
5858
ADCQ BX, R13 \
5959
MULXQ 24+rb, AX, BX \
6060
ADCQ AX, R14 \
61-
ADCQ BX, R15
61+
ADCQ BX, CX
6262

6363
#define gfpReduceBMI2() \
6464
\ // m = (T * N') mod R, store m in R8:R9:R10:R11
@@ -106,7 +106,7 @@
106106
ADCQ 32(SP), R12 \
107107
ADCQ 40(SP), R13 \
108108
ADCQ 48(SP), R14 \
109-
ADCQ 56(SP), R15 \
109+
ADCQ 56(SP), CX \
110110
ADCQ $0, AX \
111111
\
112-
gfpCarry(R12,R13,R14,R15,AX, R8,R9,R10,R11,BX)
112+
gfpCarry(R12,R13,R14,CX,AX, R8,R9,R10,R11,BX)

crypto/bn256/cloudflare/twist.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,15 @@ func (c *twistPoint) Double(a *twistPoint) {
150150
t.Add(d, d)
151151
c.x.Sub(f, t)
152152

153+
c.z.Mul(&a.y, &a.z)
154+
c.z.Add(&c.z, &c.z)
155+
153156
t.Add(C, C)
154157
t2.Add(t, t)
155158
t.Add(t2, t2)
156159
c.y.Sub(d, &c.x)
157160
t2.Mul(e, &c.y)
158161
c.y.Sub(t2, t)
159-
160-
t.Mul(&a.y, &a.z)
161-
c.z.Add(t, t)
162162
}
163163

164164
func (c *twistPoint) Mul(a *twistPoint, scalar *big.Int) {

crypto/secp256k1/curve.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,10 @@ func (BitCurve *BitCurve) IsOnCurve(x, y *big.Int) bool {
9696
// affineFromJacobian reverses the Jacobian transform. See the comment at the
9797
// top of the file.
9898
func (BitCurve *BitCurve) affineFromJacobian(x, y, z *big.Int) (xOut, yOut *big.Int) {
99+
if z.Sign() == 0 {
100+
return new(big.Int), new(big.Int)
101+
}
102+
99103
zinv := new(big.Int).ModInverse(z, BitCurve.P)
100104
zinvsq := new(big.Int).Mul(zinv, zinv)
101105

0 commit comments

Comments
 (0)