def crt(a1, a2, m1, m2): M = m1 * m2 M1 = M // m1 M2 = M // m2 M1_inv = ext_gcd(M1, m1)[1] M2_inv = ext_gcd(M2, m2)[1] if (M1_inv < 0): M1_inv = M1_inv + m1 if (M2_inv < 0): M2_inv = M2_inv + m2 n = (a1 * M1 * M1_inv + a2 * M2 * M2_inv) % M return n
def euler(n): φ = 1 for _ in range(2, n): if ext_gcd(_, n)[0] == 1: φ = φ + 1 return φ # print(euler(15))
def all_primitive_roots(p): root = primitive_root(p) euler_ = euler(p) root_list = [] for _ in range(2, euler_): # 指数与euler(m)互素 if ext_gcd(_, euler_)[0] == 1: root_list.append(_) # print(_, end=',') return root_list
def ord_of_am(a, m): # a,m需互素 if ext_gcd(a, m)[0] == 1: euler_ = euler(m) for _ in range(1, euler(m)): # 指数整除euler(m) if euler_ % _ == 0: mod = exp_mod(a, _, m) if mod == 1: return _ return euler(m)
def gen_key(p, q): n = p * q fy = (p - 1) * (q - 1) # 計算與n互質的整數個數 尤拉函式 e = 3889 # 選取e 一般選取65537 # generate d a = e b = fy r, x, y = ext_gcd(a, b) #print(x) # 計算出的x不能是負數,如果是負數,說明p、q、e選取失敗,一般情況下e選取65537 d = x # 返回: 公鑰 私鑰 return (n, e), (n, d)
def gen_key(p, q, e): n = p * q fy = (p - 1) * (q - 1) # 计算与n互质的整数个数 欧拉函数 #e = 3889 # 选取e 一般选取65537 # generate d a = e b = fy r, x, y = ext_gcd(a, b) print(x) # 计算出的x不能是负数,如果是负数,说明p、q、e选取失败,一般情况下e选取65537 d = x # 返回: 公钥 私钥 return (n, e), (n, d)
def decrypt(c, prikey): d = prikey[0] p = prikey[1] c1 = c[0] c2 = c[1] #m = c2*(c1^d)^-1 mod p c1_d = exp_mod(c1, d, p) if (c1_d < 0): c1_d += p c1_dinv = ext_gcd(c1_d, p)[1] if (c1_dinv < 0): c1_dinv += p m = ((c2 % p) * c1_dinv) % p return m
def gen_key(p, q): n = p * q euler = (p - 1) * (q - 1) e = random.randint(3, euler) a = e b = euler r, x, y = ext_gcd(a, b) while r != 1: e = random.randint(3, euler) a = e b = euler r, x, y = ext_gcd(a, b) print('r', r) print('euler', euler) print('x', x) if x < 0: print("x is negative") x = x - (x // (b // r)) * (b // r) print('x', x) d = x # error happens when x is negative print('n', n, 'e', e, 'd', d) return (n, e), (n, d)
def is_prime_Fermat(n, t=1): flag = True for _ in range(t): b = 2 while ext_gcd(b, n)[0] != 1: b = random.randint(3, n - 1) r = exp_mod(b, n - 1, n) if r != 1: flag = False if flag: # print("根据Fermat素性检验,%d为素数"%n) return 1 else: # print("根据Fermat素性检验,%d为合数"%n) return 0
def gen_key(p, q): n = p * q fy = (p - 1) * (q - 1) # 计算与n互质的整数个数 欧拉函数 e = 65537 # 选取e 一般选取65537 # generate d a = e b = fy r, x, y = ext_gcd(a, b) # 计算出的x不能是负数,如果是负数,说明p、q、e选取失败,不过可以把x加上fy,使x为正数,才能计算。 if x < 0: x = x + fy d = x # 返回: 公钥 私钥 print("n:", n) print("d:", d) return (n, e), (n, d)
def gen_key(p, q): n = p * q phi = (p - 1) * (q - 1) # 算phi(n) # 選e while (True): e = int(input("請輸入e (e與phi(n)必須互質)\n")) if (gcd(e, phi) != 1): print("e與phi(n)沒有互質,請重新輸入") continue else: break r, x, y = ext_gcd(e, phi) # 用擴展歐幾里得算 d = e^-1 mod phi(n) d = x if (d < 0): d += phi return (n, e), (n, d) #回傳公鑰<n,e>、私鑰<n,d>
d = -1 # do until d is > 0 while (d < 0): print('find p') p = makePrime(1024) print('find q') q = makePrime(1024) n = p * q r = (p - 1) * (q - 1) print('find d') e = 65537 a, d, b = ext_gcd(e, r) # write publicKey(n,e) to text file with open('./publicKey.txt', 'wb') as f: f.write(str(n)) f.write('\n') f.write(str(e)) # write privateKey(n,d) to text file with open('./privateKey.txt', 'wb') as f: f.write(str(n)) f.write('\n') f.write(str(d)) print('finish')