// Copyright 2012 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package bn256 import ( "bytes" "crypto/rand" "math/big" "testing" ) func TestGFp2Invert(t *testing.T) { pool := new(bnPool) a := newGFp2(pool) a.x.SetString("23423492374", 10) a.y.SetString("12934872398472394827398470", 10) inv := newGFp2(pool) inv.Invert(a, pool) b := newGFp2(pool).Mul(inv, a, pool) if b.x.Int64() != 0 || b.y.Int64() != 1 { t.Fatalf("bad result for a^-1*a: %s %s", b.x, b.y) } a.Put(pool) b.Put(pool) inv.Put(pool) if c := pool.Count(); c > 0 { t.Errorf("Pool count non-zero: %d\n", c) } } func isZero(n *big.Int) bool { return new(big.Int).Mod(n, p).Int64() == 0 } func isOne(n *big.Int) bool { return new(big.Int).Mod(n, p).Int64() == 1 } func TestGFp6Invert(t *testing.T) { pool := new(bnPool) a := newGFp6(pool) a.x.x.SetString("239487238491", 10) a.x.y.SetString("2356249827341", 10) a.y.x.SetString("082659782", 10) a.y.y.SetString("182703523765", 10) a.z.x.SetString("978236549263", 10) a.z.y.SetString("64893242", 10) inv := newGFp6(pool) inv.Invert(a, pool) b := newGFp6(pool).Mul(inv, a, pool) if !isZero(b.x.x) || !isZero(b.x.y) || !isZero(b.y.x) || !isZero(b.y.y) || !isZero(b.z.x) || !isOne(b.z.y) { t.Fatalf("bad result for a^-1*a: %s", b) } a.Put(pool) b.Put(pool) inv.Put(pool) if c := pool.Count(); c > 0 { t.Errorf("Pool count non-zero: %d\n", c) } } func TestGFp12Invert(t *testing.T) { pool := new(bnPool) a := newGFp12(pool) a.x.x.x.SetString("239846234862342323958623", 10) a.x.x.y.SetString("2359862352529835623", 10) a.x.y.x.SetString("928836523", 10) a.x.y.y.SetString("9856234", 10) a.x.z.x.SetString("235635286", 10) a.x.z.y.SetString("5628392833", 10) a.y.x.x.SetString("252936598265329856238956532167968", 10) a.y.x.y.SetString("23596239865236954178968", 10) a.y.y.x.SetString("95421692834", 10) a.y.y.y.SetString("236548", 10) a.y.z.x.SetString("924523", 10) a.y.z.y.SetString("12954623", 10) inv := newGFp12(pool) inv.Invert(a, pool) b := newGFp12(pool).Mul(inv, a, pool) if !isZero(b.x.x.x) || !isZero(b.x.x.y) || !isZero(b.x.y.x) || !isZero(b.x.y.y) || !isZero(b.x.z.x) || !isZero(b.x.z.y) || !isZero(b.y.x.x) || !isZero(b.y.x.y) || !isZero(b.y.y.x) || !isZero(b.y.y.y) || !isZero(b.y.z.x) || !isOne(b.y.z.y) { t.Fatalf("bad result for a^-1*a: %s", b) } a.Put(pool) b.Put(pool) inv.Put(pool) if c := pool.Count(); c > 0 { t.Errorf("Pool count non-zero: %d\n", c) } } func TestCurveImpl(t *testing.T) { pool := new(bnPool) g := &curvePoint{ pool.Get().SetInt64(1), pool.Get().SetInt64(-2), pool.Get().SetInt64(1), pool.Get().SetInt64(0), } x := pool.Get().SetInt64(32498273234) X := newCurvePoint(pool).Mul(g, x, pool) y := pool.Get().SetInt64(98732423523) Y := newCurvePoint(pool).Mul(g, y, pool) s1 := newCurvePoint(pool).Mul(X, y, pool).MakeAffine(pool) s2 := newCurvePoint(pool).Mul(Y, x, pool).MakeAffine(pool) if s1.x.Cmp(s2.x) != 0 || s2.x.Cmp(s1.x) != 0 { t.Errorf("DH points don't match: (%s, %s) (%s, %s)", s1.x, s1.y, s2.x, s2.y) } pool.Put(x) X.Put(pool) pool.Put(y) Y.Put(pool) s1.Put(pool) s2.Put(pool) g.Put(pool) if c := pool.Count(); c > 0 { t.Errorf("Pool count non-zero: %d\n", c) } } func TestOrderG1(t *testing.T) { g := new(G1).ScalarBaseMult(Order) if !g.p.IsInfinity() { t.Error("G1 has incorrect order") } one := new(G1).ScalarBaseMult(new(big.Int).SetInt64(1)) g.Add(g, one) g.p.MakeAffine(nil) if g.p.x.Cmp(one.p.x) != 0 || g.p.y.Cmp(one.p.y) != 0 { t.Errorf("1+0 != 1 in G1") } } func TestOrderG2(t *testing.T) { g := new(G2).ScalarBaseMult(Order) if !g.p.IsInfinity() { t.Error("G2 has incorrect order") } one := new(G2).ScalarBaseMult(new(big.Int).SetInt64(1)) g.Add(g, one) g.p.MakeAffine(nil) if g.p.x.x.Cmp(one.p.x.x) != 0 || g.p.x.y.Cmp(one.p.x.y) != 0 || g.p.y.x.Cmp(one.p.y.x) != 0 || g.p.y.y.Cmp(one.p.y.y) != 0 { t.Errorf("1+0 != 1 in G2") } } func TestOrderGT(t *testing.T) { gt := Pair(&G1{curveGen}, &G2{twistGen}) g := new(GT).ScalarMult(gt, Order) if !g.p.IsOne() { t.Error("GT has incorrect order") } } func TestBilinearity(t *testing.T) { for i := 0; i < 2; i++ { a, p1, _ := RandomG1(rand.Reader) b, p2, _ := RandomG2(rand.Reader) e1 := Pair(p1, p2) e2 := Pair(&G1{curveGen}, &G2{twistGen}) e2.ScalarMult(e2, a) e2.ScalarMult(e2, b) minusE2 := new(GT).Neg(e2) e1.Add(e1, minusE2) if !e1.p.IsOne() { t.Fatalf("bad pairing result: %s", e1) } } } func TestG1Marshal(t *testing.T) { g := new(G1).ScalarBaseMult(new(big.Int).SetInt64(1)) form := g.Marshal() _, ok := new(G1).Unmarshal(form) if !ok { t.Fatalf("failed to unmarshal") } g.ScalarBaseMult(Order) form = g.Marshal() g2, ok := new(G1).Unmarshal(form) if !ok { t.Fatalf("failed to unmarshal ∞") } if !g2.p.IsInfinity() { t.Fatalf("∞ unmarshaled incorrectly") } } func TestG2Marshal(t *testing.T) { g := new(G2).ScalarBaseMult(new(big.Int).SetInt64(1)) form := g.Marshal() _, ok := new(G2).Unmarshal(form) if !ok { t.Fatalf("failed to unmarshal") } g.ScalarBaseMult(Order) form = g.Marshal() g2, ok := new(G2).Unmarshal(form) if !ok { t.Fatalf("failed to unmarshal ∞") } if !g2.p.IsInfinity() { t.Fatalf("∞ unmarshaled incorrectly") } } func TestG1Identity(t *testing.T) { g := new(G1).ScalarBaseMult(new(big.Int).SetInt64(0)) if !g.p.IsInfinity() { t.Error("failure") } } func TestG2Identity(t *testing.T) { g := new(G2).ScalarBaseMult(new(big.Int).SetInt64(0)) if !g.p.IsInfinity() { t.Error("failure") } } func TestTripartiteDiffieHellman(t *testing.T) { a, _ := rand.Int(rand.Reader, Order) b, _ := rand.Int(rand.Reader, Order) c, _ := rand.Int(rand.Reader, Order) pa, _ := new(G1).Unmarshal(new(G1).ScalarBaseMult(a).Marshal()) qa, _ := new(G2).Unmarshal(new(G2).ScalarBaseMult(a).Marshal()) pb, _ := new(G1).Unmarshal(new(G1).ScalarBaseMult(b).Marshal()) qb, _ := new(G2).Unmarshal(new(G2).ScalarBaseMult(b).Marshal()) pc, _ := new(G1).Unmarshal(new(G1).ScalarBaseMult(c).Marshal()) qc, _ := new(G2).Unmarshal(new(G2).ScalarBaseMult(c).Marshal()) k1 := Pair(pb, qc) k1.ScalarMult(k1, a) k1Bytes := k1.Marshal() k2 := Pair(pc, qa) k2.ScalarMult(k2, b) k2Bytes := k2.Marshal() k3 := Pair(pa, qb) k3.ScalarMult(k3, c) k3Bytes := k3.Marshal() if !bytes.Equal(k1Bytes, k2Bytes) || !bytes.Equal(k2Bytes, k3Bytes) { t.Errorf("keys didn't agree") } } func BenchmarkPairing(b *testing.B) { for i := 0; i < b.N; i++ { Pair(&G1{curveGen}, &G2{twistGen}) } }