Pypbc 的简易用法

PBC(Pairing-Based Cryptography Library) 是实现双线性对运算的函数库 . 这个开源代码 C
函数库是由Stanford 大学开发 ,

库的地址为 http://crypto.stanford.edu/pbc/.

具体的安装步骤看我之前写的博客:

https://blog.csdn.net/weixin_39032619/article/details/109261403

这次讲一讲在学习使用这个库中的心得:

(一)包的初始化

在pypbc库中,有个对象:Element,Pairing,Parameters。

其中Parameters对象负责对对象进行初始化,规定使用哪种曲线,在pbc当中实现了好几种,有a.param,b.param……。在help里面可以看到:

There are three basic ways to instantiate a Parameters object:
     |  Parameters(param_string=s) -> a set of parameters built according to s.
     |  Parameters(n=x, short=True/False) -> a type A1 or F curve.
     |  Parameters(qbits=q, rbits=r, short=True/False) -> type A or E curve.

有三种不同的初始化方式

(1 )第一种是根据输入曲线参数来初始化出现。

例如:

stored_params = """type a
q 8780710799663312522437781984754049815806883199414208211028653399266475630880222957078625179422662221423155858769582317459277713367317481324925129998224791
h 12016012264891146079388821366740534204802954401251311822919615131047207289359704531102844802183906537786776
r 730750818665451621361119245571504901405976559617
exp2 159
exp1 107
sign1 1
sign0 1
"""

params = Parameters(param_string=stored_params)	# type a
pairing = Pairing(params)  #实例化双线性对对象

(2)第2种是根据设置群的阶数来生成曲线

q_1 = get_random_prime(60)  # 生成一个长度为60的随机素数
q_2 = get_random_prime(60)

#使用的是pbc中的a1_param参数
params = Parameters( n = q_1 * q_2 )   

#实例化双线性对对象,可以理解为e(a,b)
pairing = Pairing( params )

我们首先生成2个长度为60的随机素数,将他们的乘积作为阶数n进行曲线的初始化。

(3)第三种根据安全参数进行实例化

qbits=512, rbits=160
params = Parameters(qbits=qbits, rbits=rbits)   #参数初始化
pairing = Pairing(params)  # 根据参数实例化双线性对

(二)元素的操作

我们上面提到三个对象Element、pairing,Parameters,Element是负责元双线性对的运算,包括群之间的加减乘除。

简单介绍一下功能:

#初始化一个G1,G2,GT,Zr元素,如果value赋值则进行是运算
Element(pairing, G1||G2||GT||Zr, value=v) -> Element

#初始化一个G1||G2||GT||Zr中的元素并置为1
Element.one(pairing, G1||G2||GT||Zr) -> identity element for the given group.
#初始化一个G1||G2||GT||Zr中的元素并置为0
Element.zero(pairing, G1||G2||GT||Zr) -> identity element for the given group.

#从群中取一个随机数,并初始化一个元素,一般是取g的,也就是生成元。
Element.random(pairing, G1||G2||GT||Zr) -> random element of the given group.

