PBC库的官方网址是http://crypto.stanford.edu/pbc/,下载地址为http://crypto.stanford.edu/pbc/download.html,里面提供了linux和windows版本的PBC库。我本人不习惯在linux下面调试运行程序,为了在VS中调试,折腾了一个星期才配置好。为了记录自己的配置过程并且使更多的人少走弯路,现在将我自己的配置过程记录下来。
我选择在MinGW中对PBC和GMP库进行编译,这个过程网上有很多参考,比如这个网址http://94it.net/a/jingxuanboke/2013/0809/90464.html,自己编译不出来的话,我已经把编译好的libpbc.a、libgmp.a、libgcc.a、libmingwex.a和gmp.h文件和我自己用的PBC文件放到百度网盘中,有需要的可以自行下载,下载网址为http://pan.baidu.com/s/1gd6HAUZ,提取密码为:k63m,有可能用我的include文件会出现错误,请大家尽量下载官网的文件配置,或者参考这篇博客的评论。有了这些东西我们就可以开始在VS中配置了。关于在VS中配置PBC库,有个网址可以参考下,http://stackoverflow.com/questions/25446726/running-pbc-in-windows-visual-studio,但是这个网址没有截图,我现在将配置的过程以图的形式展示一遍。
打开VS2010,鼠标放在你自己的项目上,右击,选择>属性,之后就出来上面的截图页面了,我已经标好了顺序,在红色标号4 这里注意,附加包含目录就是把PBC文件的include目录下所有的.h文件附加进去,还要再把gmp.h文件附加进去,其中gmp.h我已经放在了网盘的include.rar文件中,可以直接解压之后把整个include目录附加。
接下来在上面的页面中配置链接器:
同理注意第3步,这一步把用MinGW编译生成的libpbc.a、libgmp.a、libgcc.a、libmingwex.a文件附加,这四个.a文件我已经放到网盘中了,可以自行下载之后按照步骤附加。
最后是命令行参数配置:
命令行参数配置是为了运行时,使程序找到自己运行时需要的参数,这里我选择了PBC\param下面的a.param参数来作为运行参数,此处就直接填写了a.param,大家可以用根据自己的需要自行选择此文件夹下的参数。这个a.param要事先放到自己的项目下面,为了防止运行时找不到参数,我将这个a.param在项目文件夹和项目的Debug文件夹下都放了一个。
这些都选择好之后。点击“应用”、“确定”。我们就可以进行VS2010中的PBC库开发了。
在用VS2010运行程序时,先生成解决方案,然后在选择开始调试不执行,这样是为了避免VS中运行控制台程序时出现控制台一闪而过的情况。
下面把我写的一个简单的代码贴上来,这个算法被称为BasicCL-PKE的无证书加密体制,可以参考这篇论文:Al-riyami S S, Paterson K G. Certificateless Public Key Cryptography[J]. Lecture Notes in Computer Science, 2003, 133(2):452--473.
#include <pbc.h>
#include <pbc_test.h>
#define LEN 6
int main(int argc, char **argv) {
pairing_t pairing;
element_t s,x,r;
element_t P,Ppub,Qu,Du,Su,Xu,Yu,V;
element_t T1,T2;
double time1,time2;
int byte;
pbc_demo_pairing_init(pairing, argc, argv);
//将变量初始化为Zr上的元素
element_init_Zr(s,pairing);
element_init_Zr(r,pairing);
element_init_Zr(x,pairing);
//将变量初始化为G1上的元素
element_init_G1(P,pairing);
element_init_G1(Ppub,pairing);
element_init_G1(Qu,pairing);
element_init_G1(Du,pairing);
element_init_G1(Su,pairing);
element_init_G1(Xu,pairing);
element_init_G1(Yu,pairing);
element_init_G1(V,pairing);
//将变量初始化为GT中的元素
element_init_GT(T1,pairing);
element_init_GT(T2,pairing);
//判断所用的配对是否为对称配对
if(!pairing_is_symmetric(pairing)){
fprintf(stderr,"只能在对称配对下运行");
exit(1);
}
printf("BasicCL-PKE scheme\n");
printf("———————————系统建立阶段——————————\n");
element_random(s);
element_random(P);
element_mul_zn(Ppub,P,s);
element_printf("P=%B\n",P);
element_printf("s=%B\n",s);
element_printf("Ppub=%B\n",Ppub);
printf("———————部分私钥提取———————\n");
element_random(Qu);//随机选取Qu
element_mul_zn(Du,Qu,s);//Du=sQu
element_printf("private key is Du=%B\n",Du);
printf("—————设置秘密值阶段————\n");
element_random(x);
element_printf("秘密值为=%B\n",x);
printf("—————设置私钥————\n");
element_mul_zn(Su,Du,x);
element_printf("完全私钥 Su=%B\n",Su);
printf("—————设置公钥————\n");
element_mul_zn(Xu,P,x);//Xu=xP
element_mul_zn(Yu,Ppub,x);//Yu=xP
printf("公钥为:\n");
element_printf("Xu=%B\n",Xu);
element_printf("Yu=%B\n",Yu);
printf("———————————加密阶段——————————\n");
pairing_apply(T1,Xu,Ppub,pairing);//T1=e(Xu,Ppub)
pairing_apply(T2,Yu,P,pairing);//T2=e(Yu,P)
//判断公钥是否正确
if(!element_cmp(T1,T2)){
element_random(r);
element_mul_zn(V,P,r);//V=rP注意顺序
pairing_apply(T1,Yu,Qu,pairing);//T1=e(Yu,Qu)
element_pow_zn(T1,T1,r);//T1^r
element_printf("V=%B\n",V);
element_printf("e(Yu,Qu)^r=%B\n",T1);
}
else
{
printf("错误! 公钥不正确\n");
exit(1);
}
printf("———————————解密阶段——————————\n");
pairing_apply(T2,V,Su,pairing);
element_printf("e(V,Su)=%B\n",T2);
byte=element_length_in_bytes(V);
printf("密文总共字节长度为%d\n",byte+128);
return 0;}
运行结果为:
关于代码的实例,我会晚点发出来,欢迎大家有问题与我私信讨论。