使用JPBC实现双线性对加密算法(BasicIdent体制的java实现)

转自  http://blog.csdn.net/qifuchenluo/article/details/45100851

前言

现在网上关于Java版的双线性对算法的实现的代码很少,我在前段时间想找下这方面的代码都找不到,结果只能自己摸索。经过一段时间的摸索,终于配置好了jPBC库并实现了一些代码。所以为了让大家学习双线性算法的实现时少走点弯路,想通过博客的形式将我前段时间的学习成果跟大家分享下,为处于研究双线对密码初级阶段,还不懂得如何用java实现算法的菜鸟们提供一篇技术性的博客。

正文

关于java配对库网址为http://gas.dia.unisa.it/projects/jpbc/index.html#.VTDrLSOl_Cw,在这个网址http://gas.dia.unisa.it/projects/jpbc/docs/pairing.html#.Vz2yzOyEAzB有基本函数的用法,只看这个网址,相信很多对于Pairing-Based Cryptography Library (JPBC)还没入门的同学肯定是看的云里雾里的,看着就烦,其实我当初就是这样的。大家先不用急,学习这个库也是一个循序渐进的过程。关于jPBC库的配置,推荐一篇博客http://blog.csdn.net/liuweiran900217/article/details/23414629,这个博客已经将jPBC的配置写的很详细了,我就不赘述了。JPBC库中函数的基本使用和一些简单的算法实现,现在还没有发现专门介绍java的PBC库的相关书籍,推荐一本李发根,吴威峰著的书——《基于配对的密码学》,这本书详细讲了PBC库中每个函数的使用,还有经典算法的代码实现,这本书是C语言版的,对照这本书来研究JPBC会相对轻松很多。

用JPBC实现的算法实例
BasicIdent的基于身份的加密体制是由Boneh和Franklin在《Identity-Based Encryption fromthe Weil Pairing》提出的,算法的加解密过程大家可以自行参考下这篇论文,过程还是比较简单的。
Ident接口
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package cn.edu.zjut.pbc;  
  2.   
  3.   
  4. public interface Ident {  
  5.       
  6.     void buildSystem();  
  7.       
  8.     void extractSecretKey();  
  9.       
  10.     void encrypt();  
  11.       
  12.     void decrypt();  
  13.   
  14. }  
这个类是核心类,包括初始化init (),配对的对称性判断checkSymmetric(),系统建立buildSystem(),密钥提取extractSecretKey(),加密encrypt(),解密decrypt()。
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package cn.edu.zjut.pbc;  
  2.   
  3. import it.unisa.dia.gas.jpbc.*;  
  4. import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;  
  5. import java.lang.reflect.Proxy;  
  6. import java.util.Calendar;  
  7. import java.text.SimpleDateFormat;  
  8. import java.util.Date;  
  9.   
  10. public class BasicIdent2 implements Ident {  
  11.   
  12.     private Element s, r, P, Ppub, Su, Qu, V, T1, T2;  
  13.     private Field G1, Zr;  
  14.     private Pairing pairing;  
  15.   
  16.     public BasicIdent2() {  
  17.         init();  
  18.     }  
  19.   
  20.     /** 
  21.     * 初始化 
  22.     */  
  23.     private void init() {  
  24.         pairing = PairingFactory.getPairing("a.properties");//  
  25.         PairingFactory.getInstance().setUsePBCWhenPossible(true);  
  26.         checkSymmetric(pairing);  
  27.         //将变量r初始化为Zr中的元素  
  28.         Zr = pairing.getZr();  
  29.         r = Zr.newElement();  
  30.         //将变量Ppub,Qu,Su,V初始化为G1中的元素,G1是加法群  
  31.         G1 = pairing.getG1();  
  32.         Ppub = G1.newElement();  
  33.         Qu = G1.newElement();  
  34.         Su = G1.newElement();  
  35.         V = G1.newElement();  
  36.         //将变量T1,T2V初始化为GT中的元素,GT是乘法群  
  37.         Field GT = pairing.getGT();  
  38.         T1 = GT.newElement();  
  39.         T2 = GT.newElement();  
  40.     }  
  41.   
  42.     /** 
  43.      * 判断配对是否为对称配对,不对称则输出错误信息 
  44.      *  
  45.      * @param pairing 
  46.      */  
  47.     private void checkSymmetric(Pairing pairing) {  
  48.         if (!pairing.isSymmetric()) {  
  49.             throw new RuntimeException("密钥不对称!");  
  50.         }  
  51.     }  
  52.   
  53.     @Override  
  54.     public void buildSystem() {  
  55.         System.out.println("-------------------系统建立阶段----------------------");  
  56.         s = Zr.newRandomElement().getImmutable();// //随机生成主密钥s  
  57.         P = G1.newRandomElement().getImmutable();// 生成G1的生成元P  
  58.         Ppub = P.mulZn(s);// 计算Ppub=sP,注意顺序  
  59.         System.out.println("P=" + P);  
  60.         System.out.println("s=" + s);  
  61.         System.out.println("Ppub=" + Ppub);  
  62.     }  
  63.   
  64.     @Override  
  65.     public void extractSecretKey() {  
  66.         System.out.println("-------------------密钥提取阶段----------------------");  
  67.         Qu = pairing.getG1().newElement().setFromHash("IDu".getBytes(), 03)  
  68.                 .getImmutable();// //从长度为3的Hash值IDu确定用户U产生的公钥Qu  
  69.         Su = Qu.mulZn(s).getImmutable();  
  70.         System.out.println("Qu=" + Qu);  
  71.         System.out.println("Su=" + Su);  
  72.     }  
  73.   
  74.     @Override  
  75.     public void encrypt() {  
  76.         System.out.println("-------------------加密阶段----------------------");  
  77.         r = Zr.newRandomElement().getImmutable();  
  78.         V = P.mulZn(r);  
  79.         T1 = pairing.pairing(Ppub, Qu).getImmutable();// 计算e(Ppub,Qu)  
  80.         T1 = T1.powZn(r).getImmutable();  
  81.         System.out.println("r=" + r);  
  82.         System.out.println("V=" + V);  
  83.         System.out.println("T1=e(Ppub,Qu)^r=" + T1);  
  84.     }  
  85.   
  86.     @Override  
  87.     public void decrypt() {  
  88.         System.out.println("-------------------解密阶段----------------------");  
  89.         T2 = pairing.pairing(V, Su).getImmutable();  
  90.         System.out.println("e(V,Su)=" + T2);  
  91.         int byt = V.getLengthInBytes();// 求V的字节长度,假设消息长度为128字节  
  92.         System.out.println("文本长度" + (byt + 128));  
  93.     }  
  94.   
  95.     public static void main(String[] args) {  
  96.         BasicIdent2 ident = new BasicIdent2();  
  97.         // 动态代理,统计各个方法耗时  
  98.         Ident identProxy = (Ident) Proxy.newProxyInstance(  
  99.                 BasicIdent2.class.getClassLoader(),  
  100.                 new Class[] { Ident.class }, new TimeCountProxyHandle(ident));  
  101.   
  102.         identProxy.buildSystem();  
  103.         identProxy.extractSecretKey();  
  104.         identProxy.encrypt();  
  105.         identProxy.decrypt();  
  106.     }  
  107.   
  108. }  
