[英]C++ handling very large integers
我使用 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
文件,編譯器將遍歷並編譯它將使用的所有必要文件。
我應該如何嘗試編譯上面的程序以解決鏈接錯誤?
元回答:
如果您正在使用bigint算法的庫,那么問問自己為什么不使用庫來實現整個RSA。
例如, http://www.gnu.org/software/gnu-crypto/包含RSA實現。 它與GMP具有相同的許可證。
但是,他們沒有與http://mattmccutchen.net/bigint/相同的許可證,這在我看來已被置於美國的公共領域。
我建議使用gmp ,它可以處理任意長的int並具有不錯的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,包括建立自己的bignum圖書館。
碰巧,Python有一個bignum庫。 編寫bignum處理程序足夠小,可以適應計算機科學任務,但仍然有足夠的陷阱使其成為一項非常重要的任務。 他的解決方案是使用Python庫生成測試數據以驗證他的bignum庫。
你應該能夠得到其他的bignum圖書館。
或者,嘗試在Python中實現原型並查看它是否足夠快。
如果您沒有將RSA作為學校作業或其他東西實施,那么我建議您查看加密++庫http://www.cryptopp.com
實現加密密碼非常容易。
這是我的方法,它結合使用平方+模塊指數的快速指數,減少了所需的空間。
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);
}
}
}
確保RSA實施不僅僅是大數字。 簡單的RSA實現往往會通過輔助通道泄漏私人信息,尤其是時間(簡單來說:計算時間取決於處理后的數據,這允許攻擊者恢復一些,可能全部的私鑰位)。 良好的RSA實施實施對策。
此外,除了模冪運算之外,還有整個填充業務,這在概念上並不困難,但是,因為所有I / O和解析代碼都有微妙的錯誤空間。 最容易編寫的代碼是已經由其他人編寫的代碼。
另一點是,一旦你的RSA代碼啟動並運行,你就可以開始設想擴展和其他情況,例如“如果我想使用的私鑰不是在RAM而是在智能卡中怎么辦?”。 一些現有的RSA實現實際上是可以處理它的API。 在Microsoft世界中,您希望查找集成在Windows中的CryptoAPI 。 您可能還想查看NSS ,這是Firefox瀏覽器用於SSL的內容。
總結一下:您可以從大整數構建符合RSA的實現,但這比正常情況下更難以正確執行,因此我的建議是使用現有的RSA實現。
我會試用GMP庫 - 它是健壯的,經過良好測試的,並且通常用於這種類型的代碼。
Openssl還有一個可以使用的Bignum類型。 我用過它並且效果很好。 如果你願意,可以用C ++或objective-C等語言輕松包裝。
https://www.openssl.org/docs/crypto/bn.html
此外,如果您不知道,要找到此形式x ^ y%z的等式的答案,請查找稱為模冪運算的算法。 大多數加密或bignum庫將具有專門用於該計算的功能。
long int通常是64位,這可能不足以處理大的整數。 您可能需要某種bigint庫。
另請參閱Stack Overflow上的這個問題
查看編譯器文檔。 某些編譯器具有定義的類型,例如__int64,它們可以為您提供大小。 也許你有一些可用的。
需要注意的是:__ int64和long long是非標准擴展名。 並非所有C ++編譯器都支持這兩種編譯器。 C ++基於C89(它出現在98,所以它不能基於C99)
(C自C99起支持'長期')
順便說一句,我不認為64位整數解決了這個問題。
我使用LibTomCrypt庫為我的加密需求取得了很大的成功。 它快速,精簡,便攜。 它可以為您做RSA,或者只是根據需要處理數學。
事實上,使用某個biginteger庫時遇到問題並不意味着,這是一個糟糕的方法。
使用long long肯定是一種糟糕的方法。
正如其他人所說,已經使用biginteger庫可能是一個很好的方法,但是你必須發布更多關於你使用提到的庫的詳細信息,以便我們能夠幫助你解決這些錯誤。
我在編寫RSA實現時使用了GMP。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.