Algorithm 计算离散对数

Algorithm 计算离散对数,algorithm,math,Algorithm,Math,给定正整数b,c,m,其中(b0。正如所说的,一般问题很难解决。然而,当且仅当您知道e将变小(如您的示例中)时,找到e的一种实用方法就是从1开始尝试每个e 顺便说一句,e==3是您的示例的第一个解决方案,您显然可以在3个步骤中发现,与解决非离散版本和天真地寻找整数解决方案相比 e=log(c+n*m)/log(b),其中n是非负整数 在9个步骤中找到e==3是一个困难的问题 离散对数的计算被认为是困难的。不 计算离散对数的有效通用方法 传统的计算机是众所周知的 我将在这里添加一个简单的brute

给定正整数
b,c,m
,其中
(b
(b**e % m == c) is True
其中**表示求幂运算(如Ruby、Python或其他一些语言中的^),而%表示模运算。解决这个问题最有效的算法(大O复杂度最低)是什么

例如:


给定b=5;c=8;m=13此算法必须找到e=7,因为5**7%13=8

来自%运算符,我假设您使用的是整数

你们正试图解决这个问题。一个合理的算法是,尽管还有许多其他算法,但没有一个特别快


寻找离散对数问题的快速解决方案的困难是一些流行密码算法的一个基本部分,因此,如果您找到比维基百科上任何一个更好的解决方案,请让我知道

这根本不是一个简单的问题。这被称为计算,它是一个逆运算


目前还没有已知的有效算法。也就是说,如果N表示m中的位数,那么所有已知算法都在O(2^(N^C))中运行,其中C>0。

正如所说的,一般问题很难解决。然而,当且仅当您知道e将变小(如您的示例中)时,找到e的一种实用方法就是从1开始尝试每个e

顺便说一句,e==3是您的示例的第一个解决方案,您显然可以在3个步骤中发现,与解决非离散版本和天真地寻找整数解决方案相比

e=log(c+n*m)/log(b),其中n是非负整数

在9个步骤中找到e==3是一个困难的问题

离散对数的计算被认为是困难的。不 计算离散对数的有效通用方法 传统的计算机是众所周知的

我将在这里添加一个简单的bruteforce算法,它尝试从
1
m
的所有可能值,如果找到了,则输出一个解决方案。请注意,问题可能有多个解决方案,或者根本没有解决方案。此算法将返回可能的最小值,如果不存在,则返回
-1

def bruteLog(b, c, m):
    s = 1
    for i in xrange(m):
        s = (s * b) % m
        if s == c:
            return i + 1
    return -1

print bruteLog(5, 8, 13)
在这里,您可以看到
3
实际上就是解决方案:

print 5**3 % 13

有一个更好的算法,但因为它经常被要求在编程竞赛中实现,所以我只给你一个链接。

由于这个问题的一个副本是在Python标签下提出的,这里是baby step,giant step的Python实现,正如@MarkBeyers指出的,这是一个合理的方法(只要模量不太大):

在上面的实现中,可以传递一个显式的
N
来搜索一个小的指数,即使
p
是加密的大指数。只要指数小于
N**2
,它就会找到该指数。当省略
N
时,总是会找到该指数,但不一定是在您的有生之年,也不一定会找到如果
p
太大,则机器内存太大

例如,如果

p = 70606432933607
a = 100001
b = 54696545758787
然后‘pow(a,b,p)’的计算结果为67385023448517

这在我的机器上花费了大约5秒。对于这些尺寸的指数和模数,我估计(基于计时实验)蛮力可能需要几个月的时间。

Python 3解决方案: 谢天谢地,这是给你的

Symphy是一个用于符号数学的Python库。它旨在成为一个功能齐全的计算机代数系统(CAS),同时使代码尽可能简单,以便理解和易于扩展。Symphy完全用Python编写

这是函数。使用此函数导入它:

from sympy.ntheory import discrete_log
他们的示例计算
\log_7(15)(mod 41)

由于它采用了(最先进的,请注意)的算法来解决它,您将得到您尝试的大多数输入。当素数模具有
p-1
因子转化为许多素数的特性时,速度会快得多


考虑一个大约100位的素数:(~2^{100})。在\sqrt{n}复杂度下,仍然是2^{50}迭代。也就是说,不要重新发明轮子。这做得很好。我还可以补充一点,当我使用大的ish输入(44 MiB与173 MiB)运行时,它的内存效率几乎是Mathematica的
乘法排序
函数的4倍如果他找到了一个真正有效的算法,他就有很大的机会得到该领域的结论。你所说的所有已知算法在时间O(C^N)内对某些C>1运行的说法是不正确的。没有已知的算法在多项式时间内运行,但仍有已知的算法是次指数的。
>>> baby_steps_giant_steps(a,67385023448517,p)
54696545758787
from sympy.ntheory import discrete_log
>>> discrete_log(41, 15, 7)
3