我是靠谱客的博主 精明墨镜,最近开发中收集的这篇文章主要介绍jPBC 2.0.0配置与测试(补充版)题注背景jPBC 2.0.0在任意平台下的配置Boneh-Boyen-Goh HIBE:一个简单的实例总结与未来 补充,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题注

随着技术博客中的文章越写越多,越写越有经验,我也越来越喜欢把各种各样自己做的有意思的东西公开给大家了~通过技术博客也认识了全国各地的朋友们,他们涉及到的领域真是包罗万象:有做设计的,有做算法的,有做密码学的,还有很多很多好玩的,有趣的人。这也是我希望看到的:大家把自己的技术,自己的心得与其他人分享,一起努力一起进步!

这一篇博客实际上是一位技术朋友希望我能撰写的。他和他团队的小伙伴们在使用jPBC这个Library的时候遇到了很多的问题,希望如果有可能的话,能得到我的帮助。帮助倒是谈不上,能互相交流一下,玩一玩技术也是不错的~ jPBC我以前也配置过,不过那个时候其稳定版本是1.2.1,还并不是特别好用。这次再配置一遍,发现2.0.0的使用比1.2.1方便得多啊,而且竟然可以在Windows下面配置了!所以我赶快做了几个测试,并把我配置的全部过程分享给大家,希望能对大家的配置和开发有所帮助。

背景

Pairing-Based Cryptography

只要是最近10年做密码学的人,就不可能不知道传说中的Pairing-Based Cryptograhphy(PBC)。在现代密码学中,人们常常用两种群来构造安全的密码学算法,即类似RSA的phi (N)群,以及离散对数群。因为各种各样的原因(具体原因太理论了,在此我不详细展开,有兴趣的朋友们可以单独联系我,我们可以讨论一下~),类似RSA的phi (N)群基本已经淘汰不用,而离散对数群得到了广泛的应用。

大家可能有所了解,phi (N)群安全的最大基础是,N=p*q,其中p和q是两个大质数,且给定N,很难分解为p*q。这也就是我们常说的大合数分解问题。在离散对数群中,也有类似的一个难题,成为离散对数难题。给定群的生成元g,和某一个群中的元素g^x,求解x本身很困难。有的人要问了,这个挺简单的啊,求log不就行了吗?需要注意的是,在连续域上面,确实有求log的快速算法(比如用数学分析中的Taylor展示求法,或者各种数值分析中的逼近算法等等),但是这些算法都是逼近算法,并不能求出准确解。当然了,一般数的log结果也是一个无线不循环小数,只能用逼近算法求。但是,在离散对数群中,我们是在用整数和整数做解,根本没有逼近算法这么回事…有兴趣的同学,可以了解一下离散对数群,并且设置一个生成元g,来尝试求一求一个数的离散对数,就会发现只能用枚举的算法来求。

但是,在密码学中,这个计算困难假设不太好用,因此密码学家扩充了离散对数难题,提出了很多别的困难假设,以用于安全性证明。其中,最直接也是最简单的扩展,为计算Diffie-Hellman问题(Computataional Diffie-Hellman Problem,CDH),以及确定Diffie-Hellman问题(Decision Diffie-Hellman Problem,DDH)。

CDH问题是说,给定生成元g,两个群中的元素g^x,g^y,再不给定x,y的情况下,求g^{xy}。DDH问题是:同样给定生成元g,两个群中的元素g^x,g^y,再给定群的一个元素g^z,确定是否满足g^z = g^{xy}。CDH问题和DDH问题是很多加密方案和签名方案的安全基础,如著名的El Gamal加密方案。

但是,Bilinear Pairing的出现,使得DDH问题在某些特定群上面并不是一个困难问题了。Bilinear Pairing最早也是为了解决DDH问题,从而破解密码学方案而提出来的。Bilinear Pairing是一个函数e,其以两个群元素g^x,g^y为输入,求出e(g,g)^{xy}。这样一来,DDH问题就可以用Bilinear Pairing求解了:给定g,g^x,g^y,g^z,我们分别求e(g,g^z)和e(g^x,g^y),看看他们是不是相等即可。

