Ubuntu22.04环境下PBC与Golang的安装与测试

994 阅读1分钟

PBC环境安装

PBC所需依赖安装

安装GMP

PBC的运行必须要依赖GMP库,所以要先安装GMP。 The GNU MP Bignum Library (gmplib.org)

# 使用wget方式获取源代码
wget https://gmplib.org/download/gmp/gmp-6.2.1.tar.xz

# 将源码解压倒指定目录中
sudo tar -zxvf gmp-6.2.1.tar.xz -C /usr/local

# 执行命令编译安装源码
cd /usr/local/gmp-6.2.1
./configure --enable-cxx
sudo make 
sudo make check
sudo make install

安装PBC之前必须要安装的库

# M4、 flex、bison 库安装
sudo apt update
sudo apt install m4, flex, bison

源码安装PBC (注: 此处安装的为PBC C语言源码)

# wget 获取pbc源码
wget https://crypto.stanford.edu/pbc/files/pbc-0.5.14.tar.gz

# 编译并安装pbc代码
tar -zxvf pbc-0.5.14.tar.gz -C /usr/local
cd /usr/local/pbc-0.5.14
./configure
sudo make
sudo make check
sudo make install

# 将编译好的pbc库添加到系统路径中
cd /etc/ld.so.conf.d

# 新建libpbc.conf文件
sudo vi libpbc.conf

# 按i进行编辑,并写入libpbc的路径,添加完后按esc推出,并输入":wq"退出
/usr/local/lib

# 更新系统缓存(使新增的libpbc路径生效)
sudo ldconfig

测试PBC库(BLS签名Test)

#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;
}

# 编译运行
gcc -Wall -o bls blstest.c -L. -lpbc -lgmp
./bls

Golang开发环境搭建

Golang源码下载与安装

# 网上获取源代码
wget https://studygolang.com/dl/golang/go1.19.1.linux-amd64.tar.gz

# 将源代码解压到指定目录中
sudo tar -zxvf go1.19.1.linux-amd64.tar.gz -C /usr/local

Golang 环境配置

# 编辑profile文件,按i进入编辑模式
sudo vim 〜/.profile

# 在.profile文件最下面添加 (由于新版GOlang默认开启go mod,所以不需要配置gopath)
export PATH=$PATH:/usr/local/go/bin

# 保存文件,并使配置文件生效
source ~/.profile

# 测试环境变量是否配置成功
go version

> go version go1.19.1 linux/amd64

PBC密码学库Go语言代码测试 (官方文档的演示代码:pbc package - github.com/Nik-U/pbc - Go Packages

安装PBC Go Wrapper

# 通过go get 的方式获取pbc go wrapper包
go get https://github.com/Nik-U/pbc

# 测试代码
package main

import (   
    "fmt"
    "github.com/Nik-U/pbc"
)

func main() {
 // In a real application, generate this once and publish it
 params := pbc.GenerateA(160, 512)

 pairing := params.NewPairing()

 // Initialize group elements. pbc automatically handles garbage collection.
 g := pairing.NewG1()
 h := pairing.NewG2()
 x := pairing.NewGT()

 // Generate random group elements and pair them
 g.Rand()
 h.Rand()
 fmt.Printf("g = %s\n", g)
 fmt.Printf("h = %s\n", h)
 x.Pair(g, h)
 fmt.Printf("e(g,h) = %s\n", x)
}

# 运行代码
go run main.go