概述
Pairing-based cryptography library是在gmp库基础上开发的free的C函数库,提供了对椭圆曲线群上的配对运算支持。本文主要针对PBC 官网的manual手册,学习使用PBC library.实践环境为ubuntu 16.04
安装PBC
- 安装Pbc library依赖的库
M4、flex、bison 其中在ununtu系统terminal中 M4、flex、bison均可以通过apt-get install方式安装。在Linux系统中键入如下命令即可安装相应的包。
sudo apt-get install M4 (装不上,先sudo apt-get update一下,不行翻墙试试)
sudo apt-get install flex
sudo apt-get install bison - 安装GMP库
GMP库下载地址如下:https://gmplib.org/
下载并解压,在terminal里进入解压后的文件夹进行安装,方法如下: ./configure
make
make check
sudo make install(需要新建文件夹的权利sudo) - Pbc library库安装
pbc(The Pairing-Based Cryptography Library)下载地址如下:http://crypto.stanford.edu/pbc/download.html
下载并解压,在terminal里进入解压文件夹安装,方法如下:
./configure
make
make install
至此pbc library 在ubuntu系统中的安装完成。接下来就是验证pbc库是否安装正确。在Windows上configure命令需要额外的选项
$ ./configure -disable-static -enable-shared
默认安装路径为/usr/local/lib
安装完后把库路径添加到LD_LIBRARY_PATH
来自: http://man.linuxde.net/ldconfig
开始使用(验证安装成功与否)
以下是两个循环群的双线性映射,G1*G2 –> GT ,每个群阶数为质数r
下载解压后的进入pbc-0.5.14文件下的pbc文件夹,执行程序
从这些示例中我们可以看出,默认情况下,系统已经设定好了pairing的一些参数,包括G1、G2以及它们的order、generator等。
关于这个小解释程序的一些介绍可以参见链接地址。基础
c++编程,用PBC库需要包含pbc.h (路径/usr/local/include/pbc)其中pbc.h中已经包含了gmp.h,为了连接pbc和GMP库,在执行时需要增加选项:
$ gcc program.c -L. -lpbc -lgmp
基于GMP的PBC的几点说明
- 输出参数一般写在输入参数之前
- 在一次调用时,同一个变量可以作为输入和输出存在
- 变量在用前一定要初始化一次,不用时一定要clear掉,为达效率,没必要的初始化和clear要避免
- PBC变量都以_t结尾。当一个函数修改一个输入变量后,这个变量返回给其他caller时的是修改的值。
- 变量自动分配内存
- PBC函数一般是重入函数。所谓可重入函数就是允许被递归调用的函数。
- 可以用GMP定义的类型
e.g :
element_t sum;
struct foo { element_t x, y; };
element_t vec[20]; - 类型解释
GMP has the mpz_t type for integers, mpq_t for rationals and so on. In contrast, PBC uses the element_t data type for elements of different algebraic structures, such as elliptic curve groups, polynomial rings and finite fields. Functions assume their inputs come from appropriate algebraic structures.
element_t: elements of an algebraic structure.代数结构中的元素(生成元)
pairing_t: pairings where elements belong; can initialize from sample pairing parameters bundled with PBC in the param subdirectory.生成元所属的队,可以从pbc-0.5.14/param文件夹下数据集例子初始化
pbc_param_t: used to generate pairing parameters.用于生成pairing参数
pbc_cm_t: parameters for constructing curves via the CM method; sometimes required by pbc_param_t.通过CM方法构建曲线的参数,需要输入pbc_param参数
field_t: algebraic structures: groups, rings and fields; used internally by pairing_t.代数学上的结构(域):可以时群,环,域。需要用到pairing_t参数
a few miscellaneous functions, such as ones controlling how random bits are generated.
一个例子:基于pbc library的bls签名实现
如何用PBC library实现the Boneh-Lynn-Shacham (BLS) signature scheme 代码在pbc-0.5.14/example/bls.c中
基础说明:阶为质数r的三个群G1,G2,GT(定理:阶为质数的群都是循环群)
定义双线性映射e:G1*G2–>GT,公开G2的一个随机生成元g.
Alice想要对我一个消息签名。她通过如下方法生成公钥和私钥:
私钥:Zr的一个随机元素x
公钥:g^x
为了签名消息,Alice将消息m作为输入,通过哈希算法得到hash值h=hash(m),对h进行签名sig=h^x,输出sig,发给Bob.
为了验证签名sig,Bob check 双线性映射式子:e(h,g^x) = e(sig, g).是否相等
其中e(h,y)=e(h,g^x)=e(h,g)^x;
若e(sig’,g)=e(sig,g)=e(h^x,g)=e(h,g)^x=e(h,y),则说明B收到的签名是A的真实签名
基于pbc library的bls实现代码:(在/pbc-0.5.14/example/bls.c)
// Boneh-Lynn-Shacham short signatures demo.
//
// See the PBC_sig library for a practical implementation.
//
// Ben Lynn
#include "/usr/local/include/pbc/pbc.h"
#include "/usr/local/include/pbc/pbc_test.h"
int main(int argc, char **argv) {
//定义变量
pairing_t pairing;
element_t g, h;
element_t public_key, sig;
element_t secret_key;
element_t temp1, temp2;
//初始化pairing这个变量
/*
pairing_t pairing;
char param[1024];
size_t count = fread(param, 1, 1024, stdin);//通过文件流读入./生成c文件 < ~/参数目录/pbc-0.5.14/param/a.param
if (!count) pbc_die("input error");
pairing_init_set_buf(pairing, param, count);
*/
pbc_demo_pairing_init(pairing, argc, argv);//在pbc_test.h中定义也是以文件流的方式读入参数
//初始化一些变量
element_init_G2(g, pairing);
element_init_G2(public_key, pairing);
element_init_G1(h, pairing);
element_init_G1(sig, pairing);
element_init_GT(temp1, pairing);
element_init_GT(temp2, pairing);
element_init_Zr(secret_key, pairing);
printf("Short signature testn");
//generate system parameters
element_random(g);
element_printf("system parameter g = %Bn", g);
//generate private key
element_random(secret_key);
element_printf("private key = %Bn", secret_key);
//compute corresponding public key
element_pow_zn(public_key, g, secret_key);
element_printf("public key = %Bn", public_key);
//generate element from a hash
//for toy pairings, should check that pairing(g, h) != 1
element_from_hash(h, "hashofmessage", 13);
element_printf("message hash = %Bn", h);
//h^secret_key is the signature
//in real life: only output the first coordinate
element_pow_zn(sig, h, secret_key);
element_printf("signature = %Bn", sig);
{
int n = pairing_length_in_bytes_compressed_G1(pairing);//计算需要多大的值用于保存压缩数据的大小
//int n = element_length_in_bytes_compressed(sig);
int i;
unsigned char *data = pbc_malloc(n);
element_to_bytes_compressed(data, sig);//压缩sig
printf("compressed = ");
for (i = 0; i < n; i++) {
printf("%02X", data[i]);//X 表示以十六进制形式输出 02 表示不足两位,前面补0输出
}
printf("n");
element_from_bytes_compressed(sig, data);//解压
element_printf("decompressed = %Bn", sig);
pbc_free(data);
}
//verification part 1
element_pairing(temp1, sig, g);//Computes a pairing: out = e(in1, in2), where in1, in2, out must be in the groups G1, G2, GT
element_printf("f(sig, g) = %Bn", temp1);
//verification part 2
//should match above
element_pairing(temp2, h, public_key);
element_printf("f(message hash, public_key) = %Bn", temp2);
if (!element_cmp(temp1, temp2)) {//比较temp1和temp2
printf("signature verifiesn");
} else {
printf("*BUG* signature does not verify *BUG*n");
}
{
int n = pairing_length_in_bytes_x_only_G1(pairing);//返回 the length in bytes needed to represent the x-coordinate of an element of G1.
//int n = element_length_in_bytes_x_only(sig);
int i;
unsigned char *data = pbc_malloc(n);
element_to_bytes_x_only(data, sig);
printf("x-coord = ");
for (i = 0; i < n; i++) {
printf("%02X", data[i]);
}
printf("n");
element_from_bytes_x_only(sig, data);//只取x轴的值进行验证,目的:减少内存的浪费
element_printf("de-x-ed = %Bn", sig);
element_pairing(temp1, sig, g);
if (!element_cmp(temp1, temp2)) {
printf("signature verifies on first guessn");
} else {
element_invert(temp1, temp1);//这里做处理的原因时只验证x轴的话,y轴的值可能互为相反数(互逆)
if (!element_cmp(temp1, temp2)) {
printf("signature verifies on second guessn");
} else {
printf("*BUG* signature does not verify *BUG*n");
}
}
pbc_free(data);
}
//a random signature shouldn't verify
element_random(sig);
element_pairing(temp1, sig, g);
if (element_cmp(temp1, temp2)) {
printf("random signature doesn't verifyn");
} else {
printf("*BUG* random signature verifies *BUG*n");
}
element_clear(sig);
element_clear(public_key);
element_clear(secret_key);
element_clear(g);
element_clear(h);
element_clear(temp1);
element_clear(temp2);
pairing_clear(pairing);
return 0;
}
执行结果如下
最后
以上就是愉快小笼包为你收集整理的PBC library 学习笔记(一)的全部内容,希望文章能够帮你解决PBC library 学习笔记(一)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复