def Signature(M, IDA, dA, PA): a = config.get_a() b = config.get_b() n = config.get_n() Gx = config.get_Gx() Gy = config.get_Gy() ZA = get_Z(IDA, PA) # A1:置M=ZA ∥ M M_ = ZA + M # A2:计算e = Hv(M),按本文本第1部分4.2.3和4.2.2给出的细节将e的数据类型转换为整数 e = hash_function(M_) e = bytes_to_int(bits_to_bytes(e)) r = 0 k = 0 while(r==0 or r+k==n): # A3:用随机数发生器产生随机数k ∈[1,n-1] k = PRG_function(1, n-1) # A4:计算椭圆曲线点(x1,y1)=[k]G,按本文本第1部分4.2.7给出的细节将x1的数据类型转换为整 数 x1 = ECG_k_point(k, Point(Gx, Gy)).x x1 = bytes_to_int(ele_to_bytes(x1)) # A5:计算r=(e+x1) modn,若r=0或r+k=n则返回A3 r = (e+x1)%n # A6:计算s = ((1 + dA)−1 ·(k−r·dA)) modn,若s=0则返回A3 s = ( inverse(1+dA, n)*(k-r*dA) ) % n # A7:按本文本第1部分4.2.1给出的细节将r、s的数据类型转换为字节串,消息M 的签名为(r,s)。 #Sig = Point(int_to_bytes(r, math.ceil(n/256)), int_to_bytes(s, math.ceil(n/256))) #Sig = Point(int_to_bytes(r, math.ceil(math.log(n, 2)/8)), int_to_bytes(s, math.ceil(math.log(n, 2)/8))) r = int_to_bytes(r, math.ceil(math.log(n, 2)/8)) s = int_to_bytes(s, math.ceil(math.log(n, 2)/8)) Sig = r for i in s: Sig.append(i) return Sig
def Verification(M, Sig, IDA, PA): a = config.get_a() b = config.get_b() n = config.get_n() Gx = config.get_Gx() Gy = config.get_Gy() ZA = get_Z(IDA, PA) r = Sig[0:int(len(Sig)/2)] s = Sig[int(len(Sig)/2): len(Sig)] r = bytes_to_int(r) s = bytes_to_int(s) if(r<1 or r>n-1 or s<1 or s>n-1): #print("wrong signature: r,s wrong range") return False M_ = ZA + M e = hash_function(M_) e = bytes_to_int(bits_to_bytes(e)) t = (r + s) % n if(t == 0): #print("wrong signature : t is 0") return False x1 = ECG_ele_add( ECG_k_point(s, Point(Gx, Gy)), ECG_k_point(t, PA) ).x R = (e + x1) % n if R!=r: #print("wrong signature: R unequal r") return False return True
def key_generation_1(): n = config.get_n() Gx = config.get_Gx() Gy = config.get_Gy() # A1. 用随机数发生器产生随机数rA ∈[1, n-1] rA = PRG_function(1, n - 1) # A2. 计算椭圆曲线点RA = [rA]G=(x1,y1) RA = ECG_k_point(rA, Point(Gx, Gy)) # A3. 将RA发送给用户B return RA, rA
def get_Z(ID, PA): a = config.get_a() a = bytes_to_bits(ele_to_bytes(a)) b = config.get_b() b = bytes_to_bits(ele_to_bytes(b)) n = config.get_n() Gx = config.get_Gx() Gx_ = bytes_to_bits(ele_to_bytes(Gx)) Gy = config.get_Gy() Gy_ = bytes_to_bits(ele_to_bytes(Gy)) ID = bytes_to_bits(str_to_bytes(ID)) ENTL = int_to_bytes(math.ceil((len(ID)-2)/8)*8, 2) ENTL = bytes_to_bits(ENTL) xA = bytes_to_bits(ele_to_bytes(PA.x)) yA = bytes_to_bits(ele_to_bytes(PA.y)) ZA = hash_function(ENTL+ID+a+b+Gx_+Gy_+xA+yA) return ZA
def Verification(M, signature, IDA, PA): a = config.get_a() b = config.get_b() n = config.get_n() Gx = config.get_Gx() Gy = config.get_Gy() ZA = get_Z(IDA, PA) r = signature[0:int(len(signature) / 2)] s = signature[int(len(signature) / 2):len(signature)] r = bytes_to_int(r) s = bytes_to_int(s) #print("r:", r) # print("s:", s) if r < 1 or r > n - 1 or s < 1 or s > n - 1: print("r或s的范围不对,验证不通过") return False M_ = ZA + M M1 = M_ + M_ # Z1+M e1 = hash_function(M1) e1 = bytes_to_int(bits_to_bytes(e1)) # print("e1:", e1) # e = hash_function(M_) # e = bytes_to_int(bits_to_bytes(e)) t = (r + s) % n # print("t:", t) if t == 0: print("t等于0,验证不通过") return False x1 = ECG_ele_add(ECG_k_point(s, Point(Gx, Gy)), ECG_k_point(t, PA)).x # print("x1:", x1) R = (e1 + x1) % n #print("R:", R) if R == r: # print("wrong signature: R unequal r") # return False print("R等于r,验证通过") else: print("R不等于r,验证不通过") return True
def key_generation_2(ZA, ZB, r_self, R_self, R_opposite, d_self, P_self, P_opposite, klen, is_send): q = config.get_q() a = config.get_a() b = config.get_b() n = config.get_n() Gx = config.get_Gx() Gy = config.get_Gy() h = config.get_h() w = math.ceil(math.ceil(math.log(n, 2)) / 2) - 1 # A4. 从R_self中取出域元素x_self,将x_self的数据类型转换为整数,计算x_self_ = 2w +(x_self&(2w−1)); x_self = R_self.x x_self = ele_to_int(x_self) y_self = R_self.y y_self = ele_to_int(y_self) x_self_ = 2**w + (x_self & (2**w - 1)) # A5. 计算t_self = (d_self + ¯ x_self·r_self)modn t_self = (d_self + x_self_ * r_self) % n # A6.1 验证R_opposite是否满足椭圆曲线方程,若不满足则协商失败; # A6.2 否则从R_opposite中取出域元素x_opposite,将x_opposite的数据类型转换为整数,计算x_opposite_ = 2w +(x_opposite&(2w−1)); x_opposite = R_opposite.x x_opposite = ele_to_int(x_opposite) y_opposite = R_opposite.y y_opposite = ele_to_int(y_opposite) if (y_opposite**2) % q != (x_opposite**3 + a * x_opposite + b) % q: print("keyExchange Fail: R_opposite do not satisfy the equation") return -1 x_opposite_ = 2**w + (x_opposite & (2**w - 1)) # A7.1 计算椭圆曲线点U_self = [h·t_self](P_opposite +[x_opposite_]R_opposite) = (xU_self,yU_self) # A7.2 若U_self是无穷远点,则A协商失败;否则将xU_self、yU_self的数据类型转换为比特串 U_self = ECG_k_point( h * t_self, ECG_ele_add(P_opposite, ECG_k_point(x_opposite_, R_opposite))) xU_self = U_self.x yU_self = U_self.y xU_self = bytes_to_bits(ele_to_bytes(xU_self)) xU_self = remove_0b_at_beginning(xU_self) yU_self = bytes_to_bits(ele_to_bytes(yU_self)) yU_self = remove_0b_at_beginning(yU_self) # A8. 计算KA=KDF(xU_self ∥yU_self ∥ZA ∥ZB,klen) k_self = KDF(xU_self + yU_self + ZA + ZB, klen) # A9. 将R_self的坐标x_self、y_self 和R_opposite的坐标x_opposite、y_opposite的数据类型转换为比特串 # 计算S_test= Hash(0x02∥yU_self ∥Hash(xU_self ∥ZA ∥ZB ∥x_self ∥y_self ∥x_opposite ∥y_opposite)) # 并检验S_test=SB是否成立,若等式不成立则从B到A的密钥确认失败; x_self = bytes_to_bits(ele_to_bytes(x_self)) x_self = remove_0b_at_beginning(x_self) y_self = bytes_to_bits(ele_to_bytes(y_self)) y_self = remove_0b_at_beginning(y_self) x_opposite = bytes_to_bits(ele_to_bytes(x_opposite)) x_opposite = remove_0b_at_beginning(x_opposite) y_opposite = bytes_to_bits(ele_to_bytes(y_opposite)) y_opposite = remove_0b_at_beginning(y_opposite) if is_send: prefix = remove_0b_at_beginning(bytes_to_bits(int_to_bytes(2, 1))) S_test = hash_function(prefix + yU_self + hash_function(xU_self + ZA + ZB + x_opposite + y_opposite + x_self + y_self)) else: prefix = remove_0b_at_beginning(bytes_to_bits(int_to_bytes(3, 1))) S_test = hash_function(prefix + yU_self + hash_function(xU_self + ZA + ZB + x_self + y_self + x_opposite + y_opposite)) S_test = remove_0b_at_beginning(S_test) # A10. (选项)计算S_target= Hash(0x03∥yU_self ∥Hash(xU_self ∥ZA ∥ZB ∥x_self ∥y_self ∥x_opposite ∥y_opposite)),并将S_target发送给用户B if is_send: prefix = remove_0b_at_beginning(bytes_to_bits(int_to_bytes(3, 1))) S_target = hash_function(prefix + yU_self + hash_function(xU_self + ZA + ZB + x_opposite + y_opposite + x_self + y_self)) else: prefix = remove_0b_at_beginning(bytes_to_bits(int_to_bytes(2, 1))) S_target = hash_function(prefix + yU_self + hash_function(xU_self + ZA + ZB + x_self + y_self + x_opposite + y_opposite)) S_target = remove_0b_at_beginning(S_target) return k_self, S_target, S_test, x_self_, t_self, x_opposite_, U_self
# print("x1:", x1) R = (e1 + x1) % n #print("R:", R) if R == r: # print("wrong signature: R unequal r") # return False print("R等于r,验证通过") else: print("R不等于r,验证不通过") return True ### test Signature ### config.default_config() parameters = config.get_parameters() point_g = Point(config.get_Gx(), config.get_Gy()) n = config.get_n() print("请输入待验证的文件:") f1 = input() f = open(f1, 'r') M = f.read() IDA = '*****@*****.**' print("请输入需要验证的签名:") f2 = input() sign = open(f2, "r") signature = sign.read().replace("[", "").replace("]", "").replace("", "").split(",") print("请输入公钥PA:")
def Signature(M, IDA, dA, PA, d1, d2): a = config.get_a() b = config.get_b() n = config.get_n() Gx = config.get_Gx() Gy = config.get_Gy() ZA = get_Z(IDA, PA) # A1:置M=ZA ∥ M M_ = ZA + M # A2:计算e = Hv(M),按本文本第1部分4.2.3和4.2.2给出的细节将e的数据类型转换为整数 # e = hash_function(M_) # e = bytes_to_int(bits_to_bytes(e)) M1 = M_ + M_ # Z1+M e1 = hash_function(M1) e1 = bytes_to_int(bits_to_bytes(e1)) # print("e1:", e1) r = 0 k = 0 k1 = 0 k2 = 0 k3 = 0 while (r == 0) or (r + k == n): # A3:用随机数发生器产生随机数k ∈[1,n-1] k = PRG_function(1, n - 1) # A4:计算椭圆曲线点(x1,y1)=[k]G,按本文本第1部分4.2.7给出的细节将x1的数据类型转换为整 数 k1 = PRG_function(1, n - 1) print("1:随机选取k1:", k1) k2 = PRG_function(1, n - 1) k3 = PRG_function(1, n - 1) Q1 = ECG_k_point(k1, Point(Gx, Gy)) print("1:计算Q1=k1*G,并把Q1发送给用户2") print("2:Q1:", Q1) print("2:随机选取k2,k3:", k2, k3) Q2 = ECG_k_point(k2, Point(Gx, Gy)) print("2:计算Q2=k2*G,Q2:", Q2) # print("k1:", k1) # print("k2:", k2) # print("k3:", k3) # x1 = ECG_k_point(k1, Point(Gx, Gy)).x # x1 = bytes_to_int(ele_to_bytes(x1)) # A5:计算r=(e+x1) modn,若r=0或r+k=n则返回A3 temp = k1 * k3 + k2 # print("temp:", temp) rx = ECG_k_point(temp, Point(Gx, Gy)).x # (k1*k3 + k2)*G rx = bytes_to_int(ele_to_bytes(rx)) print("2:利用k3,Q1,Q2计算得到rx:", rx) r = (rx + e1) % n print("2:利用rx和待签名文件的哈希值计算r") # print("r:", r) # r = (e+x1) % n # A6:计算s = ((1 + dA)−1 ·(k−r·dA)) modn,若s=0则返回A3 # s = (inverse(1+dA, n)*(k-r*dA)) % n s2 = (d2 * k3) % n s3 = (d2 * (r + k2)) % n print("2:根据d2,k2,k3计算得到s2,s3,并将r,s2,s3发送给用户1") print("1:r:", r) print("1:s2:", s2) print("1:s3:", s3) s = (d1 * k1 * s2 + d1 * s3 - r) % n print("1:根据d1,k1,r,s2,s3计算s:", s) # print("s:", s) # A7:按本文本第1部分4.2.1给出的细节将r、s的数据类型转换为字节串,消息M 的签名为(r,s)。 #Sig = Point(int_to_bytes(r, math.ceil(n/256)), int_to_bytes(s, math.ceil(n/256))) #Sig = Point(int_to_bytes(r, math.ceil(math.log(n, 2)/8)), int_to_bytes(s, math.ceil(math.log(n, 2)/8))) r = int_to_bytes(r, math.ceil(math.log(n, 2) / 8)) s = int_to_bytes(s, math.ceil(math.log(n, 2) / 8)) Sig = r for i in s: Sig.append(i) return Sig