testing in progress

mixer
tzlil.gon 2016-01-01 00:39:17 +02:00
parent 026a879de3
commit 8f75bebaea
2 changed files with 171 additions and 1 deletions

View File

@ -69,7 +69,6 @@ public class MixingText {
}
}
@Test
public void mixingTest() throws InvalidProtocolBufferException, InvalidKeySpecException {
// initialization
random = new Random();

View File

@ -0,0 +1,171 @@
package mixer;
import com.google.protobuf.ByteString;
import com.google.protobuf.GeneratedMessage;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.Message;
import meerkat.crypto.concrete.ECElGamalEncryption;
import meerkat.crypto.concrete.GlobalCryptoSetup;
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeProver;
import meerkat.crypto.mixnet.Mix2ZeroKnowledgeVerifier;
import meerkat.protobuf.ConcreteCrypto;
import meerkat.protobuf.Crypto;
import meerkat.protobuf.Mixing;
import meerkat.protobuf.Voting;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECPoint;
import org.junit.Before;
import org.junit.Test;
import prover.Prover;
import qilin.primitives.RandomOracle;
import qilin.primitives.concrete.DigestOracle;
import qilin.primitives.concrete.ECElGamal;
import qilin.primitives.concrete.ECGroup;
import qilin.primitives.generic.ElGamal;
import qilin.util.Pair;
import verifier.Verifier;
import java.io.ByteArrayInputStream;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.util.Arrays;
import java.util.Random;
import static org.junit.Assert.assertEquals;
/**
* Created by Tzlil on 12/31/2015.
*/
public class ZeroKnowledgeProofTest {
public final static String ENCRYPTION_KEY_ALGORITHM = "ECDH";
/**
* Serialize an El-Gamal public key into a form acceptable by {@link ECElGamalEncryption}
* @param pk
* @return
*/
public static ConcreteCrypto.ElGamalPublicKey serializePk(ECGroup group, ElGamal.PK<ECPoint> pk) {
ECPoint pkPoint = pk.getPK();
ECParameterSpec params = group.getCurveParams();
ECPublicKeySpec pubKeySpec = new ECPublicKeySpec(pkPoint, params);
try {
KeyFactory fact = KeyFactory.getInstance(ENCRYPTION_KEY_ALGORITHM,
GlobalCryptoSetup.getBouncyCastleProvider());
PublicKey javaPk = fact.generatePublic(pubKeySpec);
ConcreteCrypto.ElGamalPublicKey serializedPk = ConcreteCrypto.ElGamalPublicKey.newBuilder()
.setSubjectPublicKeyInfo(ByteString.copyFrom(javaPk.getEncoded())).build();
return serializedPk;
} catch (Exception e) {
throw new RuntimeException("Error converting public key!", e);
}
}
/**
* Standard (non-threshold) decryption for testing purposes.
* @param secretKey
* @return
*/
public static <T extends Message> T decrypt(Class<T> plaintextMessageType, ECElGamal.SK secretKey, ECGroup group, Crypto.RerandomizableEncryptedMessage opaqueCipher)
throws InvalidProtocolBufferException {
ConcreteCrypto.ElGamalCiphertext cipherText = ConcreteCrypto.ElGamalCiphertext.parseFrom(opaqueCipher.getData());
ByteString c1encoded = cipherText.getC1();
ByteString c2encoded = cipherText.getC2();
ECPoint c1 = group.decode(c1encoded.toByteArray());
ECPoint c2 = group.decode(c2encoded.toByteArray());
assert (group.contains(c1));
assert (group.contains(c2));
ECPoint plaintextEncoded = secretKey.decrypt(new Pair<ECPoint, ECPoint>(c1, c2));
byte[] plaintext = group.injectiveDecode(plaintextEncoded);
ByteArrayInputStream in = new ByteArrayInputStream(plaintext);
try {
java.lang.reflect.Method newBuilder = plaintextMessageType.getMethod("newBuilder");
GeneratedMessage.Builder builder = (GeneratedMessage.Builder) newBuilder.invoke(plaintextMessageType);
builder.mergeDelimitedFrom(in);
return plaintextMessageType.cast(builder.build());
} catch (Exception e) {
throw new InvalidProtocolBufferException("Plaintext protobuf error");
}
}
Random rand = new Random(0); // Insecure deterministic random for testing.
ECElGamal.SK key;
ECGroup group;
ECElGamalEncryption enc;
ConcreteCrypto.ElGamalPublicKey serializedPk;
Mix2ZeroKnowledgeVerifier verifier ;
Mix2ZeroKnowledgeProver prover ;
@Before
public void setup() throws Exception {
group = new ECGroup("secp256k1");
BigInteger sk = ECElGamal.generateSecretKey(group, rand);
key = new ECElGamal.SK(group, sk);
serializedPk = serializePk(group, key);
enc = new ECElGamalEncryption();
enc.init(serializedPk);
RandomOracle randomOracle = new DigestOracle();
verifier = new Verifier(enc,randomOracle);
prover = new Prover(new Random(),enc,randomOracle);
}
Voting.PlaintextBallot genRandomBallot(int numQuestions, int numAnswers, int maxAnswer) {
Voting.PlaintextBallot.Builder ballot = Voting.PlaintextBallot.newBuilder();
ballot.setSerialNumber(rand.nextInt(1000000));
for (int i = 0; i < numQuestions; ++i) {
Voting.BallotAnswer.Builder answers = ballot.addAnswersBuilder();
for (int j = 0; j < numAnswers; ++j) {
answers.addAnswer(rand.nextInt(maxAnswer));
}
}
return ballot.build();
}
public void oneZKPTest() throws InvalidProtocolBufferException {
Voting.PlaintextBallot msg1 = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15.
Voting.PlaintextBallot msg2 = genRandomBallot(2,3,16);
Crypto.EncryptionRandomness r1 = enc.generateRandomness(rand);
Crypto.EncryptionRandomness r2 = enc.generateRandomness(rand);
Crypto.RerandomizableEncryptedMessage e1 = enc.encrypt(msg1, enc.generateRandomness(rand));
Crypto.RerandomizableEncryptedMessage e2 = enc.encrypt(msg2, enc.generateRandomness(rand));
Crypto.RerandomizableEncryptedMessage e1Tag = enc.rerandomize(e1, r1);
Crypto.RerandomizableEncryptedMessage e2Tag = enc.rerandomize(e2, r2);
assert (decrypt(Voting.PlaintextBallot.class, key, group, e1).equals(msg1));
assert (decrypt(Voting.PlaintextBallot.class, key, group, e1Tag).equals(msg1));
assert (decrypt(Voting.PlaintextBallot.class, key, group, e2).equals(msg2));
assert (decrypt(Voting.PlaintextBallot.class, key, group, e2Tag).equals(msg2));
assert (verifier.verify(e1,e2,e1Tag,e2Tag,prover.prove(e1,e2,e1Tag,e2Tag,false,0,0,0,r1,r2)));
}
@Test
public void zeroKnowledgeProofTest() throws InvalidProtocolBufferException {
int tests = 1000;
for (int i = 0; i < tests; i ++){
System.out.println("test " + i);
oneZKPTest();
}
}
}