那么,Bilinear Pairing在密码学方面有什么正面的用途吗?即:不用于破解密码学方案,而是来构建密码学方案的正面用途。在,2001年,Boneh和Franklin在论文《Identity-Based Encryption from the Weil Pairing》,提出了一个非常高效的Identity-Based Encryption方案。这也被认为是Bilinear Pairing的第一个实际应用。自此以后,Bilinear Pairing在密码学中有了越来越多的应用,这一类使用Bilinear Pairing的密码学方案被称为Pairing-Based Cryptography。在现代密码中,越来越多的公钥密码学方案都基于Bilinear Pairing做,如Hierarchical Identity-Based Encryption,Attribute-Based Encryption,Fully Secure Signature等等。可以这么说,Bilinear Pairing为公钥密码学进一步发展打开了一扇大门。

PBC与jPBC

Pairing虽然好用,在实际中到底如何使用呢?Boneh的一个学生,Ben Lynn,在Boneh的指导下开发了Pairing-Based Cryptography Library,完全实现了Bilinear Pairing。这一个Library现在成为了测试和使用Pairing-Based Cryptography的必备函数库,估计已经被用了上百万次了吧… 这个库是用Linux C开发的,非常好用!感兴趣的朋友们可以到PBC的官方网址:http://crypto.stanford.edu/pbc/ 对这个函数库做进一步的了解。

jPBC的全称是java Pairing-Based Cryptography Library,是PBC的一个Java封装,其官方网址为http://gas.dia.unisa.it/projects/jpbc/。要知道,并不是所有开发人员都能够熟练使用C的,在现在计算机的大潮中,广泛使用的语言基本已经是C++,Java,Python等面向对象语言了。因此,PBC面向其他语言的封装就显得十分重要。据我所知,除了jPBC以外,现在也出现了很多其他语言的PBC封装,如Python的封装,C++的封装等等。

作为一个Java的忠实用户,我个人当然最喜欢用Java啦,而且Java本身还有一个好处:开发的程序仅需要做很小的修改就可以移植到Android上面,做终端应用了。jPBC也具有这样的功能。具体如何在Android上使用jPBC,我还需要进一步的研究和配置。朋友们需要耐心等待我下面的博客了…

系统配置

在最新版本的jPBC 2.0.0中,PBC库已经被封装在了jar包中。也就是说,我们已经不需要再本地再编译PBC库,然后通过设定Native Library的形式使用jPBC了,只需要将jar包放置在工程下即可进行调用。这也就意味着,jPBC已经可以在Windows下面使用了!

我的系统配置截图如下:


jPBC 2.0.0在任意平台下的配置

首先,我们需要在官方网站上面留意,什么情况下才需要本地编译PBC后才能够使用,什么情况下可以直接使用jPBC。jPBC官方网站上面有如下的说法:

To use JPBC, add to your classpath the following jars:

  1. jpbc_2.0.0-api.jar and
  2. jpbc_2.0.0-plaf.jar.

To use the PBC Wrapper, a shared C library must be compiled and installed properly as shown here.

Then, to use the wrapper, include the following jars:

  1. jpbc_2.0.0-pbc.jar and
  2. jna-3.1.0.jar.

To use the Multilinear Maps, include the following jar:

  1. jpbc_2.0.0-mm.jar.

To use the cryptosystems provided by JPBC include the following jars:

  1. jpbc-crypto-2.0.0.jar and
  2. bcprov-jdk16-1.46.
也就是说,只有当我们需要使用PBC Wrapper的时候,才需要在本地编译原始的C语言PBC文件,再使用。其他时候,我们直接引用其给出的jar包即可。这样的要求也就意味着,jPBC本身已经完全封装成为了java代码,其运行只和java本身有关,而与Windows,Linux和Mac OS等各种操作系统无关了,而这本身也是java的优势所在。

这样一来,自然而然也就引入了下一个问题:现在的jPBC能否使用在Android环境下面呢?这个我自己还并没有测试,准备这几天有时间的话就试一试,然后发一个博客告诉大家结果啦。

回到主题,jPBC的配置流程如下:

(1) 在Eclipse中新建一个工程,在这里我的工程名字就为jPBC了。建立工程后,我们需要把jar包引入其中。在Eclipse中,jar包可以通过绝对路径引入(Import Extended jar),也可以通过相对路径引入(Import jar)。在此,为了工程的拷贝方便,我选择使用相对工程引入。因此,我们需要在jPBC工程中增加一个存放jar包的文件夹,并且把jar包存入其中。右键单击jPBC工程,选择New->Folder,如图所示:


随后,在弹出的对话框中,将这个文件夹起名为lib,文件夹位置放置在jPBC工程的根目录下,如图:


