Python算法求循环群生成器的阶

Python算法求循环群生成器的阶,python,prime-factoring,secret-key,elgamal,finite-field,Python,Prime Factoring,Secret Key,Elgamal,Finite Field,我想找到从循环组中选择的生成器g,其中q是一个非常大(数百位长)的数。我从Rosetta代码中尝试了以下代码,但时间太长: def gcd(a, b): while b != 0: a, b = b, a % b return a def lcm(a, b): return (a*b) / gcd(a, b) def isPrime(p): return (p > 1) and all(f == p for f,e in factored

我想找到从循环组中选择的生成器
g
,其中q是一个非常大(数百位长)的数。我从Rosetta代码中尝试了以下代码,但时间太长:

def gcd(a, b):
    while b != 0:
        a, b = b, a % b
    return a

def lcm(a, b):
    return (a*b) / gcd(a, b)

def isPrime(p):
    return (p > 1) and all(f == p for f,e in factored(p))

primeList = [2,3,5,7]
def primes():
    for p in primeList:
        yield p
    while 1:
        p += 2
        while not isPrime(p):
            p += 2
        primeList.append(p)
        yield p

def factored( a):
    for p in primes():
        j = 0
        while a%p == 0:
            a /= p
            j += 1
        if j > 0:
            yield (p,j)
        if a < p*p: break
    if a > 1:
        yield (a,1)

def multOrdr1(a, (p,e)):
    m = p**e
    t = (p-1)*(p**(e-1)) #  = Phi(p**e) where p prime
    qs = [1,]
    for f in factored(t):
        qs = [ q * f[0]**j for j in range(1+f[1]) for q in qs ]
    qs.sort()

    for q in qs:
        if pow( a, q, m )==1: break
    return q

def multOrder(a,m):
    assert gcd(a,m) == 1
    mofs = (multOrdr1(a,r) for r in factored(m))
    return functools.reduce(lcm, mofs, 1)

if __name__ == "__main__":
    print(multOrder(37, 1000))     # 100
    b = 10**20-1
    print(multOrder(2, b))         # 3748806900
    print(multOrder(17,b))         # 1499522760
    b = 100001
    print(multOrder(54,b))
    print(pow(54, multOrder(54,b), b))
    if any( (1==pow(54,r, b)) for r in range(1,multOrder(54,b)) ):
        print('Exists a power r < 9090 where pow(54,r,b)==1')
    else:
        print('Everything checks.')
def gcd(a,b): 而b!=0: a、 b=b,a%b 归还 def lcm(a、b): 报税表(a*b)/gcd(a、b) def iPrime(p): 返回(p>1)和全部(f==p表示f,e表示系数(p)) 素数表=[2,3,5,7] def primes(): 对于primeList中的p: 产量p 而1: p+=2 虽然不是iPrime(p): p+=2 primeList.append(p) 产量p def系数(a): 对于素数()中的p: j=0 当%p==0时: a/=p j+=1 如果j>0: 收益率(p,j) 如果a1: 收益率(a,1) def multOrdr1(a,(p,e)): m=p**e t=(p-1)*(p**(e-1))#=φ(p**e),其中p素数 qs=[1,] 对于系数为(t)的f: qs=[q*f[0]**j表示范围内的j(1+f[1]),q表示范围内的q] qs.sort() 对于qs中的q: 如果功率(a,q,m)=1:中断 返回q def多路复用器(a,m): 断言gcd(a,m)=1 mofs=(系数(m)中r的multOrdr1(a,r)) 返回functools.reduce(lcm、mofs、1) 如果名称=“\uuuuu main\uuuuuuuu”: 印刷品(穆托德(371000))#100 b=10**20-1 印刷品(multOrder(2,b))#3748806900 印刷品(穆托德(17,b))#1499522760 b=100001 印刷品(穆托德(54,b)) 印刷品(战俘(54,穆托德(54,b,b)) 如果范围(1,multOrder(54,b))内的r有((1==pow(54,r,b)): 打印('存在功率r<9090,其中功率(54,r,b)=1') 其他: 打印('一切检查')
那么,您是否在寻找更高效的算法?是的。除非我在概念上遗漏了什么。我正在尝试为ElGamal加密生成密钥。您好,我还想要一个更高效的Python代码^^