func (g *Group) precompute() { g.ehw = bn256.Pair(g.h, g.w) g.ehg2 = bn256.Pair(g.h, g.g2) t := bn256.Pair(g.g1, g.g2) g.minusEg1g2 = new(bn256.GT).Neg(t) }
func BenchmarkPairGo(b *testing.B) { pa := new(bn256.G1).ScalarBaseMult(benchmarkA) qb := new(bn256.G2).ScalarBaseMult(benchmarkB) b.ResetTimer() for i := 0; i < b.N; i++ { bn256.Pair(pa, qb) } }
func TestPairing(t *testing.T) { a := bn256.Pair(new(bn256.G1).ScalarBaseMult(big.NewInt(2)), new(bn256.G2).ScalarBaseMult(big.NewInt(1))).Marshal() b := Pair(new(G1).ScalarBaseMult(big.NewInt(2)), new(G2).ScalarBaseMult(big.NewInt(1))).Marshal() base := Pair(new(G1).ScalarBaseMult(big.NewInt(1)), new(G2).ScalarBaseMult(big.NewInt(1))) b2 := new(GT).Add(base, base).Marshal() if !bytes.Equal(a, b) { t.Errorf("Pairings differ\ngot: %x\nwant: %x", a, b) } if !bytes.Equal(b, b2) { t.Errorf("Pair(2,1) != 2*Pair(1,1)\ngot: %x\nwant: %x", b, b2) } }
func TestPair(t *testing.T) { cmp := func(got *GT, want *bn256.GT) error { if gotB, wantB := got.Marshal(), want.Marshal(); !bytes.Equal(gotB, wantB) { return fmt.Errorf("Got %v want %v", got, want) } return nil } onetest := func(k1, k2 *big.Int) error { var ( got = Pair(new(G1).ScalarBaseMult(k1), new(G2).ScalarBaseMult(k2)) want = bn256.Pair(new(bn256.G1).ScalarBaseMult(k1), new(bn256.G2).ScalarBaseMult(k2)) gotB = got.Marshal() ) if g, w := got.String(), want.String(); g != w { return fmt.Errorf("(%v, %v): String: Got %q, want %q", k1, k2, g, w) } if err := cmp(got, want); err != nil { return fmt.Errorf("(%v, %v): Pair: %v", k1, k2, err) } if err := cmp(new(GT).ScalarMult(got, k1), new(bn256.GT).ScalarMult(want, k1)); err != nil { return fmt.Errorf("(%v, %v): ScalarMult: %v", k1, k2, err) } if err := cmp( new(GT).Add(new(GT).ScalarMult(got, k1), new(GT).ScalarMult(got, k2)), new(bn256.GT).Add(new(bn256.GT).ScalarMult(want, k1), new(bn256.GT).ScalarMult(want, k2)), ); err != nil { return fmt.Errorf("(%v, %v): Add: %v", k1, k2, err) } if err := cmp(new(GT).Neg(got), new(bn256.GT).Neg(want)); err != nil { return fmt.Errorf("(%v, %v): Neg: %v", k1, k2, err) } // Unmarshal and Marshal again. unmarshaled, ok := new(GT).Unmarshal(gotB) if !ok { return fmt.Errorf("(%v, %v): Unmarshal failed", k1, k2) } again := unmarshaled.Marshal() if !bytes.Equal(gotB, again) { return fmt.Errorf("(%v, %v): Umarshal+Marshal: Got %v, want %v", k1, k2, again, gotB) } return nil } big0, big1 := big.NewInt(0), big.NewInt(1) for _, test := range [][2]*big.Int{ {big0, big0}, {big0, big1}, {big1, big0}, {big1, big1}, } { if err := onetest(test[0], test[1]); err != nil { t.Error(err) } } for i := 0; i < 25; i++ { k1, err := rand.Int(rand.Reader, p) if err != nil { t.Fatal(err) } k2, err := rand.Int(rand.Reader, p) if err != nil { t.Fatal(err) } if err := onetest(k1, k2); err != nil { t.Errorf("%v (random test #%d)", err, i) } } }
// Verify verifies that sig is a valid signature of digest using the given hash // function. func (g *Group) Verify(digest []byte, hashFunc hash.Hash, sig []byte) bool { if len(sig) != SignatureSize { return false } t1, ok := new(bn256.G1).Unmarshal(sig[:2*32]) if !ok { return false } t2, ok := new(bn256.G1).Unmarshal(sig[2*32 : 4*32]) if !ok { return false } t3, ok := new(bn256.G1).Unmarshal(sig[4*32 : 6*32]) if !ok { return false } c := new(big.Int).SetBytes(sig[6*32 : 7*32]) salpha := new(big.Int).SetBytes(sig[7*32 : 8*32]) sbeta := new(big.Int).SetBytes(sig[8*32 : 9*32]) sx := new(big.Int).SetBytes(sig[9*32 : 10*32]) sdelta1 := new(big.Int).SetBytes(sig[10*32 : 11*32]) sdelta2 := new(big.Int).SetBytes(sig[11*32 : 12*32]) r1 := new(bn256.G1).ScalarMult(g.u, salpha) tmp := new(big.Int).Neg(c) tmp.Add(tmp, bn256.Order) tmpg := new(bn256.G1).ScalarMult(t1, tmp) r1.Add(r1, tmpg) r2 := new(bn256.G1).ScalarMult(g.v, sbeta) tmpg.ScalarMult(t2, tmp) r2.Add(r2, tmpg) r4 := new(bn256.G1).ScalarMult(t1, sx) tmp.Neg(sdelta1) tmp.Add(tmp, bn256.Order) tmpg.ScalarMult(g.u, tmp) r4.Add(r4, tmpg) r5 := new(bn256.G1).ScalarMult(t2, sx) tmp.Neg(sdelta2) tmp.Add(tmp, bn256.Order) tmpg.ScalarMult(g.v, tmp) r5.Add(r5, tmpg) r3 := bn256.Pair(t3, g.g2) r3.ScalarMult(r3, sx) tmp.Neg(salpha) tmp.Sub(tmp, sbeta) tmp.Mod(tmp, bn256.Order) tmpgt := new(bn256.GT).ScalarMult(g.ehw, tmp) r3.Add(r3, tmpgt) tmp.Neg(sdelta1) tmp.Sub(tmp, sdelta2) tmp.Mod(tmp, bn256.Order) tmpgt.ScalarMult(g.ehg2, tmp) r3.Add(r3, tmpgt) et3w := bn256.Pair(t3, g.w) et3w.Add(et3w, g.minusEg1g2) et3w.ScalarMult(et3w, c) r3.Add(r3, et3w) hashFunc.Reset() hashFunc.Write(digest) hashFunc.Write(t1.Marshal()) hashFunc.Write(t2.Marshal()) hashFunc.Write(t3.Marshal()) hashFunc.Write(r1.Marshal()) hashFunc.Write(r2.Marshal()) hashFunc.Write(r3.Marshal()) hashFunc.Write(r4.Marshal()) hashFunc.Write(r5.Marshal()) cprime := new(big.Int).SetBytes(hashFunc.Sum(nil)) cprime.Mod(cprime, bn256.Order) return cprime.Cmp(c) == 0 }
// Sign computes a group signature of digest using the given hash function. func (mem *MemberKey) Sign(r io.Reader, digest []byte, hashFunc hash.Hash) ([]byte, error) { var rnds [7]*big.Int for i := range rnds { var err error rnds[i], err = randomZp(r) if err != nil { return nil, err } } alpha := rnds[0] beta := rnds[1] t1 := new(bn256.G1).ScalarMult(mem.u, alpha) t2 := new(bn256.G1).ScalarMult(mem.v, beta) tmp := new(big.Int).Add(alpha, beta) t3 := new(bn256.G1).ScalarMult(mem.h, tmp) t3.Add(t3, mem.a) delta1 := new(big.Int).Mul(mem.x, alpha) delta1.Mod(delta1, bn256.Order) delta2 := new(big.Int).Mul(mem.x, beta) delta2.Mod(delta2, bn256.Order) ralpha := rnds[2] rbeta := rnds[3] rx := rnds[4] rdelta1 := rnds[5] rdelta2 := rnds[6] r1 := new(bn256.G1).ScalarMult(mem.u, ralpha) r2 := new(bn256.G1).ScalarMult(mem.v, rbeta) r3 := bn256.Pair(t3, mem.g2) r3.ScalarMult(r3, rx) tmp.Neg(ralpha) tmp.Sub(tmp, rbeta) tmp.Mod(tmp, bn256.Order) tmpgt := new(bn256.GT).ScalarMult(mem.ehw, tmp) r3.Add(r3, tmpgt) tmp.Neg(rdelta1) tmp.Sub(tmp, rdelta2) tmp.Mod(tmp, bn256.Order) tmpgt.ScalarMult(mem.ehg2, tmp) r3.Add(r3, tmpgt) r4 := new(bn256.G1).ScalarMult(t1, rx) tmp.Neg(rdelta1) tmp.Add(tmp, bn256.Order) tmpg := new(bn256.G1).ScalarMult(mem.u, tmp) r4.Add(r4, tmpg) r5 := new(bn256.G1).ScalarMult(t2, rx) tmp.Neg(rdelta2) tmp.Add(tmp, bn256.Order) tmpg.ScalarMult(mem.v, tmp) r5.Add(r5, tmpg) t1Bytes := t1.Marshal() t2Bytes := t2.Marshal() t3Bytes := t3.Marshal() hashFunc.Reset() hashFunc.Write(digest) hashFunc.Write(t1Bytes) hashFunc.Write(t2Bytes) hashFunc.Write(t3Bytes) hashFunc.Write(r1.Marshal()) hashFunc.Write(r2.Marshal()) hashFunc.Write(r3.Marshal()) hashFunc.Write(r4.Marshal()) hashFunc.Write(r5.Marshal()) c := new(big.Int).SetBytes(hashFunc.Sum(nil)) c.Mod(c, bn256.Order) salpha := new(big.Int).Mul(c, alpha) salpha.Add(salpha, ralpha) salpha.Mod(salpha, bn256.Order) sbeta := new(big.Int).Mul(c, beta) sbeta.Add(sbeta, rbeta) sbeta.Mod(sbeta, bn256.Order) sx := new(big.Int).Mul(c, mem.x) sx.Add(sx, rx) sx.Mod(sx, bn256.Order) sdelta1 := new(big.Int).Mul(c, delta1) sdelta1.Add(sdelta1, rdelta1) sdelta1.Mod(sdelta1, bn256.Order) sdelta2 := new(big.Int).Mul(c, delta2) sdelta2.Add(sdelta2, rdelta2) sdelta2.Mod(sdelta2, bn256.Order) sig := make([]byte, 0, SignatureSize) sig = append(sig, t1Bytes...) sig = append(sig, t2Bytes...) sig = append(sig, t3Bytes...) sig = appendN(sig, c) sig = appendN(sig, salpha) sig = appendN(sig, sbeta) sig = appendN(sig, sx) sig = appendN(sig, sdelta1) sig = appendN(sig, sdelta2) return sig, nil }