Skip to content

Commit c266752

Browse files
authored
Merge pull request #4 from corestario/1-eth2-compatibility
1 eth2 compatibility
2 parents 159b9e4 + c6ac2f8 commit c266752

File tree

10 files changed

+1002
-25
lines changed

10 files changed

+1002
-25
lines changed

go.mod

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
module github.com/corestario/kyber
22

33
require (
4+
github.com/kilic/bls12-381 v0.0.0-20200820230200-6b2c19996391
45
github.com/stretchr/testify v1.3.0
56
go.dedis.ch/fixbuf v1.0.3
67
go.dedis.ch/protobuf v1.0.11
78
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b
8-
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e
9+
golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339
910
)
1011

1112
go 1.12

go.sum

+5
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,11 @@ github.com/corestario/kyber v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDT
33
github.com/corestario/kyber v3.0.9/go.mod h1:rhNjUUg6ahf8HEg5HUvVBYoWY4boAafX8tYxX+PS+qg=
44
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
55
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6+
github.com/kilic/bls12-381 v0.0.0-20200820230200-6b2c19996391 h1:51kHw7l/dUDdOdW06AlUGT5jnpj6nqQSILebcsikSjA=
7+
github.com/kilic/bls12-381 v0.0.0-20200820230200-6b2c19996391/go.mod h1:XXfR6YFCRSrkEXbNlIyDsgXVNJWVUV30m/ebkVy9n6s=
68
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
79
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
10+
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
811
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
912
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
1013
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
@@ -22,3 +25,5 @@ golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b h1:Elez2XeF2p9uyVj0yEUDqQ
2225
golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
2326
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e h1:3GIlrlVLfkoipSReOMNAgApI0ajnalyLa/EZHHca/XI=
2427
golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
28+
golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339 h1:zSqWKgm/o7HAnlAzBQ+aetp9fpuyytsXnKA8eiLHYQM=
29+
golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

pairing/bls12381/bls_groups_test.go

