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

您所在的位置:网站首页 pbc品牌库 PBC Library Manual(PBC库手册)翻译(二)

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

2024-07-16 09:01| 来源: 网络整理| 查看: 265

目录

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

然后初始化一个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"); } }

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

 


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3