// 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 }
// 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 }