Initialization Vector

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

An Initialization Vector or IV is an input to a cryptographic algorithm used to provide the initial state. The IV is part of an algorithm's security parameters, including key and other state. The IV is typically random or pseudorandom, but sometimes an IV only needs to be unpredictable or unique.

Initialization Vectors are usually considered public information, but they can be kept secret. The IV used to create the ciphertext should be included in a mac of the ciphertext. Also see Authenticated Encryption.

A Nonce is an IV that is guaranteed to be unique. It is usually implemented as a persistent counter. Also see CTR mode.

Crypto++ provides the SimpleKeyingInterface class and several class methods to determine the IV requirements. The functions include IVSize, DefaultIVLength, MinIVLength, MaxIVLength, IVRequirement, CanUseRandomIVs, anUsePredictableIVs, and CanUseStructuredIVs.

To set a new IV on a keyed cipher use Resynchronize. To generate a new IV call GetNextIV. When using GetNextIV, each class can implement a different way to generate an IV based on IVRequirement.


IVRequirement is part of SimpleKeyingInterface. It is used to determine what kind of IV is needed to key an algorithm. The values returned by IVRequirement is an enumeration and listed below.

IV_Requirement values
Value Meaning
UNIQUE_IV The IV must be unique.
RANDOM_IV The IV must be random and possibly predictable.
UNPREDICTABLE_RANDOM_IV The IV must be random and unpredictable.
INTERNALLY_GENERATED_IV The IV is set by the object.
NOT_RESYNCHRONIZABLE The object does not use an IV.

IV Generation

You can use GetNextIV to generate an IV using code similar to below. The buffer size must be at least IVSize in length. The cipher class must implement SimpleKeyingInterface. The SecByteBlock is used for secure storage. The AutoSeededRandomPool is a random number generator.

AES::Encryption enc;
SecByteBlock key(enc.DefaultKeyLength()), iv(enc.IVSize());

AutoSeededRandomPool prng;
prng.GenerateBlock(key, key.size());
enc.GetNextIV(prng, iv);

enc.SetKeyWithIV(key, key.size(), iv);

If you want an UNPREDICTABLE_RANDOM_IV then you can use the AutoSeededRandomPool directly as shown below.

AutoSeededRandomPool prng;
prng.GenerateBlock(iv, iv.size());

Authenticated Encryption

Authenticated Encryption provides authenticity assurances over messages. If your application uses an IV, then the IV should be included in the MAC calculation over the ciphertext. That is, the MAC should be calculated as [math]\displaystyle{ mac = Mac_k(iv || ciphertext) }[/math], where [math]\displaystyle{ ciphertext }[/math] is the result of an encryption operation. Then send the 3-tuple [math]\displaystyle{ (iv, ciphertext, mac) }[/math] to the other party.