Bug fixes; Encryption/Rerandomization tests pass
parent
46de34fbfb
commit
984d7457c6
|
@ -152,6 +152,8 @@ task fatCapsule(type: FatCapsule){
|
|||
*===================================*/
|
||||
|
||||
repositories {
|
||||
|
||||
mavenLocal();
|
||||
|
||||
// Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral)
|
||||
maven {
|
||||
|
|
|
@ -22,6 +22,7 @@ import org.slf4j.LoggerFactory;
|
|||
import qilin.primitives.concrete.ECElGamal;
|
||||
import qilin.primitives.concrete.ECGroup;
|
||||
import qilin.primitives.PseudorandomGenerator;
|
||||
import qilin.primitives.generic.ElGamal;
|
||||
import qilin.util.PRGRandom;
|
||||
import qilin.util.Pair;
|
||||
|
||||
|
@ -49,6 +50,12 @@ public class ECElGamalEncryption extends GlobalCryptoSetup implements Encryption
|
|||
|
||||
ECGroup group;
|
||||
|
||||
public ECGroup getGroup() { return group; }
|
||||
|
||||
public ECElGamal.PK getElGamalPK() {
|
||||
return elGamalPK;
|
||||
}
|
||||
|
||||
public void init(ConcreteCrypto.ElGamalPublicKey serializedPk) throws InvalidKeySpecException {
|
||||
AsymmetricKeyParameter keyParam;
|
||||
|
||||
|
|
|
@ -4,18 +4,32 @@ import meerkat.protobuf.BulletinBoardAPI;
|
|||
import meerkat.protobuf.ConcreteCrypto;
|
||||
import meerkat.protobuf.Crypto;
|
||||
import meerkat.protobuf.Voting;
|
||||
import org.bouncycastle.math.ec.ECPoint;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import qilin.primitives.concrete.ECElGamal;
|
||||
import qilin.primitives.concrete.ECGroup;
|
||||
import qilin.primitives.generic.ElGamal;
|
||||
import qilin.util.Pair;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Random;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Test class for {@link ECElGamalEncryption}
|
||||
*/
|
||||
public class ECElGamalEncryptionTest {
|
||||
final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
/**
|
||||
* Number of times to repeat probabilistic tests.
|
||||
*/
|
||||
public final static int CONFIDENCE = 10;
|
||||
|
||||
Random rand = new Random(0); // Insecure deterministic random for testing.
|
||||
|
||||
ECElGamal.SK key;
|
||||
|
@ -37,25 +51,75 @@ public class ECElGamalEncryptionTest {
|
|||
enc.init(serializedPk);
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Testing just the key management
|
||||
* @throws Exception
|
||||
*/
|
||||
@Test
|
||||
public void testEncrypt() throws Exception {
|
||||
Voting.PlaintextBallot msg = Voting.PlaintextBallot.newBuilder()
|
||||
.setSerialNumber(1)
|
||||
.addAnswers( Voting.BallotAnswer.newBuilder()
|
||||
.addAnswer(2)
|
||||
.addAnswer(3)
|
||||
.addAnswer(0)
|
||||
)
|
||||
.addAnswers( Voting.BallotAnswer.newBuilder()
|
||||
.addAnswer(5)
|
||||
.addAnswer(6)
|
||||
.addAnswer(7)
|
||||
)
|
||||
.build();
|
||||
public void testPkSerialization() throws Exception {
|
||||
ECElGamal.PK pk = enc.getElGamalPK();
|
||||
|
||||
Crypto.RerandomizableEncryptedMessage cipherText = enc.encrypt(msg, enc.generateRandomness(rand));
|
||||
ECPoint point = enc.getGroup().sample(rand);
|
||||
Pair<ECPoint, ECPoint> cipher = pk.encrypt(point, pk.getRandom(rand));
|
||||
|
||||
Voting.PlaintextBallot decrypted = ECElGamalUtils.decrypt(Voting.PlaintextBallot.class, key, group, cipherText);
|
||||
ECPoint decrypted = key.decrypt(cipher);
|
||||
|
||||
assertEquals("Decrypted value not equal to encrypted value!", point, decrypted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEncryption() throws Exception {
|
||||
for (int i = 0; i < CONFIDENCE; ++i) {
|
||||
Voting.PlaintextBallot msg = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15.
|
||||
if (msg.getSerializedSize() > enc.getGroup().getInjectiveEncodeMsgLength()) {
|
||||
logger.error("Test Message too big (|msg|={} > max={}), expect failure.",
|
||||
msg.getSerializedSize(), enc.getGroup().getInjectiveEncodeMsgLength());
|
||||
}
|
||||
|
||||
Crypto.RerandomizableEncryptedMessage cipherText = enc.encrypt(msg, enc.generateRandomness(rand));
|
||||
|
||||
Voting.PlaintextBallot decrypted = ECElGamalUtils.decrypt(Voting.PlaintextBallot.class, key, group, cipherText);
|
||||
|
||||
assertEquals("Decrypted value differs from encrypted value (i="+i+")!", msg, decrypted);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRerandomizeModifiesCiphertext() throws Exception {
|
||||
Voting.PlaintextBallot msg = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15.
|
||||
Crypto.RerandomizableEncryptedMessage cipher1 = enc.encrypt(msg, enc.generateRandomness(rand));
|
||||
Crypto.RerandomizableEncryptedMessage cipher2 = enc.rerandomize(cipher1, enc.generateRandomness(rand));
|
||||
assertNotEquals("Rerandomized cipher identical to original!", cipher1, cipher2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRerandomizePreservesPlaintext() throws Exception {
|
||||
for (int i = 0; i < CONFIDENCE; ++i) {
|
||||
Voting.PlaintextBallot msg = genRandomBallot(2,3,16); // 2 questions with 3 answers each, in range 0-15.
|
||||
|
||||
Crypto.RerandomizableEncryptedMessage cipher = enc.encrypt(msg, enc.generateRandomness(rand));
|
||||
Crypto.RerandomizableEncryptedMessage cipher2 = cipher;
|
||||
for (int j = 0; j < CONFIDENCE; ++j)
|
||||
cipher2 = enc.rerandomize(cipher2, enc.generateRandomness(rand));
|
||||
|
||||
Voting.PlaintextBallot decrypted = ECElGamalUtils.decrypt(Voting.PlaintextBallot.class, key, group,
|
||||
cipher2);
|
||||
|
||||
assertEquals("Decrypted value differs from original encrypted value (i="+i+")!", msg, decrypted);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package meerkat.crypto.concrete;
|
||||
|
||||
import com.google.protobuf.*;
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.protobuf.GeneratedMessage;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.protobuf.Message;
|
||||
import meerkat.protobuf.ConcreteCrypto;
|
||||
import meerkat.protobuf.Crypto;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.jce.spec.ECParameterSpec;
|
||||
import org.bouncycastle.jce.spec.ECPublicKeySpec;
|
||||
import org.bouncycastle.math.ec.ECPoint;
|
||||
|
@ -14,13 +16,11 @@ import qilin.primitives.concrete.ECGroup;
|
|||
import qilin.primitives.generic.ElGamal;
|
||||
import qilin.util.Pair;
|
||||
|
||||
import java.lang.reflect.*;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.NoSuchProviderException;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.util.Random;
|
||||
|
||||
/**
|
||||
* utilities for ECElgamal
|
||||
|
@ -73,12 +73,13 @@ public class ECElGamalUtils {
|
|||
|
||||
byte[] plaintext = group.injectiveDecode(plaintextEncoded);
|
||||
|
||||
CodedInputStream ci = CodedInputStream.newInstance(plaintext);
|
||||
ByteArrayInputStream in = new ByteArrayInputStream(plaintext);
|
||||
|
||||
try {
|
||||
java.lang.reflect.Method newBuilder = plaintextMessageType.getMethod("newBuilder");
|
||||
GeneratedMessage.Builder builder = (GeneratedMessage.Builder) newBuilder.invoke(plaintextMessageType);
|
||||
return (T) builder.mergeFrom(ci).build();
|
||||
builder.mergeDelimitedFrom(in);
|
||||
return plaintextMessageType.cast(builder.build());
|
||||
} catch (Exception e) {
|
||||
logger.error("Error parsing incoming message", e);
|
||||
throw new InvalidProtocolBufferException("Plaintext protobuf error");
|
||||
|
|
Loading…
Reference in New Issue