def get_key(n=20): """ 获取公钥 p, g , (g^x)mod p 和私钥 x :param n: the long of random prime :return: p,g,y,x """ import pyunit_prime p = pyunit_prime.get_large_prime_length(n) # p = 49924286347363285385002602166419178756593347008815637398138749880304666805251999 yn = p - 1 f = 2 x_list = [] while yn != 1: print('yn:', yn) print('f:', f) print(pyunit_prime.is_prime(int(yn))) if pyunit_prime.is_prime(int(yn)): x_list.append(int(yn)) break if pyunit_prime.is_prime(f): if yn % f == 0: x_list.append(f) while yn % f == 0: yn = yn // f if yn == 1: break f += 1 else: f += 1 yn = p - 1 print('yn:', yn) print('x list:', x_list) error_list = [] import random while True: i = random.randint(2, p) if i in error_list: continue else: error_list.append(i) k = 0 for j in x_list: if fastExpMod(i, int(yn // j), p) == 1: break else: k += 1 if k == len(x_list): import random x = random.randint(1, p - 1) return p, i, fastExpMod(i, x, p), x
def data_encrypt(n, e, c_path, path=None, m=None): # path = input('请输入你的文档路径:') # D:\Workspaces\python_练习\密码学\test1.py if path: data_all = get_data(path) else: data_all = m.encode() # n = int(input('请输入公开参数n:\t')) # e = int(input('请输入公开参数e:\t')) import math data_list = standard_data(data_all, lenth=int(math.log10(n)) + 1) m_l = [] max_len = 0 for data in data_list: c = fastExpMod(int(data), e, n) if c == 0: lenth = 1 else: lenth = int(math.log10(c)) + 1 if lenth > max_len: max_len = lenth m_l.append(c) save_ctext(c_path, m_l, max_len) return c_path, max_len
def encrypt(m, p, g, y): """ 加密操作 c1 = g^k mod p c2 = m*y^k mod p :param m: 加密信息 :param p: 公开参数 :param g: 公开参数 :param y: 公开参数(g^x mod p) :return: 密文c1和c2 """ import random while True: k = random.randint(1, p - 1) if exgcd(k, p - 1)[0] == 1: break c1 = fastExpMod(g, k, p) c = fastExpMod(y, k, p) c2 = m * c % p return c1, c2
def decrypt(c1, c2, x, p): """ 解密 m = c2 * (c1^x)^(-1) mod p :param c1: 密文 :param c2: 密文 :param x: 私钥 x :param p: 公钥p :return: 明文 m """ c1 = fastExpMod(c1, x, p) c1 = cal_inv(c1, p) return c1 * c2 % p
def data_decrypt(n, d, c_max_len, c_path, m_path=None): c = get_data(c_path) import math m_list = '' lenth = 0 for m in c: lenth += 1 if lenth == len(c): m_list += str(m) elif m == 0: m_list += '00' else: m_list += '0' * (1 - int(math.log10(m))) + str(m) c = m_list c = list_split(c, c_max_len) if len(c[len(c) - 1]) < c_max_len: c[len(c) - 1] += c[len(c) - 1][len(c[len(c) - 1]) - 1] c[len(c) - 1][len(c[len(c) - 1]) - 1] = '0' res = '' for data in c: m = fastExpMod(int(data), d, n) res += str(m) m = recovery_data(res) if m_path: makefile(m_path, m) return m_path else: m_s = bytes() for data in m: m_s += data.to_bytes(1, 'little') return m_s.decode()