// Verifier for ElGamal Pair Shuffle proofs. func (ps *PairShuffle) Verify( g, h abstract.Point, X, Y, Xbar, Ybar []abstract.Point, ctx proof.VerifierContext) error { // Validate all vector lengths grp := ps.grp k := ps.k if len(X) != k || len(Y) != k || len(Xbar) != k || len(Ybar) != k { panic("mismatched vector lengths") } // P step 1 p1 := &ps.p1 if err := ctx.Get(p1); err != nil { return err } // V step 2 v2 := &ps.v2 if err := ctx.PubRand(v2); err != nil { return err } B := make([]abstract.Point, k) for i := 0; i < k; i++ { P := grp.Point().Mul(g, v2.Zrho[i]) B[i] = P.Sub(P, p1.U[i]) } // P step 3 p3 := &ps.p3 if err := ctx.Get(p3); err != nil { return err } // V step 4 v4 := &ps.v4 if err := ctx.PubRand(v4); err != nil { return err } // P step 5 p5 := &ps.p5 if err := ctx.Get(p5); err != nil { return err } // P,V step 6: simple k-shuffle if err := ps.pv6.Verify(g, p1.Gamma, ctx); err != nil { return err } // V step 7 Phi1 := grp.Point().Null() Phi2 := grp.Point().Null() P := grp.Point() // scratch Q := grp.Point() // scratch for i := 0; i < k; i++ { Phi1 = Phi1.Add(Phi1, P.Mul(Xbar[i], p5.Zsigma[i])) // (31) Phi1 = Phi1.Sub(Phi1, P.Mul(X[i], v2.Zrho[i])) Phi2 = Phi2.Add(Phi2, P.Mul(Ybar[i], p5.Zsigma[i])) // (32) Phi2 = Phi2.Sub(Phi2, P.Mul(Y[i], v2.Zrho[i])) // println("i",i) if !P.Mul(p1.Gamma, p5.Zsigma[i]).Equal( // (33) Q.Add(p1.W[i], p3.D[i])) { return errors.New("invalid PairShuffleProof") } } // println("last") // println("Phi1",Phi1.String()); // println("Phi2",Phi2.String()); // println("1",P.Add(p1.Lambda1,Q.Mul(g,p5.Ztau)).String()); // println("2",P.Add(p1.Lambda2,Q.Mul(h,p5.Ztau)).String()); if !P.Add(p1.Lambda1, Q.Mul(g, p5.Ztau)).Equal(Phi1) || // (34) !P.Add(p1.Lambda2, Q.Mul(h, p5.Ztau)).Equal(Phi2) { // (35) return errors.New("invalid PairShuffleProof") } return nil }
// Verifier for Neff simple k-shuffle proofs. func (ss *SimpleShuffle) Verify(G, Gamma abstract.Point, ctx proof.VerifierContext) error { grp := ss.grp // extract proof transcript X := ss.p0.X Y := ss.p0.Y Theta := ss.p2.Theta alpha := ss.p4.Zalpha // Validate all vector lengths k := len(Y) thlen := 2*k - 1 if k <= 1 || len(Y) != k || len(Theta) != thlen+1 || len(alpha) != thlen { return errors.New("malformed SimpleShuffleProof") } // check verifiable challenges (usually by reproducing a hash) if err := ctx.Get(ss.p0); err != nil { return err } if err := ctx.PubRand(&ss.v1); err != nil { // fills in v1 return err } t := ss.v1.Zt if err := ctx.Get(ss.p2); err != nil { return err } if err := ctx.PubRand(&ss.v3); err != nil { // fills in v3 return err } c := ss.v3.Zc if err := ctx.Get(ss.p4); err != nil { return err } // Verifier step 5 negt := grp.Scalar().Neg(t) U := grp.Point().Mul(G, negt) W := grp.Point().Mul(Gamma, negt) Xhat := make([]abstract.Point, k) Yhat := make([]abstract.Point, k) for i := 0; i < k; i++ { Xhat[i] = grp.Point().Add(X[i], U) Yhat[i] = grp.Point().Add(Y[i], W) } P := grp.Point() // scratch variables Q := grp.Point() s := grp.Scalar() good := true good = good && thver(Xhat[0], Yhat[0], Theta[0], P, Q, c, alpha[0], s) for i := 1; i < k; i++ { good = good && thver(Xhat[i], Yhat[i], Theta[i], P, Q, alpha[i-1], alpha[i], s) } for i := k; i < thlen; i++ { good = good && thver(Gamma, G, Theta[i], P, Q, alpha[i-1], alpha[i], s) } good = good && thver(Gamma, G, Theta[thlen], P, Q, alpha[thlen-1], c, s) if !good { return errors.New("incorrect SimpleShuffleProof") } return nil }