Primitive Component: PRESENT Scrambler


prim_present is an (unhardened) implementation of the encryption pass of the 64bit PRESENT block cipher. It is a fully unrolled combinational implementation that supports both key lengths specified in the paper (80bit and 128bit). Further, the number of rounds is fully configurable, and the primitive supports a 32bit block cipher flavor which is not specified in the original paper.

It should be noted, however, that reduced-round and/or 32bit versions are not secure and must not be used in a setting where cryptographic cipher strength is required. I.e., this primitive is only intended to be used as a lightweight data scrambling device.


Name type Description
DataWidth int Block size, can be 32 or 64
KeyWidth int Key size, can be 64, 80 or 128
NumRounds int Number of PRESENT rounds, has to be greater than 0

Signal Interfaces

Name In/Out Description
data_i input Plaintext input
key_i input Key input
idx_i input Round index input
data_o output Output of the ciphertext
key_o output Key output after keyschedule update
idx_o output Round index output after keyschedule update

The key_o and idx_o are useful for iterative implementations where the state of the scheduled key, as well as the current round index have to be registered in between rounds. Note that idx_i should be initialized to 1 for encryption mode, and to NumRounds for decryption mode.

Theory of Operations

             |               |
idx_i        |               | idx_o
=====/======>|               |=====/======>
 [5]         |               | [5]
             |    PRESENT    |
key_i        |               | key_o
=====/======>|   DataWidth   |=====/======>
 [KeyWidth]  |   KeyWidth    | [KeyWidth]
             |   NumRounds   |
data_i       |               |  data_o
=====/======>|               |=====/=======>
 [DataWidth] |               |  [DataWidth]
             |               |

The PRESENT module is fully unrolled and combinational, meaning that it does not have any clock, reset or handshaking inputs. The only inputs are the key and the plaintext, and the only output is the ciphertext.

The internal construction follows the the algorithm described in the original paper. The block size is 64bit and the key size can be either 80bit or 128bit, depending on the security requirements. In its original formulation, this cipher has 31 rounds comprised of an XOR operation with a round key, followed by the application of an s-box and a permutation layer, as illustrated for the encryption pass below:

NumRounds = 32;
idx_i = 1;

round_keys = key_derivation(key_i, idx_i);

state = data_i;

for (int i=0; i < NumRounds; i++) {
	state = state ^ round_keys[i];
	state = sbox4_layer(state);
	state = perm_layer(state);

data_o = state ^ round_keys[NumRounds-1];
key_o  = round_keys[NumRounds-1];
idx_o  = idx_i + NumRounds;

The reduced 32bit block-size variant implemented is non-standard and should only be used for scrambling purposes, since it is not secure. It leverages the same crypto primitives and key derivation functions as the 64bit variant, with the difference that the permutation layer is formulated for 32 instead of 64 elements.