PBC库安装

PBC库安装*

该作者写的很好!不过中间我还是遇到了很多问题,写在下面。下面是我的详细步骤。欢迎指点!

https://blog.csdn.net/u013983667/article/details/54582126?locationNum=9&fps=1

安装相关依赖

sudo apt install m4 (注意小写m,装不上,先sudo apt update一下)
sudo apt install flex
sudo apt install bison

安装 GMP

GMP库下载地址如下:

https://gmplib.org/

在这里插入图片描述
下载后解压,进入解压后的文件夹。

sudo su
 ./configure
make
make check
make install

默认安装在/usr/local/lib,我们可以查看一下。

cd /usr/local/lib
ls

安装 PBC

pbc下载地址如下:

http://crypto.stanford.edu/pbc/download.html

在这里插入图片描述
下载并解压,进入解压文件夹:

sudo su
./configure
make
make install

其中,在Windows上configure命令需要额外的选项

./configure -disable-static -enable-shared

默认安装路径为/usr/local/lib

测试

双线性映射:G1*G2 –> GT, order 为 r。
划线部分测试
打开你解压到的文件夹,也就是你上面进行编译的文件夹,里面有个pbc文件夹。

cd pbc
./pbc

生成g of G1

g := rnd(G1);
g;

生成h of G2

扫描二维码关注公众号,回复: 11539562 查看本文章
h := rnd(G2);
h;

e(g, h)

pairing(g,h);

产生两个数a,b of [0,r-1]

a := rnd(Zr);
b := rnd(Zr);

e(g^a, h^b)

pairing(g^a,    h^b);

e(g,h)^(a*b)

pairing(g,h)^(a*b);

注意

如果要在编程中使用!
这里要设置动态库指定路径 LD_LIBRARY_PATH,LD_LIBRARY_PATH是Linux系统下的环境变量名,类似于Path(设置可执行文件的搜索路径)。它用于指定查找共享库(动态链接库)时除了默认路径(./lib和./usr/lib)之外的其他路径。移植程序时的经常碰到需要使用一些特定的动态库,而这些编译好的动态库放在我们自己建立的目录里,这时可以将这些目录设置到LD_LIBRARY_PATH中。

查看LD_LIBRARY_PATH:

echo $LD_LIBRARY_PATH

1.设置LD_LIBRARY_PATH(只能一次性使用):

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib

2.把该语句加入/etc/profile里面,注销用户,再登录生效。

sudo gedit /etc/profile
把上面那条设置命令放在文件最下端,注销重新登录。

我们进入解压文件夹下(我的):

cd /home/wk/v2g/pbc-0.5.14/example
gcc bls.c -o blstest -L. -lpbc -lgmp
./blstest < ~/v2g/pbc-0.5.14/param/a.param  #后面是用于指定参数

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;
  // 实例化 paring
  pbc_demo_pairing_init(pairing, argc, argv);

  // 实例化 元素 属于 G1.G2,GT
  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);
  // 实例化 元素 属于 Zr(表示以r为模的整数环。)  r是阶 (G1.G2,GT)
  element_init_Zr(secret_key, pairing);

  printf("Short signature test\n");

  //随机生成一个元素值(因为g定义在G2,所以是G2中的任意一个)
  element_random(g);
  element_printf("system parameter g = %B\n", g);

  //随机生成私钥
  element_random(secret_key);
  element_printf("private key = %B\n", secret_key);

  //根据私钥计算出公钥
  element_pow_zn(public_key, g, secret_key);
  element_printf("public key = %B\n", public_key);

  //根据存储在缓冲区数据中的len(13)个字节--hashofmessage,确定地生成一个元素h。
  //for toy pairings, 生成的 h 要满足 pairing(g, h) != 1
  element_from_hash(h, "hashofmessage", 13);
  element_printf("message hash = %B\n", h);

  //sig = h^secret_key, is the signature
  //在现实情景中:只输出第一个坐标
  element_pow_zn(sig, h, secret_key);
  element_printf("signature = %B\n", sig);

  {
  //返回表示G1元素的压缩形式所需的长度(以字节为单位),解压缩会有一些开销。
    int n = pairing_length_in_bytes_compressed_G1(pairing);
    //int n = element_length_in_bytes_compressed(sig);返回以压缩形式保存sig所需的字节数.
    //当前仅对椭圆曲线上的点,sig是G1 上的点
    int i;
	//分配一块内存
    unsigned char *data = pbc_malloc(n);
	//将元素sig的压缩形式输出到字节数据缓冲区。当前仅对椭圆曲线上的点。
    element_to_bytes_compressed(data, sig);
    printf("compressed = ");
    for (i = 0; i < n; i++) {
	// 输出 不足两位前面补0,足,原样输出
      printf("%02X", data[i]);
    }
    printf("\n");
	//在字节数据缓冲区中将元素sig设置为压缩形式的元素。
    element_from_bytes_compressed(sig, data);
    element_printf("decompressed = %B\n", sig);

    pbc_free(data);
  }

  //verification part 1
  element_pairing(temp1, sig, g);
  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)) {
    printf("signature verifies\n");
  } else {
    printf("*BUG* signature does not verify *BUG*\n");
  }

  {
	//返回表示G1元素的x坐标所需的长度(以字节为单位)。
    int n = pairing_length_in_bytes_x_only_G1(pairing);
    //int n = element_length_in_bytes_x_only(sig);
    int i;
    unsigned char *data = pbc_malloc(n);
	//sig是椭圆曲线上的一个点。将sig的x坐标写入缓冲区数据
    element_to_bytes_x_only(data, sig);
    printf("x-coord = ");
    for (i = 0; i < n; i++) {
      printf("%02X", data[i]);
    }
    printf("\n");
	//sig是椭圆曲线上的一个点。将sig设置为由缓冲区数据表示的点的 x坐标。这不是唯一的。对于每个x坐标,在PBC中的椭圆曲线上存在两个不同的点。(它们彼此相反。)
    element_from_bytes_x_only(sig, data);
    element_printf("de-x-ed = %B\n", sig);

    element_pairing(temp1, sig, g);
	//如果temp1和temp2相同,则返回0,否则返回非零。
    if (!element_cmp(temp1, temp2)) {
      printf("signature verifies on first guess\n");
    } else {
      element_invert(temp1, temp1);
      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;
}

PBC学习

这里,贴上官方手册,里面一应俱全:

https://crypto.stanford.edu/pbc/manual/

猜你喜欢

转载自blog.csdn.net/TBBetter/article/details/103587977
PBC
今日推荐