def test(): for msg, d, qx, qy, k, r, s in curve_tests[name]: inv_s = int_to_bytes(curve._backend.n - bytes_to_int(s), len(s)) signature = native_curve.sign(msg, d, hash=None, entropy=k) assert signature[:len(r)] == r assert signature[len(r):] in (s, inv_s) assert native_curve.verify(signature, msg, b"\x04" + qx + qy, hash=None)
def EC_func(m_dict): ChameleonHash = ChameleonHash_ECC.ChameleonHash() # 实例化对象,这一步注意不可少!!! KeyTrans = key_type_transform.KeyTrans() order = ChameleonHash.order() # ************************UDP服务器端编程********************************* s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(('127.0.0.1', 12346)) # 绑定端口 data, addr = s.recvfrom(8192) # 接收A3VI发来的消息 # s.close() data_ST = pickle.loads( data ) # 收到消息后,反序列化得到 {'CH_UE': message_AUSF['CH_UE'], 'N': message_AUSF['N'], 'RG_Ope': message_AUSF['RG_Ope'], 'RG_A3VI': keys, 'ST': ST} CH_UE = data_ST['CH_UE'] # 这里假装是用后面接收到的TXID_ST上链查询到的CH_UE值 # print('***EC***参与区块链共识,备份链上数据【包含CH_UE】!!!') # **********************UDP客户端编程【发送消息给UE,提示其开始认证过程】*************************************** print('EC >> UE 开始认证') message = b'start' t = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) t.sendto(message, ('127.0.0.1', 12347)) t.close() """ UE_EC = {'Hidden_Allowed_S_NSSAI': Hidden_Allowed_S_NSSAI, 'PID_UE': PID_UE, 'A_UE': A_UE.xy, 'B_UE': B_UE.xy, 'm_UE': m1, 'T_Curr': T_Curr, 'TXID_ST': TXID_ST} """ data1, addr1 = s.recvfrom(8192) UE_EC = pickle.loads(data1) # print('***EC***收到的UE的认证消息:', UE_EC) print('***EC***收到的UE的认证消息') start_auth = time.clock() s.close() m = { 'PID_UE': UE_EC['PID_UE'], 'A_UE': UE_EC['A_UE'], 'B_UE': UE_EC['B_UE'], "T_Curr": UE_EC['T_Curr'] } b_m = pickle.dumps(m) h = hashlib.sha3_256() h.update(b_m) m_h = h.hexdigest() b_m_h = bytes(m_h, encoding='utf-8') gamma = bytes_to_int(b_m_h) m_UE = UE_EC['m_UE'] A_UE = UE_EC['A_UE'] x = A_UE[0] y = A_UE[1] A = ECC.EccPoint(x, y) B_UE = UE_EC['B_UE'] x_B = B_UE[0] y_B = B_UE[1] B = ECC.EccPoint(x_B, y_B) P = ECC._curves['P-256'].G CH_EC = P.__mul__(m_UE) + A.__mul__(gamma) print('***EC***根据用户发送的TXID_ST上链查询到的哈希值:', CH_UE) print('***EC***根据接收到的消息计算出的哈希值:', CH_EC.xy) print('****************!!!EC端验证碰撞成功!!!*********************' ) if CH_EC.xy == CH_UE else print('碰撞失败') end_auth = time.clock() print('EC端在服务认证阶段的计算开销:', (end_auth - start_auth) * 1000, 'ms') m_dict['EC_Auth'] = (end_auth - start_auth) * 1000 # 提示A3VI开始密钥协商,并将一些密钥协商材料转交给A3VI m_EC_A3VI = { 'PID_UE': UE_EC['PID_UE'], 'm_UE': m_UE, 'A_UE': A_UE, 'B_UE': UE_EC['B_UE'] } b_m_EC_A3VI = pickle.dumps(m_EC_A3VI) DokeyAgreement = True b_DokeyAgreement = pickle.dumps(DokeyAgreement) # **********************UDP客户端编程【发送消息给A3VI,提示其开始密钥协商过程】*************************************** print('+++2+++ UE <<<< EC >>>> A3VI 提示双方开始密钥协商过程') # print('服务认证阶段消息<ACK,PID_UE,m_UE,A_UE,B_UE>字节数为:', len(UE_EC['PID_UE']) + len(int_to_bytes(m_UE, 5)) + len(A.xy) + len(B.xy)) bytes_sum = A.x.__int__().bit_length() / 8 + A.y.__int__().bit_length( ) / 8 + B.x.__int__().bit_length() / 8 + B.y.__int__().bit_length() / 8 print('服务认证阶段消息<ACK,PID_UE,m_UE,A_UE,B_UE>字节数为:', len(UE_EC['PID_UE']) + len(int_to_bytes(m_UE, 32)) + bytes_sum) m_dict['5'] = len(UE_EC['PID_UE']) + len(int_to_bytes(m_UE, 32)) + bytes_sum tt = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) tt.sendto(b_m_EC_A3VI, ('127.0.0.1', 12345)) tt.sendto(b_DokeyAgreement, ('127.0.0.1', 12347)) tt.close()
def Ope_func(m_dict): curve = sslcrypto.ecc.get_curve('prime256v1') KeyTrans = key_type_transform.KeyTrans() # 注意示例化!!! # ************************UDP服务器端编程********************************* s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(('127.0.0.1', 9999)) # 绑定端口 data, addr = s.recvfrom(4096) s.close() m_UE_AMF = pickle.loads(data) # 收到消息后,反序列化得到 {'ciphertext': ciphertext, 'signature': signature} signature_UE = m_UE_AMF['signature'] ciphertext_UE = m_UE_AMF['ciphertext'] print("***AMF***收到的UE发送的消息<UText, E, σ>") start_reg = time.clock() # *****************************AMF读取用户的公钥进行验签*********************************** public_key_raw = ECC.import_key(open(r'D:\PythonProject\FUIH\ECC_file_keys\UE_publickey.pem').read()) x = public_key_raw.pointQ.x.__int__() y = public_key_raw.pointQ.y.__int__() pk_UE = KeyTrans.b_public_key(x, y) s = hashlib.sha3_256() # 这里利用sha256对密文进行哈希处理 s.update(ciphertext_UE) cipher_h = s.hexdigest() b_cipher_h_UE = bytes(cipher_h, encoding='utf-8') # 这里注意把 16进制的密文摘要转换为字节串,进行处理utf-8编码 print('***AMF***验证UE的签名成功!!!') if curve.verify(signature_UE, b_cipher_h_UE, pk_UE) else print('***AMF***验证UE的签名失败!!!') # ************************************在Operator核心网内AMF把ciphertext_UE消息转交给SMF处理******************************************************* # ***************************SMF利用Ope的私钥开始解密,获取用户注册信息CH_UE,ID_UE,ID_A3VI**************************************** print('---2--- AMF >> SMF 发送消息<UText, E>') print('服务注册阶段消息<UText, E>字节数为:', len(ciphertext_UE)) private_key_raw = ECC.import_key(open(r'D:\PythonProject\FUIH\ECC_file_keys\Ope_privatekey.pem').read()).d.__int__() sk = KeyTrans.b_private_key(private_key_raw) # 注意!!!这是Ope的私钥 b_message_UE = curve.decrypt(ciphertext_UE, sk, algo='aes-256-ofb') message_UE = pickle.loads(b_message_UE) # 这里获得UE的注册信息 {'CH_UE': CH_UE.CH(), 'N': N, 'ID_UE': ID_UE, 'ID_A3VI': ID_A3VI} print('***SMF***解密UText为:', message_UE) # print(message_UE) # print(type(message_UE)) # *****************************************SMF把注册消息转发给AUSF处理******************************************************** print('---3--- SMF >> AUSF 发送消息<CH_UE, N, ID_UE, ID_A3VI>') print('服务注册阶段消息<CH_UE, N, ID_UE, ID_A3VI>字节数为:', len(message_UE['CH_UE']) + len(int_to_bytes(message_UE['N'], 32)) + len(message_UE['ID_UE'])+len(message_UE['ID_A3VI'])) TXID_ST = b'8b60004928090023bef4292ed4e0e414a9f1eaa2d734d4b34beb5c6b2f33bb59' T_Exp = time.clock() print('AUSF需要备份存储的TXID数据量为:', len(TXID_ST)+len(message_UE['ID_UE'])+len(message_UE['ID_A3VI'])+T_Exp.__int__().bit_length()/8, 'bytes') # *************************读取Ope的公私钥,并混进环成员中,这里的公私钥形式为(x,y) d ********************************* # public_key_raw = ECC.import_key(open(r'D:\PythonProject\FUIH\ECC_file_keys\Ope_publickey.pem').read()) # x = public_key_raw.pointQ.x.__int__() # y = public_key_raw.pointQ.y.__int__() # pk_Ope = (x, y) # # private_key_raw = ECC.import_key(open(r'D:\PythonProject\FUIH\ECC_file_keys\Ope_privatekey.pem').read()).d.__int__() # sk_Ope = private_key_raw # 注意!!!这是Ope的私钥 """ 这里Ope把自己的公私钥混进环成员这里,在测试的时候,发现aosring的算法是基于secp256k1 (bitcoin)的,而我们其余的代码都是 基于secp256r1的椭圆曲线,所以这里暂时随机生成密钥,用于环签名。 """ # ******************************************************************************************* n = 30 # keys = Ring_Group.generate_RG_with_input_key(n, pk_Ope, sk_Ope) # 我们这里随机生成一些公私钥,假装找了一些其他的Ope成员形成环 keys = aosring_randkeys(n) CH_N = {'CH_UE': message_UE['CH_UE'], 'N': message_UE['N']} b_CH_N = pickle.dumps(CH_N) s = hashlib.sha3_256() # 这里利用sha256对密文进行哈希处理 s.update(b_CH_N) b_CH_N_h_0x = s.hexdigest() b_CH_N_h = bytes(b_CH_N_h_0x, encoding='utf') msg = bytes_to_int(b_CH_N_h) # AUSF开始进行环签名,生成一个半成品票据PST PST_all = aosring_sign(*keys, message=msg) PST = (PST_all[1], PST_all[2]) # 这里是签名的有效部分tees, cees[-1] 形式为 ((x, y), z) print('***AUSF***生成半成品票据PST') # AUSF把半成品票据和用户注册信息打包后,加密并签名发送给A3VI CH_UE||N||RG||PST # message_AUSF = {'CH_UE': message_UE['CH_UE'], 'N': message_UE['N'], 'RG_Ope': keys, 'PST': PST} # 这里测通信开销,我们应该只发送证书序列号就可以了,每个整数序列 cert_ID = 0x0546fe1823f7e1941da39fce14c46173 cert = [] for _ in range(n): cert.append(cert_ID) message_AUSF = {'CH_UE': message_UE['CH_UE'], 'N': message_UE['N'], 'RG_Ope': cert, 'PST': PST} b_message_AUSF = pickle.dumps(message_AUSF) # mmmm_AUSF = [message_UE['CH_UE'], message_UE['N'], keys, PST] # b_mmmm_AUSF = pickle.dumps(mmmm_AUSF) # print('<CText, E2, β>字节数字典%s vs 列表%s 对比:', len(b_message_AUSF), len(b_mmmm_AUSF)) # 开始加密和签名 public_key_raw1 = ECC.import_key(open(r'D:\PythonProject\FUIH\ECC_file_keys\A3VI_publickey.pem').read()) x1 = public_key_raw1.pointQ.x.__int__() y1 = public_key_raw1.pointQ.y.__int__() pk_A3VI = KeyTrans.b_public_key(x1, y1) ciphertext = curve.encrypt(b_message_AUSF, pk_A3VI, algo='aes-256-ofb') # 这里要用AUSF的公钥来加密 s1 = hashlib.sha3_256() # 这里利用sha256对密文进行哈希处理 s1.update(ciphertext) cipher_h = s1.hexdigest() b_cipher_h = bytes(cipher_h, encoding='utf-8') # 这里注意把 16进制的密文摘要转换为字节串,进行处理utf-8编码 signature = curve.sign(b_cipher_h, sk) # 注意!!!这是Ope的私钥 # print("Ope发送的签名为:", signature) m_AUSF_A3VI = {'ciphertext': ciphertext, 'signature': signature} # 这是AUSF需要发送的消息密文和签名 b_m_AUSF_A3VI = pickle.dumps(m_AUSF_A3VI) # 消息序列化为字节串 end_reg = time.clock() print('Ope端服务注册阶段计算开销为:', (end_reg-start_reg)*1000, 'ms') m_dict['Ope_Reg'] = (end_reg-start_reg)*1000 # gol.set_value('Ope_Reg', (end_reg-start_reg)*1000) # **********************UDP客户端编程*************************************** print('---4--- AUSF >>>> A3VI 发送消息<CText, E2, β>') print('服务注册阶段消息<CText, E2, β>字节数为:', len(ciphertext)+len(signature)) m_dict['2'] = len(ciphertext)+len(signature) m = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) m.sendto(b_m_AUSF_A3VI, ('127.0.0.1', 12345)) m.close()
def b_public_key( self, x, y ): #注意这个函数的输入应该为public_key_raw.pointQ.x.__int__() y.__int__() 是公钥(x,y) int值 b_x = int_to_bytes(x, self.__len) b_y = int_to_bytes(y, self.__len) return self.__encode_public_key(b_x, b_y) # 返回公钥的字节串值
def b_private_key(self, private_key_raw ): # 注意这个函数的输入private_key_raw.d.__init__(),应该是私钥d的int值 private_key = int_to_bytes(private_key_raw, self.__len) return private_key # 返回私钥的字节串值
def A3VI_func(m_dict): curve = sslcrypto.ecc.get_curve('prime256v1') KeyTrans = key_type_transform.KeyTrans() # 注意示例化!!! # Ring_Group = Ring_Group() # 记得实例化 ChameleonHash = ChameleonHash_ECC.ChameleonHash() # ************************UDP服务器端编程********************************* s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) s.bind(('127.0.0.1', 12345)) # 绑定端口 data, addr = s.recvfrom(4096) m_AUSF_A3VI = pickle.loads(data) # 收到消息后,反序列化得到 {'ciphertext': ciphertext, 'signature': signature} signature_AUSF = m_AUSF_A3VI['signature'] ciphertext_AUSF = m_AUSF_A3VI['ciphertext'] print("***A3VI***收到的AUSF发送的消息<CText, E2, β>") start_reg = time.clock() # *****************************A3VI读取Ope的公钥进行验签*********************************** public_key_raw = ECC.import_key(open(r'D:\PythonProject\FUIH\ECC_file_keys\Ope_publickey.pem').read()) x = public_key_raw.pointQ.x.__int__() y = public_key_raw.pointQ.y.__int__() pk_Ope = KeyTrans.b_public_key(x, y) s1 = hashlib.sha3_256() # 这里利用sha256对密文进行哈希处理 s1.update(ciphertext_AUSF) cipher_h = s1.hexdigest() b_cipher_h_AUSF = bytes(cipher_h, encoding='utf-8') # 这里注意把 16进制的密文摘要转换为字节串,进行处理utf-8编码 # assert True if curve.verify(signature_AUSF, b_cipher_h_AUSF, pk_Ope) else False # print('A3VI收到的签名为:', signature_AUSF) print('***A3VI***验签成功!!!') if curve.verify(signature_AUSF, b_cipher_h_AUSF, pk_Ope)is True else print('***A3VI***验签失败!!!') # ***************************A3VI利用自己的私钥开始解密,获取信息CH_UE,N,RG,PST**************************************** private_key_raw = ECC.import_key(open(r'D:\PythonProject\FUIH\ECC_file_keys\A3VI_privatekey.pem').read()).d.__int__() sk = KeyTrans.b_private_key(private_key_raw) # 注意!!!这是A3VI的私钥 b_message_AUSF = curve.decrypt(ciphertext_AUSF, sk, algo='aes-256-ofb') message_AUSF = pickle.loads(b_message_AUSF) # 这里获得AUSF转发的消息{'CH_UE': message_UE['CH_UE'], 'N': message_UE['N'], 'RG_Ope': keys, 'PST': PST} """ 这里A3VI把自己的公私钥混进环成员这里,在测试的时候,发现aosring的算法是基于secp256k1 (bitcoin)的,而我们其余的代码都是 基于secp256r1的椭圆曲线,所以这里暂时随机生成密钥,用于环签名。 """ n = 10 keys = aosring_randkeys(n) PST = message_AUSF['PST'] b_PST = pickle.dumps(PST) msg = bytes_to_int(b_PST) # A3VI开始进行环签名,生成一个成品票据ST ST_all = aosring_sign(*keys, message=msg) ST = (ST_all[1], ST_all[2]) end_reg = time.clock() print('A3VI端服务注册阶段计算开销:', (end_reg-start_reg)*1000, 'ms') m_dict['A3VI_Reg']=(end_reg - start_reg) * 1000 data_ST = {'CH_UE': message_AUSF['CH_UE'], 'N': message_AUSF['N'], 'RG_Ope': message_AUSF['RG_Ope'], 'RG_A3VI': keys, 'ST': ST} print('***A3VI***生成票据ST,并把消息(CH_UE, N, T_Exp, RG_OPE, RG_A3VI, ST)上链成功!票据注册成功!') # 到这一步后我们假装上链成功 """ 这里A3VI把消息发布给区块链网络,由矿工对消息data_ST进行验证,利用'RG_Ope': message_AUSF['RG_Ope'], 'RG_A3VI'对票据ST进行验签,验签成功后,打包上链存储, 生成交易的记录号 TXID_ST = b'8b60004928090023bef4292ed4e0e414a9f1eaa2d734d4b34beb5c6b2f33bb59' """ TXID_ST = b'8b60004928090023bef4292ed4e0e414a9f1eaa2d734d4b34beb5c6b2f33bb59' T_Exp = time.clock() """ 关于区块链共识以及上链存储的操作,考虑到我们的工作重点在于协议设计和分析,目前我们暂时不考虑搭建区块链部分的实验 """ # **********************UDP客户端编程*************************************** # 我们这里把data_ST发送给EC,EC得到消息后,假装自己是上链查询到的数据 b_data_ST = pickle.dumps(data_ST) m = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) m.sendto(b_data_ST, ('127.0.0.1', 12346)) # A3VI把数据上链成功后,把票据号TXID_ST和时间戳T_Exp发送给UE m_A3VI_UE = {'TXID_ST': TXID_ST, "T_Exp": T_Exp} b_m_A3VI_UE = pickle.dumps(m_A3VI_UE) m.sendto(b_m_A3VI_UE, ('127.0.0.1', 12347)) # print('服务注册阶段消息<TXDI_ST, T_Exp>字节数:', len(TXID_ST)+len(int_to_bytes(T_Exp.__int__(), 5))) print('服务注册阶段消息<TXDI_ST, T_Exp>字节数:', len(TXID_ST)+ T_Exp.__int__().bit_length()/8) m_dict['3'] = len(TXID_ST)+len(int_to_bytes(T_Exp.__int__(), 5)) # m.close() m先不要close,等密钥协商材料发给UE后再close # print('EC根据TXDI_ST上链查询消息【实际是A3VI >> EC】') # print('发送消息成功,消息内容为:', b_m_AUSF_A3VI) # 等待接收EC发送给来的密钥协商材料 agree_data, addr = s.recvfrom(4096) m_EC_A3VI = pickle.loads(agree_data) print("****A3VI****接收到的密钥协商材料为:", m_EC_A3VI) # {'PID_UE': UE_EC['PID_UE'], 'm_UE': m_UE, 'A_UE': A_UE, 'B_UE': UE_EC['B_UE']} start_agree1 = time.clock() x_A = m_EC_A3VI['A_UE'][0] y_A = m_EC_A3VI['A_UE'][1] A_UE = ECC.EccPoint(x_A, y_A) x_B = m_EC_A3VI['B_UE'][0] y_B = m_EC_A3VI['B_UE'][1] B_UE = ECC.EccPoint(x_B, y_B) # 开始计算临时的会话密钥 order = ChameleonHash.order() alpha = random.randint(1, order - 1) # 用于计算会话密钥 beta = random.randint(1, order - 1) Y = ECC.import_key(open(r'D:\PythonProject\FUIH\ECC_file_keys\A3VI_publickey.pem').read()) # 这里是Y_A3VI 即是读取的A3VI的公钥,是点值 x_A3VI = private_key_raw # 这里private_key_raw为int值的原始私钥 A_A3VI = Y.pointQ.__mul__(alpha) B_A3VI = Y.pointQ.__mul__(beta) temp = x_A3VI * (alpha + beta) K_A3VI = (A_UE + B_UE).__mul__(temp) print('***A3VI***计算出的会话密钥材料K为:', K_A3VI.xy) hash_m = [m_EC_A3VI['PID_UE'], m_EC_A3VI['m_UE'], K_A3VI.xy] b_hash_m = pickle.dumps(hash_m) # s1.update(b_hash_m[0:16]) # SK_A3VI = s1.hexdigest() b_hash_m = bytes_to_int(pickle.dumps(hash_m)) SK_A3VI = hash(b_hash_m) end_agree1 = time.clock() print('***A3VI***计算出的会话密钥[Int类型]为:', SK_A3VI) # 计算出会话密钥后,把消息【假装通过EC】发送给UE print('+++3+++ A3VI >>>> UE 发送消息<A_A3VI, B_A3VI>') m_A3VI_UE = {'A_A3VI': A_A3VI.xy, 'B_A3VI': B_A3VI.xy} bytes_sum = (A_A3VI.x.__int__().bit_length() + A_A3VI.y.__int__().bit_length())/8 + (B_A3VI.x.__int__().bit_length() + B_A3VI.y.__int__().bit_length())/8 print('密钥协商阶段消息<A_A3VI,B_A3VI>字节数为:', bytes_sum) # 这里我们不再计算,因为我们知道A_A3VI.xy B_A3VI.xy 分别为64个字节 m_dict['6'] = bytes_sum b_A3VI_UE = pickle.dumps(m_A3VI_UE) m.sendto(b_A3VI_UE, ('127.0.0.1', 12347)) m.close() # 接收UE发过来的密钥协商应答消息ACK_UE ACK_data, addr = s.recvfrom(4096) s.close() ACK_UE = pickle.loads(ACK_data) start_agree2 = time.clock() ACK_A3VI = hash(bytes_to_int(pickle.dumps([K_A3VI.xy, SK_A3VI]))) # print('ACK_UE', ACK_UE) # print('ACK_A3VI', ACK_A3VI) if ACK_A3VI == ACK_UE: print('+++++++++++++++A3VI端密钥协商成功!!!++++++++++++++++++++++++++') else: print('++++++++++++++++++++++密钥协商失败!!++++++++++++++++++++++++++++++') end_agree2 = time.clock() print('A3VI端密钥协商阶段计算开销为:', ((end_agree2-start_agree2)+(end_agree1-start_agree1)) * 1000, 'ms') m_dict['A3VI_KA'] = ((end_agree2-start_agree2)+(end_agree1-start_agree1)) * 1000