it-swarm.com.de

C++ - Verarbeitung sehr großer Ganzzahlen

Ich verwende den RSA-Algorithmus zur Verschlüsselung/Entschlüsselung, und um die Dateien zu entschlüsseln, müssen Sie mit ziemlich großen Werten umgehen. Genauer gesagt, Dinge wie 

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

Nun, das sind wirklich die einzigen Berechnungen, die schlecht gemacht werden. Ich habe versucht, die BigInteger-Bibliothek von Matt McCutchen zu verwenden, aber ich erhalte beim Compilieren eine Menge Compiler-Fehler, wie zum Beispiel:

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

Ich wunderte mich also, wie man am besten mit den wirklich großen Zahlen umgehen kann, die aus dem RSA-Algorithmus stammen.

Ich habe gehört, dass es eine Möglichkeit wäre, Ihre Variablen als doppelt lang zu deklarieren, also ...

long long decryptedCharacter;

aber ich bin mir nicht sicher, wie groß eine ganze Zahl sein kann, die gespeichert werden kann.


Zum Beispiel versuche ich folgendes Programm mit dev C++ zu kompilieren und auszuführen:

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

dann bekomme ich diese fehler.

Derek, ich dachte, durch die Einbindung der BigIntegerLibrary.hh-Datei würde der Compiler alle notwendigen Dateien durchlaufen und kompilieren.

Wie soll ich das Programm oben versuchen und kompilieren, um die Verknüpfungsfehler zu beheben?

20
Tomek

Meta-Antwort:

Wenn Sie eine Bibliothek für die Bigint-Arithmetik verwenden, fragen Sie sich, warum Sie keine Bibliothek für die gesamte RSA-Implementierung verwenden.

Beispielsweise enthält http://www.gnu.org/software/gnu-crypto/ eine RSA-Implementierung. Es hat die gleiche Lizenz wie GMP.

Sie haben jedoch nicht dieselbe Lizenz wie http://mattmccutchen.net/bigint/ , die mir in den USA gemeinfrei erscheint.

23
Steve Jessop

Tomek, das klingt so, als würden Sie nicht richtig mit dem BigInteger-Code verknüpfen. Ich denke, Sie sollten dieses Problem lösen, anstatt nach einer neuen Bibliothek zu suchen. Ich habe mir die Quelle angesehen und BigInteger::BigInteger(int) ist am definitivsten definiert. Ein kurzer Blick zeigt, dass es auch den anderen geht.

Die Link-Fehler, die Sie erhalten, implizieren, dass Sie entweder die BigInteger-Quelle nicht kompilieren oder die resultierenden Objektdateien beim Linken nicht enthalten. Bitte beachten Sie, dass die BigInteger-Quelle die Erweiterung "cc" anstelle von "cpp" verwendet. Stellen Sie also sicher, dass Sie diese Dateien ebenfalls kompilieren.

12
Derek Park

Ich würde vorschlagen, gmp zu verwenden, kann beliebig lange Ints verarbeiten und hat ordentliche C++ - Bindungen.

afaik ist auf aktuelle Hardware/Software-Long-Longs mit 64 Bit ausgelegt, so dass unsignierte Zahlen bis (2 ** 64) -1 = 18446744073709551615 handhaben können.

12
TFKyle

Um die Größe eines langen zu sehen, probieren Sie folgendes:

#include <stdio.h>

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

    return 0;
}

Auf meinem Rechner werden 8 zurückgegeben, also 8 Bytes, die 2 ^ 64 Werte speichern können.

4
Jeremy Ruten

Für die RSA-Implementierung gibt es mehr als nur große Zahlen. Eine einfache RSA-Implementierung tendiert dazu, private Informationen über Seitenkanäle zu übertragen, insbesondere das Timing (mit einfachen Worten: Die Berechnungszeit hängt von den verarbeiteten Daten ab, wodurch ein Angreifer einige, möglicherweise alle der privaten Schlüsselbits wiederherstellen kann). Gute RSA-Implementierungen implementieren Gegenmaßnahmen.

Neben der modularen Exponentiation gibt es auch das gesamte Polsterungsgeschäft, das nicht konzeptionell schwer ist, sondern wie alle E/A- und Analyse-Codes Platz für subtile Fehler bietet. Der einfachste Code zum Schreiben ist der Code, der bereits von jemand anderem geschrieben wurde.

Ein weiterer Punkt ist, dass Sie, sobald Sie Ihren RSA-Code eingerichtet haben, Erweiterungen und andere Situationen in Betracht ziehen können, z. "Was ist, wenn der private Schlüssel, den ich verwenden möchte, nicht in RAM sondern in einer Smartcard liegt?" Einige vorhandene RSA-Implementierungen sind eigentlich eine API, die das verarbeiten kann. In der Microsoft-Welt möchten Sie nach CryptoAPI suchen, die in Windows integriert ist. Vielleicht möchten Sie auch nach NSS schauen, was der Firefox-Browser für SSL verwendet.

