Friday, May 08, 2015

[asoxdypt] CTR mode

Different ways to do Counter Mode with a block cipher like AES:

  1. Use a password-based key derivation function to transform a password into a key, using the empty string as salt if the PBKDF requires a salt.  Use the key to encrypt with AES counter blocks of values 0, 1,... yielding a pseudorandom stream.  XOR the stream with the plaintext to yield ciphertext.
  2. Use a PBKDF to transform a password and salt into a key.
  3. Instead of initializing the counter at 0, start with a nonce phrase (unique message identifier), hash it to yield a 64-bit nonce, which becomes the upper 64 bits of the counter blocks.  The lower 64 bits are a counter starting at 0.  This has the disadvantage that there is high probability of collision among 2^32 messages.  We leave unstated what to do after 2^64 blocks have been consumed.
  4. Hash the nonce phrase to yield the entire 128-bit initial counter.  Succeeding blocks increment the counter from that value.  The probability of collisions seems messy to calculate, though probably better than the previous.
  5. Instead of AES (which has a 128-bit block size), use a cipher with a larger block size. This allows larger nonces and counters.  Some ciphers with larger block sizes: original Rijndael, SHACAL-2, Threefish. XSalsa20 permits a 192-bit nonce.
  6. Hash the nonce phrase into a 128-bit key.  Use that key to encrypt "secondary" counter blocks of values 0,1,...  Use the ciphertext output of the secondary counter as the counter inputs of the primary AES as before.  In other words, the primary AES has a very complicated "counter increment" function.  This is slower because there are two AES operations per block.
  7. Instead of using AES to generate the primary counters from the nonce and inputs 0,1,2..., use a keyed hash, e.g., HMAC.
  8. Use a PBKDF to transform the password, salt, and nonce phrase into a key, then use the counters 0, 1,...  This requires a PBKDF which can take 3 inputs.
  9. Instead of using the output of AES directly as a random stream, process the stream through a hash to irreversibly alter the values.  This avoids the slight statistical irregularity of blocks in the random stream not repeating: normally we would expect to see collisions among blocks by the time 2^64 blocks have gone by. (Distinguishing attack)  We leave unspecified how much AES output should be consumed by each invocation of the hash.
  10. Instead of XOR to combine the random stream and plaintext, use AES, using the random stream as a source of keys, encrypting exactly one plaintext block per key.  This will be quite slow because AES key setup is expensive..

Are there (good) standards among all of these, so that they can be referred to by name?

No comments :