java - Java 中的 BGN 实现

标签 java encryption

我正在寻找 BGN 同态加密算法在 java 中的开源实现。

我在网上找到了 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");
    }
}

公钥.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 部分。 请问有什么线索吗?我该如何解决以下异常?

最佳答案

从crypt文件看,multi结果与PublicKey中的P,Q不是同一个Element类型,multi的解密方法也和add的解密方法不一样。 我们需要重新实现 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

关于java - Java 中的 BGN 实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33581962/

相关文章:

java - 缺少前 16 个字符 - Java AES CBC 加密和 golang 解密

MySQL 连接和安全

PHP MySQL - 在不存储 key 的情况下动态加密解密数据

java - 如何以编程方式从 Android 中的 DatePicker/TimePicker Spinner 中提取值?

java - 为什么第一个 sqrt 算法比第二个更快?

java - 检修台模型 Swing

java - Java 8 更新后的 RC4 相关问题

java - int 反向符号 negate() java

java - ImageLoader 缓存并显示旧图像

java - Android XML RSA,错误 : java. security.InvalidKeyException:传递给 RSA 的未知 key 类型