PBC Library Manual(PBC库手册)翻译(二)

目录

2.教程(Tutorial)

2.1.BLS签名

2.2.导入与导出


2.教程(Tutorial)

本章将介绍如何使用PBC库实现Boneh-Lynn-Shacham(BLS)签名方案。这是基于文件example/bls.c。

给出三个素数阶群G1、G2、GT(其实这三个都是循环群,素数阶群必定是循环群)。双线性映射从G1选择一个元素,从G2中选择一个元素,并输出一个GT中的元素。我们将这些与系统参数g一起发布,其中g是G2中随机选择的元素。

Alice想要签名一个信息,她生成公私钥对,私钥是Zr中的随机元素x,相应的公钥是g^x。

为了签名一个信息,Alice先将这个信息散列(hash)到G1的一些元素h上,然后输出签名h^x。

为了去验证签名σ,Bob检查e(h, g^x) = e(σ, g)。

我们现在使用PBC库将上述转化为C代码。

2.1.BLS签名

首先包含pbc/pbc.h:

#include <pbc.h>

然后初始化一个pairing:

pairing_t pairing;
char param[1024];
size_t count = fread(param, 1, 1024, stdin);
if(!count)
    pbc_die("input error");
pairing_init_set_buf(pairing, param, count);

然后,我们在标准输入上为程序提供pairing参数。param子目录下的任何文件都可以,例如:

$ bls < param/a.param

我们需要几个element_t参数来保存系统参数、密钥和其它的数量。我么声明并初始化它们,

element_t g, h;
element_t public_key, secret_key;
element_t sig;
element_t temp1, temp2;

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);

生成系统参数,

element_random(g);

生成私钥,

element_random(secret_key);

生成相应的公钥,

element_pow_zn(public_key, g, secret_key);

当有信息需要签名时,我们首先使用一些标准hash函数计算它的hash值。许多库都可以实现这个操作,而且这个操作不涉及pairing,所以PBC库就没有提供这一步的函数。例如,我们的信息已经被hash,可能用到了其它的库。

假设这个消息的hash是"ABCDEF"(一个48比特的hash)。我们将这些字节映射到一个G1的元素h,

element_from_hash(h, "ABCDEF", 6);

然后签名它:

element_pow_zn(sig, h, secret_key);

为了去验证这个签名,我们比较应用于签名和系统参数的pairing输出,和应用于消息hash和公钥的pairing输出。如果两个pairing的输出是匹配的则签名是有效的。

pairing_apply(temp1, sig, g, pairing);
pairing_apply(temp2, h, public_key, pairing);
if(!element_cmp(temp1, temp2)){
    printf("signature verifies\n");
}else{
    printf("signature does not verify\n");
}

2.2.导入与导出

为了使签名有用,在某些阶段签名必须转换为字节进行存储或者传输:

int n = pairing_length_in_bytes_compressed_G1(pairing);
// 与下一行二选一
// int n = element_length_in_bytes_compressed(sig);
unsigned char *data = malloc(n);
element_to_bytes_compressed(data, sig);

在另一端,签名必须被解压:

element_from_bytes_compressed();

在上面的代码中省略_compression也可以,但是缓冲区data大约需要是两倍。

我们也可以只使用签名的x坐标,可以节省更多的空间:

int n = pairing_length_in_bytes_x_only_G1(pairing);
// 与下一行二选一
// int n = element_length_in_bytes_x_only(sig);
unsigned char *data = malloc(n);
element_to_bytes_compressed(data, sig);

但是,由于两个不同的点具有相同的x坐标,因此在验证过程中比较复杂。解决这个问题的一种方法是猜一个点,然后试着去验证。如果失败了我们再去尝试另一个。我们可以看出,这两个点的pairing输出是互逆的,避免了二次计算pairing的需要。(事实上,还有更好的办法解决这个问题。)

int n = pairing_length_in_bytes_x_only_G1(pairing);
// int n = element_length_in_bytes_x_only(sig);
unsigned char *data = malloc(n);

element_to_bytes_x_only(data, sig);

element_from_bytes_x_only(sig, data);

pairing_apply(temp1, sig, g, pairing);
pairing_apply(temp2, h, public_key, pairing);

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("signature does not verify\n");
    }
}

 注:删除线部分是翻译不通顺或者可能有错误的地方。

 
  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值