一、简述
二、基础知识
1、扩展欧几里得求逆元:
假设a>b;
1、若b=0,则gcd(a,b)=a,得到x=1,y=0;
2、若ab!=0
有ax1+by1=gcd(a,b);
bx2+(a%b)y2=gcd(b,a%b);
由欧几里得算法可得:gcd(a,b)=gcd(b,a%b);
即有:
ax1+by1=bx2+(a%b)y2;
即,ax1+by1=bx2+[a-(a/b)b]y2=ay2+bx2-b(a/b)y2;
由a、b系数相等得:
x1=y2,
y1=x2-(a/b)y2;
这样通过求解x2,y2来得到x1,y1。
2、rabin_miller算法
三、 代码
import random
def rabin_miller(num): # rabin_miller算法
if (num % 2 == 0):
return False
s = num - 1
t = 0
while s % 2 == 0:
s = s // 2
t += 1
for trials in range(5):
a = random.randrange(2, num - 1)
v = pow(a, s, num)
if v != 1:
i = 0
while v != (num - 1):
if i == t - 1:
return False
else:
i = i + 1
v = (v ** 2) % num
return True
def set_prime(size):
while (1):
n = random.randrange(2 ** (size - 1), 2 ** size) # 随机生成大数
if (rabin_miller(n)): # 使用素性检测
return n
def gcd(a, b): # 求最大公约数
if (a < b):
temp = a
a = b
b = temp
if (a % b != 0):
return gcd(b, a % b)
else:
return b
def ext_gcd(a, b): # 扩展欧几里得算法
if b == 0:
x1 = 1
y1 = 0
return a, x1, y1
else:
r, x1, y1 = ext_gcd(b, a % b)
x = y1
y = x1 - a // b * y1
return r, x, y
def encrypt():
size = int(input("请输入大素数大小(bit):"))
p = set_prime(size)
q = set_prime(size)
N = p * q # N
fai_N = (p - 1) * (q - 1)
e = 65537 # 公钥
if (gcd(e, fai_N) == 1):
print("e与fai_N互质")
r, x, y = ext_gcd(e, fai_N)
while (x < 0):
x += fai_N
d = x # 密钥
print("私钥d:" + str(d))
m = int(input("请输入数字明文:"))
c = pow(m, e, N) # 密文
print("密文:" + str(c))
print("明文:" + str(pow(c, d, N)))
else:
print("e与fai_N不互素,程序结束")
encrypt()