From 7bb17eb2ad3e357bc081174228fc044d183fa8b8 Mon Sep 17 00:00:00 2001 From: SK0M0R0H Date: Sat, 3 Oct 2020 01:29:31 +0200 Subject: [PATCH 1/7] add bls12-381 group --- go.mod | 3 +- go.sum | 4 + pairing/bls12381/bls_groups_test.go | 351 ++++++++++++++++++++++++++++ pairing/bls12381/group_g1.go | 141 +++++++++++ pairing/bls12381/group_g2.go | 151 ++++++++++++ pairing/bls12381/group_gt.go | 149 ++++++++++++ pairing/bls12381/scalar.go | 14 ++ pairing/bls12381/suite.go | 179 ++++++++++++++ 8 files changed, 991 insertions(+), 1 deletion(-) create mode 100644 pairing/bls12381/bls_groups_test.go create mode 100644 pairing/bls12381/group_g1.go create mode 100644 pairing/bls12381/group_g2.go create mode 100644 pairing/bls12381/group_gt.go create mode 100644 pairing/bls12381/scalar.go create mode 100644 pairing/bls12381/suite.go diff --git a/go.mod b/go.mod index 79dabbbf..b23df113 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,12 @@ module github.com/corestario/kyber require ( + github.com/kilic/bls12-381 v0.0.0-20200820230200-6b2c19996391 github.com/stretchr/testify v1.3.0 go.dedis.ch/fixbuf v1.0.3 go.dedis.ch/protobuf v1.0.11 golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b - golang.org/x/sys v0.0.0-20190124100055-b90733256f2e + golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339 ) go 1.12 diff --git a/go.sum b/go.sum index 629c02f9..2df115ed 100644 --- a/go.sum +++ b/go.sum @@ -3,6 +3,8 @@ github.com/corestario/kyber v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDT github.com/corestario/kyber v3.0.9/go.mod h1:rhNjUUg6ahf8HEg5HUvVBYoWY4boAafX8tYxX+PS+qg= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/kilic/bls12-381 v0.0.0-20200820230200-6b2c19996391 h1:51kHw7l/dUDdOdW06AlUGT5jnpj6nqQSILebcsikSjA= +github.com/kilic/bls12-381 v0.0.0-20200820230200-6b2c19996391/go.mod h1:XXfR6YFCRSrkEXbNlIyDsgXVNJWVUV30m/ebkVy9n6s= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -22,3 +24,5 @@ golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b h1:Elez2XeF2p9uyVj0yEUDqQ golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/sys v0.0.0-20190124100055-b90733256f2e h1:3GIlrlVLfkoipSReOMNAgApI0ajnalyLa/EZHHca/XI= golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339 h1:zSqWKgm/o7HAnlAzBQ+aetp9fpuyytsXnKA8eiLHYQM= +golang.org/x/sys v0.0.0-20191025090151-53bf42e6b339/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/pairing/bls12381/bls_groups_test.go b/pairing/bls12381/bls_groups_test.go new file mode 100644 index 00000000..015a1ff9 --- /dev/null +++ b/pairing/bls12381/bls_groups_test.go @@ -0,0 +1,351 @@ +package bls + +import ( + "bytes" + "crypto/cipher" + "testing" + + "github.com/corestario/kyber" + "github.com/corestario/kyber/util/random" + "github.com/stretchr/testify/require" +) + +// Code extracted from kyber/utils/test +// TODO: expose API in forked drand/kyber +// Apply a generic set of validation tests to a cryptographic Group, +// using a given source of [pseudo-]randomness. +// +// Returns a log of the pseudorandom Points produced in the test, +// for comparison across alternative implementations +// that are supposed to be equivalent. +func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { + t.Logf("\nTesting group '%s': %d-byte Point, %d-byte Scalar\n", + g.String(), g.PointLen(), g.ScalarLen()) + + points := make([]kyber.Point, 0) + ptmp := g.Point() + stmp := g.Scalar() + pzero := g.Point().Null() + szero := g.Scalar().Zero() + sone := g.Scalar().One() + + // Do a simple Diffie-Hellman test + s1 := g.Scalar().Pick(rand) + s2 := g.Scalar().Pick(rand) + if s1.Equal(szero) { + t.Fatalf("first secret is scalar zero %v", s1) + } + if s2.Equal(szero) { + t.Fatalf("second secret is scalar zero %v", s2) + } + if s1.Equal(s2) { + t.Fatalf("not getting unique secrets: picked %s twice", s1) + } + + gen := g.Point().Base() + points = append(points, gen) + + // Sanity-check relationship between addition and multiplication + p1 := g.Point().Add(gen, gen) + p2 := g.Point().Mul(stmp.SetInt64(2), nil) + if !p1.Equal(p2) { + t.Fatalf("multiply by two doesn't work: %v == %v (+) %[2]v != %[2]v (x) 2 == %v", p1, gen, p2) + } + p1.Add(p1, p1) + p2.Mul(stmp.SetInt64(4), nil) + if !p1.Equal(p2) { + t.Fatalf("multiply by four doesn't work: %v (+) %[1]v != %v (x) 4 == %v", + g.Point().Add(gen, gen), gen, p2) + } + points = append(points, p1) + + // Find out if this curve has a prime order: + // if the curve does not offer a method IsPrimeOrder, + // then assume that it is. + type canCheckPrimeOrder interface { + IsPrimeOrder() bool + } + primeOrder := true + if gpo, ok := g.(canCheckPrimeOrder); ok { + primeOrder = gpo.IsPrimeOrder() + } + + // Verify additive and multiplicative identities of the generator. + // TODO: Check GT exp + /*fmt.Println("Inverse of base")*/ + //f := ptmp.Base().(*KyberGT).f + //newFp12(nil).inverse(f, f) + //fmt.Printf("\n-Inverse: %v\n", f) + //fmt.Println("Multiply by -1") + ptmp.Mul(stmp.SetInt64(-1), nil).Add(ptmp, gen) + /*fmt.Printf(" \n\nChecking equality additive identity\nptmp: %v \n\n zero %v\n", ptmp, pzero)*/ + if !ptmp.Equal(pzero) { + t.Fatalf("generator additive identity doesn't work: (scalar -1 %v) %v (x) -1 (+) %v = %v != %v the group point identity", + stmp.SetInt64(-1), ptmp.Mul(stmp.SetInt64(-1), nil), gen, ptmp.Mul(stmp.SetInt64(-1), nil).Add(ptmp, gen), pzero) + } + // secret.Inv works only in prime-order groups + if primeOrder { + ptmp.Mul(stmp.SetInt64(2), nil).Mul(stmp.Inv(stmp), ptmp) + if !ptmp.Equal(gen) { + t.Fatalf("generator multiplicative identity doesn't work:\n%v (x) %v = %v\n%[3]v (x) %v = %v", + ptmp.Base().String(), stmp.SetInt64(2).String(), + ptmp.Mul(stmp.SetInt64(2), nil).String(), + stmp.Inv(stmp).String(), + ptmp.Mul(stmp.SetInt64(2), nil).Mul(stmp.Inv(stmp), ptmp).String()) + } + } + + p1.Mul(s1, gen) + p2.Mul(s2, gen) + if p1.Equal(p2) { + t.Fatalf("encryption isn't producing unique points: %v (x) %v == %v (x) %[2]v == %[4]v", s1, gen, s2, p1) + } + points = append(points, p1) + + dh1 := g.Point().Mul(s2, p1) + dh2 := g.Point().Mul(s1, p2) + if !dh1.Equal(dh2) { + t.Fatalf("Diffie-Hellman didn't work: %v == %v (x) %v != %v (x) %v == %v", dh1, s2, p1, s1, p2, dh2) + } + points = append(points, dh1) + //t.Logf("shared secret = %v", dh1) + + // Test secret inverse to get from dh1 back to p1 + if primeOrder { + ptmp.Mul(g.Scalar().Inv(s2), dh1) + if !ptmp.Equal(p1) { + t.Fatalf("Scalar inverse didn't work: %v != (-)%v (x) %v == %v", p1, s2, dh1, ptmp) + } + } + + // Zero and One identity secrets + //println("dh1^0 = ",ptmp.Mul(dh1, szero).String()) + if !ptmp.Mul(szero, dh1).Equal(pzero) { + t.Fatalf("Encryption with secret=0 didn't work: %v (x) %v == %v != %v", szero, dh1, ptmp, pzero) + } + if !ptmp.Mul(sone, dh1).Equal(dh1) { + t.Fatalf("Encryption with secret=1 didn't work: %v (x) %v == %v != %[2]v", sone, dh1, ptmp) + } + + // Additive homomorphic identities + ptmp.Add(p1, p2) + stmp.Add(s1, s2) + pt2 := g.Point().Mul(stmp, gen) + if !pt2.Equal(ptmp) { + t.Fatalf("Additive homomorphism doesn't work: %v + %v == %v, %[3]v (x) %v == %v != %v == %v (+) %v", + s1, s2, stmp, gen, pt2, ptmp, p1, p2) + } + ptmp.Sub(p1, p2) + stmp.Sub(s1, s2) + pt2.Mul(stmp, gen) + if !pt2.Equal(ptmp) { + t.Fatalf("Additive homomorphism doesn't work: %v - %v == %v, %[3]v (x) %v == %v != %v == %v (-) %v", + s1, s2, stmp, gen, pt2, ptmp, p1, p2) + } + st2 := g.Scalar().Neg(s2) + st2.Add(s1, st2) + if !stmp.Equal(st2) { + t.Fatalf("Scalar.Neg doesn't work: -%v == %v, %[2]v + %v == %v != %v", + s2, g.Scalar().Neg(s2), s1, st2, stmp) + } + pt2.Neg(p2).Add(pt2, p1) + if !pt2.Equal(ptmp) { + t.Fatalf("Point.Neg doesn't work: (-)%v == %v, %[2]v (+) %v == %v != %v", + p2, g.Point().Neg(p2), p1, pt2, ptmp) + } + + // Multiplicative homomorphic identities + stmp.Mul(s1, s2) + if !ptmp.Mul(stmp, gen).Equal(dh1) { + t.Fatalf("Multiplicative homomorphism doesn't work: %v * %v == %v, %[2]v (x) %v == %v != %v", + s1, s2, stmp, gen, ptmp, dh1) + } + if primeOrder { + st2.Inv(s2) + st2.Mul(st2, stmp) + if !st2.Equal(s1) { + t.Fatalf("Scalar division doesn't work: %v^-1 * %v == %v * %[2]v == %[4]v != %v", + s2, stmp, g.Scalar().Inv(s2), st2, s1) + } + st2.Div(stmp, s2) + if !st2.Equal(s1) { + t.Fatalf("Scalar division doesn't work: %v / %v == %v != %v", + stmp, s2, st2, s1) + } + } + + pick := func(rand cipher.Stream) (p kyber.Point) { + defer func() { + /*if err := recover(); err != nil {*/ + //// TODO implement Pick for GT + //p = g.Point().Mul(g.Scalar().Pick(rand), nil) + //return + /*}*/ + }() + p = g.Point().Pick(rand) + return + } + + // Test randomly picked points + last := gen + for i := 0; i < 5; i++ { + // TODO fork kyber and make that an interface + rgen := pick(rand) + if rgen.Equal(last) { + t.Fatalf("Pick() not producing unique points: got %v twice", rgen) + } + last = rgen + + ptmp.Mul(stmp.SetInt64(-1), rgen).Add(ptmp, rgen) + if !ptmp.Equal(pzero) { + t.Fatalf("random generator fails additive identity: %v (x) %v == %v, %v (+) %[3]v == %[5]v != %v", + g.Scalar().SetInt64(-1), rgen, g.Point().Mul(g.Scalar().SetInt64(-1), rgen), + rgen, g.Point().Mul(g.Scalar().SetInt64(-1), rgen), pzero) + } + if primeOrder { + ptmp.Mul(stmp.SetInt64(2), rgen).Mul(stmp.Inv(stmp), ptmp) + if !ptmp.Equal(rgen) { + t.Fatalf("random generator fails multiplicative identity: %v (x) (2 (x) %v) == %v != %[2]v", + stmp, rgen, ptmp) + } + } + points = append(points, rgen) + } + + // Test encoding and decoding + buf := new(bytes.Buffer) + for i := 0; i < 5; i++ { + buf.Reset() + s := g.Scalar().Pick(rand) + if _, err := s.MarshalTo(buf); err != nil { + t.Fatalf("encoding of secret fails: " + err.Error()) + } + if _, err := stmp.UnmarshalFrom(buf); err != nil { + t.Fatalf("decoding of secret fails: " + err.Error()) + } + if !stmp.Equal(s) { + t.Fatalf("decoding produces different secret than encoded") + } + + buf.Reset() + p := pick(rand) + if _, err := p.MarshalTo(buf); err != nil { + t.Fatalf("encoding of point fails: " + err.Error()) + } + if _, err := ptmp.UnmarshalFrom(buf); err != nil { + t.Fatalf("decoding of point fails: " + err.Error()) + } + + if !ptmp.Equal(p) { + t.Fatalf("decoding produces different point than encoded") + } + } + + // Test that we can marshal/ unmarshal null point + pzero = g.Point().Null() + b, _ := pzero.MarshalBinary() + repzero := g.Point() + err := repzero.UnmarshalBinary(b) + if err != nil { + t.Fatalf("Could not unmarshall binary %v: %v", b, err) + } + + return points +} + +// GroupTest applies a generic set of validation tests to a cryptographic Group. +func GroupTest(t *testing.T, g kyber.Group) { + testGroup(t, g, random.New()) +} + +func TestKyberG1(t *testing.T) { + GroupTest(t, NewGroupG1()) +} + +func TestKyberG2(t *testing.T) { + GroupTest(t, NewGroupG2()) +} + +func TestKyberGT(t *testing.T) { + GroupTest(t, NewGroupGT()) +} + +func TestGT(t *testing.T) { + q := newEmptyGT().Base() + //q := newEmptyGT().Base() + s := NewGroupGT().Scalar().SetInt64(2) + p := newEmptyGT() + p.Mul(s, q) + pp := newEmptyGT() + pp.Add(q, q) + t.Log(p.Equal(q)) + t.Log(pp.Equal(q)) + t.Log(pp.Equal(p)) +} + +func TestKyberPairingG2(t *testing.T) { + s := NewBLS12381Suite().(*Suite) + a := s.G1().Scalar().Pick(s.RandomStream()) + b := s.G2().Scalar().Pick(s.RandomStream()) + aG := s.G1().Point().Mul(a, nil) + bH := s.G2().Point().Mul(b, nil) + ab := s.G1().Scalar().Mul(a, b) + abG := s.G1().Point().Mul(ab, nil) + // e(aG, bG) = e(G,H)^(ab) + p1 := s.Pair(aG, bH) + // e((ab)G,H) = e(G,H)^(ab) + p2 := s.Pair(abG, s.G2().Point().Base()) + require.True(t, p1.Equal(p2)) + require.True(t, s.ValidatePairing(aG, bH, abG.Clone(), s.G2().Point().Base())) + + pRandom := s.Pair(aG, s.G2().Point().Pick(s.RandomStream())) + require.False(t, p1.Equal(pRandom)) + pRandom = s.Pair(s.G1().Point().Pick(s.RandomStream()), bH) + require.False(t, p1.Equal(pRandom)) +} + +func BenchmarkPairingSeparate(bb *testing.B) { + s := NewBLS12381Suite().(*Suite) + a := s.G1().Scalar().Pick(s.RandomStream()) + b := s.G2().Scalar().Pick(s.RandomStream()) + aG := s.G1().Point().Mul(a, nil) + bH := s.G2().Point().Mul(b, nil) + ab := s.G1().Scalar().Mul(a, b) + abG := s.G1().Point().Mul(ab, nil) + bb.ResetTimer() + for i := 0; i < bb.N; i++ { + + // e(aG, bG) = e(G,H)^(ab) + p1 := s.Pair(aG, bH) + // e((ab)G,H) = e(G,H)^(ab) + p2 := s.Pair(abG, s.G2().Point().Base()) + if !p1.Equal(p2) { + panic("aie") + } + } +} + +func BenchmarkPairingInv(bb *testing.B) { + s := NewBLS12381Suite().(*Suite) + a := s.G1().Scalar().Pick(s.RandomStream()) + b := s.G2().Scalar().Pick(s.RandomStream()) + aG := s.G1().Point().Mul(a, nil) + bH := s.G2().Point().Mul(b, nil) + ab := s.G1().Scalar().Mul(a, b) + abG := s.G1().Point().Mul(ab, nil) + bb.ResetTimer() + for i := 0; i < bb.N; i++ { + if !s.ValidatePairing(aG, bH, abG.Clone(), s.G2().Point().Base()) { + panic("aie") + } + } +} + +func TestIsValidGroup(t *testing.T) { + suite := NewBLS12381Suite() + p1 := suite.G1().Point().Pick(random.New()) + p2 := suite.G1().Point().Pick(random.New()) + + require.True(t, p1.(GroupChecker).IsInCorrectGroup()) + require.True(t, p2.(GroupChecker).IsInCorrectGroup()) +} diff --git a/pairing/bls12381/group_g1.go b/pairing/bls12381/group_g1.go new file mode 100644 index 00000000..10af6eb9 --- /dev/null +++ b/pairing/bls12381/group_g1.go @@ -0,0 +1,141 @@ +package bls + +import ( + "crypto/cipher" + "encoding/hex" + "io" + + "github.com/corestario/kyber" + "github.com/corestario/kyber/group/mod" + bls12381 "github.com/kilic/bls12-381" +) + +// KyberG1 is a kyber.Point holding a G1 point on BLS12-381 curve +type KyberG1 struct { + p *bls12381.PointG1 +} + +func NullKyberG1() *KyberG1 { + var p bls12381.PointG1 + return newKyberG1(&p) +} +func newKyberG1(p *bls12381.PointG1) *KyberG1 { + return &KyberG1{p: p} +} + +func (k *KyberG1) Equal(k2 kyber.Point) bool { + return bls12381.NewG1().Equal(k.p, k2.(*KyberG1).p) +} + +func (k *KyberG1) Null() kyber.Point { + return newKyberG1(bls12381.NewG1().Zero()) +} + +func (k *KyberG1) Base() kyber.Point { + return newKyberG1(bls12381.NewG1().One()) +} + +func (k *KyberG1) Pick(rand cipher.Stream) kyber.Point { + //panic("not implemented") + var dst, src [32]byte + rand.XORKeyStream(dst[:], src[:]) + return k.Hash(dst[:]) +} + +func (k *KyberG1) Set(q kyber.Point) kyber.Point { + k.p.Set(q.(*KyberG1).p) + return k +} + +func (k *KyberG1) Clone() kyber.Point { + var p bls12381.PointG1 + p.Set(k.p) + return newKyberG1(&p) +} + +func (k *KyberG1) EmbedLen() int { + panic("bls12-381: unsupported operation") +} + +func (k *KyberG1) Embed(data []byte, rand cipher.Stream) kyber.Point { + panic("bls12-381: unsupported operation") +} + +func (k *KyberG1) Data() ([]byte, error) { + panic("bls12-381: unsupported operation") +} + +func (k *KyberG1) Add(a, b kyber.Point) kyber.Point { + aa := a.(*KyberG1) + bb := b.(*KyberG1) + bls12381.NewG1().Add(k.p, aa.p, bb.p) + return k +} + +func (k *KyberG1) Sub(a, b kyber.Point) kyber.Point { + aa := a.(*KyberG1) + bb := b.(*KyberG1) + bls12381.NewG1().Sub(k.p, aa.p, bb.p) + return k +} + +func (k *KyberG1) Neg(a kyber.Point) kyber.Point { + aa := a.(*KyberG1) + bls12381.NewG1().Neg(k.p, aa.p) + return k +} + +func (k *KyberG1) Mul(s kyber.Scalar, q kyber.Point) kyber.Point { + if q == nil { + q = NullKyberG1().Base() + } + bls12381.NewG1().MulScalar(k.p, q.(*KyberG1).p, &s.(*mod.Int).V) + return k +} + +func (k *KyberG1) MarshalBinary() ([]byte, error) { + return bls12381.NewG1().ToCompressed(k.p), nil +} + +func (k *KyberG1) UnmarshalBinary(buff []byte) error { + var err error + k.p, err = bls12381.NewG1().FromCompressed(buff) + return err +} + +func (k *KyberG1) MarshalTo(w io.Writer) (int, error) { + buf, err := k.MarshalBinary() + if err != nil { + return 0, err + } + return w.Write(buf) +} + +func (k *KyberG1) UnmarshalFrom(r io.Reader) (int, error) { + buf := make([]byte, k.MarshalSize()) + n, err := io.ReadFull(r, buf) + if err != nil { + return n, err + } + return n, k.UnmarshalBinary(buf) +} + +func (k *KyberG1) MarshalSize() int { + return 48 +} + +func (k *KyberG1) String() string { + b, _ := k.MarshalBinary() + return "bls12-381.G1: " + hex.EncodeToString(b) +} + +func (k *KyberG1) Hash(m []byte) kyber.Point { + p, _ := bls12381.NewG1().HashToCurve(m, Domain) + k.p = p + return k + +} + +func (k *KyberG1) IsInCorrectGroup() bool { + return bls12381.NewG1().InCorrectSubgroup(k.p) +} diff --git a/pairing/bls12381/group_g2.go b/pairing/bls12381/group_g2.go new file mode 100644 index 00000000..d18a9ceb --- /dev/null +++ b/pairing/bls12381/group_g2.go @@ -0,0 +1,151 @@ +package bls + +import ( + "crypto/cipher" + "crypto/sha256" + "encoding/hex" + "io" + + "github.com/corestario/kyber" + "github.com/corestario/kyber/group/mod" + bls12381 "github.com/kilic/bls12-381" +) + +// Domain comes from the ciphersuite used by the RFC of this name compatible +// with the paired library > v18 +var Domain = []byte("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_") + +// KyberG2 is a kyber.Point holding a G2 point on BLS12-381 curve +type KyberG2 struct { + p *bls12381.PointG2 +} + +func NullKyberG2() *KyberG2 { + var p bls12381.PointG2 + return newKyberG2(&p) +} + +func newKyberG2(p *bls12381.PointG2) *KyberG2 { + return &KyberG2{p: p} +} + +func (k *KyberG2) Equal(k2 kyber.Point) bool { + return bls12381.NewG2().Equal(k.p, k2.(*KyberG2).p) +} + +func (k *KyberG2) Null() kyber.Point { + return newKyberG2(bls12381.NewG2().Zero()) +} + +func (k *KyberG2) Base() kyber.Point { + return newKyberG2(bls12381.NewG2().One()) +} + +func (k *KyberG2) Pick(rand cipher.Stream) kyber.Point { + var dst, src [32]byte + rand.XORKeyStream(dst[:], src[:]) + return k.Hash(dst[:]) +} + +func (k *KyberG2) Set(q kyber.Point) kyber.Point { + k.p.Set(q.(*KyberG2).p) + return k +} + +func (k *KyberG2) Clone() kyber.Point { + var p bls12381.PointG2 + p.Set(k.p) + return newKyberG2(&p) +} + +func (k *KyberG2) EmbedLen() int { + panic("bls12-381: unsupported operation") +} + +func (k *KyberG2) Embed(data []byte, rand cipher.Stream) kyber.Point { + panic("bls12-381: unsupported operation") +} + +func (k *KyberG2) Data() ([]byte, error) { + panic("bls12-381: unsupported operation") +} + +func (k *KyberG2) Add(a, b kyber.Point) kyber.Point { + aa := a.(*KyberG2) + bb := b.(*KyberG2) + bls12381.NewG2().Add(k.p, aa.p, bb.p) + return k +} + +func (k *KyberG2) Sub(a, b kyber.Point) kyber.Point { + aa := a.(*KyberG2) + bb := b.(*KyberG2) + bls12381.NewG2().Sub(k.p, aa.p, bb.p) + return k +} + +func (k *KyberG2) Neg(a kyber.Point) kyber.Point { + aa := a.(*KyberG2) + bls12381.NewG2().Neg(k.p, aa.p) + return k +} + +func (k *KyberG2) Mul(s kyber.Scalar, q kyber.Point) kyber.Point { + if q == nil { + q = NullKyberG2().Base() + } + bls12381.NewG2().MulScalar(k.p, q.(*KyberG2).p, &s.(*mod.Int).V) + return k +} + +func (k *KyberG2) MarshalBinary() ([]byte, error) { + return bls12381.NewG2().ToCompressed(k.p), nil +} + +func (k *KyberG2) UnmarshalBinary(buff []byte) error { + var err error + k.p, err = bls12381.NewG2().FromCompressed(buff) + return err +} + +func (k *KyberG2) MarshalTo(w io.Writer) (int, error) { + buf, err := k.MarshalBinary() + if err != nil { + return 0, err + } + return w.Write(buf) +} + +func (k *KyberG2) UnmarshalFrom(r io.Reader) (int, error) { + buf := make([]byte, k.MarshalSize()) + n, err := io.ReadFull(r, buf) + if err != nil { + return n, err + } + return n, k.UnmarshalBinary(buf) +} + +func (k *KyberG2) MarshalSize() int { + return 96 +} + +func (k *KyberG2) String() string { + b, _ := k.MarshalBinary() + return "bls12-381.G1: " + hex.EncodeToString(b) +} + +func (k *KyberG2) Hash(m []byte) kyber.Point { + pg2, _ := bls12381.NewG2().HashToCurve(m, Domain) + k.p = pg2 + return k +} + +func sha256Hash(in []byte) []byte { + h := sha256.New() + h.Write(in) + return h.Sum(nil) +} + +func (k *KyberG2) IsInCorrectGroup() bool { + return bls12381.NewG2().InCorrectSubgroup(k.p) +} diff --git a/pairing/bls12381/group_gt.go b/pairing/bls12381/group_gt.go new file mode 100644 index 00000000..6890ea75 --- /dev/null +++ b/pairing/bls12381/group_gt.go @@ -0,0 +1,149 @@ +package bls + +import ( + "crypto/cipher" + "encoding/hex" + "io" + + "github.com/corestario/kyber" + "github.com/corestario/kyber/group/mod" + bls12381 "github.com/kilic/bls12-381" +) + +type KyberGT struct { + f *bls12381.E +} + +func newEmptyGT() *KyberGT { + return newKyberGT(bls12381.NewGT().New()) +} +func newKyberGT(f *bls12381.E) *KyberGT { + return &KyberGT{ + f: f, + } +} + +func (k *KyberGT) Equal(kk kyber.Point) bool { + return k.f.Equal(kk.(*KyberGT).f) +} + +const gtLength = 576 + +func (k *KyberGT) Null() kyber.Point { + var zero [gtLength]byte + k.f, _ = bls12381.NewGT().FromBytes(zero[:]) + return k +} + +func (k *KyberGT) Base() kyber.Point { + g1 := bls12381.NewG1().One() + g2 := bls12381.NewG2().One() + e := bls12381.NewEngine() + e.AddPair(g1, g2) + k.f = e.Result() + return k + /*var baseReader, _ = blake2b.NewXOF(0, []byte("Quand il y a à manger pour huit, il y en a bien pour dix."))*/ + //_, err := NewGT().rand(baseReader) + //if err != nil { + //panic(err) + //} + /*return k*/ +} + +func (k *KyberGT) Pick(rand cipher.Stream) kyber.Point { + //panic("TODO: bls12-381.GT.Pick()") + s := mod.NewInt64(0, bls12381.NewGT().Q()).Pick(rand) + k.Base() + bls12381.NewGT().Exp(k.f, k.f, &s.(*mod.Int).V) + return k +} + +func (k *KyberGT) Set(q kyber.Point) kyber.Point { + k.f.Set(q.(*KyberGT).f) + return k +} + +func (k *KyberGT) Clone() kyber.Point { + kk := newEmptyGT() + kk.Set(k) + return kk +} + +func (k *KyberGT) Add(a, b kyber.Point) kyber.Point { + aa := a.(*KyberGT) + bb := b.(*KyberGT) + bls12381.NewGT().Mul(k.f, aa.f, bb.f) + return k +} + +func (k *KyberGT) Sub(a, b kyber.Point) kyber.Point { + aa := a.(*KyberGT) + bb := b.(*KyberGT) + bls12381.NewGT().Sub(k.f, aa.f, bb.f) + return k +} + +func (k *KyberGT) Neg(q kyber.Point) kyber.Point { + //panic("bls12-381: GT is not a full kyber.Point implementation") + aa := newEmptyGT().Null().(*KyberGT) + bb := q.(*KyberGT) + bls12381.NewGT().Sub(k.f, aa.f, bb.f) + return k +} + +func (k *KyberGT) Mul(s kyber.Scalar, q kyber.Point) kyber.Point { + //panic("bls12-381: GT is not a full kyber.Point implementation") + if q == nil { + q = newEmptyGT().Base() + } + bls12381.NewGT().Exp(k.f, q.(*KyberGT).f, &s.(*mod.Int).V) + return k +} + +func (k *KyberGT) MarshalBinary() ([]byte, error) { + return bls12381.NewGT().ToBytes(k.f), nil +} + +func (k *KyberGT) MarshalTo(w io.Writer) (int, error) { + buf, err := k.MarshalBinary() + if err != nil { + return 0, err + } + return w.Write(buf) +} + +func (k *KyberGT) UnmarshalBinary(buf []byte) error { + fe12, err := bls12381.NewGT().FromBytes(buf) + k.f = fe12 + return err +} + +func (k *KyberGT) UnmarshalFrom(r io.Reader) (int, error) { + buf := make([]byte, k.MarshalSize()) + n, err := io.ReadFull(r, buf) + if err != nil { + return n, err + } + return n, k.UnmarshalBinary(buf) +} + +func (k *KyberGT) MarshalSize() int { + return 576 +} + +func (k *KyberGT) String() string { + b, _ := k.MarshalBinary() + return "bls12-381.GT: " + hex.EncodeToString(b) +} + +func (k *KyberGT) EmbedLen() int { + panic("bls12-381.GT.EmbedLen(): unsupported operation") +} + +func (k *KyberGT) Embed(data []byte, rand cipher.Stream) kyber.Point { + panic("bls12-381.GT.Embed(): unsupported operation") +} + +func (k *KyberGT) Data() ([]byte, error) { + panic("bls12-381.GT.Data(): unsupported operation") +} diff --git a/pairing/bls12381/scalar.go b/pairing/bls12381/scalar.go new file mode 100644 index 00000000..334ff628 --- /dev/null +++ b/pairing/bls12381/scalar.go @@ -0,0 +1,14 @@ +package bls + +import ( + "math/big" + + "github.com/corestario/kyber" + "github.com/corestario/kyber/group/mod" +) + +var curveOrder, _ = new(big.Int).SetString("73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001", 16) + +func NewKyberScalar() kyber.Scalar { + return mod.NewInt64(0, curveOrder) +} diff --git a/pairing/bls12381/suite.go b/pairing/bls12381/suite.go new file mode 100644 index 00000000..33bab9ce --- /dev/null +++ b/pairing/bls12381/suite.go @@ -0,0 +1,179 @@ +package bls + +import ( + "crypto/cipher" + "crypto/sha256" + "hash" + "io" + "reflect" + + pairing "github.com/corestario/kyber/pairing" + + "github.com/corestario/kyber" + "github.com/corestario/kyber/util/random" + "github.com/corestario/kyber/xof/blake2xb" + bls12381 "github.com/kilic/bls12-381" +) + +// GroupChecker allows to verify if a Point is in the correct group or not. For +// curves which don't have a prime order, we need to only consider the points +// lying in the subgroup of prime order. That check returns true if the point is +// correct or not. +type GroupChecker interface { + kyber.Point + IsInCorrectGroup() bool +} + +type groupBls struct { + str string + newPoint func() kyber.Point + isPrime bool +} + +func (g *groupBls) String() string { + return g.str +} + +func (g *groupBls) Scalar() kyber.Scalar { + return NewKyberScalar() +} + +func (g *groupBls) ScalarLen() int { + return g.Scalar().MarshalSize() +} + +func (g *groupBls) PointLen() int { + return g.Point().MarshalSize() +} + +func (g *groupBls) Point() kyber.Point { + return g.newPoint() +} + +func (g *groupBls) IsPrimeOrder() bool { + return g.isPrime +} + +func (g *groupBls) Hash() hash.Hash { + return sha256.New() +} + +// XOF returns a newlly instantiated blake2xb XOF function. +func (g *groupBls) XOF(seed []byte) kyber.XOF { + return blake2xb.New(seed) +} + +// RandomStream returns a cipher.Stream which corresponds to a key stream from +// crypto/rand. +func (g *groupBls) RandomStream() cipher.Stream { + return random.New() +} + +func NewGroupG1() kyber.Group { + return &groupBls{ + str: "bls12-381.G1", + newPoint: func() kyber.Point { return NullKyberG1() }, + isPrime: true, + } +} + +func NewGroupG2() kyber.Group { + return &groupBls{ + str: "bls12-381.G2", + newPoint: func() kyber.Point { return NullKyberG2() }, + isPrime: false, + } +} + +func NewGroupGT() kyber.Group { + return &groupBls{ + str: "bls12-381.GT", + newPoint: func() kyber.Point { return newEmptyGT() }, + isPrime: false, + } +} + +type Suite struct { + e *bls12381.Engine +} + +func (s *Suite) String() string { + return "Suite.String()" +} + +func (s *Suite) ScalarLen() int { + return s.G1().Scalar().MarshalSize() +} + +func (s *Suite) Scalar() kyber.Scalar { + return s.G1().Scalar() +} + +func (s *Suite) PointLen() int { + return s.G1().Point().MarshalSize() +} + +func (s *Suite) Point() kyber.Point { + return s.G1().Point() +} + +func NewBLS12381Suite() pairing.Suite { + return &Suite{e: bls12381.NewEngine()} +} + +func (s *Suite) G1() kyber.Group { + return NewGroupG1() +} + +func (s *Suite) G2() kyber.Group { + return NewGroupG2() +} + +func (s *Suite) GT() kyber.Group { + return NewGroupGT() +} + +// ValidatePairing implements the `pairing.Suite` interface +func (s *Suite) ValidatePairing(p1, p2, p3, p4 kyber.Point) bool { + s.e.AddPair(p1.(*KyberG1).p, p2.(*KyberG2).p) + s.e.AddPairInv(p3.(*KyberG1).p, p4.(*KyberG2).p) + return s.e.Check() +} + +func (s *Suite) Pair(p1, p2 kyber.Point) kyber.Point { + g1point := p1.(*KyberG1).p + g2point := p2.(*KyberG2).p + gt := newKyberGT(s.e.AddPair(g1point, g2point).Result()) + return gt +} + +// New implements the kyber.Encoding interface. +func (s *Suite) New(t reflect.Type) interface{} { + panic("Suite.Encoding: deprecated in drand") +} + +// Read is the default implementation of kyber.Encoding interface Read. +func (s *Suite) Read(r io.Reader, objs ...interface{}) error { + panic("Suite.Read(): deprecated in drand") +} + +// Write is the default implementation of kyber.Encoding interface Write. +func (s *Suite) Write(w io.Writer, objs ...interface{}) error { + panic("Suite.Write(): deprecated in drand") +} + +// Hash returns a newly instantiated sha256 hash function. +func (s *Suite) Hash() hash.Hash { + return sha256.New() +} + +// XOF returns a newlly instantiated blake2xb XOF function. +func (s *Suite) XOF(seed []byte) kyber.XOF { + return blake2xb.New(seed) +} + +// RandomStream returns a cipher.Stream which corresponds to a key stream from +// crypto/rand. +func (s *Suite) RandomStream() cipher.Stream { + return random.New() +} From cc66a9856a5678722a22b025e7d6011983de9a0c Mon Sep 17 00:00:00 2001 From: SK0M0R0H Date: Sat, 3 Oct 2020 01:49:30 +0200 Subject: [PATCH 2/7] add bls tests from kyber-bls12381 --- go.sum | 1 + pairing/bls12381/bls_groups_test.go | 13 ------------- sign/bls/bls_test.go | 23 ++++++++++++++--------- 3 files changed, 15 insertions(+), 22 deletions(-) diff --git a/go.sum b/go.sum index 2df115ed..09c92c04 100644 --- a/go.sum +++ b/go.sum @@ -7,6 +7,7 @@ github.com/kilic/bls12-381 v0.0.0-20200820230200-6b2c19996391 h1:51kHw7l/dUDdOdW github.com/kilic/bls12-381 v0.0.0-20200820230200-6b2c19996391/go.mod h1:XXfR6YFCRSrkEXbNlIyDsgXVNJWVUV30m/ebkVy9n6s= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= diff --git a/pairing/bls12381/bls_groups_test.go b/pairing/bls12381/bls_groups_test.go index 015a1ff9..1479ab7e 100644 --- a/pairing/bls12381/bls_groups_test.go +++ b/pairing/bls12381/bls_groups_test.go @@ -270,19 +270,6 @@ func TestKyberGT(t *testing.T) { GroupTest(t, NewGroupGT()) } -func TestGT(t *testing.T) { - q := newEmptyGT().Base() - //q := newEmptyGT().Base() - s := NewGroupGT().Scalar().SetInt64(2) - p := newEmptyGT() - p.Mul(s, q) - pp := newEmptyGT() - pp.Add(q, q) - t.Log(p.Equal(q)) - t.Log(pp.Equal(q)) - t.Log(pp.Equal(p)) -} - func TestKyberPairingG2(t *testing.T) { s := NewBLS12381Suite().(*Suite) a := s.G1().Scalar().Pick(s.RandomStream()) diff --git a/sign/bls/bls_test.go b/sign/bls/bls_test.go index 26480ac3..70e33c48 100644 --- a/sign/bls/bls_test.go +++ b/sign/bls/bls_test.go @@ -4,16 +4,18 @@ import ( "crypto/rand" "testing" - "github.com/stretchr/testify/require" "github.com/corestario/kyber" + curve "github.com/corestario/kyber/pairing/bls12381" "github.com/corestario/kyber/pairing/bn256" "github.com/corestario/kyber/util/random" + "github.com/stretchr/testify/require" ) func TestBLS(t *testing.T) { msg := []byte("Hello Boneh-Lynn-Shacham") - suite := bn256.NewSuite() + suite := curve.NewBLS12381Suite() private, public := NewKeyPair(suite, random.New()) + sig, err := Sign(suite, private, msg) require.Nil(t, err) err = Verify(suite, public, msg, sig) @@ -22,7 +24,7 @@ func TestBLS(t *testing.T) { func TestBLSFailSig(t *testing.T) { msg := []byte("Hello Boneh-Lynn-Shacham") - suite := bn256.NewSuite() + suite := curve.NewBLS12381Suite() private, public := NewKeyPair(suite, random.New()) sig, err := Sign(suite, private, msg) require.Nil(t, err) @@ -34,7 +36,7 @@ func TestBLSFailSig(t *testing.T) { func TestBLSFailKey(t *testing.T) { msg := []byte("Hello Boneh-Lynn-Shacham") - suite := bn256.NewSuite() + suite := curve.NewBLS12381Suite() private, _ := NewKeyPair(suite, random.New()) sig, err := Sign(suite, private, msg) require.Nil(t, err) @@ -46,7 +48,7 @@ func TestBLSFailKey(t *testing.T) { func TestBLSAggregateSignatures(t *testing.T) { msg := []byte("Hello Boneh-Lynn-Shacham") - suite := bn256.NewSuite() + suite := curve.NewBLS12381Suite() private1, public1 := NewKeyPair(suite, random.New()) private2, public2 := NewKeyPair(suite, random.New()) sig1, err := Sign(suite, private1, msg) @@ -64,7 +66,7 @@ func TestBLSAggregateSignatures(t *testing.T) { func TestBLSFailAggregatedSig(t *testing.T) { msg := []byte("Hello Boneh-Lynn-Shacham") - suite := bn256.NewSuite() + suite := curve.NewBLS12381Suite() private1, public1 := NewKeyPair(suite, random.New()) private2, public2 := NewKeyPair(suite, random.New()) sig1, err := Sign(suite, private1, msg) @@ -80,9 +82,10 @@ func TestBLSFailAggregatedSig(t *testing.T) { t.Fatal("bls: verification succeeded unexpectedly") } } + func TestBLSFailAggregatedKey(t *testing.T) { msg := []byte("Hello Boneh-Lynn-Shacham") - suite := bn256.NewSuite() + suite := curve.NewBLS12381Suite() private1, public1 := NewKeyPair(suite, random.New()) private2, public2 := NewKeyPair(suite, random.New()) _, public3 := NewKeyPair(suite, random.New()) @@ -98,10 +101,11 @@ func TestBLSFailAggregatedKey(t *testing.T) { t.Fatal("bls: verification succeeded unexpectedly") } } + func TestBLSBatchVerify(t *testing.T) { msg1 := []byte("Hello Boneh-Lynn-Shacham") msg2 := []byte("Hello Dedis & Boneh-Lynn-Shacham") - suite := bn256.NewSuite() + suite := curve.NewBLS12381Suite() private1, public1 := NewKeyPair(suite, random.New()) private2, public2 := NewKeyPair(suite, random.New()) sig1, err := Sign(suite, private1, msg1) @@ -114,10 +118,11 @@ func TestBLSBatchVerify(t *testing.T) { err = BatchVerify(suite, []kyber.Point{public1, public2}, [][]byte{msg1, msg2}, aggregatedSig) require.Nil(t, err) } + func TestBLSFailBatchVerify(t *testing.T) { msg1 := []byte("Hello Boneh-Lynn-Shacham") msg2 := []byte("Hello Dedis & Boneh-Lynn-Shacham") - suite := bn256.NewSuite() + suite := curve.NewBLS12381Suite() private1, public1 := NewKeyPair(suite, random.New()) private2, public2 := NewKeyPair(suite, random.New()) sig1, err := Sign(suite, private1, msg1) From 4058e3aac204d3e6db036118ebdd4478dfb70bf2 Mon Sep 17 00:00:00 2001 From: Luannet Date: Sat, 3 Oct 2020 05:21:26 +0200 Subject: [PATCH 3/7] bls + tbls tests --- sign/bls/bls_test.go | 17 ++++++++--------- sign/tbls/tbls.go | 4 ++-- sign/tbls/tbls_test.go | 34 ++++++++++++++++++++++++++++------ 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/sign/bls/bls_test.go b/sign/bls/bls_test.go index 70e33c48..6880f5ee 100644 --- a/sign/bls/bls_test.go +++ b/sign/bls/bls_test.go @@ -6,7 +6,6 @@ import ( "github.com/corestario/kyber" curve "github.com/corestario/kyber/pairing/bls12381" - "github.com/corestario/kyber/pairing/bn256" "github.com/corestario/kyber/util/random" "github.com/stretchr/testify/require" ) @@ -154,7 +153,7 @@ func TestBLSFailBatchVerify(t *testing.T) { } func BenchmarkBLSKeyCreation(b *testing.B) { - suite := bn256.NewSuite() + suite := curve.NewBLS12381Suite() b.ResetTimer() for i := 0; i < b.N; i++ { NewKeyPair(suite, random.New()) @@ -162,7 +161,7 @@ func BenchmarkBLSKeyCreation(b *testing.B) { } func BenchmarkBLSSign(b *testing.B) { - suite := bn256.NewSuite() + suite := curve.NewBLS12381Suite() private, _ := NewKeyPair(suite, random.New()) msg := []byte("Hello many times Boneh-Lynn-Shacham") b.ResetTimer() @@ -172,7 +171,7 @@ func BenchmarkBLSSign(b *testing.B) { } func BenchmarkBLSAggregateSigs(b *testing.B) { - suite := bn256.NewSuite() + suite := curve.NewBLS12381Suite() private1, _ := NewKeyPair(suite, random.New()) private2, _ := NewKeyPair(suite, random.New()) msg := []byte("Hello many times Boneh-Lynn-Shacham") @@ -188,7 +187,7 @@ func BenchmarkBLSAggregateSigs(b *testing.B) { } func BenchmarkBLSVerifyAggregate(b *testing.B) { - suite := bn256.NewSuite() + suite := curve.NewBLS12381Suite() private1, public1 := NewKeyPair(suite, random.New()) private2, public2 := NewKeyPair(suite, random.New()) msg := []byte("Hello many times Boneh-Lynn-Shacham") @@ -205,7 +204,7 @@ func BenchmarkBLSVerifyAggregate(b *testing.B) { } func BenchmarkBLSVerifyBatchVerify(b *testing.B) { - suite := bn256.NewSuite() + suite := curve.NewBLS12381Suite() numSigs := 100 privates := make([]kyber.Scalar, numSigs) @@ -232,7 +231,7 @@ func BenchmarkBLSVerifyBatchVerify(b *testing.B) { } func TestBinaryMarshalAfterAggregation_issue400(t *testing.T) { - suite := bn256.NewSuite() + suite := curve.NewBLS12381Suite() _, public1 := NewKeyPair(suite, random.New()) _, public2 := NewKeyPair(suite, random.New()) @@ -242,7 +241,7 @@ func TestBinaryMarshalAfterAggregation_issue400(t *testing.T) { workingBits, err := workingKey.MarshalBinary() require.Nil(t, err) - workingPoint := suite.G2().Point() + workingPoint := suite.G1().Point() err = workingPoint.UnmarshalBinary(workingBits) require.Nil(t, err) @@ -252,7 +251,7 @@ func TestBinaryMarshalAfterAggregation_issue400(t *testing.T) { bits, err := aggregatedKey.MarshalBinary() require.Nil(t, err) - point := suite.G2().Point() + point := suite.G1().Point() err = point.UnmarshalBinary(bits) require.Nil(t, err) } diff --git a/sign/tbls/tbls.go b/sign/tbls/tbls.go index b2ac725d..82a67758 100644 --- a/sign/tbls/tbls.go +++ b/sign/tbls/tbls.go @@ -86,7 +86,7 @@ func Recover(suite pairing.Suite, public *share.PubPoly, msg []byte, sigs [][]by if err = bls.Verify(suite, public.Eval(i).V, msg, s.Value()); err != nil { return nil, err } - point := suite.G1().Point() + point := suite.G2().Point() if err := point.UnmarshalBinary(s.Value()); err != nil { return nil, err } @@ -95,7 +95,7 @@ func Recover(suite pairing.Suite, public *share.PubPoly, msg []byte, sigs [][]by break } } - commit, err := share.RecoverCommit(suite.G1(), pubShares, t, n) + commit, err := share.RecoverCommit(suite.G2(), pubShares, t, n) if err != nil { return nil, err } diff --git a/sign/tbls/tbls_test.go b/sign/tbls/tbls_test.go index cb49b1e8..d66f70ac 100644 --- a/sign/tbls/tbls_test.go +++ b/sign/tbls/tbls_test.go @@ -3,21 +3,21 @@ package tbls import ( "testing" - "github.com/stretchr/testify/require" - "github.com/corestario/kyber/pairing/bn256" + curve "github.com/corestario/kyber/pairing/bls12381" "github.com/corestario/kyber/share" "github.com/corestario/kyber/sign/bls" + "github.com/stretchr/testify/require" ) func TestTBLS(test *testing.T) { var err error msg := []byte("Hello threshold Boneh-Lynn-Shacham") - suite := bn256.NewSuite() + suite := curve.NewBLS12381Suite() n := 10 t := n/2 + 1 - secret := suite.G1().Scalar().Pick(suite.RandomStream()) - priPoly := share.NewPriPoly(suite.G2(), t, secret, suite.RandomStream()) - pubPoly := priPoly.Commit(suite.G2().Point().Base()) + secret := suite.G2().Scalar().Pick(suite.RandomStream()) + priPoly := share.NewPriPoly(suite.G1(), t, secret, suite.RandomStream()) + pubPoly := priPoly.Commit(suite.G1().Point().Base()) sigShares := make([][]byte, 0) for _, x := range priPoly.Shares(n) { sig, err := Sign(suite, x, msg) @@ -29,3 +29,25 @@ func TestTBLS(test *testing.T) { err = bls.Verify(suite, pubPoly.Commit(), msg, sig) require.Nil(test, err) } + +func TestTBLSFail(test *testing.T) { + var err error + msg := []byte("Hello threshold Boneh-Lynn-Shacham") + suite := curve.NewBLS12381Suite() + n := 10 + t := n/2 + 1 + secret := suite.G2().Scalar().Pick(suite.RandomStream()) + priPoly := share.NewPriPoly(suite.G1(), t, secret, suite.RandomStream()) + pubPoly := priPoly.Commit(suite.G1().Point().Base()) + sigShares := make([][]byte, 0) + for _, x := range priPoly.Shares(n) { + sig, err := Sign(suite, x, msg) + require.Nil(test, err) + sigShares = append(sigShares, sig) + } + sig, err := Recover(suite, pubPoly, msg, sigShares, t-1, n) + require.Nil(test, err) + if bls.Verify(suite, pubPoly.Commit(), msg, sig) == nil { + test.Fatal("bls: verification succeeded unexpectedly") + } +} From 355ede7d2fac7d60c0c23b4de598266a1d52f12b Mon Sep 17 00:00:00 2001 From: SK0M0R0H Date: Mon, 5 Oct 2020 00:34:21 +0200 Subject: [PATCH 4/7] GT Point interface --- pairing/bls12381/bls_groups_test.go | 39 +++++++++++------------------ pairing/bls12381/group_gt.go | 20 ++++----------- 2 files changed, 20 insertions(+), 39 deletions(-) diff --git a/pairing/bls12381/bls_groups_test.go b/pairing/bls12381/bls_groups_test.go index 1479ab7e..3c2b316a 100644 --- a/pairing/bls12381/bls_groups_test.go +++ b/pairing/bls12381/bls_groups_test.go @@ -71,14 +71,7 @@ func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { } // Verify additive and multiplicative identities of the generator. - // TODO: Check GT exp - /*fmt.Println("Inverse of base")*/ - //f := ptmp.Base().(*KyberGT).f - //newFp12(nil).inverse(f, f) - //fmt.Printf("\n-Inverse: %v\n", f) - //fmt.Println("Multiply by -1") ptmp.Mul(stmp.SetInt64(-1), nil).Add(ptmp, gen) - /*fmt.Printf(" \n\nChecking equality additive identity\nptmp: %v \n\n zero %v\n", ptmp, pzero)*/ if !ptmp.Equal(pzero) { t.Fatalf("generator additive identity doesn't work: (scalar -1 %v) %v (x) -1 (+) %v = %v != %v the group point identity", stmp.SetInt64(-1), ptmp.Mul(stmp.SetInt64(-1), nil), gen, ptmp.Mul(stmp.SetInt64(-1), nil).Add(ptmp, gen), pzero) @@ -108,7 +101,6 @@ func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { t.Fatalf("Diffie-Hellman didn't work: %v == %v (x) %v != %v (x) %v == %v", dh1, s2, p1, s1, p2, dh2) } points = append(points, dh1) - //t.Logf("shared secret = %v", dh1) // Test secret inverse to get from dh1 back to p1 if primeOrder { @@ -119,7 +111,6 @@ func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { } // Zero and One identity secrets - //println("dh1^0 = ",ptmp.Mul(dh1, szero).String()) if !ptmp.Mul(szero, dh1).Equal(pzero) { t.Fatalf("Encryption with secret=0 didn't work: %v (x) %v == %v != %v", szero, dh1, ptmp, pzero) } @@ -174,23 +165,10 @@ func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { } } - pick := func(rand cipher.Stream) (p kyber.Point) { - defer func() { - /*if err := recover(); err != nil {*/ - //// TODO implement Pick for GT - //p = g.Point().Mul(g.Scalar().Pick(rand), nil) - //return - /*}*/ - }() - p = g.Point().Pick(rand) - return - } - // Test randomly picked points last := gen for i := 0; i < 5; i++ { - // TODO fork kyber and make that an interface - rgen := pick(rand) + rgen := g.Point().Pick(rand) if rgen.Equal(last) { t.Fatalf("Pick() not producing unique points: got %v twice", rgen) } @@ -228,7 +206,7 @@ func testGroup(t *testing.T, g kyber.Group, rand cipher.Stream) []kyber.Point { } buf.Reset() - p := pick(rand) + p := g.Point().Pick(rand) if _, err := p.MarshalTo(buf); err != nil { t.Fatalf("encoding of point fails: " + err.Error()) } @@ -270,6 +248,19 @@ func TestKyberGT(t *testing.T) { GroupTest(t, NewGroupGT()) } +func TestGenZero(t *testing.T) { + g := NewGroupGT() + gen := g.Point().Base() + zero := g.Point().Null() + p := g.Point().Base() + q := g.Point().Base() + t.Log(p.Equal(q)) + p.Mul(g.Scalar().SetInt64(-1), p) + q.Add(p, gen) + t.Log(q.Equal(zero)) + t.Log(q.Equal(gen)) +} + func TestKyberPairingG2(t *testing.T) { s := NewBLS12381Suite().(*Suite) a := s.G1().Scalar().Pick(s.RandomStream()) diff --git a/pairing/bls12381/group_gt.go b/pairing/bls12381/group_gt.go index 6890ea75..c08334e4 100644 --- a/pairing/bls12381/group_gt.go +++ b/pairing/bls12381/group_gt.go @@ -30,8 +30,7 @@ func (k *KyberGT) Equal(kk kyber.Point) bool { const gtLength = 576 func (k *KyberGT) Null() kyber.Point { - var zero [gtLength]byte - k.f, _ = bls12381.NewGT().FromBytes(zero[:]) + k.f = bls12381.NewGT().New() return k } @@ -42,16 +41,9 @@ func (k *KyberGT) Base() kyber.Point { e.AddPair(g1, g2) k.f = e.Result() return k - /*var baseReader, _ = blake2b.NewXOF(0, []byte("Quand il y a à manger pour huit, il y en a bien pour dix."))*/ - //_, err := NewGT().rand(baseReader) - //if err != nil { - //panic(err) - //} - /*return k*/ } func (k *KyberGT) Pick(rand cipher.Stream) kyber.Point { - //panic("TODO: bls12-381.GT.Pick()") s := mod.NewInt64(0, bls12381.NewGT().Q()).Pick(rand) k.Base() bls12381.NewGT().Exp(k.f, k.f, &s.(*mod.Int).V) @@ -79,20 +71,18 @@ func (k *KyberGT) Add(a, b kyber.Point) kyber.Point { func (k *KyberGT) Sub(a, b kyber.Point) kyber.Point { aa := a.(*KyberGT) bb := b.(*KyberGT) - bls12381.NewGT().Sub(k.f, aa.f, bb.f) + bls12381.NewGT().Inverse(k.f, bb.f) + bls12381.NewGT().Mul(k.f, aa.f, k.f) return k } func (k *KyberGT) Neg(q kyber.Point) kyber.Point { - //panic("bls12-381: GT is not a full kyber.Point implementation") - aa := newEmptyGT().Null().(*KyberGT) - bb := q.(*KyberGT) - bls12381.NewGT().Sub(k.f, aa.f, bb.f) + aa := q.(*KyberGT) + bls12381.NewGT().Inverse(k.f, aa.f) return k } func (k *KyberGT) Mul(s kyber.Scalar, q kyber.Point) kyber.Point { - //panic("bls12-381: GT is not a full kyber.Point implementation") if q == nil { q = newEmptyGT().Base() } From 5148b68e2d74d3c95edf153ee1bcc4c3db1c1bb6 Mon Sep 17 00:00:00 2001 From: SK0M0R0H Date: Mon, 5 Oct 2020 00:37:39 +0200 Subject: [PATCH 5/7] remove gen-zero test --- pairing/bls12381/bls_groups_test.go | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/pairing/bls12381/bls_groups_test.go b/pairing/bls12381/bls_groups_test.go index 3c2b316a..0a4b5814 100644 --- a/pairing/bls12381/bls_groups_test.go +++ b/pairing/bls12381/bls_groups_test.go @@ -248,19 +248,6 @@ func TestKyberGT(t *testing.T) { GroupTest(t, NewGroupGT()) } -func TestGenZero(t *testing.T) { - g := NewGroupGT() - gen := g.Point().Base() - zero := g.Point().Null() - p := g.Point().Base() - q := g.Point().Base() - t.Log(p.Equal(q)) - p.Mul(g.Scalar().SetInt64(-1), p) - q.Add(p, gen) - t.Log(q.Equal(zero)) - t.Log(q.Equal(gen)) -} - func TestKyberPairingG2(t *testing.T) { s := NewBLS12381Suite().(*Suite) a := s.G1().Scalar().Pick(s.RandomStream()) From 47f89fe576f73b7412ed84d055849931e1ae7615 Mon Sep 17 00:00:00 2001 From: SK0M0R0H Date: Mon, 5 Oct 2020 01:13:58 +0200 Subject: [PATCH 6/7] fix Null/Base for G1 and G2, implementation Pick in the original way --- pairing/bls12381/group_g1.go | 13 +++++++------ pairing/bls12381/group_g2.go | 12 +++++++----- pairing/bls12381/group_gt.go | 1 + 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/pairing/bls12381/group_g1.go b/pairing/bls12381/group_g1.go index 10af6eb9..b84bdff7 100644 --- a/pairing/bls12381/group_g1.go +++ b/pairing/bls12381/group_g1.go @@ -28,18 +28,19 @@ func (k *KyberG1) Equal(k2 kyber.Point) bool { } func (k *KyberG1) Null() kyber.Point { - return newKyberG1(bls12381.NewG1().Zero()) + k.Set(newKyberG1(bls12381.NewG1().Zero())) + return k } func (k *KyberG1) Base() kyber.Point { - return newKyberG1(bls12381.NewG1().One()) + k.Set(newKyberG1(bls12381.NewG1().One())) + return k } func (k *KyberG1) Pick(rand cipher.Stream) kyber.Point { - //panic("not implemented") - var dst, src [32]byte - rand.XORKeyStream(dst[:], src[:]) - return k.Hash(dst[:]) + s := mod.NewInt64(0, bls12381.NewG1().Q()).Pick(rand) + k.Mul(s, nil) + return k } func (k *KyberG1) Set(q kyber.Point) kyber.Point { diff --git a/pairing/bls12381/group_g2.go b/pairing/bls12381/group_g2.go index d18a9ceb..554e28d8 100644 --- a/pairing/bls12381/group_g2.go +++ b/pairing/bls12381/group_g2.go @@ -34,17 +34,19 @@ func (k *KyberG2) Equal(k2 kyber.Point) bool { } func (k *KyberG2) Null() kyber.Point { - return newKyberG2(bls12381.NewG2().Zero()) + k.Set(newKyberG2(bls12381.NewG2().Zero())) + return k } func (k *KyberG2) Base() kyber.Point { - return newKyberG2(bls12381.NewG2().One()) + k.Set(newKyberG2(bls12381.NewG2().One())) + return k } func (k *KyberG2) Pick(rand cipher.Stream) kyber.Point { - var dst, src [32]byte - rand.XORKeyStream(dst[:], src[:]) - return k.Hash(dst[:]) + s := mod.NewInt64(0, bls12381.NewG2().Q()).Pick(rand) + k.Mul(s, nil) + return k } func (k *KyberG2) Set(q kyber.Point) kyber.Point { diff --git a/pairing/bls12381/group_gt.go b/pairing/bls12381/group_gt.go index c08334e4..ba7f0681 100644 --- a/pairing/bls12381/group_gt.go +++ b/pairing/bls12381/group_gt.go @@ -10,6 +10,7 @@ import ( bls12381 "github.com/kilic/bls12-381" ) +// KyberGT is a kyber.Point holding a G1 point on BLS12-381 curve type KyberGT struct { f *bls12381.E } From c6ac2f8b01e74471128f7423eadee9fb8a061cf9 Mon Sep 17 00:00:00 2001 From: SK0M0R0H Date: Mon, 5 Oct 2020 01:50:30 +0200 Subject: [PATCH 7/7] naming update --- pairing/bls12381/bls_groups_test.go | 2 +- pairing/bls12381/group_g1.go | 105 ++++++++++++++-------------- pairing/bls12381/group_g2.go | 104 +++++++++++++-------------- pairing/bls12381/group_gt.go | 100 +++++++++++++------------- pairing/bls12381/scalar.go | 2 +- pairing/bls12381/suite.go | 24 +++---- 6 files changed, 169 insertions(+), 168 deletions(-) diff --git a/pairing/bls12381/bls_groups_test.go b/pairing/bls12381/bls_groups_test.go index 0a4b5814..b34ad115 100644 --- a/pairing/bls12381/bls_groups_test.go +++ b/pairing/bls12381/bls_groups_test.go @@ -1,4 +1,4 @@ -package bls +package bls12381 import ( "bytes" diff --git a/pairing/bls12381/group_g1.go b/pairing/bls12381/group_g1.go index b84bdff7..1c68d69b 100644 --- a/pairing/bls12381/group_g1.go +++ b/pairing/bls12381/group_g1.go @@ -1,4 +1,4 @@ -package bls +package bls12381 import ( "crypto/cipher" @@ -7,104 +7,105 @@ import ( "github.com/corestario/kyber" "github.com/corestario/kyber/group/mod" - bls12381 "github.com/kilic/bls12-381" + bls "github.com/kilic/bls12-381" ) -// KyberG1 is a kyber.Point holding a G1 point on BLS12-381 curve -type KyberG1 struct { - p *bls12381.PointG1 +// pointG1 is a kyber.Point holding a G1 point on BLS12-381 curve +type pointG1 struct { + p *bls.PointG1 } -func NullKyberG1() *KyberG1 { - var p bls12381.PointG1 - return newKyberG1(&p) +func newPointG1() *pointG1 { + var p bls.PointG1 + return toPointG1(&p) } -func newKyberG1(p *bls12381.PointG1) *KyberG1 { - return &KyberG1{p: p} + +func toPointG1(p *bls.PointG1) *pointG1 { + return &pointG1{p: p} } -func (k *KyberG1) Equal(k2 kyber.Point) bool { - return bls12381.NewG1().Equal(k.p, k2.(*KyberG1).p) +func (k *pointG1) Equal(k2 kyber.Point) bool { + return bls.NewG1().Equal(k.p, k2.(*pointG1).p) } -func (k *KyberG1) Null() kyber.Point { - k.Set(newKyberG1(bls12381.NewG1().Zero())) +func (k *pointG1) Null() kyber.Point { + k.Set(toPointG1(bls.NewG1().Zero())) return k } -func (k *KyberG1) Base() kyber.Point { - k.Set(newKyberG1(bls12381.NewG1().One())) +func (k *pointG1) Base() kyber.Point { + k.Set(toPointG1(bls.NewG1().One())) return k } -func (k *KyberG1) Pick(rand cipher.Stream) kyber.Point { - s := mod.NewInt64(0, bls12381.NewG1().Q()).Pick(rand) +func (k *pointG1) Pick(rand cipher.Stream) kyber.Point { + s := mod.NewInt64(0, bls.NewG1().Q()).Pick(rand) k.Mul(s, nil) return k } -func (k *KyberG1) Set(q kyber.Point) kyber.Point { - k.p.Set(q.(*KyberG1).p) +func (k *pointG1) Set(q kyber.Point) kyber.Point { + k.p.Set(q.(*pointG1).p) return k } -func (k *KyberG1) Clone() kyber.Point { - var p bls12381.PointG1 +func (k *pointG1) Clone() kyber.Point { + var p bls.PointG1 p.Set(k.p) - return newKyberG1(&p) + return toPointG1(&p) } -func (k *KyberG1) EmbedLen() int { +func (k *pointG1) EmbedLen() int { panic("bls12-381: unsupported operation") } -func (k *KyberG1) Embed(data []byte, rand cipher.Stream) kyber.Point { +func (k *pointG1) Embed(data []byte, rand cipher.Stream) kyber.Point { panic("bls12-381: unsupported operation") } -func (k *KyberG1) Data() ([]byte, error) { +func (k *pointG1) Data() ([]byte, error) { panic("bls12-381: unsupported operation") } -func (k *KyberG1) Add(a, b kyber.Point) kyber.Point { - aa := a.(*KyberG1) - bb := b.(*KyberG1) - bls12381.NewG1().Add(k.p, aa.p, bb.p) +func (k *pointG1) Add(a, b kyber.Point) kyber.Point { + aa := a.(*pointG1) + bb := b.(*pointG1) + bls.NewG1().Add(k.p, aa.p, bb.p) return k } -func (k *KyberG1) Sub(a, b kyber.Point) kyber.Point { - aa := a.(*KyberG1) - bb := b.(*KyberG1) - bls12381.NewG1().Sub(k.p, aa.p, bb.p) +func (k *pointG1) Sub(a, b kyber.Point) kyber.Point { + aa := a.(*pointG1) + bb := b.(*pointG1) + bls.NewG1().Sub(k.p, aa.p, bb.p) return k } -func (k *KyberG1) Neg(a kyber.Point) kyber.Point { - aa := a.(*KyberG1) - bls12381.NewG1().Neg(k.p, aa.p) +func (k *pointG1) Neg(a kyber.Point) kyber.Point { + aa := a.(*pointG1) + bls.NewG1().Neg(k.p, aa.p) return k } -func (k *KyberG1) Mul(s kyber.Scalar, q kyber.Point) kyber.Point { +func (k *pointG1) Mul(s kyber.Scalar, q kyber.Point) kyber.Point { if q == nil { - q = NullKyberG1().Base() + q = newPointG1().Base() } - bls12381.NewG1().MulScalar(k.p, q.(*KyberG1).p, &s.(*mod.Int).V) + bls.NewG1().MulScalar(k.p, q.(*pointG1).p, &s.(*mod.Int).V) return k } -func (k *KyberG1) MarshalBinary() ([]byte, error) { - return bls12381.NewG1().ToCompressed(k.p), nil +func (k *pointG1) MarshalBinary() ([]byte, error) { + return bls.NewG1().ToCompressed(k.p), nil } -func (k *KyberG1) UnmarshalBinary(buff []byte) error { +func (k *pointG1) UnmarshalBinary(buff []byte) error { var err error - k.p, err = bls12381.NewG1().FromCompressed(buff) + k.p, err = bls.NewG1().FromCompressed(buff) return err } -func (k *KyberG1) MarshalTo(w io.Writer) (int, error) { +func (k *pointG1) MarshalTo(w io.Writer) (int, error) { buf, err := k.MarshalBinary() if err != nil { return 0, err @@ -112,7 +113,7 @@ func (k *KyberG1) MarshalTo(w io.Writer) (int, error) { return w.Write(buf) } -func (k *KyberG1) UnmarshalFrom(r io.Reader) (int, error) { +func (k *pointG1) UnmarshalFrom(r io.Reader) (int, error) { buf := make([]byte, k.MarshalSize()) n, err := io.ReadFull(r, buf) if err != nil { @@ -121,22 +122,22 @@ func (k *KyberG1) UnmarshalFrom(r io.Reader) (int, error) { return n, k.UnmarshalBinary(buf) } -func (k *KyberG1) MarshalSize() int { +func (k *pointG1) MarshalSize() int { return 48 } -func (k *KyberG1) String() string { +func (k *pointG1) String() string { b, _ := k.MarshalBinary() return "bls12-381.G1: " + hex.EncodeToString(b) } -func (k *KyberG1) Hash(m []byte) kyber.Point { - p, _ := bls12381.NewG1().HashToCurve(m, Domain) +func (k *pointG1) Hash(m []byte) kyber.Point { + p, _ := bls.NewG1().HashToCurve(m, Domain) k.p = p return k } -func (k *KyberG1) IsInCorrectGroup() bool { - return bls12381.NewG1().InCorrectSubgroup(k.p) +func (k *pointG1) IsInCorrectGroup() bool { + return bls.NewG1().InCorrectSubgroup(k.p) } diff --git a/pairing/bls12381/group_g2.go b/pairing/bls12381/group_g2.go index 554e28d8..1ba66f81 100644 --- a/pairing/bls12381/group_g2.go +++ b/pairing/bls12381/group_g2.go @@ -1,4 +1,4 @@ -package bls +package bls12381 import ( "crypto/cipher" @@ -8,109 +8,109 @@ import ( "github.com/corestario/kyber" "github.com/corestario/kyber/group/mod" - bls12381 "github.com/kilic/bls12-381" + bls "github.com/kilic/bls12-381" ) // Domain comes from the ciphersuite used by the RFC of this name compatible // with the paired library > v18 var Domain = []byte("BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_") -// KyberG2 is a kyber.Point holding a G2 point on BLS12-381 curve -type KyberG2 struct { - p *bls12381.PointG2 +// pointG2 is a kyber.Point holding a G2 point on BLS12-381 curve +type pointG2 struct { + p *bls.PointG2 } -func NullKyberG2() *KyberG2 { - var p bls12381.PointG2 - return newKyberG2(&p) +func newPointG2() *pointG2 { + var p bls.PointG2 + return toPointG2(&p) } -func newKyberG2(p *bls12381.PointG2) *KyberG2 { - return &KyberG2{p: p} +func toPointG2(p *bls.PointG2) *pointG2 { + return &pointG2{p: p} } -func (k *KyberG2) Equal(k2 kyber.Point) bool { - return bls12381.NewG2().Equal(k.p, k2.(*KyberG2).p) +func (k *pointG2) Equal(k2 kyber.Point) bool { + return bls.NewG2().Equal(k.p, k2.(*pointG2).p) } -func (k *KyberG2) Null() kyber.Point { - k.Set(newKyberG2(bls12381.NewG2().Zero())) +func (k *pointG2) Null() kyber.Point { + k.Set(toPointG2(bls.NewG2().Zero())) return k } -func (k *KyberG2) Base() kyber.Point { - k.Set(newKyberG2(bls12381.NewG2().One())) +func (k *pointG2) Base() kyber.Point { + k.Set(toPointG2(bls.NewG2().One())) return k } -func (k *KyberG2) Pick(rand cipher.Stream) kyber.Point { - s := mod.NewInt64(0, bls12381.NewG2().Q()).Pick(rand) +func (k *pointG2) Pick(rand cipher.Stream) kyber.Point { + s := mod.NewInt64(0, bls.NewG2().Q()).Pick(rand) k.Mul(s, nil) return k } -func (k *KyberG2) Set(q kyber.Point) kyber.Point { - k.p.Set(q.(*KyberG2).p) +func (k *pointG2) Set(q kyber.Point) kyber.Point { + k.p.Set(q.(*pointG2).p) return k } -func (k *KyberG2) Clone() kyber.Point { - var p bls12381.PointG2 +func (k *pointG2) Clone() kyber.Point { + var p bls.PointG2 p.Set(k.p) - return newKyberG2(&p) + return toPointG2(&p) } -func (k *KyberG2) EmbedLen() int { +func (k *pointG2) EmbedLen() int { panic("bls12-381: unsupported operation") } -func (k *KyberG2) Embed(data []byte, rand cipher.Stream) kyber.Point { +func (k *pointG2) Embed(data []byte, rand cipher.Stream) kyber.Point { panic("bls12-381: unsupported operation") } -func (k *KyberG2) Data() ([]byte, error) { +func (k *pointG2) Data() ([]byte, error) { panic("bls12-381: unsupported operation") } -func (k *KyberG2) Add(a, b kyber.Point) kyber.Point { - aa := a.(*KyberG2) - bb := b.(*KyberG2) - bls12381.NewG2().Add(k.p, aa.p, bb.p) +func (k *pointG2) Add(a, b kyber.Point) kyber.Point { + aa := a.(*pointG2) + bb := b.(*pointG2) + bls.NewG2().Add(k.p, aa.p, bb.p) return k } -func (k *KyberG2) Sub(a, b kyber.Point) kyber.Point { - aa := a.(*KyberG2) - bb := b.(*KyberG2) - bls12381.NewG2().Sub(k.p, aa.p, bb.p) +func (k *pointG2) Sub(a, b kyber.Point) kyber.Point { + aa := a.(*pointG2) + bb := b.(*pointG2) + bls.NewG2().Sub(k.p, aa.p, bb.p) return k } -func (k *KyberG2) Neg(a kyber.Point) kyber.Point { - aa := a.(*KyberG2) - bls12381.NewG2().Neg(k.p, aa.p) +func (k *pointG2) Neg(a kyber.Point) kyber.Point { + aa := a.(*pointG2) + bls.NewG2().Neg(k.p, aa.p) return k } -func (k *KyberG2) Mul(s kyber.Scalar, q kyber.Point) kyber.Point { +func (k *pointG2) Mul(s kyber.Scalar, q kyber.Point) kyber.Point { if q == nil { - q = NullKyberG2().Base() + q = newPointG2().Base() } - bls12381.NewG2().MulScalar(k.p, q.(*KyberG2).p, &s.(*mod.Int).V) + bls.NewG2().MulScalar(k.p, q.(*pointG2).p, &s.(*mod.Int).V) return k } -func (k *KyberG2) MarshalBinary() ([]byte, error) { - return bls12381.NewG2().ToCompressed(k.p), nil +func (k *pointG2) MarshalBinary() ([]byte, error) { + return bls.NewG2().ToCompressed(k.p), nil } -func (k *KyberG2) UnmarshalBinary(buff []byte) error { +func (k *pointG2) UnmarshalBinary(buff []byte) error { var err error - k.p, err = bls12381.NewG2().FromCompressed(buff) + k.p, err = bls.NewG2().FromCompressed(buff) return err } -func (k *KyberG2) MarshalTo(w io.Writer) (int, error) { +func (k *pointG2) MarshalTo(w io.Writer) (int, error) { buf, err := k.MarshalBinary() if err != nil { return 0, err @@ -118,7 +118,7 @@ func (k *KyberG2) MarshalTo(w io.Writer) (int, error) { return w.Write(buf) } -func (k *KyberG2) UnmarshalFrom(r io.Reader) (int, error) { +func (k *pointG2) UnmarshalFrom(r io.Reader) (int, error) { buf := make([]byte, k.MarshalSize()) n, err := io.ReadFull(r, buf) if err != nil { @@ -127,17 +127,17 @@ func (k *KyberG2) UnmarshalFrom(r io.Reader) (int, error) { return n, k.UnmarshalBinary(buf) } -func (k *KyberG2) MarshalSize() int { +func (k *pointG2) MarshalSize() int { return 96 } -func (k *KyberG2) String() string { +func (k *pointG2) String() string { b, _ := k.MarshalBinary() return "bls12-381.G1: " + hex.EncodeToString(b) } -func (k *KyberG2) Hash(m []byte) kyber.Point { - pg2, _ := bls12381.NewG2().HashToCurve(m, Domain) +func (k *pointG2) Hash(m []byte) kyber.Point { + pg2, _ := bls.NewG2().HashToCurve(m, Domain) k.p = pg2 return k } @@ -148,6 +148,6 @@ func sha256Hash(in []byte) []byte { return h.Sum(nil) } -func (k *KyberG2) IsInCorrectGroup() bool { - return bls12381.NewG2().InCorrectSubgroup(k.p) +func (k *pointG2) IsInCorrectGroup() bool { + return bls.NewG2().InCorrectSubgroup(k.p) } diff --git a/pairing/bls12381/group_gt.go b/pairing/bls12381/group_gt.go index ba7f0681..d8f50862 100644 --- a/pairing/bls12381/group_gt.go +++ b/pairing/bls12381/group_gt.go @@ -1,4 +1,4 @@ -package bls +package bls12381 import ( "crypto/cipher" @@ -7,95 +7,95 @@ import ( "github.com/corestario/kyber" "github.com/corestario/kyber/group/mod" - bls12381 "github.com/kilic/bls12-381" + bls "github.com/kilic/bls12-381" ) -// KyberGT is a kyber.Point holding a G1 point on BLS12-381 curve -type KyberGT struct { - f *bls12381.E +// pointGT is a kyber.Point holding a G1 point on BLS12-381 curve +type pointGT struct { + f *bls.E } -func newEmptyGT() *KyberGT { - return newKyberGT(bls12381.NewGT().New()) +func newPointGT() *pointGT { + return toPointGT(bls.NewGT().New()) } -func newKyberGT(f *bls12381.E) *KyberGT { - return &KyberGT{ +func toPointGT(f *bls.E) *pointGT { + return &pointGT{ f: f, } } -func (k *KyberGT) Equal(kk kyber.Point) bool { - return k.f.Equal(kk.(*KyberGT).f) +func (k *pointGT) Equal(kk kyber.Point) bool { + return k.f.Equal(kk.(*pointGT).f) } const gtLength = 576 -func (k *KyberGT) Null() kyber.Point { - k.f = bls12381.NewGT().New() +func (k *pointGT) Null() kyber.Point { + k.f = bls.NewGT().New() return k } -func (k *KyberGT) Base() kyber.Point { - g1 := bls12381.NewG1().One() - g2 := bls12381.NewG2().One() - e := bls12381.NewEngine() +func (k *pointGT) Base() kyber.Point { + g1 := bls.NewG1().One() + g2 := bls.NewG2().One() + e := bls.NewEngine() e.AddPair(g1, g2) k.f = e.Result() return k } -func (k *KyberGT) Pick(rand cipher.Stream) kyber.Point { - s := mod.NewInt64(0, bls12381.NewGT().Q()).Pick(rand) +func (k *pointGT) Pick(rand cipher.Stream) kyber.Point { + s := mod.NewInt64(0, bls.NewGT().Q()).Pick(rand) k.Base() - bls12381.NewGT().Exp(k.f, k.f, &s.(*mod.Int).V) + bls.NewGT().Exp(k.f, k.f, &s.(*mod.Int).V) return k } -func (k *KyberGT) Set(q kyber.Point) kyber.Point { - k.f.Set(q.(*KyberGT).f) +func (k *pointGT) Set(q kyber.Point) kyber.Point { + k.f.Set(q.(*pointGT).f) return k } -func (k *KyberGT) Clone() kyber.Point { - kk := newEmptyGT() +func (k *pointGT) Clone() kyber.Point { + kk := newPointGT() kk.Set(k) return kk } -func (k *KyberGT) Add(a, b kyber.Point) kyber.Point { - aa := a.(*KyberGT) - bb := b.(*KyberGT) - bls12381.NewGT().Mul(k.f, aa.f, bb.f) +func (k *pointGT) Add(a, b kyber.Point) kyber.Point { + aa := a.(*pointGT) + bb := b.(*pointGT) + bls.NewGT().Mul(k.f, aa.f, bb.f) return k } -func (k *KyberGT) Sub(a, b kyber.Point) kyber.Point { - aa := a.(*KyberGT) - bb := b.(*KyberGT) - bls12381.NewGT().Inverse(k.f, bb.f) - bls12381.NewGT().Mul(k.f, aa.f, k.f) +func (k *pointGT) Sub(a, b kyber.Point) kyber.Point { + aa := a.(*pointGT) + bb := b.(*pointGT) + bls.NewGT().Inverse(k.f, bb.f) + bls.NewGT().Mul(k.f, aa.f, k.f) return k } -func (k *KyberGT) Neg(q kyber.Point) kyber.Point { - aa := q.(*KyberGT) - bls12381.NewGT().Inverse(k.f, aa.f) +func (k *pointGT) Neg(q kyber.Point) kyber.Point { + aa := q.(*pointGT) + bls.NewGT().Inverse(k.f, aa.f) return k } -func (k *KyberGT) Mul(s kyber.Scalar, q kyber.Point) kyber.Point { +func (k *pointGT) Mul(s kyber.Scalar, q kyber.Point) kyber.Point { if q == nil { - q = newEmptyGT().Base() + q = newPointGT().Base() } - bls12381.NewGT().Exp(k.f, q.(*KyberGT).f, &s.(*mod.Int).V) + bls.NewGT().Exp(k.f, q.(*pointGT).f, &s.(*mod.Int).V) return k } -func (k *KyberGT) MarshalBinary() ([]byte, error) { - return bls12381.NewGT().ToBytes(k.f), nil +func (k *pointGT) MarshalBinary() ([]byte, error) { + return bls.NewGT().ToBytes(k.f), nil } -func (k *KyberGT) MarshalTo(w io.Writer) (int, error) { +func (k *pointGT) MarshalTo(w io.Writer) (int, error) { buf, err := k.MarshalBinary() if err != nil { return 0, err @@ -103,13 +103,13 @@ func (k *KyberGT) MarshalTo(w io.Writer) (int, error) { return w.Write(buf) } -func (k *KyberGT) UnmarshalBinary(buf []byte) error { - fe12, err := bls12381.NewGT().FromBytes(buf) +func (k *pointGT) UnmarshalBinary(buf []byte) error { + fe12, err := bls.NewGT().FromBytes(buf) k.f = fe12 return err } -func (k *KyberGT) UnmarshalFrom(r io.Reader) (int, error) { +func (k *pointGT) UnmarshalFrom(r io.Reader) (int, error) { buf := make([]byte, k.MarshalSize()) n, err := io.ReadFull(r, buf) if err != nil { @@ -118,23 +118,23 @@ func (k *KyberGT) UnmarshalFrom(r io.Reader) (int, error) { return n, k.UnmarshalBinary(buf) } -func (k *KyberGT) MarshalSize() int { +func (k *pointGT) MarshalSize() int { return 576 } -func (k *KyberGT) String() string { +func (k *pointGT) String() string { b, _ := k.MarshalBinary() return "bls12-381.GT: " + hex.EncodeToString(b) } -func (k *KyberGT) EmbedLen() int { +func (k *pointGT) EmbedLen() int { panic("bls12-381.GT.EmbedLen(): unsupported operation") } -func (k *KyberGT) Embed(data []byte, rand cipher.Stream) kyber.Point { +func (k *pointGT) Embed(data []byte, rand cipher.Stream) kyber.Point { panic("bls12-381.GT.Embed(): unsupported operation") } -func (k *KyberGT) Data() ([]byte, error) { +func (k *pointGT) Data() ([]byte, error) { panic("bls12-381.GT.Data(): unsupported operation") } diff --git a/pairing/bls12381/scalar.go b/pairing/bls12381/scalar.go index 334ff628..e7f2cbc9 100644 --- a/pairing/bls12381/scalar.go +++ b/pairing/bls12381/scalar.go @@ -1,4 +1,4 @@ -package bls +package bls12381 import ( "math/big" diff --git a/pairing/bls12381/suite.go b/pairing/bls12381/suite.go index 33bab9ce..ff809013 100644 --- a/pairing/bls12381/suite.go +++ b/pairing/bls12381/suite.go @@ -1,4 +1,4 @@ -package bls +package bls12381 import ( "crypto/cipher" @@ -12,7 +12,7 @@ import ( "github.com/corestario/kyber" "github.com/corestario/kyber/util/random" "github.com/corestario/kyber/xof/blake2xb" - bls12381 "github.com/kilic/bls12-381" + bls "github.com/kilic/bls12-381" ) // GroupChecker allows to verify if a Point is in the correct group or not. For @@ -72,7 +72,7 @@ func (g *groupBls) RandomStream() cipher.Stream { func NewGroupG1() kyber.Group { return &groupBls{ str: "bls12-381.G1", - newPoint: func() kyber.Point { return NullKyberG1() }, + newPoint: func() kyber.Point { return newPointG1() }, isPrime: true, } } @@ -80,7 +80,7 @@ func NewGroupG1() kyber.Group { func NewGroupG2() kyber.Group { return &groupBls{ str: "bls12-381.G2", - newPoint: func() kyber.Point { return NullKyberG2() }, + newPoint: func() kyber.Point { return newPointG2() }, isPrime: false, } } @@ -88,13 +88,13 @@ func NewGroupG2() kyber.Group { func NewGroupGT() kyber.Group { return &groupBls{ str: "bls12-381.GT", - newPoint: func() kyber.Point { return newEmptyGT() }, + newPoint: func() kyber.Point { return newPointGT() }, isPrime: false, } } type Suite struct { - e *bls12381.Engine + e *bls.Engine } func (s *Suite) String() string { @@ -118,7 +118,7 @@ func (s *Suite) Point() kyber.Point { } func NewBLS12381Suite() pairing.Suite { - return &Suite{e: bls12381.NewEngine()} + return &Suite{e: bls.NewEngine()} } func (s *Suite) G1() kyber.Group { @@ -135,15 +135,15 @@ func (s *Suite) GT() kyber.Group { // ValidatePairing implements the `pairing.Suite` interface func (s *Suite) ValidatePairing(p1, p2, p3, p4 kyber.Point) bool { - s.e.AddPair(p1.(*KyberG1).p, p2.(*KyberG2).p) - s.e.AddPairInv(p3.(*KyberG1).p, p4.(*KyberG2).p) + s.e.AddPair(p1.(*pointG1).p, p2.(*pointG2).p) + s.e.AddPairInv(p3.(*pointG1).p, p4.(*pointG2).p) return s.e.Check() } func (s *Suite) Pair(p1, p2 kyber.Point) kyber.Point { - g1point := p1.(*KyberG1).p - g2point := p2.(*KyberG2).p - gt := newKyberGT(s.e.AddPair(g1point, g2point).Result()) + g1point := p1.(*pointG1).p + g2point := p2.(*pointG2).p + gt := toPointGT(s.e.AddPair(g1point, g2point).Result()) return gt }