from gmpy2 import mpz, random_state, mpz_urandomb, mpz_random from Matrix_Construct import matrix_construct import numpy as np import random import sys rand = random_state(random.randrange(sys.maxsize)) bits = 128 # 建立Access对象 class Access(object): def __init__(self, policy_list, att_list): # 初始化后生成访问矩阵M self.m_matrix = matrix_construct(policy_list) # 访问列表要拉平,变成一个一维数组,方便后面操作 self.policy = [] for i in range(len(policy_list)): self.policy.extend(policy_list[i]) # 相当于用户属性组,即是policy_list中的一行 self.att = att_list # 秘密分享函数 def secretSharing(access, secret): lambda_vector = [] # 生成随机向量v v_vector = [] v_vector.append(secret) count = 0 while (count < access.m_matrix.shape[1] - 1): v_vector.append(mpz_urandomb(rand, bits - 2)) count = count + 1 # 矩阵M与向量v相乘,得到lambda向量 lambda_vector = np.matmul(access.m_matrix, np.array(v_vector)) return lambda_vector # omega向量重建函数 def omegaReconstruct(access): # 得到向量Ma ma = np.array(get_ma(access.m_matrix, access.policy, access.att)) # Ma的转置 ma_trans = np.array(ma.T) ma_row = len(ma_trans) # 向量e=[1,0,0,.....] e_vector = [] e_vector.append(1) count = 0 while (count < ma_row - 1): e_vector.append(0) count += 1 # 求Ma的转置矩阵的伪逆矩阵 ma_trans_inv = np.linalg.pinv(ma_trans) # 计算得出omega向量 omega_temp = np.matmul(ma_trans_inv, np.array(e_vector)) omega_vector = [] for i in range(len(ma)): omega_vector.append(mpz(round(omega_temp[i]))) return omega_vector # 由矩阵M生成Ma的函数 def get_ma(m_matrix, policy, att): str_policy = '' for pp in policy: if pp < 10: str_policy += '000' + str(pp) elif pp >= 10 & pp < 100: str_policy += '00' + str(pp) elif pp >= 100 & pp < 1000: str_policy += '0' + str(pp) else: str_policy += str(pp) str_att = '' for aa in att: if aa < 10: str_att += '000' + str(aa) elif aa >= 10 & aa < 100: str_att += '00' + str(aa) elif aa >= 100 & aa < 1000: str_att += '0' + str(aa) else: str_att += str(aa) # 找对应用户属性组在矩阵M中对应的是哪几行 att_index = int((str_policy.find(str_att) + 1) / 4) att_len = len(att) ma = [] for i in range(att_len): ma.append(m_matrix[att_index + i]) return ma def sentence_to_number(sentence, base=10): num = 0 for char in sentence: num = num * base + ord(char) return num def number_to_sentence(number, base=10): sentence = "" while number > 0: char_code = number % base sentence = chr(char_code) + sentence number //= base return sentence if __name__ == "__main__": policy_list = [[1, 3, 4, 6, 8, 9], [1, 3, 4, 6, 8, 9, 34, 56, 67]] att_list = np.array([1, 3, 4, 6, 8, 9], dtype=np.int_) ac = Access(policy_list, att_list) sentence = "Hello World" # 使用进制转换法 number2 = sentence_to_number(sentence, base=128) s = mpz(number2) lam_vector = secretSharing(ac, s) omg_vector = omegaReconstruct(ac) print(omg_vector) s_un = np.inner(lam_vector[:6], omg_vector) new_sentence2 = number_to_sentence(s_un, base=128) print(new_sentence2) # 输出:Hello World

2023-04-17by@qjs13667164495-kBu46&@ChatGPT.Model: gpt-3.5
qjs13667164495-kBu46

from gmpy2 import mpz, random_state, mpz_urandomb, mpz_random
from Matrix_Construct import matrix_construct
import numpy as np
import random
import sys

rand = random_state(random.randrange(sys.maxsize))
bits = 128

建立Access对象

class Access(object):

def __init__(self, policy_list, att_list):
    # 初始化后生成访问矩阵M
    self.m_matrix = matrix_construct(policy_list)

    # 访问列表要拉平,变成一个一维数组,方便后面操作
    self.policy = []
    for i in range(len(policy_list)):
        self.policy.extend(policy_list[i])

    # 相当于用户属性组,即是policy_list中的一行
    self.att = att_list

秘密分享函数

def secretSharing(access, secret):
lambda_vector = []

