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()
PYTHON CPABE
于 2022-10-11 16:39:34 首次发布