离散对数暴力破解:有人能给我解释一下c++和c++的NTL运行时的区别吗?

Discrete logarithm brute force: Can someone explain me the runtime differences between C++ and C++ with NTL?

本文关键字:c++ 一下 NTL 区别 运行时 破解 解释 离散对数      更新时间:2023-10-16

这是一个运行时和/或时间复杂度的问题,而不是加密问题,所以请继续阅读:

在大学里,我们必须实现一个强力离散对数算法来找到diffie hellman交换的秘密,我开始用c++和NTL库实现它,这样我就不用担心数据类型和大质数了。

我的示例数是以下的25位素数,我们想找到离散对数:

p = 20084173;  /* the prime */
g = 2;         /* the generator */
a = 7709318;   /* the logarithm of a */
b = 6676335;   /* the logarithm of b */

我用NTL在 c++中实现了以下代码:

int main() {
    ZZ p, g, a, b;
    // 25 Bit
    p = 20084173;
    g = 2;
    a = 7709318;
    b = 6676335;
    exhaustiveSearch(p, g, a);
    exhaustiveSearch(p, g, b);
    return 0;
}
ZZ exhaustiveSearch(ZZ p, ZZ g, ZZ t) {
    ZZ i, x;
    i = 0;
    x = 1;
    while ((x = (x % p)) != t) {
        i++;
        x = x * g;
    }
    cout << endl << endl << "p = " << p << endl << "g = " << g << endl << "t = " << t << endl << "secret: = " << i << endl;
    return i;
}

输出(7.581):

p = 20084173
g = 2
t = 7709318
secret: = 557254
p = 20084173
g = 2
t = 6676335
secret: = 8949383
-> time: 7.581s

嗯,我认为这真的很长,所以我测试了它没有NTL和c++中正常的long ->想象所有的ZZ都被long (0.124):

p = 20084173
g = 2
t = 7709318
Secret: = 557254
p = 20084173
g = 2
t = 6676335
Secret: = 8949383
-> time: 0.124s

谁能解释一下为什么NTL这么慢?请记住,我不是这个领域的专家,只是想弄清楚密码学的基础知识,以及如何在简单的例子中实现这些。

谢谢!

总的来说。 NTL是一个功能强大且编写良好的库,用于长整数和其他与加密相关的算法,但它显然无法在处理小数字时击败内置类型的效率。注意,当使用long类型时,所有操作都转换为单个cpu指令。它是最快的,但仅限于32/64位。

另一方面,ZZ是一个成熟的类,需要管理它的内存,并且能够操作任意长度的整数。这是要付出代价的。

可能的优化。话虽如此,您可以尝试并优化一些事情,考虑到ZZ是一个类的事实,因此避免创建不必要的临时对象可能是有意义的。

例如,考虑 行
x = x * g;

在两个对象上调用operator*,并再次将新值赋给x。看看它的实现,我们看到:

inline ZZ operator*(const ZZ& a, const ZZ& b)
      { ZZ x; mul(x, a, b); NTL_OPT_RETURN(ZZ, x); }

,创建并返回一个新的临时对象。我认为调用

会更有效率。
x *= g

,因为operator*=的实现避免了临时创建

inline ZZ& operator*=(ZZ& x, const ZZ& a)
  { mul(x, x, a); return x; }
使用ZZ_p

另一件要考虑的事情是,你实际上是在Z_p中做算术(即在Z模p中),所以可能你想使用类ZZ_p在必要时自动执行缩减。

使用NTL和GMP如果你关心(long)算法的性能,一个好主意是构建NTL,使其在底层的long算法中使用GMP。这在某种程度上提供了比普通NTL更好的性能。