接下来,将jPBC中所有的jar文件拷贝到lib文件夹中。注意,虽然都拷贝过来了,但是有关PBC Wrapper的内容都无法使用,因为我们现在并没有本地Shared PBC Library。拷贝进lib后,右键点击jPBC工程,选择Refresh,我们就可以看到lib文件夹下面已经有jar文件了。然后,同样右键点击jPBC工程,选择Properties,再弹出的对话框中选择Java Bulid Path,如图所示。


在右面选择Add JARS,将jPBC的所有jar文件引入其中。在此我仅引入了jPBC核心的两个jar包,即为api和plaf,如图所示。


这样jPBC就算配置完成了。

Boneh-Boyen-Goh HIBE:一个简单的实例

Boneh-Boyen-Goh HIBE算法是这三位密码学家2005年在Eurocrypt上面发表的一篇论文《Hierarchical Identity-Based Encryption with Constant Size Ciphertext》中提出的HIBE算法。这个算法非常的高效,并且设计的很美观。后面的很多很多算法和方案都是从这个论文的方案改过来的。我以这个HIBE算法为例,在jPBC下面实现这个算法。算法本身是怎么回事,希望大家试着去阅读一下原始论文,在此我也就不详细解释了。
HIBE实现的截图如下图所示。

源代码包含了很多的文件,但是核心文件就是BBGHIBE.java文件。

Util.java

Util.java文件中存储了在实现过程中用到的Hash函数。
import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.jpbc.Pairing;

public class Util {
	public static Element hash_id(Pairing pairing, String id){
		byte[] byte_identity = id.getBytes();
		Element hash = pairing.getZr().newElement().setFromHash(byte_identity, 0, byte_identity.length);
		return hash;
	}
}

BBGHIBEMasterKey.java

这个类只是用于存储master secret key,有点像一个C中的结构体了。
import it.unisa.dia.gas.jpbc.Element;

public class BBGHIBEMasterKey {
	public Element alpha;
}

BBGHIBESecretKey.java

这个类是用于存放secret key的,具体key的格式大家需要阅读原始论文。
import it.unisa.dia.gas.jpbc.Element;

public class BBGHIBESecretKey {
	public String[] identityVector;
	public Element K_1;
	public Element K_2;
	public Element[] E;
}

BBGHIBECiphertext.java

这个类用于存放ciphertext,同样地,具体的格式需要大家阅读原始论文。
import it.unisa.dia.gas.jpbc.Element;

public class BBGHIBECiphertext {
	Element C_0;
	Element C_1;
	Element C_2;
}

BBGHIBE.java

这个类是核心类。包含了Setup,KeyGen,Delegate,Encrypt,以及Decrypt算法。在此只有一个地方需要说明,原文中假设明文是在Z_T群中,但是在实际实现中,将任意一个String映射到G_T群是一个很麻烦的工作(虽然这个工作的确可以做)。因此,在加密时,我实际上是加密了一个随机给出的G_T群元素。这样做的话,方案实际上就不是一个Encryption方案了,而是一个秘钥封装方案,但这也是可行的,不降低方案本身的安全性。
import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.jpbc.Pairing;
import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;

public class BBGHIBE {
	public static final boolean isDebug = true;
	private Pairing pairing;
	private int MAX_DEPTH;
	//Public parameters
	private Element g;
	private Element h;
	private Element[] u;
	private Element E_g_g;
	
	/**
	 * System setup algorithms, takes the max depth of hierarchy as input, and outputs the master secret key
	 * @param perperties The file name of the elliptic curve parameters
	 * @param D Maximal depth of hierarchy
	 * @return Master Secret Key
	 */
	public BBGHIBEMasterKey Setup(String perperties, int D){
		// Generate curve parameters
		pairing = PairingFactory.getPairing(perperties);
		
		this.MAX_DEPTH = D;
		
		//generate alpha
		Element alpha = pairing.getZr().newRandomElement().getImmutable();
		
		// Generate public parameters
		this.g = pairing.getG1().newRandomElement().getImmutable();
		this.h = pairing.getG1().newRandomElement().getImmutable();
		this.u = new Element[this.MAX_DEPTH];
		for (int i=0; i<this.u.length; i++){
			this.u[i] = pairing.getG1().newRandomElement().getImmutable();
		}
		this.E_g_g = pairing.pairing(this.g, this.g).powZn(alpha).getImmutable();
		
		//generate master secret key
		BBGHIBEMasterKey masterKey = new BBGHIBEMasterKey();
		masterKey.alpha = alpha.duplicate().getImmutable();
		return masterKey;
	}
	
