PBC library 学习笔记(一)

来源:互联网 发布:mac系统软件下载 编辑:程序博客网 时间:2024/05/22 09:49

Pairing-based cryptography library是在gmp库基础上开发的free的C函数库,提供了对椭圆曲线群上的配对运算支持。本文主要针对PBC 官网的manual手册,学习使用PBC library.实践环境为ubuntu 16.04

安装PBC

  1. 安装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
  2. 安装GMP库
    GMP库下载地址如下:https://gmplib.org/
    下载并解压,在terminal里进入解压后的文件夹进行安装,方法如下: ./configure
    make
    make check
    sudo make install(需要新建文件夹的权利sudo)
  3. 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
  1. 开始使用(验证安装成功与否)
    以下是两个循环群的双线性映射,G1*G2 –> GT ,每个群阶数为质数r
    下载解压后的进入pbc-0.5.14文件下的pbc文件夹,执行程序


    这里写图片描述
    从这些示例中我们可以看出,默认情况下,系统已经设定好了pairing的一些参数,包括G1、G2以及它们的order、generator等。
    关于这个小解释程序的一些介绍可以参见链接地址。

  2. 基础

    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 test\n");  //generate system parameters  element_random(g);  element_printf("system parameter g = %B\n", g);  //generate private key  element_random(secret_key);  element_printf("private key = %B\n", secret_key);  //compute corresponding public key  element_pow_zn(public_key, g, secret_key);  element_printf("public key = %B\n", 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 = %B\n", 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 = %B\n", 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 = %B\n", 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) = %B\n", temp1);  //verification part 2  //should match above  element_pairing(temp2, h, public_key);  element_printf("f(message hash, public_key) = %B\n", temp2);  if (!element_cmp(temp1, temp2)) {//比较temp1和temp2    printf("signature verifies\n");  } 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 = %B\n", sig);    element_pairing(temp1, sig, g);    if (!element_cmp(temp1, temp2)) {      printf("signature verifies on first guess\n");    } else {      element_invert(temp1, temp1);//这里做处理的原因时只验证x轴的话,y轴的值可能互为相反数(互逆)      if (!element_cmp(temp1, temp2)) {        printf("signature verifies on second guess\n");      } 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 verify\n");  } 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;}

执行结果如下
这里写图片描述

3 0