目录

  • 前提引入
  • 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

当然也会有更好更高效率的方法,仅供参考