	/**
	 * Key Generation algorithm to generate secret key associated with the given identity vector
	 * @param msk master secret key
	 * @param identityVector the given identity vector
	 * @return secret key associated with the given identity vector
	 */
	public BBGHIBESecretKey KeyGen(BBGHIBEMasterKey msk, String[] identityVector){
		//Determine the validity of Identity Vector
		assert(identityVector.length <= this.MAX_DEPTH);
		
		//generate the secret key
		Element r = pairing.getZr().newRandomElement().getImmutable();
		BBGHIBESecretKey secretKey = new BBGHIBESecretKey();
		secretKey.identityVector = new String[identityVector.length];
		System.arraycopy(identityVector, 0, secretKey.identityVector, 0, identityVector.length);
		
		//compute K_1
		secretKey.K_1 = this.g.powZn(r).getImmutable();
		
		//compute K_2
		secretKey.K_2 = this.h.duplicate();
		for (int i=0; i<identityVector.length; i++){
			secretKey.K_2 = secretKey.K_2.mul(this.u[i].powZn(Util.hash_id(pairing, identityVector[i])));
		}
		secretKey.K_2 = secretKey.K_2.powZn(r);
		secretKey.K_2 = secretKey.K_2.mul(this.g.powZn(msk.alpha)).getImmutable();
		
		//compute E
		secretKey.E = new Element[this.MAX_DEPTH];
		for (int i=identityVector.length; i<this.MAX_DEPTH; i++){
			secretKey.E[i] = this.u[i].powZn(r).getImmutable();
		}
		return secretKey;
	}
	
	/**
	 * Delegation algorithm to delegate a secret key for the user's subordinate
	 * @param secretkey the secret key for the supervisor
	 * @param identity the identity for the user's subordinate
	 * @return secret key for the user's subordinate
	 */
	public BBGHIBESecretKey Delegate(BBGHIBESecretKey secretkey, String identity){
		//Determine the validity of Identity Vector
		assert(secretkey.identityVector.length < this.MAX_DEPTH);
		
		//delegate the secret key
		BBGHIBESecretKey delegateKey = new BBGHIBESecretKey();
		String[] delegateIV = new String[secretkey.identityVector.length + 1];
		System.arraycopy(secretkey.identityVector, 0, delegateIV, 0, secretkey.identityVector.length);
		delegateIV[secretkey.identityVector.length] = identity;
		delegateKey.identityVector = delegateIV;
		Element r = pairing.getZr().newRandomElement().getImmutable();
		
		//compute K_1
		delegateKey.K_1 = secretkey.K_1.duplicate();
		delegateKey.K_1 = delegateKey.K_1.mul(this.g.powZn(r)).getImmutable();
				
		//compute K_2
		delegateKey.K_2 = this.h.duplicate();
		for (int i=0; i<delegateIV.length; i++){
			delegateKey.K_2 = delegateKey.K_2.mul(this.u[i].powZn(Util.hash_id(pairing, delegateIV[i])));
		}
		delegateKey.K_2 = delegateKey.K_2.powZn(r);
		delegateKey.K_2 = delegateKey.K_2.mul(secretkey.K_2);
		delegateKey.K_2 = delegateKey.K_2.mul(secretkey.E[secretkey.identityVector.length].powZn(Util.hash_id(pairing, identity))).getImmutable();
		
		//compute b
		delegateKey.E = new Element[this.MAX_DEPTH];
		for (int i=secretkey.identityVector.length; i<this.MAX_DEPTH; i++){
			delegateKey.E[i] = this.u[i].powZn(r).mul(secretkey.E[i]).getImmutable();
		}
		return delegateKey;
	}
	
	/**
	 * Encrypt algorithm to an identity vector
	 * @param identityVector the target identity vector
	 * @return the ciphertext
	 */
	public BBGHIBECiphertext Encrypt(String[] identityVector){
		//Determine the validity of Identity Vector
		assert(identityVector.length <= this.MAX_DEPTH);
		
		//Generate a random message
		Element message = pairing.getGT().newRandomElement();
		if (isDebug){
			System.out.println("Infor - encrypt: the generated random message is " + message);
		}
		
		//Encrypt that message
		Element s = pairing.getZr().newRandomElement().getImmutable();
		BBGHIBECiphertext ciphertext = new BBGHIBECiphertext();
		//compute C_0
		ciphertext.C_0 = this.E_g_g.powZn(s).mul(message).getImmutable();
		
		//compute C_2
		ciphertext.C_2 = this.g.powZn(s).getImmutable();
				
		//compute c_1
		ciphertext.C_1 = this.h.duplicate();
		for (int i=0; i<identityVector.length; i++){
			ciphertext.C_1 = ciphertext.C_1.mul(this.u[i].powZn(Util.hash_id(pairing, identityVector[i])));
		}
		ciphertext.C_1 = ciphertext.C_1.powZn(s).getImmutable();
		return ciphertext;
	}
	
