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