密码学之BGN同态加密算法

BGN同态加密算法:

      BGN是一种同态加密方案,是Bonel h等人在2005提出的一种具有全同态性质的加密方案。和传统的仅能支持单同态的elgamal和paillier加密方案不一样,BGN能够同时支持加同态和一次乘同态运算。

      由于乘法同态的实现是通过双线性对性质实现的,所以仅仅只能实现一次的乘同态。

      BGN一般的加密方案如下:

BGN在JAVA中的实现:

BGN的实现主要使用JAVA中的大整数math.BigInteger类以及双线性库JPBC实现,具体代码如下:

package BGN;

import java.math.BigInteger;
import java.security.SecureRandom;

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;

public class BGNEncryption {

	public static final String start = "start";
	public static final String end = "end";
	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); 
		param = a1.generate();
		TypeA1Pairing pairing = new TypeA1Pairing(param);
		order = param.getBigInteger("n"); 
		r = param.getBigInteger("n0");
		q = param.getBigInteger("n1");
		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());
//		double t1 = System.currentTimeMillis();
		Element T = PK.doPairing(C, D);
//		double t2 = System.currentTimeMillis();
//		System.out.println("一次对运算操作的时间"+(t2-t1)+"ms");
		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 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(256);
		BigInteger f = PK.getN();
		Element P = PK.getP();
		Element Q = PK.getQ();
		BigInteger order = PK.getN();
		int len1 = P.getLengthInBytes();
		int len2 = Q.getLengthInBytes();
		int len3 = order.bitLength();
		Element msg1 = b.encrypt(PK, 20);
		int len = msg1.getLengthInBytes();
		Element msg2 = b.encrypt(PK, 25);
		int len6 = msg2.getLengthInBytes();
		Element add = b.add(PK, msg1, msg2);
		String jiemi = b.decrypt(PK, b.q, add);
		System.out.println("Addition: "+jiemi);
		int len4 = add.getLengthInBytes();
//		double t5 = System.currentTimeMillis();
		Element mul = b.mul(PK, msg1, msg2);
//		double t6 = System.currentTimeMillis();
//		System.out.println("一次同态乘法的时间"+(t6-t5)+"ms");
		System.out.println("Mul: " + b.decryptMul(PK, b.q, mul));
		int len5 = mul.getLengthInBytes();
		System.out.println("P的长度:"+len1);
		System.out.println("Q的长度:"+len2);
		System.out.println("阶为:"+len3);
		System.out.println("msg1的长度:"+len);
		System.out.println("加同态"+len4);
		System.out.println("乘同态"+len5);
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;
	}
}

同态实验结果:

Addition: 45
Mul: 500
P的长度:130
Q的长度:130
阶为:512
msg1的长度:130
加同态130
乘同态130

代码出处:https://stackoverflow.com/questions/33581962/bgn-implementation-in-java

                  https://github.com/andyjojo/bgn

  • 12
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 20
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值