from charm.toolbox.pairinggroup import PairingGroup, ZR, G1, G2, GT, pair
# from charm.toolbox.secretutil import SecretUtil
from charm.toolbox.ABEnc import ABEnc
debug=False
class node:
def __init__(self,att=None,gate=None,children=None):
"""
:param att: 属性值默认为int类型,其中内部节点null,外部节点为int
:param gate:用两个数字表示(t,n),建议直接使用元组,其中t表示门限值,n表示子节点个数
:param children:是个子节点索引列表,里面记录孩子在那儿
:parm valid :用于秘密恢复,表示此节点是否可以恢复
所以进行建立节点的时候需要注意参数
"""
self.gate=gate
self.children=children
self.att=att
self.valid=None
self.secretshare=None#这个值就是group().random()类型的
def isLeaf(self):
if self.children==None:
return True
return False
def tostring(self):
"""
将🌿子节点属性值和门限值转化为string???
:return:
"""
pass
"""
关于树的构建在构建node的时候已经暗含进去了
因此这个访问树的功能就是进行秘密共享和秘密的恢复
"""
def nodeshare(accesstree,node1):
#如果是叶子```````````````````````节点不需要在进行分享
if not node1.isLeaf():
"如果不是叶子节点,则首先生成一个随机多项式,多项式的常数项为当前节点的秘密值"
"多项式的次数则由当前节点对应的门限值决定"
coef=randomp(node1.gate[0],node1.secretshare)
for i in node1.children:
childrennode=accesstree[i]
childrennode.secretshare=qx(group.random(seed=i),coef)
print(childrennode.secretshare)
# temp=xxx
# xxx=xxx**childrennode.secretshare
# print(xxx)
# xxx=temp
# nodeshare(accesstree,childrennode,xxx)
nodeshare(accesstree,childrennode)
# else:
# print(type(node1.att))
def randomp(d,s):
"""
:param d: 为门限值
:param s: 为秘密
:return: 多项式列表
"""
coef=[]
coef.append(s)
for i in range(1,d):
coef.append(group.random())
return coef
def qx(index,coef):
res=coef[0]
for i in range(1,len(coef)):
exp=group.random(seed=i)
temp=index
res=res+coef[i]*(index**exp)
index=temp
return res
def noderecover(accesstree,node1,userattlist):
if not node1.isLeaf():
validchildrenlist=[]
#遍历每一个子节点
for i in node1.children:
#print(i)
childnode=accesstree[i]
#递归调用,恢复子节点的秘密值
if noderecover(accesstree,childnode,userattlist):
str1="the node with index "+str(i)+" is satisfied!!!"
print(str1)
validchildrenlist.append(i)
if len(validchildrenlist)==node1.gate[0]:
node1.valid=True
break
else:
str2="the node with index "+str(i)+" is not satisfied!!!"
print(str2)
if len(validchildrenlist)==node1.gate[0]:
print("validchildrenlist",validchildrenlist)
secret=group.random(GT)#机智如我
secret=secret/secret
for i in validchildrenlist:
delta=lagrange(i,validchildrenlist,0)
secret=secret*(accesstree[i].secretshare**delta)
node1.secretshare=secret
else:
if node1.att in userattlist:
node1.valid=True
return node1.valid
def lagrange(i,s,x):
print("i",i)
res=group.random()
res=res/res
ielement=group.random(seed=i)
xelement=group.random(seed=x)
for j in s:
if i!=j:
numerator=xelement-group.random(seed=j)
denominator=ielement-group.random(seed=j)
res=res*(numerator/denominator)
return res
class cpabe_00(ABEnc):
# 这一步主要是设置一个椭圆曲线参数,至于为什么要用util却是不杂理解
def __init__(self, groupobj):
ABEnc.__init__(self)
global group
group = groupobj
def setup(self):
#选取基本参数
g=group.random(G1)
alpha,beta=group.random(),group.random()
#进行简单计算
g_alpha=g**alpha
g_beta=g**beta
egg_alpha=pair(g,g)**alpha
msk={'g_alpha':g_alpha}
pk={'g':g,'egg_alpha':egg_alpha,'g_beta':g_beta}
#########
#########建议的话是以文件形式保存下来
#########
return (msk,pk)
def keygen(self, pk, msk, userattlist):
t = group.random()
D=msk['g_alpha']*(pk['g_beta']**t)
D0=pk['g']**t
K_x=[group.hash(s,G1)**t for s in userattlist]
k_x={}
for i in range(0,len(K_x)):
k_x[userattlist[i]]=K_x[i]
#key={'D':D,'D0':D0,'Datt':k_x,"userattlist":userattlist,"t":t}
key = {'D': D, 'D0': D0, 'Datt': k_x, "userattlist": userattlist}
#########
#########仍然是建议以文件形式保存下来,,,,,另外关于t的处理方式,后续注意一下
#########
return key
#def encrypt(self, pk,sk, message,accesstree):
def encrypt(self, pk, message, accesstree):
s = group.random()
C = message*(pk['egg_alpha']**s)
C0 = pk['g']**s
#开始进行秘密共享,首先设置根结点秘密值为s
accesstree[0].secretshare=s
#进行共享,使得每个叶子节点获得对应的秘密分片
#xxx=pair(pk['g'],pk['g_beta']**(sk['t']))
nodeshare(accesstree,accesstree[0])
#x=pair(pk['g'], pk['g_beta']) ** (sk['t'] * s)
#print('x',x)
C1={}
C2={}
for i in range(len(accesstree)):
if accesstree[i].isLeaf():
r=group.random()
#这个稍微改了一点
Hi=group.hash(str(accesstree[i].att), G1)
c1=(pk['g_beta']**accesstree[i].secretshare)*(Hi**-r)
c2=pk['g']**r
str1='C1-'+str(accesstree[i].att)
str2='C2-'+str(accesstree[i].att)
C1[str1]=c1
C2[str2]=c2
#ct={"C":C,'C0':C0,"C1":C1,"C2":C2,'x':x}
ct = {"C": C, 'C0': C0, "C1": C1, "C2": C2}
return ct
def decrypt(self, sk,ct,accesstree):
userattlist=[int(i) for i in sk['userattlist']]
#print(userattlist)
C,C0=ct['C'],ct['C0']
D,D0=sk['D'],sk['D0']
for i in range(len(accesstree)):
if accesstree[i].isLeaf():
if accesstree[i].att in userattlist:
C1string='C1-'+str(accesstree[i].att)
c1=ct['C1'][C1string]
C2string='C2-'+str(accesstree[i].att)
c2=ct['C2'][C2string]
Dattstring=str(accesstree[i].att)
Datt=sk['Datt'][Dattstring]
accesstree[i].secretshare=pair(c1,D0)*pair(c2,Datt)
print(accesstree[i].secretshare)
treeok=noderecover(accesstree,accesstree[0],userattlist)
if treeok:
#egg_alphas=pair(C0,D)/ct['x']
egg_alphas = pair(C0, D) / accesstree[0].secretshare
print("secret",accesstree[0].secretshare)
return C/egg_alphas
else:
print("the access tree is not satisfied")
return None
def main():
# Get the eliptic curve with the bilinear mapping feature needed.
groupObj = PairingGroup('SS512')
cpabe = cpabe_00(groupObj)
(msk, pk) = cpabe.setup()
attr_list = ['1','2','3','4']
m = groupObj.random(GT)#############比较难搞的是怎么将真正想要加密的东西和GT上的东西联系在一起
cpkey = cpabe.keygen(pk, msk, attr_list)
#此处为相应的访问树
accesstree=[]
accesstree.append(node(gate=(4,4),children=[1,2,3,4]))
accesstree.append(node(att=1))
accesstree.append(node(att=2))
accesstree.append(node(att=3))
accesstree.append(node(att=4))
#ct=cpabe.encrypt(pk,cpkey,m,accesstree)
ct = cpabe.encrypt(pk, m, accesstree)
res=cpabe.decrypt(cpkey,ct,accesstree)
print('m',m)
print('res',res)
if __name__=="__main__":
debug = True
main()