From d14739644394986cb584acb45ed9b214dff1c501 Mon Sep 17 00:00:00 2001 From: Kévin Le Gouguec Date: Tue, 27 Nov 2018 08:58:46 +0100 Subject: Mise en commun du code TBC et ΘCB3 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Il ne devrait pas varier selon les paramètres AFAICT. --- src/cipher.c | 170 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 170 insertions(+) create mode 100644 src/cipher.c (limited to 'src/cipher.c') diff --git a/src/cipher.c b/src/cipher.c new file mode 100644 index 0000000..7f1152a --- /dev/null +++ b/src/cipher.c @@ -0,0 +1,170 @@ +#include +#include + +#include "cipher.h" +#include "constants.h" +#include "parameters.h" +#include "tweakey.h" + + +enum permutation +{ + PERMUTATION_ENCRYPTION = 0, + PERMUTATION_DECRYPTION = 1, + PERMUTATION_NONE +}; + +typedef enum permutation permutation; + +const uint8_t PERMUTATIONS[2][BLOCK_BYTES] = { + /* PI(i) */ + [0] = { 13, 9, 14, 8, 10, 11, 12, 15, + 4, 5, 3, 1, 2, 6, 0, 7 }, + /* PI^-1(i) */ + [1] = { 14, 11, 12, 10, 8, 9, 13, 15, + 3, 1, 4, 5, 6, 0, 2, 7 } +}; + + +struct cipher_state +{ + uint8_t X[BLOCK_BYTES]; +}; + + +typedef struct cipher_state cipher_state; + + +static void _state_init(cipher_state *X, const uint8_t message[BLOCK_BYTES]) +{ + memcpy(X->X, message, sizeof(X->X)); +} + + +static void _compute_round_tweakeys( + const uint8_t key[KEY_BYTES], + const uint8_t tweak[TWEAK_BYTES], + uint8_t RTK[ROUNDS][ROUND_TWEAKEY_BYTES] +) +{ + tweakey_state TK; + tweakey_state_init(&TK, key, tweak); + tweakey_state_extract(&TK, RTK[0], 0); + + for (uint8_t i=1; iX[j] ^ RTK[j]; + } + + for (size_t j=0; jX[dest_j] ^= F[j]; + } +} + +static void _linear_layer(cipher_state *X) +{ + X->X[15] ^= X->X[1]; + X->X[15] ^= X->X[2]; + X->X[15] ^= X->X[3]; + X->X[15] ^= X->X[4]; + X->X[15] ^= X->X[5]; + X->X[15] ^= X->X[6]; + X->X[15] ^= X->X[7]; + + X->X[14] ^= X->X[7]; + X->X[13] ^= X->X[7]; + X->X[12] ^= X->X[7]; + X->X[11] ^= X->X[7]; + X->X[10] ^= X->X[7]; + X->X[9] ^= X->X[7]; +} + +static void _permutation_layer(cipher_state *X, permutation p) +{ + if (p == PERMUTATION_NONE) + { + return; + } + + uint8_t X_old[BLOCK_BYTES]; + memcpy(X_old, X, sizeof(X_old)); + + const uint8_t *pi = PERMUTATIONS[p]; + + for (size_t j=0; jX[pi[j]] = X_old[j]; + } +} + +static void _one_round_egfn(cipher_state *X, const uint8_t RTK[ROUND_TWEAKEY_BYTES], permutation p) +{ + _nonlinear_layer(X, RTK); + _linear_layer(X); + _permutation_layer(X, p); +} + + +void lilliput_tbc_encrypt( + const uint8_t key[KEY_BYTES], + const uint8_t tweak[TWEAK_BYTES], + const uint8_t message[BLOCK_BYTES], + uint8_t ciphertext[BLOCK_BYTES] +) +{ + cipher_state X; + _state_init(&X, message); + + uint8_t RTK[ROUNDS][ROUND_TWEAKEY_BYTES]; + _compute_round_tweakeys(key, tweak, RTK); + + for (uint8_t i=0; i