# 生成随机向量v
v_vector = []
v_vector.append(secret)
count = 0
while (count < access.m_matrix.shape[1] - 1):
    v_vector.append(mpz_urandomb(rand, bits - 2))
    count = count + 1

# 矩阵M与向量v相乘,得到lambda向量
lambda_vector = np.matmul(access.m_matrix, np.array(v_vector))
return lambda_vector

omega向量重建函数

def omegaReconstruct(access):
# 得到向量Ma
ma = np.array(get_ma(access.m_matrix, access.policy, access.att))

# Ma的转置
ma_trans = np.array(ma.T)
ma_row = len(ma_trans)

# 向量e=[1,0,0,.....]
e_vector = []
e_vector.append(1)
count = 0
while (count < ma_row - 1):
    e_vector.append(0)
    count += 1

# 求Ma的转置矩阵的伪逆矩阵
ma_trans_inv = np.linalg.pinv(ma_trans)

# 计算得出omega向量
omega_temp = np.matmul(ma_trans_inv, np.array(e_vector))

omega_vector = []
for i in range(len(ma)):
    omega_vector.append(mpz(round(omega_temp[i])))
return omega_vector

由矩阵M生成Ma的函数

def get_ma(m_matrix, policy, att):
str_policy = ''
for pp in policy:
if pp < 10:
str_policy += '000' + str(pp)
elif pp >= 10 & pp < 100:
str_policy += '00' + str(pp)
elif pp >= 100 & pp < 1000:
str_policy += '0' + str(pp)
else:
str_policy += str(pp)
str_att = ''
for aa in att:
if aa < 10:
str_att += '000' + str(aa)
elif aa >= 10 & aa < 100:
str_att += '00' + str(aa)
elif aa >= 100 & aa < 1000:
str_att += '0' + str(aa)
else:
str_att += str(aa)

# 找对应用户属性组在矩阵M中对应的是哪几行
att_index = int((str_policy.find(str_att) + 1) / 4)
att_len = len(att)
ma = []
for i in range(att_len):
    ma.append(m_matrix[att_index + i])
return ma

def sentence_to_number(sentence, base=10):
num = 0
for char in sentence:
num = num * base + ord(char)
return num

def number_to_sentence(number, base=10):
sentence = ""
while number > 0:
char_code = number % base
sentence = chr(char_code) + sentence
number //= base
return sentence

if name == "main":
policy_list = [[1, 3, 4, 6, 8, 9], [1, 3, 4, 6, 8, 9, 34, 56, 67]]
att_list = np.array([1, 3, 4, 6, 8, 9], dtype=np.int_)
ac = Access(policy_list, att_list)

sentence = "Hello World"
# 使用进制转换法
number2 = sentence_to_number(sentence, base=128)
s = mpz(number2)
lam_vector = secretSharing(ac, s)
omg_vector = omegaReconstruct(ac)
print(omg_vector)
s_un = np.inner(lam_vector[:6], omg_vector)
new_sentence2 = number_to_sentence(s_un, base=128)
print(new_sentence2)  # 输出:Hello World
Avatar
Avatar

测试多行访问策略

policy_list = [[1, 3, 4, 6, 8, 9], [1, 3, 4, 6, 8, 9, 34, 56, 67], [2, 3, 5, 6, 7, 9, 34, 45, 56, 78]]
att_list = np.array([1, 3, 4, 6, 8, 9], dtype=np.int_)
ac = Access(policy_list, att_list)

sentence = "Hello World"
# 使用进制转换法
number2 = sentence_to_number(sentence, base=128)
s = mpz(number2)
lam_vector = secretSharing(ac, s)
omg_vector = omegaReconstruct(ac)
print(omg_vector)
s_un = np.inner(lam_vector[:6], omg_vector)
new_sentence2 = number_to_sentence(s_un, base=128)
print(new_sentence2)  # 输出:Hello World
qjs13667164495-kBu46

请优化上述代码的矩阵与向量的乘法np.matmul

Avatar
Avatar

可以使用numpy中的dot函数代替matmul函数,因为在矩阵与向量的乘法中,dot函数更快。同时,可以将numpy数组转换为gmpy2中的mpz类型,从而减少计算时间。优化后的代码如下:

from gmpy2 import mpz, random_state, mpz_urandomb, mpz_random
import numpy as np
import random
import sys

rand = random_state(random.randrange(sys.maxsize))
bits = 128


