【问题标题】:Fast Algorithm for Modular Multiplicatiion模乘法的快速算法
【发布时间】:2021-12-03 10:54:50
【问题描述】:

我试图实现一个大型素数生成器,生成一个 2048 位长度的素数的平均时间约为 40 秒。我从调用堆栈的分析中看到,大部分时间(99%)被模乘占用,性能变化很大,改变了这个算法。我正在使用 boost::multiprecision::cpp_int 或类似于 boost::multiprecision::uint1024_t 的类型 uint2048_t。 这是我使用的两种算法,其中第一种(不知道为什么)比第二种快得多。我使用的第一个(仅适用于 boost::multiprecision 整数)是一种计算模乘的非常简单的算法,顺便说一下,其中大部分时间都是取自模运算。

template <typename T>
T mulMod(const T& x, const T& y, const T& p) {
    using boost::multiprecision::cpp_int;
    cpp_int rv = (cpp_int{x} * cpp_int{y}) % cpp_int{p};
    return T{rv};
}
template <typename T>
T mulMod(T a, T b, const T& p) {
    T rv = 0;
    a %= p;
    while (b > 0) {
        if (b & 1)
            rv = (rv + a) % p;
        a = (a << 1) % p;
        b >>= 1;
    }
    return rv;
}

是否有更快的算法(可能用 C++ 实现)来执行模乘?

【问题讨论】:

  • 对于快速乘法,您可以尝试Karatsuba method
  • 这取决于您使用模乘的目的:素数是否小于a, b?他们会在计算之间重复吗?您可能想尝试蒙哥马利模算术。
  • 实际使用的T是什么类型?对我来说,boost 可以使用比第二个代码中使用的算法更有效的算法似乎并不奇怪。
  • @JérômeRichard boost::mutliprecision::cpp_int 或 uint2048_t(类似于 boost:multiprecision:uint1024_t)。事实是我利用了 uint2048_t 类型的溢出。也许有更有效的算法并且不使用超过 2048 位

标签: c++ algorithm performance cryptography primes


【解决方案1】:

你开始说你想生成素数。 但是你没有提到模乘和素数之间的联系。

Knuth 第 2 卷有大量关于 bignum 算术和寻找大素数的资料。

评论提到了蒙哥马利模算术。 这是一个链接https://en.wikipedia.org/wiki/Montgomery_modular_multiplication

OpenSSL 具有 BN (bignum) 包,其中包括蒙哥马利乘法和大素数生成。

Gnu Multi Precision (gmp) 库有类似的例程。

您的第二个 mulMod() 例程可以进行优化。 当它在循环中做 mod p 时,参数不大于 2*p 所以 mod 可以这样完成 if( arg >= p) arg -= p.

【讨论】:

    猜你喜欢
    • 2010-12-17
    • 2015-03-02
    • 1970-01-01
    • 1970-01-01
    • 2014-11-12
    • 1970-01-01
    • 2017-01-25
    • 2011-12-16
    • 1970-01-01
    相关资源
    最近更新 更多