近些年,在身份认证和零知识证明这一领域,双线性映射使用越来越多,也存在一些算法实现库,本文使用库PBC实现一个基本的零知识证明流程。
一、库的下载、编译和使用 (windows 尝试失败,Ubuntu下测试成功)
PBC库是一个Linux下的工程,如果想在win下运行,需要先将其编译成win下的lib库。
首先下载MinGW,下载安装管理器mingw-get-setup.exe, 安装好安装管理器后,将基本选项中的所有依赖进行安装。
进入MinGW安装目录中的/msys/1.0,会看到一个msys.bat批处理文件,双击运行会出现一个模拟的Linux环境(可以通过gcc -v 判断刚才的依赖库有没有安装成功):
下载gmp源码,解压到自定义目录(路径中不能有中文),在上面命令行中进入这个路径,执行:./configure --enable-static --disable-shared
执行成功后,该目录下回多次makefile文件,依存执行make 和make install 两个命令。这时候文件夹下回生成一个.libs文件夹,里面的libgmp.a是我们接下来需要的库。此外gmp文件目录下还有一个gmp.h文件也是我么需要的。
下载pbc源码,解压到自定义目录,同时将上面的lib文件和.h文件放到和解压路径路径同级的目录下,分别放到lib文件夹和include文件夹中。
pbc还要4.8版本的编译,后面好多的库都是依托Linux开发,放弃win下使用,转战Ubuntu。
二、Ubuntu下的使用
Python 安装3.x,需要安装几个依赖 sudo apt-get install m4 flex bison libssl-dev
下载 gmp库 OpenSSL库 pbc库 还有最新的charm-crypto的源码。
解压命令: tar -zxvf xx.tar.gz tar -jxvf xx.tar.bz2
使用【./configure】 【make】 【make install】 三个命令将每个库编译安装(openssl 用./config)
然后打开源码先执行./configure.sh(需要先用chmod改权限) 再执行Python setup.py install
测试:
输入Python 进行命令行:测试下面代码
from charm.toolbox.integergroup import IntegerGroup
group1 = IntegerGroup()
group1.paramgen(1024)
g = group1.randomGen()
print(g)
如果上面步骤没问题的话,现在pbc的动态库应该编好了,放在/usr/local/lib下的.so文件。
添加环境变量,让程序运行时可以找到这个库
vim ~/.bashrc 编辑当前用户环境变量文件
添加:export LIBRARY_PATH=$LIBRARY_PATH:/usr/local/lib
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib
source ~/.bashrc 生效修改
测试下面代码(如果没有添加环境变量,下面代码会提示找不到依赖库):
from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair
group2 = PairingGroup('SS512')
g1 = group2.random(G1)
g2 = group2.random(G2)
print('g1:', g1)
print('g2:', g2)
三、开始实现一个简单的基于双线性映射的承诺方案
代码:
from charm.toolbox.pairinggroup import PairingGroup,ZR,G1,G2,GT,pair
import random
# 初始化双线性群
BP = PairingGroup('SS512')
# 生成公共参数
g = BP.random(G1)
h = BP.random(G2)
p = 257
k = 100
# 生成陷门信息和公共参考串
ri = [random.randint(1, p) for _ in range(k)]
gi = [g ** each for each in ri]
# 生成消息
mi = [random.randint(1000, 2000) for _ in range(k)]
# 生成承诺信息
ti = [random.randint(1, p) for _ in range(k)]
t0 = random.randint(1, p)
ci = [mi[i] * (h ** ti[i]) for i in range(k)]
ck_1 = g ** t0
for j in range(k):
ck_1 = ck_1 * (gi[j] ** ti[j])
D = h ** t0
# 验证承诺
v1 = BP.pair_prod(ck_1, h)
v2 = BP.pair_prod(g, D)
for j in range(k):
v2 = v2 * BP.pair_prod(gi[j], ci[j]/mi[j])
if v1 == v2:
print('verify ok!')
print('v1:', v1)
print('v2:', v2)