Zusammenfassend: Sie Can kann eine RSA-kompatible Implementierung aus großen Ganzzahlen aufbauen, dies ist jedoch schwieriger als das, was normalerweise der Fall ist. Daher empfehle ich eine vorhandene RSA-Implementierung.

3
Thomas Pornin

Hier ist mein Ansatz: Er kombiniert schnelle Exponentiation mit Quadrierung + modulare Exponentiation, wodurch der Platzbedarf reduziert wird.

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

Wenn Sie RSA nicht als Schulaufgabe oder ähnliches implementieren, empfiehlt sich ein Blick auf die Crypto ++ - Bibliothek http://www.cryptopp.com

Es ist so einfach, Krypto-Sachen schlecht zu implementieren.

3
tfinniga

Für RSA benötigen Sie eine Bignum-Bibliothek. Die Zahlen sind viel zu groß, um in eine 64-Bit-Länge zu passen. Ich hatte einmal einen Kollegen an der Universität, der einen Auftrag zur Implementierung von RSA erhielt, einschließlich des Baus einer eigenen Bignum-Bibliothek.

Python hat eine Bignum-Bibliothek. Das Schreiben von Bignum-Handlern ist klein genug, um in einen Informatikauftrag zu passen, hat aber immer noch genug Stichwörter, um es zu einer nicht trivialen Aufgabe zu machen. Seine Lösung bestand darin, die Python-Bibliothek zu verwenden, um Testdaten zur Validierung seiner Bignum-Bibliothek zu generieren.

Sie sollten andere Bignum-Bibliotheken erhalten können.

Alternativ können Sie einen Prototyp in Python implementieren und prüfen, ob er schnell genug ist.

Ich würde die Bibliothek GMP ausprobieren - sie ist robust, gut getestet und wird häufig für diese Art von Code verwendet.

2
Greg Hewgill

Openssl hat auch einen Bignum - Typ, den Sie verwenden können. Ich habe es benutzt und es funktioniert gut. Einfach in eine Oo-Sprache wie C++ oder Objective-C zu packen, wenn Sie möchten.

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

Falls Sie nicht wussten, dass Sie die Antwort auf die Gleichung dieser Form x ^ y% z finden wollen, suchen Sie nach einem Algorithmus, der als modulare Exponentiation bezeichnet wird. Die meisten Krypto- oder Bignum-Bibliotheken werden speziell für diese Berechnung eine Funktion haben.

2
robottobor

Ein Long Int ist in der Regel 64 Bit, was wahrscheinlich nicht ausreicht, um eine so große Ganzzahl zu handhaben. Sie werden wahrscheinlich eine Bigint-Bibliothek benötigen.

Siehe auch diese Frage über Stack Overflow

1
Adam Pierce

Überprüfen Sie Ihre Compiler-Dokumentation. Einige Compiler haben Typen wie __int64 definiert, die ihre Größe angeben. Vielleicht haben Sie einige davon zur Verfügung.

1
Scott Langham

Nur zu beachten: __int64 und long long sind nicht standardmäßige Erweiterungen. Keiner von beiden wird garantiert von allen C++ - Compilern unterstützt. C++ basiert auf C89 (es wurde 98 herausgegeben, daher konnte es nicht auf C99 basieren)

(C hat Unterstützung für "long" seit C99)

Ich glaube übrigens nicht, dass 64-Bit-Integer dieses Problem lösen.

1
David Ameller

Ich hatte viel Erfolg mit der Bibliothek LibTomCrypt für meine Krypto-Anforderungen. Es ist schnell, schlank und tragbar. Es kann Ihre RSA für Sie erledigen oder nur die Mathematik handhaben, wenn Sie möchten.

1
adum

Die Tatsache, dass Sie ein Problem mit der Verwendung einer Biginteger-Bibliothek haben, bedeutet nicht, dass dies ein schlechter Ansatz ist. 

Mit long long ist definitiv ein schlechter Ansatz. 

Wie andere bereits sagten, ist die Verwendung einer Biginteger-Bibliothek wahrscheinlich ein guter Ansatz, aber Sie müssen mehr Details zu haw, die Sie erwähnen, verwenden, damit wir Ihnen helfen können, diese Fehler zu beheben.

0
Maciej Hehl

Ich habe GMP verwendet, als ich die RSA-Implementierung geschrieben habe.

0
Vaibhav Bajpai