平方求幂取余,模幂,快速幂取余数

以下的内容来自 维基百科:模幂

从右到左的二位算法

第三种方法结合了第二种算法和平方求幂原理,使所需步骤大大减少,同时也与第二种方法一样减少了内存占用量。

首先把\(e\)表示成二进制,即:

\[e = \sum_{i=0}^{n-1} a_i 2^i \]

此时\(e\)的长度为\(n\)位。对任意\(i\)\(0\leq i < n\)),\(a_i\)可取0或1任一值。由定义有\(a_{n-1}=1\)

\(b^e\)的值可写作:

\[b^e = b^{\left( \sum_{i=0}^{n-1} a_i 2^i \right)} = \prod_{i=0}^{n-1} \left( b^{2^i} \right) ^ {a_i} \]

因此答案\(c\)即为:

\[c \equiv \prod_{i=0}^{n-1} \left( b^{2^i} \right) ^ {a_i}\ (\mbox{mod}\ m) \]

伪代码

下述伪代码基于布魯斯·施奈爾所著《应用密码学》。其中baseexponentmodulus分别对应上式中的 \(b\)\(e\)\(m\)

function modular_pow(base, exponent, modulus)
    if modulus = 1 then return 0
    Assert :: (modulus - 1) * (modulus - 1) does not overflow base
    result := 1
    base := base mod modulus
    while exponent > 0
        if (exponent mod 2 == 1):
           result := (result * base) mod modulus
        exponent := exponent >> 1
        base := (base * base) mod modulus
    return result

注意到在首次进入循环时,变量base等于\(b\)。在第三行代码中重复执行平方运算,会确保在每次循环结束时,变量base等于\(b^{2^i} \bmod m\),其中\(i\)是循环执行次数。

posted @ 2023-03-20 20:30  Revc  阅读(47)  评论(0编辑  收藏  举报