Example #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
}
Example #2
0
// Verify that this shuffle is a valid shuffle of the specified ciphertexts,
// with respect to the given public keys
func (s *VerifiableShuffle) Verify(ciphers []*elgamal.CipherText, pks []*elgamal.PubKey, nonce string, position int) error {
	c1, c2 := elgamal.Unpack(ciphers)
	shufC1, shufC2 := elgamal.Unpack(s.Shuffled)
	sumpk := elgamal.SumKeys(pks[position:])

	// Check the shuffle proof
	verifier := shuffle.Verifier(pks[0].Suite, pks[0].Base, sumpk.Key, c1, c2, shufC1, shufC2)
	err := proof.HashVerify(pks[0].Suite, "ElGamalShuffle"+nonce, verifier, s.ShuffleProof)
	if err != nil {
		return err
	}

	// Check the decryption proofs
	for i := range ciphers {
		err = pks[position].VerifyProof(s.Shuffled[i], s.Decrypted[i].C2, s.DecryptionProofs[i], nonce)
		if err != nil {
			return err
		}
	}

	return nil
}
Example #3
0
func TestShuffle(T *testing.T) {
	amount := 6
	servers := 3
	suite := ed25519.NewAES128SHA256Ed25519(true)
	sks, pks := make([]*elgamal.PriKey, servers), make([]*elgamal.PubKey, servers)

	// Generate keys for the shuffle servers
	for i := 0; i < servers; i++ {
		sks[i], pks[i] = elgamal.GenerateKeyPair(suite)
	}

	// Generate random plaintexts, encrypt them all to the sum of all server public keys
	sumpks := elgamal.SumKeys(pks)
	points, ciphers := make([]abstract.Point, amount), make([]*elgamal.CipherText, amount)
	for i := 0; i < amount; i++ {
		points[i], _ = suite.Point().Pick(nil, suite.Cipher(nil))
		ciphers[i] = sumpks.Encrypt(points[i])
	}

	var shuffle *VerifiableShuffle
	var err error
	for i := 0; i < servers; i++ {
		shuffle, err = ShuffleDecrypt(suite, ciphers, pks, sks[i], "nonce", i)
		if err != nil {
			T.Fatalf("Failed to create proof: %v", err)
		}
		if err = shuffle.Verify(ciphers, pks, "nonce", i); err != nil {
			T.Fatal("Shuffle verification failed: ", err)
		}

		// These are the ones that should be shuffled by the next server
		ciphers = shuffle.Decrypted
	}

	for i := 0; i < amount; i++ {
		T.Log(str(points[i]), str(shuffle.Decrypted[i].C2))
	}
}