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
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
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
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
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
请优化上述代码的矩阵与向量的乘法np.matmul
可以使用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
请优化上述代码中矩阵与向量之间的乘法np.dot