# Truncating the output of AES-128

I'd like to use the output of a pseudorandom function (PRF) as a one time pad.

I want to use AES-128 (as it's commonly used as a PRF). As we know AES-128 output 128 bits.

Question: Would be secure to truncate the output of AES-128 and get only 32 or 64 bits of it as one time pad to mask some 32 or 64 bits value respectively?

• Why don't you use AES in CTR mode? Which doesn't need a padding? – kelalaka Feb 20 at 15:14
• Or a XOF such as SHAKE256, which doesn't require the seed to be in any particular format – Natanael Feb 20 at 15:48
• @Natanael it seems AES is faster than SHA, look at here, page 11: fc14.ifca.ai/papers/fc14_submission_52.pdf – Ay. Feb 20 at 15:54
• @Ay. SHAKE256 is based on SHA3, not SHA1, and should be much faster than SHA1. Perhaps even KangarooTwelve from the same team for more speed. keccak.team/kangarootwelve.html – Natanael Feb 20 at 16:40
• @Natanael If any of the SHA-3 functions performed better than SHA-1 in a fair comparison (hardware SHA-3 vs. software SHA-1 being unfair), I would be rather surprised. See bench.cr.yp.to/results-hash.html for a large collection of measurements. Heuristically: SHA-3 was engineered to have a much higher security margin than SHA-1, not to run faster; both of them pay the high cost of collision resistance, while AES does not. (But of course AES also invites timing side channels in software, which none of the SHAs do.) – Squeamish Ossifrage Feb 21 at 0:54

What you describe is exactly using AES-CTR to encrypt a 32-bit or 64-bit message. So, yes.

• Even, from 1 bit to 128. – kelalaka Feb 20 at 18:45
• AES-CTR works on any number of bits. Obviously you can't reduce the adversary's probability of correctly guessing what one-bit message was below $1/2$, but that's not AES's fault. – Squeamish Ossifrage Feb 20 at 18:46

AES-128 instantiates a pseudorandom permutation (PRP) (and a PRP is also a PRF). Theoretically, truncating AES-128's output does not weaken its security, which depends only on its key size. Intuitively, an attacker gets less information from, say, a 64-bit output than from a 128-bit output. So, for example, distinguishing the truncated 64-bit output from a random 64-bit string is at least as hard as distinguishing AES-128's 128-bit output from a random 128-bit string.

A true one-time-pad requires a true random number generator to generate the pads. However, let's assume that what you really want to have is a cipher that simulates a one-time-pad. Such a cipher, which creates a key stream is called a stream cipher. So what you want is a stream cipher with limited output, based on AES.

As written in other answers there are known ways of generating a stream cipher from a block cipher. Probably the best known one is counter mode or CTR. There are other modes possible, but note that some of these streaming modes depend on the plaintext and are therefore different from how an OTP is used. So lets focus on counter mode.

Counter mode depends as the name suggests on a counter which is generated starting from an initial counter value. This value is commonly generated from a nonce, which is either deterministically generated or random. If the nonce is indeed unique then you can use AES to generate the key stream, take as many bits you want from it, and then XOR them with the plaintext message of 32 or 64 bit.

The problem occurs if you want to encrypt more 32 or 64 bit values. In that case you need a new nonce, or you would generate a many time pad or Vigenère cipher, which is obviously not secure. You can simply store a random nonce with the encrypted bits, but then you would expand the ciphertext possibly by a large margin compared to the plaintext (depending on the size of the nonce); probably at least by 64 bits.

It may be that you need Format Preserving Encryption (FPE) or a block cipher with small small sized blocks instead. This is deterministic encryption, so identical plaintext will lead to identical ciphertext, leaking information. The advantage is that it doesn't leak any actual bits of the plaintext, like CTR does when it generates the Vigenère cipher / many-time-pad. Depending on the information in the plaintext, the many-time-pad will likely completely compromise security including confidentiality.

Beware that neither of the options given provides integrity / authenticity. This will be particularly hard to achieve anyway if you want to keep the ciphertext near the size of the plaintext. Probably best to use FPE with a few bits set to a checksum to that there is at least a high chance of detecting integrity issues (especially if multiple ciphertext are altered).