2017-02-22 1 views
0

Ich möchte XOR-Operation in AES vor und nach der Verschlüsselung in AES (wie DESX) mit neuen Schlüsseln durchführen. Die XOR-Operation benötigt jedoch zu viel Zeit.Wie kann ich XOR-Operationen in Crypto ++ durchführen?

Wie kann ich die XOR-Betriebszeit reduzieren?

Hier ist mein Code:

string XOR(string value, string key) 
{ 
    string retval(value); 

    short unsigned int klen=key.length(); 
    short unsigned int vlen=value.length(); 
    short unsigned int k=0; 
    short unsigned int v=0; 

    for(v;v<vlen;v++) 
    { 
     retval[v]=value[v]^key[k]; 
     k=(++k<klen?k:0); 
    } 

    return retval; 
} 

int main(int argc, char* argv[]) 
{ 
    AutoSeededRandomPool prng; 

    byte key1[AES::DEFAULT_KEYLENGTH]; 
    prng.GenerateBlock(key1, sizeof(key1)); 

    byte key[AES::DEFAULT_KEYLENGTH]; 
    prng.GenerateBlock(key, sizeof(key)); 

    byte key2[AES::DEFAULT_KEYLENGTH]; 
    prng.GenerateBlock(key2, sizeof(key2)); 

    byte iv[AES::BLOCKSIZE]; 
    prng.GenerateBlock(iv, sizeof(iv)); 

    string plain = "AESX CBC Mode Test"; 
    string cipher,encoded, encodediv, encodedkey1, encodedkey, 
    encodedkey2, recovered, prerecovered, postrecovered, 
    prewhiten, postwhiten; 

    // Pretty print key1 
    StringSource(key1, sizeof(key1), true, 
     new HexEncoder(
      new StringSink(encodedkey1) 
     ) // HexEncoder 
    ); // StringSource 
    cout << "key1: " << encodedkey1 << endl; 

    // Pretty print iv 
    StringSource(iv, sizeof(iv), true, 
     new HexEncoder(
      new StringSink(encodediv) 
     ) // HexEncoder 
    ); // StringSource 
    cout << "iv: " << encodediv << endl; 

    // Pretty print key 
    StringSource(key, sizeof(key), true, 
     new HexEncoder(
      new StringSink(encodedkey) 
     ) // HexEncoder 
    ); // StringSource 
    cout << "key: " << encodedkey << endl; 

    // Pretty print key2 
    StringSource(key2, sizeof(key2), true, 
     new HexEncoder(
      new StringSink(encodedkey2) 
     ) // HexEncoder 
    ); // StringSource 
    cout << "key2: " << encodedkey2 << endl; 

    cout << "plain text: " << plain << endl; 

    prewhiten = XOR(plain, encodedkey1); 

    try 
    { 
     cout << "pre whiten text: " << prewhiten << endl; 

     CBC_Mode<AES>::Encryption e; 
     e.SetKeyWithIV(key, sizeof(key), iv); 

     // The StreamTransformationFilter removes 
     // padding as required. 
     StringSource s(prewhiten, true, 
      new StreamTransformationFilter(e, 
       new StringSink(cipher) 
      ) // StreamTransformationFilter 
     ); // StringSource 

    } 
    catch(const CryptoPP::Exception& e) 
    { 
     cerr << e.what() << endl; 
     exit(1); 
    } 

    /*********************************\ 
    \*********************************/ 

    // Pretty print 
    encoded.clear(); 
    StringSource(cipher, true, 
     new HexEncoder(
      new StringSink(encoded) 
     ) // HexEncoder 
    ); // StringSource 
    cout << "cipher text: " << encoded << endl; 

    postwhiten = XOR(encoded, encodedkey2); 

    cout << "post whiten text: " << postwhiten << endl; 

    //decryption 

    prerecovered = XOR(postwhiten, encodedkey2); 

    encoded.clear(); 
    StringSource(prerecovered, true, 
     new HexEncoder(
      new StringSink(encoded) 
     ) // HexEncoder 
    ); // StringSource 

    cout << "pre recovered text: " << encoded << endl; 

    try 
    { 
     CBC_Mode<AES>::Decryption d; 
     d.SetKeyWithIV(key, sizeof(key), iv); 

     // The StreamTransformationFilter removes 
     // padding as required. 
     StringSource s(prerecovered, true, 
      new HexDecoder(
       new StreamTransformationFilter(d, 
        new StringSink(recovered) 
       ) // StreamTransformationFilter 
      )//HexDecoder 
     ); // StringSource 

     cout << "recovered text: " << recovered << endl; 
    } 
    catch(const CryptoPP::Exception& e) 
    { 
     cerr << e.what() << endl; 
     exit(1); 
    } 

    postrecovered = XOR(recovered, encodedkey1); 

    cout << "post recovered text: " << postrecovered << endl; 

    return 0; 
} 

Jede Hilfe würde geschätzt.

+3

XOR benötigt viel weniger Zeit als das Lesen oder Schreiben eines Wortes aus dem Speicher. – stark

