【问题标题】:C++ handling very large integersC++ 处理非常大的整数
【发布时间】:2010-09-12 13:35:01
【问题描述】:

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

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&)'

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

我听说有可能将你的变量声明为双长,所以...

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 文件,编译器会遍历并编译它将使用的所有必要文件。

我应该如何尝试编译上述程序以解决链接错误?

【问题讨论】:

标签: c++ rsa biginteger integer


【解决方案1】:

long int 通常是 64 位,这可能不足以处理这么大的整数。您可能需要某种 bigint 库。

另请参阅 Stack Overflow 上的 this question

【讨论】:

    【解决方案2】:

    要查看 long long 的大小,试试这个:

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

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

    【讨论】:

      【解决方案3】:

      查看您的编译器文档。一些编译器定义了诸如 __int64 之类的类型,这些类型为您提供了它们的大小。也许你有一些可用的。

      【讨论】:

        【解决方案4】:

        请注意:__int64 和 long long 是非标准扩展。不能保证所有 C++ 编译器都支持这两者。 C++是基于C89(98年出来的,所以不能基于C99)

        (自 C99 起,C 就支持 'long long')

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

        【讨论】:

        • C++ 实际上可以追溯到 80 年代初,尽管您说得对,当前的标准早于 C99。
        • 这在技术上是正确的,尽管与手头的情况有些无关。 OTOH,这个问题特别提到了“long long”,所以我不知道downvote来自哪里。 +1 抵消。 PS @CaptainSegfault C++ 在 98 年首次标准化,该标准基于 1990 年的 ISO C 标准(即 C89)。
        【解决方案5】:

        我会试用 GMP 库 - 它功能强大、经过良好测试,并且通常用于此类代码。

        【讨论】:

          【解决方案6】:

          我建议使用gmp,它可以处理任意长的整数,并且具有不错的 C++ 绑定。

          当前硬件/软件上的 afaik long long 是 64 位的,因此 unsigned 可以处理高达 (2**64)-1 == 18446744073709551615 的数字,这比您必须处理 RSA 的数字小得多。

          【讨论】:

          • 64 位数字对于 RSA 安全要求来说是微不足道的。最低 1024bit,推荐 2048bit 和 4096。
          【解决方案7】:

          对于 RSA,您需要一个 bignum 库。这些数字太大了,无法容纳 64 位长。我曾经有一个大学同事,他接到了一个实施 RSA 的任务,包括建立他自己的 bignum 库。

          碰巧的是,Python 有一个 bignum 库。编写 bignum 处理程序小到足以适合计算机科学任务,但仍然有足够的陷阱使其成为一项不平凡的任务。他的解决方案是使用 Python 库生成测试数据来验证他的 bignum 库。

          您应该可以获取其他 bignum 库。

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

          【讨论】:

            【解决方案8】:

            事实上,您在使用某些 biginteger 库时遇到问题并不意味着这是一种不好的方法。

            使用 long long 绝对是一种不好的方法。

            正如其他人所说,已经使用 biginteger 库可能是一种好方法,但您必须发布更多关于您如何使用提到的库的详细信息,以便我们能够帮助您解决这些错误。

            【讨论】:

              【解决方案9】:

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

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

              【讨论】:

                【解决方案10】:

                如果您没有将 RSA 用作学校作业或其他东西,那么我建议您查看 crypto++ 库 http://www.cryptopp.com

                糟糕地实现加密技术就是这么容易。

                【讨论】:

                  【解决方案11】:

                  使用LibTomCrypt 库满足我的加密需求,我取得了很大的成功。它快速、精简且便携。它可以为你做你的 RSA,或者如果你想只处理数学。

                  【讨论】:

                    【解决方案12】:

                    Openssl 还有一个Bignum 可以使用。我已经使用它并且效果很好。如果需要,可以轻松地用 C++ 或 Objective-C 等 oo 语言进行封装。

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

                    另外,如果您不知道,要找到 x^y % z 形式的方程的答案,请查找一种称为模幂运算的算法。大多数加密或 bignum 库都有专门用于此计算的函数。

                    【讨论】:

                      【解决方案13】:

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

                      【讨论】:

                        【解决方案14】:

                        这是我的方法,它结合了使用平方和模幂的快速求幂,从而减少了所需的空间。

                        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); 
                              }
                          }
                        }
                        

                        【讨论】:

                          【解决方案15】:

                          要确保 RSA 实施的安全,不仅仅是大数字。一个简单的 RSA 实现往往会通过侧通道泄漏私人信息,尤其是时间(简单来说:计算时间取决于处理的数据,这允许攻击者恢复一些,可能是全部的私钥位)。良好的 RSA 实施会实施对策。

                          此外,除了模幂运算之外,还有整个填充业务,这在概念上并不难,但与所有 I/O 和解析代码一样,存在细微错误的空间。最容易写的代码是别人已经写过的代码。

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

                          总结一下:您可以从大整数构建符合 RSA 的实现,但这比通常看起来更难以正确执行,所以我的建议是使用现有的 RSA实施。

                          【讨论】:

                            猜你喜欢
                            • 1970-01-01
                            • 2013-05-30
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2012-07-03
                            • 1970-01-01
                            • 2010-10-31
                            • 2013-08-05
                            相关资源
                            最近更新 更多