Beispiel #1
0
func (ps *PairShuffle) Prove(
	pi []int, g, h abstract.Point, beta []abstract.Scalar,
	X, Y []abstract.Point, rand cipher.Stream,
	ctx proof.ProverContext) error {

	grp := ps.grp
	k := ps.k
	if k != len(pi) || k != len(beta) {
		panic("mismatched vector lengths")
	}

	// Compute pi^-1 inverse permutation
	piinv := make([]int, k)
	for i := 0; i < k; i++ {
		piinv[pi[i]] = i
	}

	// P step 1
	p1 := &ps.p1
	z := grp.Scalar() // scratch

	// pick random secrets
	u := make([]abstract.Scalar, k)
	w := make([]abstract.Scalar, k)
	a := make([]abstract.Scalar, k)
	var tau0, nu, gamma abstract.Scalar
	ctx.PriRand(u, w, a, &tau0, &nu, &gamma)

	// compute public commits
	p1.Gamma = grp.Point().Mul(g, gamma)
	wbeta := grp.Scalar() // scratch
	wbetasum := grp.Scalar().Set(tau0)
	p1.Lambda1 = grp.Point().Null()
	p1.Lambda2 = grp.Point().Null()
	XY := grp.Point()  // scratch
	wu := grp.Scalar() // scratch
	for i := 0; i < k; i++ {
		p1.A[i] = grp.Point().Mul(g, a[i])
		p1.C[i] = grp.Point().Mul(g, z.Mul(gamma, a[pi[i]]))
		p1.U[i] = grp.Point().Mul(g, u[i])
		p1.W[i] = grp.Point().Mul(g, z.Mul(gamma, w[i]))
		wbetasum.Add(wbetasum, wbeta.Mul(w[i], beta[pi[i]]))
		p1.Lambda1.Add(p1.Lambda1, XY.Mul(X[i],
			wu.Sub(w[piinv[i]], u[i])))
		p1.Lambda2.Add(p1.Lambda2, XY.Mul(Y[i],
			wu.Sub(w[piinv[i]], u[i])))
	}
	p1.Lambda1.Add(p1.Lambda1, XY.Mul(g, wbetasum))
	p1.Lambda2.Add(p1.Lambda2, XY.Mul(h, wbetasum))
	if err := ctx.Put(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
	b := make([]abstract.Scalar, k)
	for i := 0; i < k; i++ {
		b[i] = grp.Scalar().Sub(v2.Zrho[i], u[i])
	}
	d := make([]abstract.Scalar, k)
	for i := 0; i < k; i++ {
		d[i] = grp.Scalar().Mul(gamma, b[pi[i]])
		p3.D[i] = grp.Point().Mul(g, d[i])
	}
	if err := ctx.Put(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
	r := make([]abstract.Scalar, k)
	for i := 0; i < k; i++ {
		r[i] = grp.Scalar().Add(a[i], z.Mul(v4.Zlambda, b[i]))
	}
	s := make([]abstract.Scalar, k)
	for i := 0; i < k; i++ {
		s[i] = grp.Scalar().Mul(gamma, r[pi[i]])
	}
	p5.Ztau = grp.Scalar().Neg(tau0)
	for i := 0; i < k; i++ {
		p5.Zsigma[i] = grp.Scalar().Add(w[i], b[pi[i]])
		p5.Ztau.Add(p5.Ztau, z.Mul(b[i], beta[i]))
	}
	if err := ctx.Put(p5); err != nil {
		return err
	}

	// P,V step 6: embedded simple k-shuffle proof
	return ps.pv6.Prove(g, gamma, r, s, rand, ctx)
}
Beispiel #2
0
// The "Simple k-shuffle" defined in section 3 of
// Neff, "Verifiable Mixing (Shuffling) of ElGamal Pairs", 2004.
// The Scalar vector y must be a permutation of Scalar vector x
// but with all elements multiplied by common Scalar gamma.
func (ss *SimpleShuffle) Prove(G abstract.Point, gamma abstract.Scalar,
	x, y []abstract.Scalar, rand cipher.Stream,
	ctx proof.ProverContext) error {

	grp := ss.grp

	k := len(x)
	if k <= 1 {
		panic("can't shuffle length 1 vector")
	}
	if k != len(y) {
		panic("mismatched vector lengths")
	}

	//	// Dump input vectors to show their correspondences
	//	for i := 0; i < k; i++ {
	//		println("x",grp.Scalar().Mul(gamma,x[i]).String())
	//	}
	//	for i := 0; i < k; i++ {
	//		println("y",y[i].String())
	//	}

	// Step 0: inputs
	for i := 0; i < k; i++ { // (4)
		ss.p0.X[i] = grp.Point().Mul(G, x[i])
		ss.p0.Y[i] = grp.Point().Mul(G, y[i])
	}
	if err := ctx.Put(ss.p0); err != nil {
		return err
	}

	// V step 1
	if err := ctx.PubRand(&ss.v1); err != nil {
		return err
	}
	t := ss.v1.Zt

	// P step 2
	gamma_t := grp.Scalar().Mul(gamma, t)
	xhat := make([]abstract.Scalar, k)
	yhat := make([]abstract.Scalar, k)
	for i := 0; i < k; i++ { // (5) and (6) xhat,yhat vectors
		xhat[i] = grp.Scalar().Sub(x[i], t)
		yhat[i] = grp.Scalar().Sub(y[i], gamma_t)
	}
	thlen := 2*k - 1 // (7) theta and Theta vectors
	theta := make([]abstract.Scalar, thlen)
	ctx.PriRand(theta)
	Theta := make([]abstract.Point, thlen+1)
	Theta[0] = thenc(grp, G, nil, nil, theta[0], yhat[0])
	for i := 1; i < k; i++ {
		Theta[i] = thenc(grp, G, theta[i-1], xhat[i],
			theta[i], yhat[i])
	}
	for i := k; i < thlen; i++ {
		Theta[i] = thenc(grp, G, theta[i-1], gamma,
			theta[i], nil)
	}
	Theta[thlen] = thenc(grp, G, theta[thlen-1], gamma, nil, nil)
	ss.p2.Theta = Theta
	if err := ctx.Put(ss.p2); err != nil {
		return err
	}

	// V step 3
	if err := ctx.PubRand(&ss.v3); err != nil {
		return err
	}
	c := ss.v3.Zc

	// P step 4
	alpha := make([]abstract.Scalar, thlen)
	runprod := grp.Scalar().Set(c)
	for i := 0; i < k; i++ { // (8)
		runprod.Mul(runprod, xhat[i])
		runprod.Div(runprod, yhat[i])
		alpha[i] = grp.Scalar().Add(theta[i], runprod)
	}
	gammainv := grp.Scalar().Inv(gamma)
	rungamma := grp.Scalar().Set(c)
	for i := 1; i < k; i++ {
		rungamma.Mul(rungamma, gammainv)
		alpha[thlen-i] = grp.Scalar().Add(theta[thlen-i], rungamma)
	}
	ss.p4.Zalpha = alpha
	if err := ctx.Put(ss.p4); err != nil {
		return err
	}

	return nil
}