IDEA

From Crypto++ Wiki
Jump to navigation Jump to search
IDEA
Documentation
#include <cryptopp/idea.h>

IDEA is the International Data Encryption Standard by Massey and Lai. The cipher is a 64-bit block cipher which uses 126-bit keys and a 64-bit initialization vector (IV). IDEA is a popular choice in open source projects such as OpenPGP. To license IDEA, visit the patent holder's pages at http://www.media-crypt.com/.

Note: if your project is using encryption alone to secure your data, encryption alone is usually not enough. Please take a moment to read Authenticated Encryption and consider using an algorithm or mode like CCM, GCM, EAX or ChaCha20Poly1305.

Sample Programs

There are three sample programs. The first shows IDEA key and block sizes. The second and third use filters in a pipeline). Pipelining is a high level abstraction and it handles buffering input, buffering output and padding for you.

If you are benchmarking then you may want to visit Benchmarks | Sample Program . It shows you how to use StreamTransformation::ProcessString method to process blocks at a time. Calling a cipher's ProcessString or ProcessBlock eventually call a cipher's ProcessAndXorBlock or AdvancedProcessBlocks, and they are the lowest level API you can use.

The first example dumps the minimum, maximum, and default key lengths used by IDEA.

cout << "key length: " << IDEA::DEFAULT_KEYLENGTH << endl;
cout << "key length (min): " << IDEA::MIN_KEYLENGTH << endl;
cout << "key length (max): " << IDEA::MAX_KEYLENGTH << endl;
cout << "block size: " << IDEA::BLOCKSIZE << endl;

Output from the above snippet produces the following.

key length: 16
key length (min): 16
key length (max): 16
block size: 8

The following program demonstrates CBC encryption using IDEA. The key is declared on the stack using a SecByteBlock to ensure the sensitive material is zeroized. Similar could be used for both plain text and recovered text.

AutoSeededRandomPool prng;

SecByteBlock key(IDEA::DEFAULT_KEYLENGTH);
prng.GenerateBlock(key, key.size());

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

string plain = "CBC Mode Test";
string cipher, encoded, recovered;

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

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

    CBC_Mode< IDEA >::Encryption e;
    e.SetKeyWithIV(key, key.size(), iv);

    // The StreamTransformationFilter adds padding
    //  as required. ECB and CBC Mode must be padded
    //  to the block size of the cipher.
    StringSource(plain, true, 
        new StreamTransformationFilter(e,
            new StringSink(cipher)
        ) // StreamTransformationFilter
    ); // StringSource
}
catch(const CryptoPP::Exception& e)
{
    cerr << e.what() << endl;
    exit(1);
}

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

// Pretty print
StringSource(cipher, true,
    new HexEncoder(
        new StringSink(encoded)
    ) // HexEncoder
); // StringSource

cout << "cipher text: " << encoded << endl;

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

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

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

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

A typical output is shown below. Note that each run will produce different results because the key and initialization vector are randomly generated.

$ ./Driver.exe
key: 4EBD7428913EA57705EAB5182F8767BA
iv: ED45E447DF547332
plain text: CBC Mode Test
cipher text: F41CA8D3566CB9B94C9B7508BB6AA0B0
recovered text: CBC Mode Test

By switching to EAX mode, authenticity assurances can placed on the cipher text for nearly no programming costs. Below the StreamTransformationFilter was replaced by AuthenticatedEncryptionFilter and AuthenticatedDecryptionFilter.

EAX< IDEA >::Encryption e;
e.SetKeyWithIV(key, key.size(), iv);

StringSource(plain, true, 
    new AuthenticatedEncryptionFilter(e,
        new StringSink(cipher)
    ) // StreamTransformationFilter
); // StringSource

...

EAX< IDEA >::Decryption d;
d.SetKeyWithIV(key, key.size(), iv);

StringSource s(cipher, true, 
    new AuthenticatedDecryptionFilter(d,
        new StringSink(recovered)
    ) // StreamTransformationFilter
); // StringSource

Typical output is as follows. Notice the additional cipher text bytes due to the MAC bytes. See EAX Mode for details.

$ ./Driver.exe
key: 4864D73F3661D9623FA9633ADBE25358
iv: CF6413625C6DA9CF
plain text: EAX Mode Test
cipher text: 5FA114ACE5BEAC891E4AC89C9B97DE8C354F7EAF3F
recovered text: EAX Mode Test

To manually insert bytes into the filter, perform multiple Puts. Though Get is used below, a StringSink could easily be attached and save the administrivia.

const size_t SIZE = 16 * 4;
string plain(SIZE, 0x00);

for(size_t i = 0; i < plain.size(); i++)
    plain[i] = 'A' + (i%26);
...

CBC_Mode < IDEA >::Encryption encryption(key, sizeof(key), iv);
StreamTransformationFilter encryptor(encryption, NULL);

for(size_t j = 0; j < plain.size(); j++)
    encryptor.Put((byte)plain[j]);

encryptor.MessageEnd();
size_t ready = encryptor.MaxRetrievable();

string cipher(ready, 0x00);
encryptor.Get((byte*) &cipher[0], cipher.size());

Downloads

IDEA-CBC-Filter.zip - Demonstrates encryption and decryption using IDEA in CBC mode with filters (confidentiality only)

IDEA-CTR-Filter.zip - Demonstrates encryption and decryption using IDEA in CTR mode with filters (confidentiality only)

IDEA-EAX-Filter.zip - Demonstrates encryption and decryption using IDEA in EAX mode with filters (confidentiality and authenticity)