+316
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,316 @@
1+
package bls12381
2+
3+
import (
4+
"bytes"
5+
"crypto/cipher"
6+
"testing"
7+
8+
"github.com/corestario/kyber"
9+
"github.com/corestario/kyber/util/random"
10+
"github.com/stretchr/testify/require"
11+
)
12+
13+
// Code extracted from kyber/utils/test
14+
// TODO: expose API in forked drand/kyber
15+
// Apply a generic set of validation tests to a cryptographic Group,
16+
// using a given source of [pseudo-]randomness.
17+
//
18+
// Returns a log of the pseudorandom Points produced in the test,
19+
// for comparison across alternative implementations
20+
// that are supposed to be equivalent.
21+
func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point {
22+
t.Logf("\nTesting group '%s': %d-byte Point, %d-byte Scalar\n",
23+
g.String(), g.PointLen(), g.ScalarLen())
24+
25+
points := make([]kyber.Point, 0)
26+
ptmp := g.Point()
27+
stmp := g.Scalar()
28+
pzero := g.Point().Null()
29+
szero := g.Scalar().Zero()
30+
sone := g.Scalar().One()
31+
32+
// Do a simple Diffie-Hellman test
33+
s1 := g.Scalar().Pick(rand)
34+
s2 := g.Scalar().Pick(rand)
35+
if s1.Equal(szero) {
36+
t.Fatalf("first secret is scalar zero %v", s1)
37+
}
38+
if s2.Equal(szero) {
39+
t.Fatalf("second secret is scalar zero %v", s2)
40+
}
41+
if s1.Equal(s2) {
42+
t.Fatalf("not getting unique secrets: picked %s twice", s1)
43+
}
44+
45+
gen := g.Point().Base()
46+
points = append(points, gen)
47+
48+
// Sanity-check relationship between addition and multiplication
49+
p1 := g.Point().Add(gen, gen)
50+
p2 := g.Point().Mul(stmp.SetInt64(2), nil)
51+
if !p1.Equal(p2) {
52+
t.Fatalf("multiply by two doesn't work: %v == %v (+) %[2]v != %[2]v (x) 2 == %v", p1, gen, p2)
53+
}
54+
p1.Add(p1, p1)
55+
p2.Mul(stmp.SetInt64(4), nil)
56+
if !p1.Equal(p2) {
57+
t.Fatalf("multiply by four doesn't work: %v (+) %[1]v != %v (x) 4 == %v",
58+
g.Point().Add(gen, gen), gen, p2)
59+
}
60+
points = append(points, p1)
61+
62+
// Find out if this curve has a prime order:
63+
// if the curve does not offer a method IsPrimeOrder,
64+
// then assume that it is.
65+
type canCheckPrimeOrder interface {
66+
IsPrimeOrder() bool
67+
}
68+
primeOrder := true
69+
if gpo, ok := g.(canCheckPrimeOrder); ok {
70+
primeOrder = gpo.IsPrimeOrder()
71+
}
72+
73+
// Verify additive and multiplicative identities of the generator.
74+
ptmp.Mul(stmp.SetInt64(-1), nil).Add(ptmp, gen)
75+
if !ptmp.Equal(pzero) {
76+
t.Fatalf("generator additive identity doesn't work: (scalar -1 %v) %v (x) -1 (+) %v = %v != %v the group point identity",
77+
stmp.SetInt64(-1), ptmp.Mul(stmp.SetInt64(-1), nil), gen, ptmp.Mul(stmp.SetInt64(-1), nil).Add(ptmp, gen), pzero)
78+
}
79+
// secret.Inv works only in prime-order groups
80+
if primeOrder {
81+
ptmp.Mul(stmp.SetInt64(2), nil).Mul(stmp.Inv(stmp), ptmp)
82+
if !ptmp.Equal(gen) {
83+
t.Fatalf("generator multiplicative identity doesn't work:\n%v (x) %v = %v\n%[3]v (x) %v = %v",
84+
ptmp.Base().String(), stmp.SetInt64(2).String(),
85+
ptmp.Mul(stmp.SetInt64(2), nil).String(),
86+
stmp.Inv(stmp).String(),
87+
ptmp.Mul(stmp.SetInt64(2), nil).Mul(stmp.Inv(stmp), ptmp).String())
88+
}
89+
}
90+
91+
p1.Mul(s1, gen)
92+
p2.Mul(s2, gen)
93+
if p1.Equal(p2) {
94+
t.Fatalf("encryption isn't producing unique points: %v (x) %v == %v (x) %[2]v == %[4]v", s1, gen, s2, p1)
95+
}
96+
points = append(points, p1)
97+
98+
dh1 := g.Point().Mul(s2, p1)
99+
dh2 := g.Point().Mul(s1, p2)
100+
if !dh1.Equal(dh2) {
101+
t.Fatalf("Diffie-Hellman didn't work: %v == %v (x) %v != %v (x) %v == %v", dh1, s2, p1, s1, p2, dh2)
102+
}
103+
points = append(points, dh1)
104+
105+
// Test secret inverse to get from dh1 back to p1
106+
if primeOrder {
107+
ptmp.Mul(g.Scalar().Inv(s2), dh1)
108+
if !ptmp.Equal(p1) {
109+
t.Fatalf("Scalar inverse didn't work: %v != (-)%v (x) %v == %v", p1, s2, dh1, ptmp)
110+
}
111+
}
112+
113+
// Zero and One identity secrets
114+
if !ptmp.Mul(szero, dh1).Equal(pzero) {
115+
t.Fatalf("Encryption with secret=0 didn't work: %v (x) %v == %v != %v", szero, dh1, ptmp, pzero)
116+
}
117+
if !ptmp.Mul(sone, dh1).Equal(dh1) {
118+
t.Fatalf("Encryption with secret=1 didn't work: %v (x) %v == %v != %[2]v", sone, dh1, ptmp)
119+
}
120+
121+
// Additive homomorphic identities
122+
ptmp.Add(p1, p2)
123+
stmp.Add(s1, s2)
124+
pt2 := g.Point().Mul(stmp, gen)
125+
if !pt2.Equal(ptmp) {
126+
t.Fatalf("Additive homomorphism doesn't work: %v + %v == %v, %[3]v (x) %v == %v != %v == %v (+) %v",
127+
s1, s2, stmp, gen, pt2, ptmp, p1, p2)
128+
}
129+
ptmp.Sub(p1, p2)
130+
stmp.Sub(s1, s2)
131+
pt2.Mul(stmp, gen)
132+
if !pt2.Equal(ptmp) {
133+
t.Fatalf("Additive homomorphism doesn't work: %v - %v == %v, %[3]v (x) %v == %v != %v == %v (-) %v",
134+
s1, s2, stmp, gen, pt2, ptmp, p1, p2)
135+
}
136+
st2 := g.Scalar().Neg(s2)
137+
st2.Add(s1, st2)
138+
if !stmp.Equal(st2) {
139+
t.Fatalf("Scalar.Neg doesn't work: -%v == %v, %[2]v + %v == %v != %v",
140+
s2, g.Scalar().Neg(s2), s1, st2, stmp)
141+
}
142+
pt2.Neg(p2).Add(pt2, p1)
143+
if !pt2.Equal(ptmp) {
144+
t.Fatalf("Point.Neg doesn't work: (-)%v == %v, %[2]v (+) %v == %v != %v",
145+
p2, g.Point().Neg(p2), p1, pt2, ptmp)
146+
}
147+
148+
// Multiplicative homomorphic identities
149+
stmp.Mul(s1, s2)
150+
if !ptmp.Mul(stmp, gen).Equal(dh1) {
151+
t.Fatalf("Multiplicative homomorphism doesn't work: %v * %v == %v, %[2]v (x) %v == %v != %v",
152+
s1, s2, stmp, gen, ptmp, dh1)
153+
}
154+
if primeOrder {
155+
st2.Inv(s2)
156+
st2.Mul(st2, stmp)
157+
if !st2.Equal(s1) {
158+
t.Fatalf("Scalar division doesn't work: %v^-1 * %v == %v * %[2]v == %[4]v != %v",
159+
s2, stmp, g.Scalar().Inv(s2), st2, s1)
160+
}
161+
st2.Div(stmp, s2)
162+
if !st2.Equal(s1) {
163+
t.Fatalf("Scalar division doesn't work: %v / %v == %v != %v",
164+
stmp, s2, st2, s1)
165+
}
166+
}
167+
168+
// Test randomly picked points
169+
last := gen
170+
for i := 0; i < 5; i++ {
171+
rgen := g.Point().Pick(rand)
172+
if rgen.Equal(last) {
173+
t.Fatalf("Pick() not producing unique points: got %v twice", rgen)
174+
}
175+
last = rgen
176+
177+
ptmp.Mul(stmp.SetInt64(-1), rgen).Add(ptmp, rgen)
178+
if !ptmp.Equal(pzero) {
179+
t.Fatalf("random generator fails additive identity: %v (x) %v == %v, %v (+) %[3]v == %[5]v != %v",
180+
g.Scalar().SetInt64(-1), rgen, g.Point().Mul(g.Scalar().SetInt64(-1), rgen),
181+
rgen, g.Point().Mul(g.Scalar().SetInt64(-1), rgen), pzero)
182+
}
183+
if primeOrder {
184+
ptmp.Mul(stmp.SetInt64(2), rgen).Mul(stmp.Inv(stmp), ptmp)
185+
if !ptmp.Equal(rgen) {
186+
t.Fatalf("random generator fails multiplicative identity: %v (x) (2 (x) %v) == %v != %[2]v",
187+
stmp, rgen, ptmp)
188+
}
189+
}
190+
points = append(points, rgen)
191+
}
192+
193+
// Test encoding and decoding
194+
buf := new(bytes.Buffer)
195+
for i := 0; i < 5; i++ {
196+
buf.Reset()
197+
s := g.Scalar().Pick(rand)
198+
if _, err := s.MarshalTo(buf); err != nil {
199+
t.Fatalf("encoding of secret fails: " + err.Error())
200+
}
201+
if _, err := stmp.UnmarshalFrom(buf); err != nil {
202+
t.Fatalf("decoding of secret fails: " + err.Error())
203+
}
204+
if !stmp.Equal(s) {
205+
t.Fatalf("decoding produces different secret than encoded")
206+
}
207+
208+
buf.Reset()
209+
p := g.Point().Pick(rand)
210+
if _, err := p.MarshalTo(buf); err != nil {
211+
t.Fatalf("encoding of point fails: " + err.Error())
212+
}
213+
if _, err := ptmp.UnmarshalFrom(buf); err != nil {
214+
t.Fatalf("decoding of point fails: " + err.Error())
215+
}
216+
217+
if !ptmp.Equal(p) {
218+
t.Fatalf("decoding produces different point than encoded")
219+
}
220+
}
221+
222+
// Test that we can marshal/ unmarshal null point
223+
pzero = g.Point().Null()
224+
b, _ := pzero.MarshalBinary()
225+
repzero := g.Point()
226+
err := repzero.UnmarshalBinary(b)
227+
if err != nil {
228+
t.Fatalf("Could not unmarshall binary %v: %v", b, err)
229+
}
230+
231+
return points
232+
}
233+
234+
// GroupTest applies a generic set of validation tests to a cryptographic Group.
235+
func GroupTest(t *testing.T, g kyber.Group) {
236+
testGroup(t, g, random.New())
237+
}
238+
239+
func TestKyberG1(t *testing.T) {
240+
GroupTest(t, NewGroupG1())
241+
}
242+
243+
func TestKyberG2(t *testing.T) {
244+
GroupTest(t, NewGroupG2())
245+
}
246+
247+
func TestKyberGT(t *testing.T) {
248+
GroupTest(t, NewGroupGT())
249+
}
250+
251+
func TestKyberPairingG2(t *testing.T) {
252+
s := NewBLS12381Suite().(*Suite)
253+
a := s.G1().Scalar().Pick(s.RandomStream())
254+
b := s.G2().Scalar().Pick(s.RandomStream())
255+
aG := s.G1().Point().Mul(a, nil)
256+
bH := s.G2().Point().Mul(b, nil)
257+
ab := s.G1().Scalar().Mul(a, b)
258+
abG := s.G1().Point().Mul(ab, nil)
259+
// e(aG, bG) = e(G,H)^(ab)
260+
p1 := s.Pair(aG, bH)
261+
// e((ab)G,H) = e(G,H)^(ab)
262+
p2 := s.Pair(abG, s.G2().Point().Base())
263+
require.True(t, p1.Equal(p2))
264+
require.True(t, s.ValidatePairing(aG, bH, abG.Clone(), s.G2().Point().Base()))
265+
266+
pRandom := s.Pair(aG, s.G2().Point().Pick(s.RandomStream()))
267+
require.False(t, p1.Equal(pRandom))
268+
pRandom = s.Pair(s.G1().Point().Pick(s.RandomStream()), bH)
269+
require.False(t, p1.Equal(pRandom))
270+
}
271+
272+
func BenchmarkPairingSeparate(bb *testing.B) {
273+
s := NewBLS12381Suite().(*Suite)
274+
a := s.G1().Scalar().Pick(s.RandomStream())
275+
b := s.G2().Scalar().Pick(s.RandomStream())
276+
aG := s.G1().Point().Mul(a, nil)
277+
bH := s.G2().Point().Mul(b, nil)
278+
ab := s.G1().Scalar().Mul(a, b)
279+
abG := s.G1().Point().Mul(ab, nil)
280+
bb.ResetTimer()
281+
for i := 0; i < bb.N; i++ {
282+
283+
// e(aG, bG) = e(G,H)^(ab)
284+
p1 := s.Pair(aG, bH)
285+
// e((ab)G,H) = e(G,H)^(ab)
286+
p2 := s.Pair(abG, s.G2().Point().Base())
287+
if !p1.Equal(p2) {
288+
panic("aie")
289+
}
290+
}
291+
}
292+
293+
func BenchmarkPairingInv(bb *testing.B) {
294+
s := NewBLS12381Suite().(*Suite)
295+
a := s.G1().Scalar().Pick(s.RandomStream())
296+
b := s.G2().Scalar().Pick(s.RandomStream())
297+
aG := s.G1().Point().Mul(a, nil)
298+
bH := s.G2().Point().Mul(b, nil)
299+
ab := s.G1().Scalar().Mul(a, b)
300+
abG := s.G1().Point().Mul(ab, nil)
301+
bb.ResetTimer()
302+
for i := 0; i < bb.N; i++ {
303+
if !s.ValidatePairing(aG, bH, abG.Clone(), s.G2().Point().Base()) {
304+
panic("aie")
305+
}
306+
}
307+
}
308+
309+
func TestIsValidGroup(t *testing.T) {
310+
suite := NewBLS12381Suite()
311+
p1 := suite.G1().Point().Pick(random.New())
312+
p2 := suite.G1().Point().Pick(random.New())
313+
314+
require.True(t, p1.(GroupChecker).IsInCorrectGroup())
315+
require.True(t, p2.(GroupChecker).IsInCorrectGroup())
316+
}

0 commit comments

Comments
 (0)