2015-11-07 15 views
9

Poszukuję opensource implementacji homomorficznego algorytmu szyfrowania BGN w java.Implementacja BGN w Javie

Znalazłem następujący kod online dla BGN. Próbuję go wykonać, ale mam problemy.

dokładniej schemat próbuje wdrożyć following (strona 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 Class: Drobny

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

Na wykonanie, dodatek działa. Ale mnożenie nie działa z następującym błędem:

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) 

Wziąłem wyżej kod z Here i usunięte Android część. Czy jest na to jakaś wskazówka? Jak mogę rozwiązać poniżej wyjątek?

+0

Weź schemat, że kod ten ma na celu wdrożenie i sprawdź, czy każde pole zawiera elementy typu, który ma zawierać. Błąd mówi, że nie można umieścić elementu grupy GT w zmiennej elementu grupy G1. –

+1

@ArtjomB. ** GT ** nie został nigdzie utworzony w kodzie. Utworzono i dodano G1. – Azam

+0

Wynik parowania jest zawsze w GT. Problem polega na tym, że jest to prawdopodobnie napisane dla starszej wersji jPBC. Użyj 'Element x = element.duplicate();' zamiast 'Element x = f.newElement(); x.set (element); ', ale to nie rozwiąże problemu, ponieważ' aux' jest elementem krzywej G1 podczas odszyfrowywania, ale 'K' jest elementem krzywej. –

Odpowiedz

4

z dokumentu krypty, wynik wielu nie jest taki sam Typ elementu z P, Q w PublicKey i metoda odszyfrowywania dla wielu również nie jest taka sama z tą dla dodania. musimy reimplement metody Mul i decryptMul jak

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

następnie odszyfrować kod test jest tak:

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

wyjście jest jak

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

To wydaje się być prawidłowym rozwiązaniem Umer. Czy możesz testować? Nadal jesteś w pętli? –

+0

Niestety, nie mam czasu na sprawdzenie tego. Ale ponieważ nie widzę żadnych zniżek, a od kiedy osiągnąłeś rzeczywiste wyniki, wezmę udział w grze i przyznaję ci punkty. –

+0

OK. możesz pobrać https://github.com/andyjojo/bgn uruchomić główną metodę org.onezero.bgn.BGNEncryption, aby sprawdzić później lub inną, która chce to sprawdzić lub użyć. – andy