C ++处理非常大的整数

我正在使用RSAalgorithm进行encryption/解密,并且为了解密文件,您必须处理一些相当大的值。 更具体地说,像

P = C^d % n = 62^65 % 133 

现在,这真的是唯一的计算,病态的做法。 我曾尝试使用Matt McCutchen的BigInteger库,但在链接过程中遇到了很多编译错误,例如:

 encryption.o(.text+0x187):encryption.cpp: undefined reference to `BigInteger::BigInteger(int)' encryption.o(.text+0x302):encryption.cpp: undefined reference to `operator<<(std::ostream&, BigInteger const&)' encryption.o(.text$_ZNK10BigIntegermlERKS_[BigInteger::operator*(BigInteger const&) const]+0x63):encryption.cpp: undefined reference to `BigInteger::multiply(BigInteger const&, BigInteger const&)' 

所以我想知道什么是处理来自RSAalgorithm的真正大整数的最好方法。

我听说有可能将声明你的variables为双倍长,所以…

 long long decryptedCharacter; 

但我不确定究竟可以存储多大的整数。


那么举个例子,我尝试使用dev C ++编译并运行下面的程序:

 #include iostream #include "bigint\BigIntegerLibrary.hh" using namespace std; int main() { BigInteger a = 65536; cout << (a * a * a * a * a * a * a * a); return 0; } 

那么我得到这些错误。

Derek,我认为通过包含BigIntegerLibrary.hh文件,编译器会通过编译所有必要的文件。

我应该如何尝试编译上面的程序来解决链接错误?

元回答:

如果你正在使用bigintalgorithm的库,那么问自己为什么你没有在整个RSA实现中使用一个库。

例如, http://www.gnu.org/software/gnu-crypto/包含一个RSA实现。; 它与GMP具有相同的许可证。

然而,他们没有像http://mattmccutchen.net/bigint/那样的许可证,我觉得这个许可证在美国已经被置入了公有领域。;

我build议使用gmp ,它可以处理任意长整数,并有体面的C ++绑定。

afaik在当前的硬件/软件中的长整数是64位,所以无符号可以处理高达(2 ** 64)-1 == 18446744073709551615的数字,这比你不得不用RSA处理的数字要小得多。

Tomek,这听起来像你没有正确链接到BigInteger代码。 我认为你应该解决这个问题,而不是寻找一个新的图书馆。 我看了一下源代码, BigInteger::BigInteger(int)是最明确定义的。 简短的一眼就可以看出其他人也是如此。

您所得到的链接错误意味着您要么忽略编译BigInteger源代码,要么忽略在链接时包含生成的目标文件。 请注意,BigInteger源使用“cc”扩展名而不是“cpp”,因此请确保您正在编译这些文件。

要查看长长的大小,请尝试以下操作:

 #include <stdio.h> int main(void) { printf("%d\n", sizeof(long long)); return 0; } 

在我的机器上它返回8意味着8个字节可以存储2 ^ 64的值。

对于RSA,您需要一个bignum库。 这些数字太大,不适合64位长的长。 我曾经有一个在大学里的同事得到RSA的任务,包括build立他自己的图书馆。

碰巧,Python有一个bignum库。 编写高质量的处理程序足够小,以适应计算机科学的任务,但仍然有足够的陷阱,使其成为一个不平凡的任务。 他的解决scheme是使用Python库生成testing数据来validation他的bignum库。

你应该可以得到其他的bignum库。

另外,尝试在Python中实现一个原型,看看它是否足够快。

如果你没有把RSA作为一个学校任务或者其他的东西,那么我会build议看一下crypto ++库http://www.cryptopp.com

这很容易实施密码的东西很糟糕。

这是我的方法,它结合快速指数使用平方+模指数减less所需的空间。

 long long mod_exp (long long n, long long e, long long mod) { if(e == 1) { return (n % mod); } else { if((e % 2) == 1) { long long temp = mod_exp(n, (e-1)/2, mod); return ((n * temp * temp) % mod); } else { long long temp = mod_exp(n, e/2, mod); return ((temp*temp) % mod); } } } 

我会尝试GMP库 – 它是健壮的,经过很好的testing,并且通常用于这种types的代码。

Openssl也有一个可以使用的Bignumtypes。 我用它,它运作良好。 如果你愿意,可以用C ++或Objective-C这样的语言轻松包装。

https://www.openssl.org/docs/crypto/bn.html

另外,如果你不知道,为了find这个forms的方程的答案x ^ y%z,查找一个叫做模幂的algorithm。 大多数encryption或者标准库都将具有专门用于该计算的function。

还有更多的安全RSA的实施比大数字。 一个简单的RSA实现倾向于通过边信道泄漏私人信息,尤其是计时(简单地说:计算时间取决于处理的数据,这允许攻击者恢复一些,可能是所有的私钥位)。 好的RSA实施实施对策。

而且,除了模幂运算之外,还有整个填充业务,这在概念上并不困难,但是,由于所有的I / O和parsing代码都有微妙的缺陷空间。 最简单的代码是已经被其他人编写的代码。

另一点是,一旦你的RSA代码启动并运行,你可能会开始想象扩展和其他情况,例如“如果我要使用的私钥不在RAM中,而是在智能卡中呢?”。 一些现有的RSA实现实际上是可以处理这个的API。 在微软的世界里,你要查找集成在Windows中的CryptoAPI 。 您可能还想看看NSS ,这是Firefox浏览器用于SSL的内容。

总结一下:你可以用大整数构build符合RSA标准的实现,但是这比正常情况下难以正确执行,所以我的build议是使用现有的RSA实现。

long int通常是64位,这可能不足以处理一个很大的整数。 你可能需要一个bigint类库。

另请参阅Stack Overflow上的这个问题

看看你的编译器文档。 一些编译器具有定义的types,例如__int64,它们可以提供它们的大小。 也许你有一些可用的。

只要注意:__int64和long long是非标准扩展。 所有的C ++编译器都不能保证它们的支持。 C ++是基于C89(它出现在98年,所以它不能基于C99)

(自C99以来,C已经支持了很长的一段时间)

顺便说一句,我不认为64位整数解决这个问题。

事实上,使用一些biginteger库有一个问题并不意味着,这是一个坏的方法。

长时间使用肯定是一个不好的方法。

正如其他人所说,已经使用biginteger库可能是一个很好的方法,但你必须发布更多的细节上你使用提到的库,我们可以帮助您解决这些错误。

我在编写RSA实现时使用了GMP。

为了满足我的密码需求,我使用LibTomCrypt库取得了很大的成功。 它快速,精益和便携。 它可以为你做你的RSA,或者只是在你想要的时候处理math。