我正在寻找java中BGN同态加密算法的开源实现。
我在网上找到了以下BGN代码。我试图执行它但有问题。
更紧密的方案是尝试实施following(第3,4页):
Add(pk;C1;C2): Choose t0 R [1, n] and output C0 = C1 + C2 + [t0]Q E G. Mult(pk;C1;C2): Choose u R [1, n] and output D = ^e(C1;C2).e(Q;Q)u E n.
package bgn;
import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.jpbc.Field;
import it.unisa.dia.gas.jpbc.PairingParameters;
import it.unisa.dia.gas.plaf.jpbc.pairing.a1.TypeA1CurveGenerator;
import it.unisa.dia.gas.plaf.jpbc.pairing.a1.TypeA1Pairing;
import it.unisa.dia.gas.plaf.jpbc.util.math.BigIntegerUtils;
import java.math.BigInteger;
import java.security.SecureRandom;
public class BGNEncryption {
public BGNEncryption()
{
}
private PairingParameters param;
private BigInteger r;
private BigInteger q; //This is the private key.
private BigInteger order;
private SecureRandom rng;
public PublicKey gen(int bits) {
rng = new SecureRandom();
TypeA1CurveGenerator a1 = new TypeA1CurveGenerator(rng, 2, bits); //Requires 2 prime numbers.
param = a1.generate();
TypeA1Pairing pairing = new TypeA1Pairing(param);
order = param.getBigInteger("n"); //Must extract the prime numbers for both keys.
r = param.getBigInteger("n0");
q = param.getBigInteger("n1");
System.out.println(order + " " + " r"+ r + " q"+ q + "");
Field<?> f = pairing.getG1();
Element P = f.newRandomElement();
P = P.mul(param.getBigInteger("l"));
Element Q = f.newElement();
Q = Q.set(P);
Q = Q.mul(r);
return new PublicKey(pairing, P, Q,
order);
}
public Element encrypt(PublicKey PK, int msg)
{
BigInteger t = BigIntegerUtils.getRandom(PK.getN());
int m = msg;
System.out.println("Hash is " + m);
Field<?> f = PK.getField();
Element A = f.newElement();
Element B = f.newElement();
Element C = f.newElement();
A = A.set(PK.getP());
A = A.mul(BigInteger.valueOf(m));
B = B.set(PK.getQ());
B = B.mul(t);
C = C.set(A);
C = C.add(B);
return C;
}
public Element add(PublicKey PK, Element A, Element B){
BigInteger t = BigIntegerUtils.getRandom(PK.getN());
Field<?> f = PK.getField();
Element output = f.newElement();
Element aux = f.newElement();
aux.set(PK.getQ());
aux.mul(t);
output.set(A);
output.add(B);
output.add(aux);
return output;
}
public Element mul(PublicKey PK, Element C, Element D){
BigInteger t = BigIntegerUtils.getRandom(PK.getN()); //Make sure product is NOT infinite.
Field<?> f = PK.getField();
Element Q = PK.getQ();
Element output = f.newElement();
Element aux = f.newElement();
aux.set(PK.doPairing(C, D));
output.set(PK.doPairing(Q,Q));
output.pow(t);
output.mul(aux);
return output;
}
public String decrypt(PublicKey PK, BigInteger sk, Element C) {
Field<?> f = PK.getField();
Element T = f.newElement();
Element K = f.newElement();
Element aux = f.newElement();
T = T.set(PK.getP());
T = T.mul(sk);
K = K.set(C);
K = K.mul(sk);
aux = aux.set(T);
BigInteger m = new BigInteger("1");
while (!aux.isEqual(K)) {
//This is a brute force implementation of finding the discrete logarithm.
//Performance may be improved using algorithms such as Pollard's Kangaroo.
aux = aux.add(T);
m = m.add(BigInteger.valueOf(1));
}
return m.toString();
}
public static void main(String[] args)
{
BGNEncryption b = new BGNEncryption();
PublicKey PK = b.gen(32);
Element msg = b.encrypt(PK, 1);
Element msg2 = b.encrypt(PK, 1);
Element add = b.add(PK, msg, msg2);
Element mul = b.mul(PK, msg, msg2);
System.out.println("Addition: "+ b.decrypt(PK, b.q, add));
// System.out.println("Mul: "+ b.decrypt(PK, b.q, mul));
long t = System.currentTimeMillis();
System.out.println(b.decrypt(PK, b.q, msg2));
System.out.println("Decryption took "
+ (System.currentTimeMillis() - t) + " ms");
}
}
PublicKey.Java类:
package bgn;
import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.jpbc.Field;
import it.unisa.dia.gas.plaf.jpbc.pairing.a1.TypeA1Pairing;
import java.math.BigInteger;
public class PublicKey {
private TypeA1Pairing map;
private Element P, Q;
private BigInteger n;
private Field<?> f;
public PublicKey(TypeA1Pairing pairing, Element gen, Element point,
BigInteger order) {
map = pairing;
P = gen.set(gen);
Q = point.set(point);
n = order;
f = pairing.getG1();
}
public Element doPairing(Element A, Element B) {
return map.pairing(A, B);
}
public Element getP() {
return this.P;
}
public Element getQ() {
return this.Q;
}
public BigInteger getN() {
return this.n;
}
public Field<?> getField() {
return this.f;
}
}
执行时,添加工作正常。但乘法不适用于以下错误:
Exception in thread "main" java.lang.ClassCastException: it.unisa.dia.gas.plaf.jpbc.field.gt.GTFiniteElement cannot be cast to it.unisa.dia.gas.plaf.jpbc.field.curve.CurveElement
at it.unisa.dia.gas.plaf.jpbc.field.curve.CurveElement.set(CurveElement.java:55)
at it.unisa.dia.gas.plaf.jpbc.field.curve.CurveElement.set(CurveElement.java:12)
at bgn.BGNEncryption.mul(BGNEncryption.java:82)
at bgn.BGNEncryption.main(BGNEncryption.java:118)
我从Here获取了以上代码并删除了Android部分。 有什么线索吗?我如何解决以下异常?
答案 0 :(得分:4)
来自crypt文档,多重结果与PublicKey中P,Q的元素类型不同,multi的解密方法也与添加的解密方法不同。 我们需要重新实现方法mul和decryptMul像
public Element mul(PublicKey PK, Element C, Element D) {
BigInteger t = BigIntegerUtils.getRandom(PK.getN());
Element T = PK.doPairing(C, D);
Element K = PK.doPairing(PK.getQ(), PK.getQ());
K = K.pow(t);
return T.mul(K);
}
public String decryptMul(PublicKey PK, BigInteger sk, Element C) {
Element PSK = PK.doPairing(PK.getP(), PK.getP());
PSK.pow(sk);
Element CSK = C.duplicate();
CSK.pow(sk);
Element aux = PSK.duplicate();
BigInteger m = new BigInteger("1");
while (!aux.isEqual(CSK)) {
aux = aux.mul(PSK);
m = m.add(BigInteger.valueOf(1));
}
return m.toString();
}
然后解密测试代码就像:
public static void main(String[] args) {
BGNEncryption b = new BGNEncryption();
PublicKey PK = b.gen(32);
Element msg1 = b.encrypt(PK, 32);
Element msg2 = b.encrypt(PK, 15);
Element add = b.add(PK, msg1, msg2);
System.out.println("Addition: " + b.decrypt(PK, b.q, add));
Element mul = b.mul(PK, msg1, msg2);
System.out.println("Mul: " + b.decryptMul(PK, b.q, mul));
}
输出就像
17578994648374341643 r4284550243 q4102879801
Hash is 32
Hash is 15
Addition: 47
Mul: 480