CPABE中KEK树实现用户撤销

参考链接: https://blog.csdn.net/qq_32318629/article/details/108378081
参考论文:A Traceable and Revocable Ciphertext-Policy
Attribute-based Encryption Scheme Based
on Privacy Protection

KEK树

构建一棵完全二叉树,二叉树的叶子节点是系统中的用户。
用户撤销KEK树KEK完全二叉树和最小覆盖集的性质:在这里插入图片描述

完全二叉树

在这里插入图片描述

python实现

class Node(object):
    """节点类"""

    def __init__(self, id, parent=None, lchild=None, rchild=None, isleaf=False):
        self.u = None
        self.id = id
        self.parent = parent
        self.lchild = lchild
        self.rchild = rchild
        self.isleaf = isleaf

    def getId(self):
        return self.id

    def getParent(self):
        return self.parent

    def getLchild(self):
        return self.lchild

    def getRchild(self):
        return self.rchild

from math import *
from node import *

class Tree(object):
    """树类"""
    def __init__(self, root = None):
        self.root = root

    def creatTree(self, U):
        #有bug,该函数创建的是满二叉树,用户个数必须为2^n个,而不是完全二叉树
        '''
        :param U:系統中用戶列表
        :return:返回树的根节点和用户身份编号字典
        '''
        n = len(U)
        N = 2 * n - 1
        nodelist = []
        identity_list = {}
        nodelist.append(Node(0))
        #计算树的深度
        depth = floor(log2(N)) + 1
        #依据节点个数算出树的深度,然后创建节点,并存在nodelist列表中
        for i in range(1, depth + 1):
            #树的每一层的节点实例化
            #每一层节点的编号为(2^(i-1),2^i-1)
            min = (int)(pow(2, i - 1))
            max = (int)(pow(2, i))
            for j in range(min, max):
                node = Node(j)
                if i == depth:
                    node.isleaf = True
                    identity_list[U[j-min]] = j
                nodelist.append(node)
        #print("len:", len(nodelist))
        #树的节点编号从1开始,将树中的节点依据二叉树的性质连接
        for i in range(1, len(nodelist)):
            node = nodelist[i]
            if(i != 1):
                node.parent = nodelist[(int)(i / 2)]
                #print(i,node.parent.id)
            if node.isleaf == False:
                node.lchild = nodelist[2 * i]
                node.rchild = nodelist[2 * i + 1]
        self.root = nodelist[1]
        return (nodelist[1], identity_list)

    def creatTree2(self, U):
        '''
        创建完全二叉树
        :param U:系統中用戶列表
        :return:返回树的根节点和用户身份编号字典
        '''
        n = len(U)
        N = 2 * n - 1
        # 存储节点的列表
        nodelist = [Node(0)]
        identity_list = {}
        for i in range(1, N+1):
            node = Node(i)
            nodelist.append(node)
        for i in range(1, N+1):
            # 非叶非父母节点
            if i != 1 and 2 * i + 1 <= N:
                nodelist[i].lchild = nodelist[2 * i]
                nodelist[i].rchild = nodelist[2 * i + 1]
                nodelist[i].parent = nodelist[(int)(i / 2)]
            # 根节点,无父母
            if i == 1:
                nodelist[i].lchild = nodelist[2 * i]
                nodelist[i].rchild = nodelist[2 * i + 1]
            # 叶结点
            if i != 1 and 2 * i > N:
                nodelist[i].parent = nodelist[(int)(i / 2)]
                nodelist[i].isleaf = True
                nodelist[i].u = U[i - n]
                identity_list[U[i - n]] = i
        self.root = nodelist[1]
        return identity_list

    #返回叶子节点到根节点的路径
    def getPath(self, leaf):
    # 返回路径ID列表
        if leaf == None:
            return []
        path = []
        temp = leaf
        while(temp.parent != None):
            path.insert(0,temp.id)
            #print("temp.id", temp.id)
            #print("temp.parent", temp.parent.id)
            temp = temp.parent
        path.insert(0,temp.id)
        return path

    def getPath2(self, leaf):
    # 返回路径节点列表
        if leaf == None:
            return []
        path = []
        temp = leaf
        while(temp.parent != None):
            # 每次在开头插入元素
            path.insert(0, temp)
            temp = temp.parent
        path.insert(0, temp)
        return path

    def SearchU(self, Root, u):
        if Root == None:
            return
        if Root.isleaf:
            if Root.u == u:
                res = Root.id
                return [res, Root]
        #use = self.SearchU(Root.lchild, u)
        if self.SearchU(Root.lchild, u) == None:
            return self.SearchU(Root.rchild, u)
        else:
            return self.SearchU(Root.lchild, u)



'''查找覆盖集, 先找到撤销列表中所有节点的路径集合,然后判断生成最小覆盖集'''
def cover(tree, reList):
    minCover = []
    revocable = []
    # 把撤销列表中用户的路径节点添加到revocable中
    for node in reList:
        tempList = tree.getPath2(node)
        #print(tempList)
        for i in tempList:
            if i not in revocable:
                revocable.append(i)
		# 对于revocable中的节点,如果节点左孩子不在撤销列表则将左孩子添加到mincover列表中,右孩子同理。
    for i in revocable:
        if i.isleaf == True:
            continue
        if i.lchild not in revocable:
            minCover.append(i.lchild.id)
        if i.rchild not in revocable:
            minCover.append(i.rchild.id)
    # 如果revocable为空,即系统中没有撤销用户,那么此时根节点就是最小覆盖集。
    if len(revocable) == 0:
        minCover.append(1)

    return minCover

使用charm-crypto复现论文A Traceable and Revocable Ciphertext-Policy
Attribute-based Encryption Scheme Based
on Privacy Protection完整代码。地址:https://github.com/xuekema/Revocable-CPABE-KEK_Tree

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

☆年青新☆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值