EC encryption code; compiles but not tested
parent
c3e651e34b
commit
b8cc3feedb
|
@ -90,7 +90,6 @@ idea {
|
||||||
|
|
||||||
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
|
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
|
||||||
|
|
||||||
println "Adding $srcDir"
|
|
||||||
// add protobuf generated sources to generated source dir.
|
// add protobuf generated sources to generated source dir.
|
||||||
if ("test".equals(sourceSet.name)) {
|
if ("test".equals(sourceSet.name)) {
|
||||||
testSourceDirs += file(srcDir)
|
testSourceDirs += file(srcDir)
|
||||||
|
|
|
@ -46,6 +46,7 @@ dependencies {
|
||||||
compile 'com.google.protobuf:protobuf-java:3.+'
|
compile 'com.google.protobuf:protobuf-java:3.+'
|
||||||
|
|
||||||
// Crypto
|
// Crypto
|
||||||
|
compile 'org.factcenter.qilin:qilin:1.+'
|
||||||
compile 'org.bouncycastle:bcprov-jdk15on:1.53'
|
compile 'org.bouncycastle:bcprov-jdk15on:1.53'
|
||||||
compile 'org.bouncycastle:bcpkix-jdk15on:1.53'
|
compile 'org.bouncycastle:bcpkix-jdk15on:1.53'
|
||||||
|
|
||||||
|
@ -81,7 +82,6 @@ idea {
|
||||||
|
|
||||||
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
|
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
|
||||||
|
|
||||||
println "Adding $srcDir"
|
|
||||||
// add protobuf generated sources to generated source dir.
|
// add protobuf generated sources to generated source dir.
|
||||||
if ("test".equals(sourceSet.name)) {
|
if ("test".equals(sourceSet.name)) {
|
||||||
testSourceDirs += file(srcDir)
|
testSourceDirs += file(srcDir)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package meerkat.crypto;
|
package meerkat.crypto;
|
||||||
|
|
||||||
|
import com.google.protobuf.InvalidProtocolBufferException;
|
||||||
import com.google.protobuf.Message;
|
import com.google.protobuf.Message;
|
||||||
import static meerkat.protobuf.Crypto.*;
|
import static meerkat.protobuf.Crypto.*;
|
||||||
|
|
||||||
|
@ -15,6 +16,6 @@ public interface Encryption {
|
||||||
*/
|
*/
|
||||||
RerandomizableEncryptedMessage encrypt(Message plaintext, EncryptionRandomness rnd); // TODO: type of exception; throws
|
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;
|
DSA = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message BigInteger {
|
||||||
|
bytes data = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// A digital signature
|
// A digital signature
|
||||||
message Signature {
|
message Signature {
|
||||||
SignatureType type = 1;
|
SignatureType type = 1;
|
||||||
|
|
|
@ -73,7 +73,6 @@ idea {
|
||||||
|
|
||||||
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
|
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
|
||||||
|
|
||||||
println "Adding $srcDir"
|
|
||||||
// add protobuf generated sources to generated source dir.
|
// add protobuf generated sources to generated source dir.
|
||||||
if ("test".equals(sourceSet.name)) {
|
if ("test".equals(sourceSet.name)) {
|
||||||
testSourceDirs += file(srcDir)
|
testSourceDirs += file(srcDir)
|
||||||
|
|
|
@ -73,7 +73,6 @@ idea {
|
||||||
|
|
||||||
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
|
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
|
||||||
|
|
||||||
println "Adding $srcDir"
|
|
||||||
// add protobuf generated sources to generated source dir.
|
// add protobuf generated sources to generated source dir.
|
||||||
if ("test".equals(sourceSet.name)) {
|
if ("test".equals(sourceSet.name)) {
|
||||||
testSourceDirs += file(srcDir)
|
testSourceDirs += file(srcDir)
|
||||||
|
|
|
@ -72,7 +72,6 @@ idea {
|
||||||
|
|
||||||
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
|
def srcDir = "${protobuf.generatedFilesBaseDir}/$sourceSet.name/java"
|
||||||
|
|
||||||
println "Adding $srcDir"
|
|
||||||
// add protobuf generated sources to generated source dir.
|
// add protobuf generated sources to generated source dir.
|
||||||
if ("test".equals(sourceSet.name)) {
|
if ("test".equals(sourceSet.name)) {
|
||||||
testSourceDirs += file(srcDir)
|
testSourceDirs += file(srcDir)
|
||||||
|
|
Loading…
Reference in New Issue