	/**
	 * Decrypt the ciphertext using a secret key
	 * @param identityVector the receive identity vector
	 * @param ciphertext the ciphertext
	 * @param secretKey the secret key for the receiver or for the receiver's supervisor
	 * @return the message
	 */
	public Element decrypt(String[] identityVector, BBGHIBECiphertext ciphertext, BBGHIBESecretKey secretKey){
		//Determine the validity of Identity Vector, the ciphertext and the secret key
		//Secret Key Identity Vector depth needs to be smaller than ciphertext Identity Vector depth
		assert(identityVector.length >= secretKey.identityVector.length);
		
		//the identity vector for the secret key should match the receiver's identity vector
		for (int i=0; i<secretKey.identityVector.length; i++){
			assert(secretKey.identityVector[i].equals(identityVector[i]));
		}
		
		Element K = secretKey.K_2.duplicate();
		for (int i=secretKey.identityVector.length; i<identityVector.length; i++){
			K.mul(secretKey.E[i].powZn(Util.hash_id(pairing, identityVector[i])));
		}
		Element message = pairing.pairing(secretKey.K_1, ciphertext.C_1);
		message = message.div(pairing.pairing(K, ciphertext.C_2));
		message = message.mul(ciphertext.C_0);
		System.out.println("Infor - decrypt: the message is " + message);
		return message;
	}
}

TestBBGHIBE.java

这个类用于测试BBGHIBE方案。我们选取1层到7层的用户,加密时候也加密给1-7层,看解密是否成功。
public class TestBBGHIBE {
    private static void testBBEHIBE() {
		BBGHIBE bbgHIBE = new BBGHIBE();
    	BBGHIBEMasterKey msk = bbgHIBE.Setup("a.properties", 7);
    	String[] testI1 = {"Depth 1"};
    	String testI2 = "Depth 2";
    	String testI3 = "Depth 3";
    	String testI4 = "Depth 4";
    	String testI5 = "Depth 5";
    	String testI6 = "Depth 6";
    	String testI7 = "Depth 7";
    	String[] receiver = new String[7];
    	receiver[0] = testI1[0];
    	receiver[1] = testI2;
    	receiver[2] = testI3;
    	receiver[3] = testI4;
    	receiver[4] = testI5;
    	receiver[5] = testI6;
    	receiver[6] = testI7;
    	String[] ciphertextIV = new String[7];
    	System.arraycopy(receiver, 0, ciphertextIV, 0, 7);
    	//KeyGen for depth 1
    	if (BBGHIBE.isDebug){
    		System.out.println("Generate secret key for user at depth 1");
    	}
    	BBGHIBESecretKey SKDepth1 = bbgHIBE.KeyGen(msk, testI1);
    	
    	//Delegation for depth 2
    	if (BBGHIBE.isDebug){
    		System.out.println("Generate secret key for user at depth 2");
    	}
    	BBGHIBESecretKey SKDepth2 = bbgHIBE.Delegate(SKDepth1, testI2);

    	//Delegation for depth 3
    	if (BBGHIBE.isDebug){
    		System.out.println("Generate secret key for user at depth 3");
    	}
    	BBGHIBESecretKey SKDepth3 = bbgHIBE.Delegate(SKDepth2, testI3);
    	
    	//Delegation for depth 4
    	if (BBGHIBE.isDebug){
    		System.out.println("Generate secret key for user at depth 4");
    	}
    	BBGHIBESecretKey SKDepth4 = bbgHIBE.Delegate(SKDepth3, testI4);
    	
    	//Delegation for depth 5
    	if (BBGHIBE.isDebug){
    		System.out.println("Generate secret key for user at depth 5");
    	}
    	BBGHIBESecretKey SKDepth5 = bbgHIBE.Delegate(SKDepth4, testI5);
    	
    	//Delegation for depth 6
    	if (BBGHIBE.isDebug){
    		System.out.println("Generate secret key for user at depth 6");
    	}
    	BBGHIBESecretKey SKDepth6 = bbgHIBE.Delegate(SKDepth5, testI6);
    	
    	//Delegation for depth 7
    	if (BBGHIBE.isDebug){
    		System.out.println("Generate secret key for user at depth 7");
    	}
    	BBGHIBESecretKey SKDepth7 = bbgHIBE.Delegate(SKDepth6, testI7);
    	
    	//encryption
    	if (BBGHIBE.isDebug){
    		System.out.println("Encryption");
    	}
    	BBGHIBECiphertext ciphertext = bbgHIBE.Encrypt(ciphertextIV);
    	
    	//Decryption for depth 1
    	if (BBGHIBE.isDebug){
    		System.out.println("Dncryption for user at depth 1");
    	}
    	bbgHIBE.decrypt(ciphertextIV, ciphertext, SKDepth1);
    	
    	//Decryption for depth 2
    	if (BBGHIBE.isDebug){
    		System.out.println("Dncryption for user at depth 2");
    	}
    	bbgHIBE.decrypt(ciphertextIV, ciphertext, SKDepth2);
    	
    	//Decryption for depth 3
    	if (BBGHIBE.isDebug){
    		System.out.println("Dncryption for user at depth 3");
    	}
    	bbgHIBE.decrypt(ciphertextIV, ciphertext, SKDepth3);
    	
    	//Decryption for depth 4
    	if (BBGHIBE.isDebug){
    		System.out.println("Dncryption for user at depth 4");
    	}
    	bbgHIBE.decrypt(ciphertextIV, ciphertext, SKDepth4);
    	
    	//Decryption for depth 5
    	if (BBGHIBE.isDebug){
    		System.out.println("Dncryption for user at depth 5");
    	}
    	bbgHIBE.decrypt(ciphertextIV, ciphertext, SKDepth5);
    	
    	//Decryption for depth 6
    	if (BBGHIBE.isDebug){
    		System.out.println("Dncryption for user at depth 6");
    	}
    	bbgHIBE.decrypt(ciphertextIV, ciphertext, SKDepth6);
    	
    	//Decryption for depth 7
    	if (BBGHIBE.isDebug){
    		System.out.println("Dncryption for user at depth 7");
    	}
    	bbgHIBE.decrypt(ciphertextIV, ciphertext, SKDepth7);
    }
	