+0

'k = (++ k stark

Antwort

0

How can I do XOR operation in Crypto++?

Es gibt zwei Möglichkeiten, die Bibliothek zum Ausführen eines XOR zu verwenden. Zuerst gibt es zwei Funktionen xorbuf in misc.h. Die erste Implementierung ist unten gezeigt, und sie verwendet einen einzelnen in/out-Puffer mit einer Maske:

void xorbuf(byte *buf, const byte *mask, size_t count) 
{ 
    size_t i=0; 
    if (IsAligned<word32>(buf) && IsAligned<word32>(mask)) 
    { 
     if (!CRYPTOPP_BOOL_SLOW_WORD64 && IsAligned<word64>(buf) && IsAligned<word64>(mask)) 
     { 
      for (i=0; i<count/8; i++) 
       ((word64*)(void*)buf)[i] ^= ((word64*)(void*)mask)[i]; 
      count -= 8*i; 
      if (!count) 
       return; 
      buf += 8*i; 
      mask += 8*i; 
     } 

     for (i=0; i<count/4; i++) 
      ((word32*)(void*)buf)[i] ^= ((word32*)(void*)mask)[i]; 
     count -= 4*i; 
     if (!count) 
      return; 
     buf += 4*i; 
     mask += 4*i; 
    } 

    for (i=0; i<count; i++) 
     buf[i] ^= mask[i]; 
} 

Es gibt einen zweiten xorbuf(byte *output, const byte *input, const byte *mask, size_t count) die in und aus Puffern mit einer Maske getrennten verwendet.

Der zweite Weg zu XOR ist ein ArrayXorSink von filters.h. Intern ruft ArrayXorSinkxorbuf für Sie auf. Sie würden dies verwenden, bevorzugen Sie pipelines.

size_t ArrayXorSink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) 
{ 
    // Avoid passing NULL pointer to xorbuf 
    size_t copied = 0; 
    if (m_buf && begin) 
    { 
     copied = STDMIN(length, SaturatingSubtract(m_size, m_total)); 
     xorbuf(m_buf+m_total, begin, copied); 
    } 
    m_total += copied; 
    return length - copied; 
} 

string XOR(string value, string key) 
{ 
    string retval(value); 

    short unsigned int klen=key.length(); 
    short unsigned int vlen=value.length(); 
    short unsigned int k=0; 
    short unsigned int v=0; 

    for(v;v<vlen;v++) 
    { 
     retval[v]=value[v]^key[k]; 
     k=(++k<klen?k:0); 
    } 

    return retval; 
} 

Dazu Sie so etwas wie das folgende tun könnte. Es fragt den Compiler inline die Funktion, und es übergibt die value und key durch konstanten Verweis, um die Kopien zu vermeiden.

inline string XOR(const string& value, const string& key) 
{ 
    ASSERT(key.length() == value.length()); 

    string retval(value); 
    xorbuf(&retval[0], &key[0], retval.length()); 
    return retval; 
} 

Der Trick ist, Sie 0, um die Adresse des Elements zu nehmen, die nicht konstante Zeiger zu erhalten und mögliche undefinierte Verhalten zu vermeiden. Möglicherweise müssen Sie zu einem byte* umwandeln.


How can I reduce the XOR operation time?

Sie wollen wahrscheinlich ein Operand größer, dass 1-Byte, wenn sein möglich verwenden. Die Bibliothek xorbuf verwendet word32 und word64, wenn verfügbar.

Wenn Sie AVX haben, können Sie auch Puffer mit bis zu 512 Bit verwenden. Wenn Sie Ihre Puffer ausgerichtet halten, wird GCC versuchen, die größeren Puffer bei -O3 und höher zu verwenden. -O3 ist von Bedeutung, weil GCC dann eine aggressive Vektorisierung startet und die Funktionen von AVX und AVX2 nutzt.

Die Crypto ++ Bibliothek ertrug vor einigen Jahren eine nicht-triviale Menge an Schmerzen, weil ihre Puffer nicht so ausgerichtet waren, wie GCC erwartet wurde, und sie verursachte SEGFAULT -O3 und darüber. Siehe beispielsweise Crash on Cygwin i386 with -O3.

Das Ausrichtungsproblem war nicht auf Cygwin beschränkt; Cygwin demonstrierte es zufällig. Das Problem tauchte gelegentlich unter anderen Plattformen und CPUs auf, wie ARM, als NEON aktiviert wurde. Wir glauben, dass alle Probleme geklärt sind.

+0

Danke für deine Antwort jww.Gibt es eine Möglichkeit, Zeichenketten in crypto ++ zu xorieren? Nach der Verschlüsselung ist das Ergebnis string. –

+0

@ T.Rifle - benutze 'xorbuf' wie oben beschrieben. – jww

+0

jww - Ich bin sehr neu in C++, so leid für die Frage. Wie man ein Byte wirft? Es gibt einen Fehler: ungültige Konvertierung von 'char *' in 'byte * {aka unsigned char *}' [-fpermissiv] –

Verwandte Themen