如何评估一个模数的指数塔

时间:2014-01-26 19:02:23

标签: algorithm math language-agnostic

我想找到一个快速算法来评估如下表达式,其中 P 是素数。

A ^ B ^ C ^ D ^ E mod P

示例:

(9 ^ (3 ^ (15 ^ (3 ^ 15)))) mod 65537 = 16134

问题是中间结果可能会变得太大而无法处理。

1 个答案:

答案 0 :(得分:13)

基本上,对于给定的a^T mod ma和一个非常庞大的术语m,问题会减少到计算T。但是,我们能够使用给定模数T mod n评估nT快得多。所以我们问:“是否有整数n,这样a^(T mod n) mod m = a^T mod m?”

现在如果am是互质的,我们知道n = phi(m)根据Euler's theorem符合我们的条件:

  a^T                               (mod m)
= a^((T mod phi(m)) + k * phi(m))   (mod m)    (for some k)
= a^(T mod phi(m)) * a^(k * phi(m)) (mod m)
= a^(T mod phi(m)) * (a^phi(m))^k   (mod m)
= a^(T mod phi(m)) * 1^k            (mod m)
= a^(T mod phi(m))                  (mod m)

如果我们可以计算phi(m)(例如在O(m^(1/2))中很容易做到,或者如果我们知道m的素数分解),我们就会将问题简化为计算T mod phi(m) 1}}和一个简单的modular exponentiation

如果am不是互质的,该怎么办?情况不像以前那么令人愉快,因为对于所有n,可能没有有效a^T mod m = a^(T mod n) mod m属性T。但是,我们可以证明a^k mod m的序列k = 0, 1, 2, ...在某个点之后进入一个循环,即存在xCx, C < m,这样所有a^y = a^(y + C)都是y >= x

示例:对于a = 2, m = 12,我们得到序列2^0, 2^1, ... = 1, 2, 4, 8, 4, 8, ... (mod 12)。我们可以看到包含参数x = 2C = 2的循环。

通过计算序列元素a^0, a^1, ...,我们可以通过暴力找到周期长度,直到我们找到两个带X < Y的索引a^X = a^Y。现在我们设置x = XC = Y - X。这给了我们一个每次递归O(m)指数的算法。

如果我们想做得更好怎么办?感谢Math Exchange的Jyrki Lahtonen提供the essentials for the following algorithm

让我们评估序列d_k = gcd(a^k, m),直到我们找到x d_x = d_{x+1}。这将最多需要log(m)个GCD计算,因为xm的素数因子分解中的最高指数限制。让C = phi(m / d_x)。所有a^{k + C} = a^kWe can now prove that k >= x,因此我们在O(m^(1/2))时间内找到了周期参数。

我们假设我们找到了xC,现在想要计算a^T mod m。 如果T < x,使用简单的模幂运算执行任务是微不足道的。否则,我们有T >= x,因此可以使用循环:

  a^T                                     (mod m)
= a^(x + ((T - x) mod C))                 (mod m)
= a^(x + (-x mod C) + (T mod C) + k*C)    (mod m)     (for some k)
= a^(x + (-x mod C) + k*C) * a^(T mod C)  (mod m)
= a^(x + (-x mod C)) * a^(T mod C)        (mod m)

同样,我们将问题简化为相同形式的子问题(“compute T mod C”)和两个简单​​的模幂运算。

由于模数在每次迭代中减少了至少1,因此对于此算法的运行时间,我们得到O(P^(1/2) * min (P, n))的非常弱的界限,其中n是堆栈的高度。在实践中,我们应该好多了,因为模量预计会呈指数下降。当然这个论点有点手持波动,也许一些更具数学倾向的人可以改进它。

有一些边缘情况需要考虑,实际上让您的生活更轻松:如果m = 1(在这种情况下结果为0)或a是倍数的倍数,您可以立即停止m(在这种情况下,结果也是0)。

编辑:可以证明x = C = phi(m)有效,因此作为快速而肮脏的解决方案,我们可以使用公式

a^T = a^(phi(m) + T mod phi(m))  (mod m)

代表T >= phi(m)甚至T >= log_2(m)