Пример #1
0
// ShuffleDecrypt performs a shuffle and partial decyption of the given ciphertexts, producing correctness
// proofs in the process
func ShuffleDecrypt(suite abstract.Suite, ciphertexts []*elgamal.CipherText,
	pks []*elgamal.PubKey, sk *elgamal.PriKey, nonce string, position int) (*VerifiableShuffle, error) {
	amount := len(ciphertexts)
	if amount == 0 {
		panic("Can't shuffle 0 ciphertexts")
	}

	c1, c2 := elgamal.Unpack(ciphertexts)

	// The ciphertexts are encrypted against these public keys; it still includes ours
	// The proof of the shuffle will also be w.r.t. this public key
	sumpk := elgamal.SumKeys(pks[position:])

	// Do the shuffle, create a proof of its correctness
	shuffledC1, shuffledC2, prover := shuffle.Shuffle(suite, sumpk.Base, sumpk.Key, c1, c2, suite.Cipher(nil))
	shuffleProof, err := proof.HashProve(suite, "ElGamalShuffle"+nonce, suite.Cipher(nil), prover)
	if err != nil {
		return nil, err
	}
	shuffled := elgamal.Pack(shuffledC1, shuffledC2)

	// Do the partial decryption, create a proof of its correctness
	decryptionProofs, decrypted := make([][]byte, amount), make([]*elgamal.CipherText, amount)
	for i := range shuffledC1 {
		decrypted[i], decryptionProofs[i], err = sk.PartialProofDecrypt(shuffled[i], nonce)
		if err != nil {
			return nil, err
		}
	}

	return &VerifiableShuffle{shuffled, decrypted, decryptionProofs, shuffleProof}, nil
}
Пример #2
0
func (v *stateVector) addShuffle(suite abstract.Suite, shuf *shuffler,
	rand abstract.Cipher) error {

	// Get the previous shuffle state.
	i := len(v.States)
	prev := v.States[i-1]
	X, Y := prev.X, prev.Dec

	// Compute the new base using the public keys of the remaining
	// servers.
	H := suite.Point().Null()
	for j := i - 1; j < shuf.N; j++ {
		H = suite.Point().Add(H, shuf.HH[j])
	}

	// Do a key-shuffle.
	Xbar, Ybar, prover := shuffle.Shuffle(suite, nil, H, X, Y, rand)
	prf, err := proof.HashProve(suite, "PairShuffle", rand, prover)
	if err != nil {
		return err
	}

	// Seeded random for the decryption proof.
	seed := abstract.Sum(suite, prf)
	prfRand := suite.Cipher(seed)

	// Scratch space for calculations.
	zs := suite.Secret()
	zp := suite.Point()

	// Peel off a layer of encryption.
	dec := make([]abstract.Point, len(Xbar))
	decPrf := make([]*decryptionProof, len(Xbar))
	for j := range Xbar {
		// Decryption.
		zp.Mul(Xbar[j], shuf.h)
		dec[j] = suite.Point().Sub(Ybar[j], zp)

		// Decryption proof.
		t := suite.Secret().Pick(rand)
		T := suite.Point().Mul(Xbar[j], t)
		c := suite.Secret().Pick(prfRand)
		s := suite.Secret().Add(t, zs.Mul(c, shuf.h))
		decPrf[j] = &decryptionProof{T, s}
	}

	// Append the new state to the state vector.
	state := &shuffleState{H, Xbar, Ybar, dec, prf, decPrf}
	v.States = append(v.States, state)
	return nil
}