2015-11-07 12 views
9

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?

+0

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. –

+1

@ArtjomB. ** GT ** non è stato creato da nessuna parte nel codice. G1 è stato creato e aggiunto. – Azam

+0

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. –

risposta

4

dal documento criptato, il multi risultato non è lo stesso tipo di elemento con P, Q in PublicKey e il metodo decrypt per multi non è uguale a quello per addizione. dobbiamo reimplementare metodo mul e decryptMul come

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(); 
} 

quindi decifrare il codice di prova è come:

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)); 
} 

stampa ricorda

17578994648374341643 r4284550243 q4102879801 
Hash is 32 
Hash is 15 
Addition: 47 
Mul: 480 
+0

Questa sembra una soluzione valida Umer. Puoi testare? Sei ancora in loop? –

+0

Siamo spiacenti, non ho tempo per controllare questo. Ma visto che non vedo alcun downvotes e dato che hai prodotto risultati reali, prenderò la scommessa e ti assegnerò i punti. –

+0

OK. è possibile scaricare https://github.com/andyjojo/bgn eseguire il metodo principale org.onezero.bgn.BGNEncryption per controllare in seguito o altri che vogliono controllarlo o utilizzarlo. – andy