import random def fastExpMod(b, n, m): ''' return : b^n mod m ''' result = 1 while n != 0: if (n & 1) == 1: # 按位与操作 result = (result * b) % m b = (b * b) % m n = n >> 1 # 位数右移操作 return result def Euclid(a, b): ''' 欧几里得算法 ax + by = gcd(a,b) Return : [x , y , gcd(a,b)] ''' X = [1, 0, a] Y = [0, 1, b] while Y[2] != 0: Q = X[2] // Y[2] NEW_Y = [i * Q for i in Y] T = list(map(lambda x: x[0] - x[1], zip(X, NEW_Y))) X = Y.copy() Y = T.copy() return X def fermatPrimeTest(m, k): ''' 费马素性检验算法 m : 给定整数 k : 安全参数,重复K次 ''' if m % 2 == 0: return False for i in range(k): a = random.randint(2, m - 2) g = Euclid(a, m) if g[2] == 1: r = fastExpMod(a, m - 1, m) if r == 1: continue else: return False else: return False return True def findPrime(lower, upper): ''' return : 一个位于upper和lower之间的素数 ''' while True: n = random.randint(lower, upper) if fermatPrimeTest(n, 6) == True: return n def selectE(fn): ''' fn : euler function Return : e ''' while True: e = random.randint(1, fn) temp = Euclid(e, fn) if temp[2] == 1: return e def keyGenerate(lower, upper): ''' 给定两个素数p和q生成的区间 return : e,n,d ''' p = findPrime(lower, upper) q = findPrime(lower, upper) print("p:" + str(p) + " q:" + str(q)) # print("q:"+str(q)) n = p * q fn = (p - 1) * (q - 1) e = selectE(fn) temp = Euclid(e, fn) # 欧几里得算法求逆元 d = temp[0] if d < 0: # 由于e和fn互素故一定存在逆元 d = d + fn # 保证d为正数 return e, n, d def start(): e, n, d = keyGenerate(2**256, 2**257) # 密钥生成 # 更改keyGenerate函数的两个参数,可以改变生成素数的位数大小。 print("public key (e,n):", end="") print("(" + str(e) + " , " + str(n) + ")\n") print("private key d: " + str(d) + "\n") m = random.randint(1, n) # m < n m为明文 print("Plaintext: " + str(m)) c = fastExpMod(m, e, n) # 加密 c为密文 m^e mod n print("\nEncryption of PlainText: " + str(c)) x = fastExpMod(c, d, n) # 解密 c^d mod n print("\nDecryption of CipherText: " + str(x)) if x == m: print("\nThe plaintext and ciphertext are the same.") import time def test_RSA_parameters(p_bits, q_bits): p = findPrime(2 ** (p_bits - 1), 2 ** p_bits) q = findPrime(2 ** (q_bits - 1), 2 ** q_bits) n = p * q fn = (p - 1) * (q - 1) e = selectE(fn) temp = Euclid(e, fn) d = temp[0] if d < 0: d = d + fn print(f"p: {p}, q: {q}, n: {n}, e: {e}, d: {d}") print(f"\np-1: {p - 1}, q-1: {q - 1}, gcd(p-1, q-1): {Euclid(p - 1, q - 1)[2]}") print(f"\nAbsolute difference |p-q|: {abs(p - q)}") # 测试加密和解密 m = random.randint(1, n - 1) c = fastExpMod(m, e, n) decrypted_m = fastExpMod(c, d, n) print(f"\nOriginal message: {m}, Encrypted: {c}, Decrypted: {decrypted_m}") print("\nEncryption and decryption successful!" if m == decrypted_m else "Decryption failed!") # 测量将 n 分解为两个素数的时间 start_time = time.time() factor1, factor2 = factorize_n(n) end_time = time.time() factorization_time = end_time - start_time print(f"\nFactorization time: {factorization_time:.6f} seconds") print(f"Factors: {factor1}, {factor2}") # 重复加密攻击测试 repeat_encryption_test(m, e, n) def factorize_n(n): # 从 sqrt(n) 开始向下试除 start = int(n ** 0.5) for i in range(start, 1, -1): if n % i == 0: return i, n // i return n, 1 # 如果 n 是素数 def repeat_encryption_test(m, e, n, repetitions=10): encrypted_messages = [] c = m for _ in range(repetitions): c = fastExpMod(c, e, n) encrypted_messages.append(c) print(f"Repeated encryption {len(encrypted_messages)}: {c}") # 检查是否有重复的密文 unique_ciphertexts = set(encrypted_messages) if len(unique_ciphertexts) == len(encrypted_messages): print("\nNo repeated ciphertexts found. Repeated encryption attack is less likely.") else: print("\nRepeated ciphertexts found. Repeated encryption attack is possible.") if __name__ == "__main__": # start() test_RSA_parameters(20, 20) test_RSA_parameters(5, 5)
理解问题import random def fastExpMod(b, n, m): ''' return : b^n mod m ''' result = 1 while n != 0: if (n & 1) == 1: # 按位与操作 result = (result * b) % m b = (b * b) % m n = n >> 1 # 位数右移操作 return result def Euclid(a, b): ''' 欧几里得算法 ax + by = gcd(a,b) Return : [x , y , gcd(a,b)] ''' X = [1, 0, a] Y = [0, 1, b] while Y[2] != 0: Q = X[2] // Y[2] NEW_Y = [i * Q for i in Y] T = list(map(lambda x: x[0] - x[1], zip(X, NEW_Y))) X = Y.copy() Y = T.copy() return X def fermatPrimeTest(m, k): ''' 费马素性检验算法 m : 给定整数 k : 安全参数,重复K次 ''' if m % 2 == 0: return False for i in range(k): a = random.randint(2, m - 2) g = Euclid(a, m) if g[2] == 1: r = fastExpMod(a, m - 1, m) if r == 1: continue else: return False else: return False return True def findPrime(lower, upper): ''' return : 一个位于upper和lower之间的素数 ''' while True: n = random.randint(lower, upper) if fermatPrimeTest(n, 6) == True: return n def selectE(fn): ''' fn : euler function Return : e ''' while True: e = random.randint(1, fn) temp = Euclid(e, fn) if temp[2] == 1: return e def keyGenerate(lower, upper): ''' 给定两个素数p和q生成的区间 return : e,n,d ''' p = findPrime(lower, upper) q = findPrime(lower, upper) print("p:" + str(p) + " q:" + str(q)) # print("q:"+str(q)) n = p * q fn = (p - 1) * (q - 1) e = selectE(fn) temp = Euclid(e, fn) # 欧几里得算法求逆元 d = temp[0] if d < 0: # 由于e和fn互素故一定存在逆元 d = d + fn # 保证d为正数 return e, n, d def start(): e, n, d = keyGenerate(2**256, 2**257) # 密钥生成 # 更改keyGenerate函数的两个参数,可以改变生成素数的位数大小。 print("public key (e,n):", end="") print("(" + str(e) + " , " + str(n) + ")\n") print("private key d: " + str(d) + "\n") m = random.randint(1, n) # m < n m为明文 print("Plaintext: " + str(m)) c = fastExpMod(m, e, n) # 加密 c为密文 m^e mod n print("\nEncryption of PlainText: " + str(c)) x = fastExpMod(c, d, n) # 解密 c^d mod n print("\nDecryption of CipherText: " + str(x)) if x == m: print("\nThe plaintext and ciphertext are the same.") import time def test_RSA_parameters(p_bits, q_bits): p = findPrime(2 ** (p_bits - 1), 2 ** p_bits) q = findPrime(2 ** (q_bits - 1), 2 ** q_bits) n = p * q fn = (p - 1) * (q - 1) e = selectE(fn) temp = Euclid(e, fn) d = temp[0] if d < 0: d = d + fn print(f"p: {p}, q: {q}, n: {n}, e: {e}, d: {d}") print(f"\np-1: {p - 1}, q-1: {q - 1}, gcd(p-1, q-1): {Euclid(p - 1, q - 1)[2]}") print(f"\nAbsolute difference |p-q|: {abs(p - q)}") # 测试加密和解密 m = random.randint(1, n - 1) c = fastExpMod(m, e, n) decrypted_m = fastExpMod(c, d, n) print(f"\nOriginal message: {m}, Encrypted: {c}, Decrypted: {decrypted_m}") print("\nEncryption and decryption successful!" if m == decrypted_m else "Decryption failed!") # 测量将 n 分解为两个素数的时间 start_time = time.time() factor1, factor2 = factorize_n(n) end_time = time.time() factorization_time = end_time - start_time print(f"\nFactorization time: {factorization_time:.6f} seconds") print(f"Factors: {factor1}, {factor2}") # 重复加密攻击测试 repeat_encryption_test(m, e, n) def factorize_n(n): # 从 sqrt(n) 开始向下试除 start = int(n ** 0.5) for i in range(start, 1, -1): if n % i == 0: return i, n // i return n, 1 # 如果 n 是素数 def repeat_encryption_test(m, e, n, repetitions=10): encrypted_messages = [] c = m for _ in range(repetitions): c = fastExpMod(c, e, n) encrypted_messages.append(c) print(f"Repeated encryption {len(encrypted_messages)}: {c}") # 检查是否有重复的密文 unique_ciphertexts = set(encrypted_messages) if len(unique_ciphertexts) == len(encrypted_messages): print("\nNo repeated ciphertexts found. Repeated encryption attack is less likely.") else: print("\nRepeated ciphertexts found. Repeated encryption attack is possible.") if __name__ == "__main__": # start() test_RSA_parameters(20, 20) test_RSA_parameters(5, 5)
已完成理解「import random def fastExpMod(b, n, m): ''' return : b^n mod m ''' result = 1 while n != 0: if (n & 1) == 1: # 按位与操作 result = (result * b) % m b = (b * b) % m n = n >> 1 # 位数右移操作 return result def Euclid(a, b): ''' 欧几里得算法 ax + by = gcd(a,b) Return : [x , y , gcd(a,b)] ''' X = [1, 0, a] Y = [0, 1, b] while Y[2] != 0: Q = X[2] // Y[2] NEW_Y = [i * Q for i in Y] T = list(map(lambda x: x[0] - x[1], zip(X, NEW_Y))) X = Y.copy() Y = T.copy() return X def fermatPrimeTest(m, k): ''' 费马素性检验算法 m : 给定整数 k : 安全参数,重复K次 ''' if m % 2 == 0: return False for i in range(k): a = random.randint(2, m - 2) g = Euclid(a, m) if g[2] == 1: r = fastExpMod(a, m - 1, m) if r == 1: continue else: return False else: return False return True def findPrime(lower, upper): ''' return : 一个位于upper和lower之间的素数 ''' while True: n = random.randint(lower, upper) if fermatPrimeTest(n, 6) == True: return n def selectE(fn): ''' fn : euler function Return : e ''' while True: e = random.randint(1, fn) temp = Euclid(e, fn) if temp[2] == 1: return e def keyGenerate(lower, upper): ''' 给定两个素数p和q生成的区间 return : e,n,d ''' p = findPrime(lower, upper) q = findPrime(lower, upper) print("p:" + str(p) + " q:" + str(q)) # print("q:"+str(q)) n = p * q fn = (p - 1) * (q - 1) e = selectE(fn) temp = Euclid(e, fn) # 欧几里得算法求逆元 d = temp[0] if d < 0: # 由于e和fn互素故一定存在逆元 d = d + fn # 保证d为正数 return e, n, d def start(): e, n, d = keyGenerate(2**256, 2**257) # 密钥生成 # 更改keyGenerate函数的两个参数,可以改变生成素数的位数大小。 print("public key (e,n):", end="") print("(" + str(e) + " , " + str(n) + ")\n") print("private key d: " + str(d) + "\n") m = random.randint(1, n) # m < n m为明文 print("Plaintext: " + str(m)) c = fastExpMod(m, e, n) # 加密 c为密文 m^e mod n print("\nEncryption of PlainText: " + str(c)) x = fastExpMod(c, d, n) # 解密 c^d mod n print("\nDecryption of CipherText: " + str(x)) if x == m: print("\nThe plaintext and ciphertext are the same.") import time def test_RSA_parameters(p_bits, q_bits): p = findPrime(2 ** (p_bits - 1), 2 ** p_bits) q = findPrime(2 ** (q_bits - 1), 2 ** q_bits) n = p * q fn = (p - 1) * (q - 1) e = selectE(fn) temp = Euclid(e, fn) d = temp[0] if d < 0: d = d + fn print(f"p: {p}, q: {q}, n: {n}, e: {e}, d: {d}") print(f"\np-1: {p - 1}, q-1: {q - 1}, gcd(p-1, q-1): {Euclid(p - 1, q - 1)[2]}") print(f"\nAbsolute difference |p-q|: {abs(p - q)}") # 测试加密和解密 m = random.randint(1, n - 1) c = fastExpMod(m, e, n) decrypted_m = fastExpMod(c, d, n) print(f"\nOriginal message: {m}, Encrypted: {c}, Decrypted: {decrypted_m}") print("\nEncryption and decryption successful!" if m == decrypted_m else "Decryption failed!") # 测量将 n 分解为两个素数的时间 start_time = time.time() factor1, factor2 = factorize_n(n) end_time = time.time() factorization_time = end_time - start_time print(f"\nFactorization time: {factorization_time:.6f} seconds") print(f"Factors: {factor1}, {factor2}") # 重复加密攻击测试 repeat_encryption_test(m, e, n) def factorize_n(n): # 从 sqrt(n) 开始向下试除 start = int(n ** 0.5) for i in range(start, 1, -1): if n % i == 0: return i, n // i return n, 1 # 如果 n 是素数 def repeat_encryption_test(m, e, n, repetitions=10): encrypted_messages = [] c = m for _ in range(repetitions): c = fastExpMod(c, e, n) encrypted_messages.append(c) print(f"Repeated encryption {len(encrypted_messages)}: {c}") # 检查是否有重复的密文 unique_ciphertexts = set(encrypted_messages) if len(unique_ciphertexts) == len(encrypted_messages): print("\nNo repeated ciphertexts found. Repeated encryption attack is less likely.") else: print("\nRepeated ciphertexts found. Repeated encryption attack is possible.") if __name__ == "__main__": # start() test_RSA_parameters(20, 20) test_RSA_parameters(5, 5)」
展开阅读网页
这段代码是一个Python实现的RSA加密算法示例,包括密钥生成、加密、解密以及一些测试函数。下面是对代码中各个部分的解释:
-
fastExpMod
函数实现了快速幂算法,用于计算 $ b^n \mod m $。这是一种基础运算,用于RSA算法中的模指数运算12。 -
Euclid
函数实现了欧几里得算法,用于求两个数的最大公约数(GCD)。此外,它还返回一组整数解 $ x, y $ 使得 $ ax + by = \text{gcd}(a, b) $14。 -
fermatPrimeTest
函数使用费马素性检验来测试一个数是否为素数。它基于费马小定理,如果 $ a^{(m-1)} \mod m = 1 $ 对于某个 $ a $ 来说成立,那么 $ m $ 可能是素数38。 -
findPrime
函数使用fermatPrimeTest
来找到一个位于指定区间内的素数。 -
selectE
函数选择一个与欧拉函数 $ \phi(n) $ 互质的数 $ e $,这是RSA算法中公钥的一部分。 -
keyGenerate
函数生成RSA密钥。它首先找到两个素数 $ p $ 和 $ q $,然后计算 $ n = pq $ 和 $ \phi(n) $,接着选择公钥指数 $ e $ 和私钥指数 $ d $。 -
start
函数演示了如何使用keyGenerate
函数生成密钥,并对一个随机明文进行加密和解密。 -
test_RSA_parameters
函数测试了RSA参数的生成,包括密钥生成、加密、解密,并测量了将 $ n $ 分解为两个素数所需的时间。 -
factorize_n
函数尝试将一个合数 $ n $ 分解为其素因子。 -
repeat_encryption_test
函数测试了重复加密攻击的可能性,通过重复加密同一个明文并检查是否产生了重复的密文。
最后,if __name__ == "__main__":
部分调用了 test_RSA_parameters
函数,用以测试不同位大小的素数生成的RSA参数,并执行了相关的测试。