最后使用了动态代理(java自带的代理模式)用来统计各个阶段的耗时。
[java]  view plain  copy
  在CODE上查看代码片 派生到我的代码片
  1. package cn.edu.zjut.pbc;  
  2.   
  3.   
  4. import java.lang.reflect.InvocationHandler;  
  5. import java.lang.reflect.Method;  
  6.   
  7. /** 
  8.  * 时间统计处理机,用于统计各方法耗时 
  9.  * @author Administrator 
  10.  * 
  11.  */  
  12. public class TimeCountProxyHandle implements InvocationHandler {  
  13.   
  14.     private Object proxied;  
  15.   
  16.     public TimeCountProxyHandle(Object obj) {  
  17.         proxied = obj;  
  18.     }  
  19.   
  20.     @Override  
  21.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
  22.         long begin = System.currentTimeMillis();  
  23.         Object result = method.invoke(proxied, args);  
  24.         long end = System.currentTimeMillis();  
  25.         System.out.println(method.getName() + "耗时:" + (end - begin) + "ms");  
  26.         return result;  
  27.     }  
  28. }  
运行结果展示

由于电脑配置的不同,运行耗时会有差异,大家对于这篇博客如有任何问题,欢迎在CSDN上与我讨论。
  • 11
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MIRACL库提供了实现线性对计算的函数。下面是一个简单的示例代码,用于计算双线性对: ```c #include <miracl.h> int main() { // 初始化MIRACL库 miracl *mip = mirsys(1000, 16); mip->IOBASE = 16; // 定义双线性对参数 big a, b, p, n; epoint *G1, *G2; ecurve *C1, *C2; big order; // 初始化参数 a = mirvar(0); b = mirvar(3); p = mirvar("FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFF"); n = mirvar("400000000000000000002BEC12BE2262D39BCF14D"); order = mirvar("400000000000000000002BEC12BE2262D39BCF14B"); G1 = epoint_init(); G2 = epoint_init(); C1 = ecurve_init(); C2 = ecurve_init(); // 设置参数 ecurve_init(a, b, p, MR_PROJECTIVE); epoint_set(MIRACL_INFINITY, 0, G1); epoint_set(MIRACL_INFINITY, 0, G2); ecurve_mult(n, G1, G1); ecurve_mult(n, G2, G2); ecurve_copy(C1, &ecurve); ecurve_copy(C2, &ecurve2); // 计算双线性对 big x, y; epoint *P = epoint_init(); epoint *Q = epoint_init(); epoint_set(x, y, 0, P); epoint_set(x, y, 0, Q); big r = mirvar(0); pairing(P, Q, r); // 输出结果 cotnum(r, stdout); // 释放资源 mirkill(a); mirkill(b); mirkill(p); mirkill(n); mirkill(order); epoint_free(P); epoint_free(Q); epoint_free(G1); epoint_free(G2); ecurve_free(C1); ecurve_free(C2); mirsys_end(); return 0; } ``` 在上面的示例代码中,我们首先初始化MIRACL库,并定义了双线性对所需的参数。然后我们使用`ecurve_init()`函数初始化了椭圆曲线,使用`epoint_set()`函数设置了点坐标,最后使用`pairing()`函数计算双线性对。最后我们使用`cotnum()`函数将结果输出到控制台,并释放了所有资源。 需要注意的是,在使用MIRACL库时,必须先初始化MIRACL库,并在使用完之后释放所有资源,否则可能导致内存泄漏等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值