PYTHON CPABE

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()
  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值