web-dev-qa-db-ja.com

非常に大きな整数を処理するC ++

暗号化/復号化にRSAアルゴリズムを使用しています。ファイルを復号化するには、かなり大きな値を処理する必要があります。より具体的には、次のようなもの

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

いまや、それが実際に行われている唯一の計算です。 Matt McCutchenのBigInteger Libraryを使用してみましたが、リンク中に次のような多くのコンパイラエラーが発生します。

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アルゴリズムから出てくる非常に大きな整数を処理するための最良の方法は何だろうと思いました。

変数をdouble longとして宣言する可能性があると聞いたので、...

long long decryptedCharacter;

しかし、格納できる整数の大きさが正確にわかりません。


たとえば、開発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;
}

その後、それらのエラーが発生します。

デレク、BigIntegerLibrary.hhファイルを含めることにより、コンパイラーが使用する必要のあるすべてのファイルを調べてコンパイルすると思いました。

リンクエラーを解決するには、上記のプログラムをどのようにコンパイルする必要がありますか?

23
Tomek

メタ答え:

Bigint演算にライブラリを使用している場合は、RSA実装全体にライブラリを使用していない理由を自問してください。

たとえば、 http://www.gnu.org/software/gnu-crypto/ には、RSA実装が含まれています。 GMPと同じライセンスです。

ただし、それらには http://mattmccutchen.net/bigint/ と同じライセンスがありません。これは、米国のパブリックドメインに配置されているように見えます。

23
Steve Jessop

Tomek、BigIntegerコードに正しくリンクしていないようです。新しいライブラリを探すのではなく、この問題を解決する必要があると思います。私はソースを見て、BigInteger::BigInteger(int)が最も明確に定義されています。簡単に一目でわかるように、他の人も同じです。

発生しているリンクエラーは、BigIntegerソースのコンパイルを怠るか、リンクしたときに結果のオブジェクトファイルを含めることを怠っていることを意味します。 BigIntegerソースは「cpp」ではなく「cc」拡張子を使用するため、これらのファイルもコンパイルしていることを確認してください。

13
Derek Park

gmp を使用することをお勧めします。任意に長い整数を処理でき、適切なC++バインディングがあります。

現在のハードウェア/ソフトウェアでのafaik long longは64ビットであるため、unsignedは(2 ** 64)-1 == 18446744073709551615までの数値を処理できます。これは、RSAで処理する必要がある数値よりもかなり小さいです。

12
TFKyle

安全なRSA実装には、単なる大きな数だけではありません。単純なRSA実装は、サイドチャネル、特にタイミングを通じて秘密情報を漏らす傾向があります(簡単に言うと、計算時間は処理されたデータに依存するため、攻撃者は秘密鍵ビットの一部またはすべてを回復できます)。適切なRSA実装は、対策を実装します。

また、モジュラー指数を超えて、概念的に難しくないパディングビジネス全体がありますが、すべてのI/Oと解析コードと同様に、微妙なバグの余地があります。書くのが最も簡単なコードは、他の誰かがすでに書いたコードです。

別のポイントは、RSAコードを起動して実行すると、拡張機能やその他の状況を想像し始めることができるということです。 「使用したい秘密鍵がRAMではなくスマートカードにない場合はどうなりますか?」。既存の一部のRSA実装は、実際にはそれを処理できるAPIです。Microsoftの世界では、 lookup CryptoAPI 、これはWindowsに統合されています。また、Firefoxブラウザーが使用する [〜#〜] nss [〜#〜] を参照することもできます。 SSL。

まとめると、あなたはcan大きな整数からRSA準拠の実装を構築できますが、これは通常の見た目よりも正しく行うのが難しいので、私のアドバイスは、既存のRSA実装を使用することです。

3
Thomas Pornin

これが私のアプローチです。これは、必要なスペースを削減する2乗+モジュラー指数を使用した高速指数を組み合わせています。

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

RSAを学校の課題などとして実装していない場合は、crypto ++ライブラリを確認することをお勧めします http://www.cryptopp.com

暗号をうまく実装するのはとても簡単です。

3
tfinniga

Long longのサイズを確認するには、次を試してください。

#include <stdio.h>

int main(void) {
    printf("%d\n", sizeof(long long));

    return 0;
}

私のマシンでは、8を返します。これは、2 ^ 64の値を格納できる8バイトを意味します。

3
Jeremy Ruten

RSAの場合、bignumライブラリが必要です。数値は長すぎて64ビットlong longに収まりません。私はかつて大学に同僚がいて、自分のbignumライブラリの構築を含め、RSAを実装するための割り当てを受けました。

たまたま、Pythonにはbignumライブラリーがあります。bignumハンドラーの作成は、コンピューターサイエンスの割り当てに適合するには十分小さいですが、それでも、それを簡単なタスクにするのに十分な落とし穴があります。彼の解決策はPythonライブラリを使用して、彼のbignumライブラリを検証するためのテストデータを生成します。

他のbignumライブラリを取得できるはずです。

または、Python=でプロトタイプを実装してみて、十分に高速かどうかを確認します。

[〜#〜] gmp [〜#〜] ライブラリを試してみます。これは堅牢で、十分にテストされており、このタイプのコードで一般的に使用されています。

2
Greg Hewgill

Opensslには、使用可能な Bignum タイプもあります。私はそれを使いました、そしてそれはうまくいきます。必要に応じて、C++やObjective-Cなどのoo言語で簡単にラップできます。

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

また、ご存じない場合は、この形式x ^ y%zの方程式の答えを見つけるために、指数剰余と呼ばれるアルゴリズムを調べてください。ほとんどの暗号ライブラリまたはbignumライブラリには、この計算専用の関数があります。

2
robottobor

Long intは通常64ビットですが、これほど大きな整数を処理するにはおそらく十分ではありません。おそらく、なんらかのbigintライブラリが必要になります。

スタックオーバーフローの この質問 も参照してください

1
Adam Pierce

コンパイラのドキュメントを確認してください。一部のコンパイラには、サイズを指定する__int64などの型が定義されています。多分あなたはそれらのいくつかを利用可能にしたでしょう。

1
Scott Langham

注:__int64およびlong longは非標準の拡張機能です。どちらもすべてのC++コンパイラでサポートされているとは限りません。 C++はC89に基づいています(98で登場したため、C99に基づくことはできませんでした)

(CはC99以降「long long」をサポートしています)

ちなみに、64ビット整数はこの問題を解決するとは思わない。

1
David Ameller

私は暗号化のニーズに LibTomCrypt ライブラリを使用して多くの成功を収めてきました。高速、無駄のない、ポータブルです。それはあなたのためにあなたのRSAをすることができます、またはあなたが望むなら単に数学を処理することができます。

1
adum

Bigintegerライブラリの使用に問題があるという事実は、悪いアプローチであることを意味しません。

Long longを使用することは、明らかに悪いアプローチです。

他の人がすでにbigintegerライブラリを使用することはおそらく良いアプローチであると述べましたが、これらのエラーを解決するために私たちが言及できるライブラリを使用する方法について、より詳細に投稿する必要があります。

0
Maciej Hehl

RSA実装を作成するときにGMPを使用しました。

0
Vaibhav Bajpai