EC encryption code; compiles but not tested
parent
c3e651e34b
commit
b8cc3feedb
|
@ -90,7 +90,6 @@ idea {
|
|||
|
||||
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
|
||||
|
||||
println "Adding $srcDir"
|
||||
// add protobuf generated sources to generated source dir.
|
||||
if ("test".equals(sourceSet.name)) {
|
||||
testSourceDirs += file(srcDir)
|
||||
|
|
|
@ -46,6 +46,7 @@ dependencies {
|
|||
compile 'com.google.protobuf:protobuf-java:3.+'
|
||||
|
||||
// Crypto
|
||||
compile 'org.factcenter.qilin:qilin:1.+'
|
||||
compile 'org.bouncycastle:bcprov-jdk15on:1.53'
|
||||
compile 'org.bouncycastle:bcpkix-jdk15on:1.53'
|
||||
|
||||
|
@ -81,7 +82,6 @@ idea {
|
|||
|
||||
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
|
||||
|
||||
println "Adding $srcDir"
|
||||
// add protobuf generated sources to generated source dir.
|
||||
if ("test".equals(sourceSet.name)) {
|
||||
testSourceDirs += file(srcDir)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package meerkat.crypto;
|
||||
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.protobuf.Message;
|
||||
import static meerkat.protobuf.Crypto.*;
|
||||
|
||||
|
@ -15,6 +16,6 @@ public interface Encryption {
|
|||
*/
|
||||
RerandomizableEncryptedMessage encrypt(Message plaintext, EncryptionRandomness rnd); // TODO: type of exception; throws
|
||||
|
||||
RerandomizableEncryptedMessage rerandomize(RerandomizableEncryptedMessage msg, EncryptionRandomness rnd);
|
||||
RerandomizableEncryptedMessage rerandomize(RerandomizableEncryptedMessage msg, EncryptionRandomness rnd) throws InvalidProtocolBufferException;
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
package meerkat.crypto.concrete;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import com.google.protobuf.InvalidProtocolBufferException;
|
||||
import com.google.protobuf.Message;
|
||||
import meerkat.crypto.Encryption;
|
||||
import meerkat.protobuf.ConcreteCrypto;
|
||||
import meerkat.protobuf.Crypto;
|
||||
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
|
||||
import org.bouncycastle.crypto.params.ECDomainParameters;
|
||||
import org.bouncycastle.crypto.params.ECKeyParameters;
|
||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.bouncycastle.crypto.util.PublicKeyFactory;
|
||||
import org.bouncycastle.jce.spec.ECParameterSpec;
|
||||
import org.bouncycastle.math.ec.ECCurve;
|
||||
import org.bouncycastle.math.ec.ECFieldElement;
|
||||
import org.bouncycastle.math.ec.ECPoint;
|
||||
import org.bouncycastle.util.BigIntegers;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import qilin.primitives.concrete.ECElGamal;
|
||||
import qilin.primitives.concrete.ECGroup;
|
||||
import qilin.primitives.PseudorandomGenerator;
|
||||
import qilin.util.PRGRandom;
|
||||
import qilin.util.Pair;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.security.spec.*;
|
||||
|
||||
/**
|
||||
* Created by talm on 17/11/15.
|
||||
*/
|
||||
public class ECElGamalEncryption implements Encryption {
|
||||
final Logger logger = LoggerFactory.getLogger(getClass());
|
||||
|
||||
public final static String KEY_ALGORITHM = "ECDH";
|
||||
|
||||
/**
|
||||
* The Qilin format El-Gamal public key
|
||||
*/
|
||||
ECElGamal.PK elGamalPK;
|
||||
|
||||
ECCurve curve;
|
||||
|
||||
ECGroup group;
|
||||
|
||||
public void init(ConcreteCrypto.ElGamalPublicKey serializedPk) throws InvalidKeySpecException {
|
||||
AsymmetricKeyParameter keyParam;
|
||||
|
||||
try {
|
||||
keyParam = PublicKeyFactory.createKey(serializedPk.getSubjectPublicKeyInfo().toByteArray());
|
||||
} catch (IOException e) {
|
||||
// Shouldn't every happen
|
||||
logger.error("Invalid Public Key Encoding", e);
|
||||
throw new InvalidKeySpecException("Invalid Public Key Encoding", e);
|
||||
}
|
||||
|
||||
if (!(keyParam instanceof ECPublicKeyParameters)) {
|
||||
logger.error("Public key is a {}, not a valid public EC Key!", keyParam.getClass());
|
||||
throw new InvalidKeySpecException("Not a valid EC public key!");
|
||||
}
|
||||
|
||||
ECDomainParameters params = ((ECKeyParameters) keyParam).getParameters();
|
||||
ECParameterSpec ecParams = new ECParameterSpec(params.getCurve(), params.getG(), params.getN(), params.getH(),
|
||||
params.getSeed());
|
||||
|
||||
curve = params.getCurve();
|
||||
group = new ECGroup(ecParams);
|
||||
|
||||
elGamalPK = new ECElGamal.PK(group, ((ECPublicKeyParameters) keyParam).getQ());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Crypto.RerandomizableEncryptedMessage encrypt(Message plaintext, Crypto.EncryptionRandomness rnd) {
|
||||
byte[] msg = plaintext.toByteArray();
|
||||
ECPoint encodedMsg = group.injectiveEncode(plaintext.toByteArray(), new PRGRandom(msg));
|
||||
|
||||
BigInteger rndInt = BigIntegers.fromUnsignedByteArray(rnd.getData().toByteArray());
|
||||
Pair<ECPoint,ECPoint> cipherText = elGamalPK.encrypt(encodedMsg, rndInt);
|
||||
ConcreteCrypto.ElGamalCiphertext encodedCipherText = ConcreteCrypto.ElGamalCiphertext.newBuilder()
|
||||
.setC1(ByteString.copyFrom(cipherText.a.getEncoded(true)))
|
||||
.setC2(ByteString.copyFrom(cipherText.b.getEncoded(true)))
|
||||
.build();
|
||||
|
||||
return Crypto.RerandomizableEncryptedMessage.newBuilder()
|
||||
.setData(encodedCipherText.toByteString())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Crypto.RerandomizableEncryptedMessage rerandomize(Crypto.RerandomizableEncryptedMessage msg, Crypto.EncryptionRandomness rnd) throws InvalidProtocolBufferException {
|
||||
BigInteger rndInt = BigIntegers.fromUnsignedByteArray(rnd.getData().toByteArray());
|
||||
Pair<ECPoint,ECPoint> randomizer = elGamalPK.encrypt(curve.getInfinity(), rndInt);
|
||||
ConcreteCrypto.ElGamalCiphertext originalEncodedCipher= ConcreteCrypto.ElGamalCiphertext.parseFrom(msg.getData());
|
||||
|
||||
Pair<ECPoint,ECPoint> originalCipher = new Pair<>(
|
||||
curve.decodePoint(originalEncodedCipher.getC1().toByteArray()),
|
||||
curve.decodePoint(originalEncodedCipher.getC2().toByteArray()));
|
||||
Pair<ECPoint,ECPoint> newCipher = elGamalPK.add(originalCipher, randomizer);
|
||||
|
||||
return Crypto.RerandomizableEncryptedMessage.newBuilder()
|
||||
.setData(
|
||||
ConcreteCrypto.ElGamalCiphertext.newBuilder()
|
||||
.setC1(ByteString.copyFrom(newCipher.a.getEncoded(true)))
|
||||
.setC2(ByteString.copyFrom(newCipher.b.getEncoded(true)))
|
||||
.build().toByteString()
|
||||
).build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
// Protobufs for specific crypto primitives
|
||||
|
||||
syntax = "proto3";
|
||||
|
||||
package meerkat;
|
||||
|
||||
import 'meerkat/crypto.proto';
|
||||
|
||||
option java_package = "meerkat.protobuf";
|
||||
|
||||
|
||||
message ElGamalPublicKey {
|
||||
// DER-encoded SubjectPublicKeyInfo as in RFC 3279
|
||||
bytes subject_public_key_info = 1;
|
||||
}
|
||||
|
||||
// An El-Gamal ciphertext
|
||||
// Each group element should be an ASN.1 encoded curve point with compression.
|
||||
message ElGamalCiphertext {
|
||||
bytes c1 = 1; // First group element
|
||||
bytes c2 = 2; // Second group element
|
||||
}
|
|
@ -9,6 +9,10 @@ enum SignatureType {
|
|||
DSA = 1;
|
||||
}
|
||||
|
||||
message BigInteger {
|
||||
bytes data = 1;
|
||||
}
|
||||
|
||||
// A digital signature
|
||||
message Signature {
|
||||
SignatureType type = 1;
|
||||
|
|
|
@ -73,7 +73,6 @@ idea {
|
|||
|
||||
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
|
||||
|
||||
println "Adding $srcDir"
|
||||
// add protobuf generated sources to generated source dir.
|
||||
if ("test".equals(sourceSet.name)) {
|
||||
testSourceDirs += file(srcDir)
|
||||
|
|
|
@ -73,7 +73,6 @@ idea {
|
|||
|
||||
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
|
||||
|
||||
println "Adding $srcDir"
|
||||
// add protobuf generated sources to generated source dir.
|
||||
if ("test".equals(sourceSet.name)) {
|
||||
testSourceDirs += file(srcDir)
|
||||
|
|
|
@ -72,7 +72,6 @@ idea {
|
|||
|
||||
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
|
||||
|
||||
println "Adding $srcDir"
|
||||
// add protobuf generated sources to generated source dir.
|
||||
if ("test".equals(sourceSet.name)) {
|
||||
testSourceDirs += file(srcDir)
|
||||
|
|
Loading…
Reference in New Issue