// Open reveals which member private key made the given signature. The return // value will match the result of calling Tag on the member private key in // question. func (priv *PrivateKey) Open(sig []byte) ([]byte, bool) { if len(sig) != 12*32 { return nil, false } t1, ok := new(bn256.G1).Unmarshal(sig[:2*32]) if !ok { return nil, false } t2, ok := new(bn256.G1).Unmarshal(sig[2*32 : 4*32]) if !ok { return nil, false } t3, ok := new(bn256.G1).Unmarshal(sig[4*32 : 6*32]) if !ok { return nil, false } a := new(bn256.G1).ScalarMult(t1, priv.xi1) b := new(bn256.G1).ScalarMult(t2, priv.xi2) a.Add(a, b) a.Neg(a) a.Add(t3, a) return a.Marshal(), true }
// Update alters mem to create a member private key for an updated Group. (Note // that the Group of mem must also be updated.) This functions returns false if // mem is the member private key that has been revoked. func (mem *MemberKey) Update(r *Revocation) bool { if mem.x.Cmp(r.x) == 0 { return false } d := new(big.Int).Sub(mem.x, r.x) d.Mod(d, bn256.Order) d.ModInverse(d, bn256.Order) newA := new(bn256.G1).ScalarMult(r.a, d) t := new(bn256.G1).ScalarMult(mem.a, d) t.Neg(t) newA.Add(newA, t) mem.a = newA return true }
func TestG1(t *testing.T) { cmp := func(got *G1, want *bn256.G1) 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(k *big.Int) error { var ( got = new(G1).ScalarBaseMult(k) gotB = got.Marshal() want = new(bn256.G1).ScalarBaseMult(k) ) if g, w := got.String(), want.String(); g != w { // TODO: Minor implementation difference causes String for // golang.org/x/crypto/bn256.G1 to return (1, -2) for k=1, // while (1, 65000549695646603732796438742359905742825358107623003571877145026864184071781) // for this package. The two are identical since // (-2 mod p) == 65000549695646603732796438742359905742825358107623003571877145026864184071781 // So, ignore that difference. if k.Cmp(big.NewInt(1)) == 0 { w = "bn256.G1(1, 65000549695646603732796438742359905742825358107623003571877145026864184071781)" } if g != w { return fmt.Errorf("k=%v: String: Got %q, want %q", k, g, w) } } if err := cmp(got, want); err != nil { return fmt.Errorf("k=%v: ScalarBaseMult: %v", k, err) } if err := cmp( new(G1).Add(got, new(G1).ScalarBaseMult(big.NewInt(3))), new(bn256.G1).Add(want, new(bn256.G1).ScalarBaseMult(big.NewInt(3))), ); err != nil { return fmt.Errorf("k=%v: Add: %v", k, err) } if err := cmp(new(G1).Neg(got), new(bn256.G1).Neg(want)); err != nil { return fmt.Errorf("k=%v: Neg: %v", k, err) } // Unmarshal and Marshal again. unmarshaled, ok := new(G1).Unmarshal(gotB) if !ok { return fmt.Errorf("k=%v: Unmarshal failed", k) } again := unmarshaled.Marshal() if !bytes.Equal(gotB, again) { return fmt.Errorf("k=%v: Umarshal+Marshal: Got %v, want %v", k, again, gotB) } return nil } if err := onetest(big.NewInt(0)); err != nil { t.Error(err) } if err := onetest(big.NewInt(1)); err != nil { t.Error(err) } for i := 0; i < 100; i++ { k, err := rand.Int(rand.Reader, p) if err != nil { t.Fatal(err) } if err := onetest(k); 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 }