目录
- 前提引入
- Miller Rabin素性检测
- 素数判断
- 生成长度为n的素数(十进制)
- 某个数的全部素因子
- 模m的最小原根
- 模m的所有原根
- 模m的随机原根
- a模m的逆
- a模m的阶(order
- 生成长度为n的安全素数(十进制
- 安全素数p的随机原根
前提引入
写这个的时候也参考和比较了不少博客文章
能力和知识有限……部分函数在一些极限时运行较慢,欢迎评论提出建议
请自行添加import和其他变量
部分函数会调用前面的函数,如素数判断会调用rabin
import random
import math
等,还可以
import time
比较运行时间,择优
start=time.time()
'''
函数
'''
end=time.time()
print(end-start)
小(<1000)素数列表:
small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]
Miller Rabin素性检测
有一点点小缺陷(我也不理解
def rabin(m):
u=0
r=m-1
while r%2==0:
u=u+1
r=r//2
for i in range(20):
a=random.randint(2, m-1)
z=pow(a,r,m)
if z!=1 and z!=m-1:
for j in range(1,u):
z=(z*z)%m
if z==1:
return False
if z!=m-1:
return False
return True
这是按照百度写的
素数判断
def is_prime(m):
if m<2:
return False
if m in small_primes:
return True
for i in small_primes:
if m%i==0:
return False
return rabin(m)
生成长度为n的素数(十进制)
def length(n):
while True:
m=random.randint(pow(10,n-1)+1, pow(10,n))
if is_prime(m):
return m
某个数的全部素因子
def prime_factors(n):
factors = []
k=2
while n!=1 and k*k<n:
if n%k==0:
factors.append(k)
while n%k==0:
n=n//k
k=k+1
return factors
模m的最小原根
def min_root(m):
factors=prime_factors(m-1)
flag=False
for i in range(2,m):
for j in factors:
if pow(i,(m-1)//j,m)==1:
flag=False
break
else:
flag=True
if flag==True:
return i
模m的所有原根
def all_root(m):
g=min_root(m)
roots=[]
for k in range(1,m):
if math.gcd(k, m-1)==1:
roots.append(pow(g,k,m))
return roots
模m的随机原根
def a_root(m):
factors=prime_factors(m-1)
flag=False
while True:
g=random.randint(2,m)
for j in factors:
if pow(g,(m-1)//j,m)==1:
flag=False
break
else:
flag=True
if flag==True:
return g
a模m的逆
def modinv(a,m):
x1,x2,x3=1,0,a
y1,y2,y3=0,1,m
while y3!=0:
q=x3//y3
t1,t2,t3=x1-q*y1,x2-q*y2,x3-q*y3
x1,x2,x3=y1,y2,y3
y1,y2,y3=t1,t2,t3
return x1%m
a模m的阶(order
def order(a,m):
for k in range(1,m):
if pow(a,k,m)==1:
return k
生成长度为n的安全素数(十进制
安全素数p:p=2*q+1,p、q均为素数,此时p称为安全素数
主要用于减少p-1的因子
def safe_length(n):
while True:
p=random.randint(5*pow(10,n-2), 5*pow(10,n-1)-1)
if p%10!=7 and is_prime(p) and is_prime(2*p+1):
return 2*p+1
在C语言的Miracl库中有一个nxsafeprime函数可以快速生成一个安全素数
但我在python没有找到
在openssl中有一个指令openssl -generate -safe同样可以做到
python也有一个OpenSSL库,希望有会用的小伙伴可以分享一下
(好像gensafeprime也有
安全素数p的随机原根
最小原根和全部原根可参考上文对该函数进行修改
def safe_root(p):
while True:
g=random.randint(2,p)
if pow(g,2,p)!=1 and pow(g,(p-1)//2,p)!=1:
return g
当然也会有更好更高效率的方法,仅供参考