	public static void main(String[] args){
		testBBEHIBE();
	}
}

运行结果如图所示。

总结与未来

新版jPBC完全脱离了PBC的依赖,实现了完全基于Java的对运算,抛开了平台本身的限制,这必须强调是jPBC工程作出的最大贡献!对于Bilinear Groups,现在已经出现了很多很多的扩展,如Composite-Order Bilinear Groups,Dual Pairing Vector Space,Multi-linear Groups等等。这些在jPBC都已经得到了实现。我最新的工作已经完成了对于jPBC中,Composite-Order Bilinear Groups以及Dual Pairing Vector Space的调用,并已经调试成功。在接下来的博客中我有时间就会更新这类的工作。对于Multi-linear Groups,这还是密码学的一个新的研究方向,我正在研究对于Multi-linear Groups的相关理论使用,以及如何用jPBC来实际使用Multi-linear Groups。如果有进展,我会及时更新。
如果有任何问题,欢迎在博客中与我讨论,或者给我发邮件~

补充

在这个博客发表后,有几个朋友问我:完全按照上述配置,运行后会Throw Exception,如图。

这个是我的问题,因为中间有一个步骤我给忽略掉了… 在源代码中有这样一行代码:
pairing = PairingFactory.getPairing(perperties);

这行代码的意思是,读取perperoties(这里我给拼错了…)中的参数,初始化Pairing。而Properties传进来的是一个路径。所以,我们需要把参数放置在这个路径里面。在我的调用过程中,其路径代码为:
BBGHIBEMasterKey msk = bbgHIBE.Setup("a.properties", 7);

这是一个相对路径。因此,我们需要把a.properties放置在工程的根目录下面。比如,如果工程路径为D:workspacesjPBC,那么a.properties就放在这个目录下面。那么,a.properties从哪里能够拿到呢?实际上,jPBC压缩包中,有一个param文件夹,里面放置的就是典型的参数,直接用里面的a.properties即可。

最后

以上就是精明墨镜为你收集整理的jPBC 2.0.0配置与测试(补充版)题注背景jPBC 2.0.0在任意平台下的配置Boneh-Boyen-Goh HIBE:一个简单的实例总结与未来 补充的全部内容,希望文章能够帮你解决jPBC 2.0.0配置与测试(补充版)题注背景jPBC 2.0.0在任意平台下的配置Boneh-Boyen-Goh HIBE:一个简单的实例总结与未来 补充所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部