Sto cercando l'implementazione opensource dell'algoritmo di crittografia omomorfica BGN in java.Implementazione BGN in Java
Ho trovato il seguente codice online per BGN. Sto cercando di eseguirlo ma avendo problemi.
schema più da vicino sta cercando di implementare following (pagina 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 Classe: bene
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;
}
}
In esecuzione, inoltre sta lavorando. Ma la moltiplicazione non sta funzionando con seguente errore:
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)
ho preso sopra il codice da Here e rimosso Android parte. Qualsiasi indizio su di esso per favore? Come posso risolvere sotto l'eccezione?
Prendere lo schema che si suppone questo codice per implementare e controlla se ogni campo contiene gli elementi di un tipo che dovrebbe contenere. L'errore dice che non puoi mettere un elemento di gruppo di GT in una variabile dell'elemento di gruppo G1. –
@ArtjomB. ** GT ** non è stato creato da nessuna parte nel codice. G1 è stato creato e aggiunto. – Azam
Il risultato di un abbinamento è sempre in GT. Il problema è che questo è probabilmente scritto per una versione precedente di jPBC. Usa 'Element x = element.duplicate();' invece di 'Element x = f.newElement(); x.set (elemento); ', ma questo non risolve il tuo problema, perché' aux' è un elemento di curva G1 durante la decrittazione, ma 'K' è un elemento di curva. –