这是一个运行时和/或时间复杂度问题,而不是加密问题,所以请继续阅读:
在大学里,我们必须实现一个强制离散对数算法,以便在一个难以理解的hellman交换中找到秘密,然后我开始用C ++和NTL库实现它,所以我不必担心数据类型和大素数。我的示例数字如下,带有25位素数,我们想要找到离散对数:
p = 20084173; /* the prime */
g = 2; /* the generator */
a = 7709318; /* the logarithm of a */
b = 6676335; /* the logarithm of b */
我在 C ++ with NTL :
中实现了以下功能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.581s):
p = 20084173
g = 2
t = 7709318
secret: = 557254
p = 20084173
g = 2
t = 6676335
secret: = 8949383
-> time: 7.581s
嗯,我认为这真的很长,所以我测试了没有NTL和普通的长篇C ++ - &gt;想象所有ZZ被长(0.124s):
取代p = 20084173
g = 2
t = 7709318
Secret: = 557254
p = 20084173
g = 2
t = 6676335
Secret: = 8949383
-> time: 0.124s
有人可以解释一下为什么NTL会慢得多吗?请记住,我不是这个领域的专家,只是想弄清楚加密基础知识以及如何在简单的例子中实现这些基础知识。
谢谢!
答案 0 :(得分:1)
一般来说。 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一起使用如果您关心(长)算术的性能,一个好主意是建立NTL,以便它使用GMP作为底层长算术。这提供了比普通NTL更好的性能。