跳转到内容

大步小步算法

维基百科,自由的百科全书

群论中,大步小步算法(英语:baby-step giant-step)是丹尼尔·尚克斯英语Daniel Shanks发明的一种中途相遇算法,用于计算离散对数或者有限阿贝尔群[1]其中离散对数问题在公钥加密领域有着非常重要的地位。

许多常用的加密系统都基于离散对数极难计算这一假设——计算越困难,这些系统提供的数据传输就越安全。增加离散对数计算难度的一种方法,是把密码系统建立在更大的群上。

理论

[编辑]

这是一种空间换时间的算法,实质上是求解离散对数的朴素算法(枚举并试乘)的一个相当简单的改进。

给出一个 循环群 、该群的一个生成元 和一个元素 。试找到一个整数 满足

大步小步算法把 代换成:

于是有:

该算法先对 的不同取值计算出 的值,然后固定一个 ,并对 尝试不同的取值,带入上面同余式的右边,看是否与某个(已经预先算出的)同余式左边的值相匹配。

算法

[编辑]

给出C++17版本的代码:

#include <cmath>
#include <cstdint>
#include <unordered_map>

std::uint32_t pow_m(std::uint32_t base, std::uint32_t exp, std::uint32_t mod) {
        // 这里需要实现快速幂算法
}


///计算满足 g^x % mod == h 的x
std::optional<std::uint32_t> babystep_giantstep(std::uint32_t g, std::uint32_t h, std::uint32_t mod) {
        const auto m = static_cast<std::uint32_t>(std::ceil(std::sqrt(mod)));
        auto table = std::unordered_map<std::uint32_t, std::uint32_t>{};
        auto e = std::uint64_t{1}; // 临时值可能大于32位整数的范围
        for (auto i = std::uint32_t{0}; i < m; ++i) {
                table[static_cast<std::uint32_t>(e)] = i;
                e = (e * g) % mod;
        }
        const auto factor = pow_m(g, mod-m-1, mod);
        e = h;
        for (auto i = std::uint32_t{}; i < m; ++i) {
                if (auto it = table.find(static_cast<std::uint32_t>(e)); it != table.end()) {
                        return {i*m + it->second};
                }
                e = (e * factor) % mod;
        }
        return std::nullopt;
}

实务应用

[编辑]

加速大步小步算法的最佳方式,是使用高效的表格查找机制。在此情况下,最适合的是使用杂凑表(hash table)。杂凑是针对第二个元件(即元素对的第二个值)进行,并且在主循环的第 1 步中,会对 γ 做杂凑,然后检查对应的记忆体位置。由于杂凑表可以在 (常数时间)内进行新增与查询操作,因此这个过程不会拖慢整体的大步小步算法。

此算法的空间复杂度为 ,而时间复杂度则为 。这样的执行时间比起暴力的 执行时间来得更优。

当模数是一个不是太大的质数时,窃听者可以使用大步小步算法来推导在Diffie–Hellman金钥交换中产生的私钥。如果模数不是质数,则可以使用Pohlig–Hellman算法,其算法复杂度更低,也有可能解出相同的问题。 [2]


延伸阅读

[编辑]

参考资料

[编辑]
  1. ^ Daniel Shanks, Class number, a theory of factorization and genera, In Proc. Symp. Pure Math. 20 (Providence, R.I.: American Mathematical Society), 1971, 20: 415—440 (英语) 
  2. ^ Maurer, Ueli M.; Wolf, Stefan, The Diffie-Hellman protocol, Designs, Codes and Cryptography, 2000, 19 (2–3): 147–171, MR 1759615, doi:10.1023/A:1008302122286