#根据给定的值生成哈希函数
Element.from_hash(pairing, G1||G2||GT||Zr -> element whose value is determined by the given hash value.

各个函数的使用简单的举个例子

#从G2中取一个随机数,并初始化一个元素,一般是取g的,也就是生成元。
g = Element.random( pairing, G2 )

#初始化一个GT元素
a = Element( pairing, GT )
#初始化一个G2元素
b = Element( pairing, G2 )
#初始化一个Zr元素
c = Element( pairing, Zr )
#初始化一个GT中的元素并置为1
Element.one( pairing, GT )
#初始化一个Zr中的元素并置为0
Element.zero( pairing, Zr )

'''对群进行运算一般使用Element,而不是直接在数值上进行运算。(当然直接运算也可以)。其中pairing代表我们初始化的双线性对,G2代表返回值的类型,value=就是值等于多少,G2中的元素做底数,Zr中的元素做指数,其实也能使用b = g ** c是同样的效果,但下面这样写更加工整,看着更明白,减少出错。
'''
b = Element( pairing, G2, value = g ** c )   # b = g^c

# a = e(g,g),注意:type(a) = GT。
a = pairing.apply(g,g)

(三)方案的实现

代码请结合2004年Boneh的论文方案来阅读,其中**[params, g]公共参数**,近来我在看学术论文时经常看到公共参数生成算法,该算法返回公共参数pp,pp作为方案其余各算法的隐含输入,这样写法是为了结合工程习惯。Pbc library公共参数生成算法中的qbits和rbits用法具体请阅读**官方文档**,
在这里插入图片描述
在这里插入图片描述

—— KeyGen:输入安全参数生成群G1,G2的阶p,并挑选一个属于Zp^*的随机数α,G1的生成元g,输出
A p u b = [ g , h = g α ]  and  A p r i v = α A_{p u b}=\left[g, h=g^{\alpha}\right] \text { and } A_{p r i v}=\alpha Apub=[g,h=gα] and Apriv=α
—— PEKS(A_pub,W):W是明文message,首先计算t=e(H1(W),hr)∈G2,r是Zp*的一个随机数。输出密文
S = PEKS ⁡ ( A p u b , W ) = [ g r , H 2 ( t ) ] S=\operatorname{PEKS}\left(A_{p u b}, W\right)=\left[g^{r}, H_{2}(t)\right] S=PEKS(Apub,W)=[gr,H2(t)]
—— Trapdoor(A_priv,W):输出
 output  T W = H 1 ( W ) α ∈ G 1 \text { output } T_{W}=H_{1}(W)^{\alpha} \in G_{1}  output TW=H1(W)αG1
—— Test(A_pub,S ,T_w):让S=[A,B],A=g^r,B=H2(t),判断 H2(e(T_w,A)) = B 是否成立,如果成立返回yes,否则返回no。

注意:PEKS论文中PEKS定义为 G 1 × G 1 → G 2 G_1 \times G_1 \rightarrow G_2 G1×G1G2
使用的是对称双线性对。而我们熟知的定义是 G 1 × G 2 → G T G_1 \times G_2 \rightarrow G_T G1×G2GT
二者的表述不同,转换一下表示为(论文中的G1)=(定义中的G1,G2),(论文中的G2)=(定义中的GT),而在pypbc中是使用我们熟知的定义来表示的,与论文中有所不同。

from pypbc import *
import hashlib

Hash1 = hashlib.sha256
Hash2 = hashlib.sha256


# 公钥可搜索加密-2004-Boneh


# 密钥生成算法,输入安全参数qbits和rbits,返回[params, g, pk, sk]
def KeyGen(qbits=512, rbits=160):
    params = Parameters(qbits=qbits, rbits=rbits)   #参数初始化
    pairing = Pairing(params)  # 根据参数实例化双线性对
    # 返回公共参数,PEKS是对称双线性对,G1=G2,二者的生成元是一样的,G2同样可以替换为G1
    g = Element.random(pairing, G2)  # g是G2的一个生成元
    sk = Element.random(pairing, Zr) # 私钥是一个素数域Zp内的随机数
    pk = Element(pairing, G2, value=g ** sk)   # 公钥是[g, h = g^α] α=sk
    return [params, g, sk, pk]


# PEKS算法,输入公共参数[params, g],公钥pk,关键字word,返回[A, B] (具体参考论文)
def PEKS(params, g, pk, word):
    #PEKS 算法输入公钥pk(论文中是h),G1的生成元g,关键字W
    pairing = Pairing(params)
    #首先生成t = e(H1(W),h^r),H1(W)是对关键字进行哈希函数处理,这里使用的是hash256算法
    hash_value = Element.from_hash(pairing, G1, Hash1(str(word).encode('utf-8')).hexdigest())
    r = Element.random(pairing, Zr)  #定义一个Zp内的随机数r
    h_r = Element(pairing,G1,value = pk ** r)
    # t = pairing.apply(hash_value, h_r)

    # g_r = Element(pairing,G1,value = g ** r)
    t = pairing.apply(hash_value, pk ** r)  #生成双线性对e(H1(W),h^r)
    return [g**r, Hash2(str(t).encode('utf-8')).hexdigest()]


# 陷门生成算法,输入公共参数[params],私钥sk,待查关键字word,返回陷门td
def Trapdoor(params, sk, word):
    pairing = Pairing(params)
    hash_value = Element.from_hash(pairing, G1, Hash1(str(word).encode('utf-8')).hexdigest())
    return hash_value ** sk


# 测试算法,输入公共参数[params],公钥pk,S=[A, B],陷门td,返回布尔值True/False
def Test(params, pk, cipher, td):
    pairing = Pairing(params)
    [A, B] = cipher
    td = Element(pairing, G1, value=str(td))
    temp = pairing.apply(td, A)
    temp = Hash2(str(temp).encode('utf-8')).hexdigest()
    return temp == B


if __name__ == '__main__':

    [params, g, sk, pk] = KeyGen(512, 160)
    message= 'father'
    cipher = PEKS(params, g, pk, message)
    keyword = 'father'
    td = Trapdoor(params, sk, keyword)
    B=Test(params, pk, cipher, td)
    print(B)
    if B:
        print("在密文中检索到关键字%s"%keyword)
    else:
        assert (Test(params, pk, cipher, td), '密文中无法检索到该关键字')

  • 6
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 18
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值