赞
踩
class CryptSM2(object): def __init__(self, private_key, public_key, ecc_table): self.private_key = private_key self.public_key = public_key self.para_len = len(ecc_table['n']) self.ecc_a3 = ( int(ecc_table['a'], base=16) + 3) % int(ecc_table['p'], base=16) self.ecc_table = ecc_table def _kg(self, k, Point): # kP运算 Point = '%s%s' % (Point, '1') mask_str = '8' for i in range(self.para_len - 1): mask_str += '0' mask = int(mask_str, 16) Temp = Point flag = False for n in range(self.para_len * 4): if (flag): Temp = self._double_point(Temp) if (k & mask) != 0: if (flag): Temp = self._add_point(Temp, Point) else: flag = True Temp = Point k = k << 1 return self._convert_jacb_to_nor(Temp) def _double_point(self, Point): # 倍点 l = len(Point) len_2 = 2 * self.para_len if l < self.para_len * 2: return None else: x1 = int(Point[0:self.para_len], 16) y1 = int(Point[self.para_len:len_2], 16) if l == len_2: z1 = 1 else: z1 = int(Point[len_2:], 16) T6 = (z1 * z1) % int(self.ecc_table['p'], base=16) T2 = (y1 * y1) % int(self.ecc_table['p'], base=16) T3 = (x1 + T6) % int(self.ecc_table['p'], base=16) T4 = (x1 - T6) % int(self.ecc_table['p'], base=16) T1 = (T3 * T4) % int(self.ecc_table['p'], base=16) T3 = (y1 * z1) % int(self.ecc_table['p'], base=16) T4 = (T2 * 8) % int(self.ecc_table['p'], base=16) T5 = (x1 * T4) % int(self.ecc_table['p'], base=16) T1 = (T1 * 3) % int(self.ecc_table['p'], base=16) T6 = (T6 * T6) % int(self.ecc_table['p'], base=16) T6 = (self.ecc_a3 * T6) % int(self.ecc_table['p'], base=16) T1 = (T1 + T6) % int(self.ecc_table['p'], base=16) z3 = (T3 + T3) % int(self.ecc_table['p'], base=16) T3 = (T1 * T1) % int(self.ecc_table['p'], base=16) T2 = (T2 * T4) % int(self.ecc_table['p'], base=16) x3 = (T3 - T5) % int(self.ecc_table['p'], base=16) if (T5 % 2) == 1: T4 = (T5 + ((T5 + int(self.ecc_table['p'], base=16)) >> 1) - T3) % int(self.ecc_table['p'], base=16) else: T4 = (T5 + (T5 >> 1) - T3) % int(self.ecc_table['p'], base=16) T1 = (T1 * T4) % int(self.ecc_table['p'], base=16) y3 = (T1 - T2) % int(self.ecc_table['p'], base=16) form = '%%0%dx' % self.para_len form = form * 3 return form % (x3, y3, z3) def _add_point(self, P1, P2): # 点加函数,P2点为仿射坐标即z=1,P1为Jacobian加重射影坐标 len_2 = 2 * self.para_len l1 = len(P1) l2 = len(P2) if (l1 < len_2) or (l2 < len_2): return None else: X1 = int(P1[0:self.para_len], 16) Y1 = int(P1[self.para_len:len_2], 16) if (l1 == len_2): Z1 = 1 else: Z1 = int(P1[len_2:], 16) x2 = int(P2[0:self.para_len], 16) y2 = int(P2[self.para_len:len_2], 16) T1 = (Z1 * Z1) % int(self.ecc_table['p'], base=16) T2 = (y2 * Z1) % int(self.ecc_table['p'], base=16) T3 = (x2 * T1) % int(self.ecc_table['p'], base=16) T1 = (T1 * T2) % int(self.ecc_table['p'], base=16) T2 = (T3 - X1) % int(self.ecc_table['p'], base=16) T3 = (T3 + X1) % int(self.ecc_table['p'], base=16) T4 = (T2 * T2) % int(self.ecc_table['p'], base=16) T1 = (T1 - Y1) % int(self.ecc_table['p'], base=16) Z3 = (Z1 * T2) % int(self.ecc_table['p'], base=16) T2 = (T2 * T4) % int(self.ecc_table['p'], base=16) T3 = (T3 * T4) % int(self.ecc_table['p'], base=16) T5 = (T1 * T1) % int(self.ecc_table['p'], base=16) T4 = (X1 * T4) % int(self.ecc_table['p'], base=16) X3 = (T5 - T3) % int(self.ecc_table['p'], base=16) T2 = (Y1 * T2) % int(self.ecc_table['p'], base=16) T3 = (T4 - X3) % int(self.ecc_table['p'], base=16) T1 = (T1 * T3) % int(self.ecc_table['p'], base=16) Y3 = (T1 - T2) % int(self.ecc_table['p'], base=16) form = '%%0%dx' % self.para_len form = form * 3 return form % (X3, Y3, Z3) def _convert_jacb_to_nor(self, Point): # Jacobian加重射影坐标转换成仿射坐标 len_2 = 2 * self.para_len x = int(Point[0:self.para_len], 16) y = int(Point[self.para_len:len_2], 16) z = int(Point[len_2:], 16) z_inv = pow(z, int(self.ecc_table['p'], base=16) - 2, int(self.ecc_table['p'], base=16)) z_invSquar = (z_inv * z_inv) % int(self.ecc_table['p'], base=16) z_invQube = (z_invSquar * z_inv) % int(self.ecc_table['p'], base=16) x_new = (x * z_invSquar) % int(self.ecc_table['p'], base=16) y_new = (y * z_invQube) % int(self.ecc_table['p'], base=16) z_new = (z * z_inv) % int(self.ecc_table['p'], base=16) if z_new == 1: form = '%%0%dx' % self.para_len form = form * 2 return form % (x_new, y_new) else: return None def verify(self, Sign, data): # 验签函数,sign签名r||s,E消息hash,public_key公钥 r = int(Sign[0:self.para_len], 16) s = int(Sign[self.para_len:2 * self.para_len], 16) e = int(data.hex(), 16) t = (r + s) % int(self.ecc_table['n'], base=16) if t == 0: return 0 P1 = self._kg(s, self.ecc_table['g']) P2 = self._kg(t, self.public_key) # print(P1) # print(P2) if P1 == P2: P1 = '%s%s' % (P1, 1) P1 = self._double_point(P1) else: P1 = '%s%s' % (P1, 1) P1 = self._add_point(P1, P2) P1 = self._convert_jacb_to_nor(P1) x = int(P1[0:self.para_len], 16) return (r == ((e + x) % int(self.ecc_table['n'], base=16))) def sign(self, data, K): # 签名函数, data消息的hash,private_key私钥,K随机数,均为16进制字符串 E = data.hex() # 消息转化为16进制字符串 e = int(E, 16) d = int(self.private_key, 16) k = int(K, 16) P1 = self._kg(k, self.ecc_table['g']) x = int(P1[0:self.para_len], 16) R = ((e + x) % int(self.ecc_table['n'], base=16)) if R == 0 or R + k == int(self.ecc_table['n'], base=16): return None d_1 = pow(d + 1, int(self.ecc_table['n'], base=16) - 2, int(self.ecc_table['n'], base=16)) S = (d_1 * (k + R) - R) % int(self.ecc_table['n'], base=16) if S == 0: return None else: return '%064x%064x' % (R, S)
# -*- coding: utf-8 -*- import binascii from gmssl.sm2 import default_ecc_table import Sm2Calc def main(): default_ecc_table = { 'n': 'FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123', 'p': '8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3', 'g': '421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2', 'a': '787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498', # 'b': '28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93', } while 1: print("======================= SM2倍点试做 ========================") print("操作:\n==== 1.倍点运算\n==== 2.点加\n 选择:", end='') calc_Point = Sm2Calc.CryptSM2(private_key=None, public_key=None, ecc_table=default_ecc_table) chose = input() if chose == "1": print("输入初始点:", end='') point_in = input() diy_len = point_in print("输入点的倍数:", end='') k = int(input()) bei_Point = calc_Point._kg(k, point_in) print("点乘结果是:", bei_Point) elif chose == "2": print("输入点1:", end='') point_1n = input() point_1stn = '%s%s' % (point_1n, 1) print("输入点2:", end='') point_2n = input() add_Jacobian = calc_Point._add_point(point_1stn, point_2n) add_Point = calc_Point._convert_jacb_to_nor(add_Jacobian) # print("ss:", point_1stn) print("点加结果是:", add_Point) if __name__ == '__main__': main()
0x421DEBD6 1B62EAB6 746434EB C3CC315E 32220B3B ADD50BDC 4C4E6C14 7FEDD43D // Gx
0x0680512B CBB42C07 D47349D2 153B70C4 E5D7FDFC BFA36EA1 A85841B9 E46E09A2 // Gy
0x8542D69E 4C044F18 E8B92435 BF6FF7DE 45728391 5C45517D 722EDB8B 08F1DFC3 // p
0x787968B4 FA32C3FD 2417842E 73BBFEFF 2F3C848B 6831D7E0 EC65228B 3937E498 // a
k = 0x0000000000000000000000000000000000000000000000000000000000000001
Qx = 0x421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D
Qy = 0x0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2
k = 0x0000000000000000000000000000000000000000000000000000000000000002
Qx = 0x5E1E24ACC7FB884895BB954DE21FE26456357D9EE8A32410635F35CDFB0D2846
Qy = 0x8314D639881A8BAF1BDD076BF82B090020D80F7A5ACC3C56BDB61BBD305708F4
k = 0x0000000000000000000000000000000000000000000000000000000000000003
Qx = 0x126FE19E98F4548A976C436D97B8C8A8F14405FF9A6D58B556355D70C2C19E69
Qy = 0x4BD3A18E69CC107212729F6473030132DE0B75BF7482CA5510B532EF7BDDCB93
k = 0x0000000000000000000000000000000000000000000000000000000000000004
Qx = 0x7579488E…45FE9DFD
Qy = 0x53233A1C…E06D6ED4
k = 0x0000000000000000000000000000000000000000000000000000000000000005
Qx = 0x69FB7B95…BFB03FDB
Qy = 0x4B38C759…191BAB3B
k = 0x0000000000000000000000000000000000000000000000000000000000000006
Qx = 0x832CD887…F5BF7A50
Qy = 0x19785C14…1808C891
k = 0x0000000000000000000000000000000000000000000000000000000000000007
Qx = 0x446F914C…284B2D18
Qy = 0x777E0C31…414F65F9
k = 0x0000000000000000000000000000000000000000000000000000000000000008
Qx = 0x2C79ACF6…8155E905
Qy = 0x650F9BB6…B0CE5307
k = 0x000000000000000000000000000000000000000000000000000000000000FFFF
Qx = 0x5FD0FD63…85E1CE60
Qy = 0x82FA4AAD…AC203D1B
k = 0x00000000000000000000000000000000000000000000000000000000FF00FFFF
Qx = 0x45C843E6…E47E234F
Qy = 0x230A83AF…36EC861C
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。