# 建立Access对象
class Access(object):

    def __init__(self, policy_list, att_list):
        # 初始化后生成访问矩阵M
        self.m_matrix = matrix_construct(policy_list)

        # 访问列表要拉平,变成一个一维数组,方便后面操作
        self.policy = []
        for i in range(len(policy_list)):
            self.policy.extend(policy_list[i])

        # 相当于用户属性组,即是policy_list中的一行
        self.att = att_list


# 秘密分享函数
def secretSharing(access, secret):
    lambda_vector = []

    # 生成随机向量v
    v_vector = []
    v_vector.append(secret)
    count = 0
    while (count < access.m_matrix.shape[1] - 1):
        v_vector.append(mpz_urandomb(rand, bits - 2))
        count = count + 1

    # 矩阵M与向量v相乘,得到lambda向量
    lambda_vector = np.dot(access.m_matrix, np.array(v_vector, dtype=mpz))
    return lambda_vector


# omega向量重建函数
def omegaReconstruct(access):
    # 得到向量Ma
    ma = np.array(get_ma(access.m_matrix, access.policy, access.att), dtype=mpz)

    # Ma的转置
    ma_trans = np.array(ma.T, dtype=mpz)
    ma_row = len(ma_trans)

    # 向量e=[1,0,0,.....]
    e_vector = []
    e_vector.append(1)
    count = 0
    while (count < ma_row - 1):
        e_vector.append(0)
        count += 1

    # 求Ma的转置矩阵的伪逆矩阵
    ma_trans_inv = np.linalg.pinv(ma_trans)

    # 计算得出omega向量
    omega_temp = np.dot(ma_trans_inv, np.array(e_vector, dtype=mpz))

    omega_vector = []
    for i in range(len(ma)):
        omega_vector.append(mpz(round(omega_temp[i])))
    return omega_vector


# 由矩阵M生成Ma的函数
def get_ma(m_matrix, policy, att):
    str_policy = ''
    for pp in policy:
        if pp < 10:
            str_policy += '000' + str(pp)
        elif pp >= 10 & pp < 100:
            str_policy += '00' + str(pp)
        elif pp >= 100 & pp < 1000:
            str_policy += '0' + str(pp)
        else:
            str_policy += str(pp)
    str_att = ''
    for aa in att:
        if aa < 10:
            str_att += '000' + str(aa)
        elif aa >= 10 & aa < 100:
            str_att += '00' + str(aa)
        elif aa >= 100 & aa < 1000:
            str_att += '0' + str(aa)
        else:
            str_att += str(aa)

    # 找对应用户属性组在矩阵M中对应的是哪几行
    att_index = int((str_policy.find(str_att) + 1) / 4)
    att_len = len(att)
    ma = []
    for i in range(att_len):
        ma.append(m_matrix[att_index + i])
    return ma


def sentence_to_number(sentence, base=10):
    num = 0
    for char in sentence:
        num = num * base + ord(char)
    return num


def number_to_sentence(number, base=10):
    sentence = ""
    while number > 0:
        char_code = number % base
        sentence = chr(char_code) + sentence
        number //= base
    return sentence


if __name__ == "__main__":
    # 测试单行访问策略
    policy_list = [[1, 3, 4, 6, 8, 9]]
    att_list = np.array([1, 3, 4, 6, 8, 9], dtype=np.int_)
    ac = Access(policy_list, att_list)

    sentence = "Hello World"
    # 使用进制转换法
    number2 = sentence_to_number(sentence, base=128)
    s = mpz(number2)
    lam_vector = secretSharing(ac, s)
    omg_vector = omegaReconstruct(ac)
    print(omg_vector)
    s_un = np.inner(lam_vector[:6], omg_vector)
    new_sentence2 = number_to_sentence(s_un, base=128)
    print(new_sentence2)  # 输出:Hello World

    # 测试多行访问策略
    policy_list = [[1, 3, 4, 6, 8, 9], [1, 3, 4, 6, 8, 9, 34, 56, 67], [2, 3, 5, 6, 7, 9, 34, 45, 56, 78]]
    att_list = np.array([1, 3, 4, 6, 8, 9], dtype=np.int_)
    ac = Access(policy_list, att_list)

    sentence = "Hello World"
    # 使用进制转换法
    number2 = sentence_to_number(sentence, base=128)
    s = mpz(number2)
    lam_vector = secretSharing(ac, s)
    omg_vector = omegaReconstruct(ac)
    print(omg_vector)
    s_un = np.inner(lam_vector[:6], omg_vector)
    new_sentence2 = number_to_sentence(s_un, base=128)
    print(new_sentence2)  # 输出:Hello World
qjs13667164495-kBu46

请优化上述代码中矩阵与向量之间的乘法np.dot

Avatar