#include /* debug */ #include #include /* debug */ #include #include "cipher.h" #include "constants.h" #include "parameters.h" #include "tweakey.h" #include "debug.h" static void _debug_announce_round(FILE* debug, uint8_t i) { if (!debug) return; fprintf(debug, "\n"); fprintf(debug, "One round EGFN round : %"PRIu8"\n", i); fprintf(debug, " State :\n"); } 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]; FILE* debug; }; typedef struct cipher_state cipher_state; static void _state_init(cipher_state *X, const uint8_t message[BLOCK_BYTES], FILE* debug) { memcpy(X->X, message, sizeof(X->X)); X->debug = debug; } 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, NULL); tweakey_state_extract(&TK, RTK[0], 0); for (uint8_t i=1; idebug, " Non Linear Layer :", sizeof(X->X), X->X, 10); debug_dump_buffer(X->debug, " Subtweakey :", ROUND_TWEAKEY_BYTES, RTK, 66); uint8_t F[ROUND_TWEAKEY_BYTES]; for (size_t j=0; jX[j] ^ RTK[j]; } debug_dump_buffer(X->debug, " Variables xored :", sizeof(F), F, 66); for (size_t j=0; jdebug, " Variables sboxed :", sizeof(F), F, 66); for (size_t j=0; j<8; j++) { size_t dest_j = 15-j; X->X[dest_j] ^= F[j]; } debug_dump_buffer(X->debug, " State non linearized :", sizeof(X->X), X->X, 10); } static void _linear_layer(cipher_state *X) { debug_dump_buffer(X->debug, " Linear Layer :", sizeof(X->X), X->X, 10); debug_dump_buffer(X->debug, " State linearized :", sizeof(X->X), X->X, 10); } static void _permutation_layer(cipher_state *X, permutation p) { if (p == PERMUTATION_NONE) { return; } debug_dump_buffer(X->debug, " Permutation Layer :", sizeof(X->X), X->X, 10); debug_dump_buffer(X->debug, " State permuted :", sizeof(X->X), X->X, 10); } 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], FILE *debug ) { debug_dump_lanes(debug, "Tweak :", TWEAK_BYTES, tweak, 0); debug_dump_lanes(debug, "Key :", KEY_BYTES, key, 0); debug_dump_buffer(debug, "Message :", BLOCK_BYTES, message, 0); cipher_state X; _state_init(&X, message, debug); uint8_t RTK[ROUNDS][ROUND_TWEAKEY_BYTES]; _compute_round_tweakeys(key, tweak, RTK); for (uint8_t i=0; i