testing in progress
parent
026a879de3
commit
8f75bebaea
|
@ -69,7 +69,6 @@ public class MixingText {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mixingTest() throws InvalidProtocolBufferException, InvalidKeySpecException {
|
||||
// initialization
|
||||
random = new Random();
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue