Bug fixes; Encryption/Rerandomization tests pass
							parent
							
								
									46de34fbfb
								
							
						
					
					
						commit
						984d7457c6
					
				|  | @ -153,6 +153,8 @@ task fatCapsule(type: FatCapsule){ | |||
| 
 | ||||
| repositories { | ||||
| 
 | ||||
|         mavenLocal(); | ||||
|          | ||||
|         // Prefer the local nexus repository (it may have 3rd party artifacts not found in mavenCentral) | ||||
|         maven {  | ||||
|             url nexusRepository | ||||
|  |  | |||
|  | @ -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(); | ||||
| 
 | ||||
|         ECPoint point = enc.getGroup().sample(rand); | ||||
|         Pair<ECPoint, ECPoint> cipher = pk.encrypt(point, pk.getRandom(rand)); | ||||
| 
 | ||||
|         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