tweakey.c (3180B)
1 /* 2 Implementation of the Lilliput-AE tweakable block cipher. 3 4 Authors, hereby denoted as "the implementer": 5 Alexandre Adomnicai, 6 Kévin Le Gouguec, 7 Léo Reynaud, 8 2019. 9 10 For more information, feedback or questions, refer to our website: 11 https://paclido.fr/lilliput-ae 12 13 To the extent possible under law, the implementer has waived all copyright 14 and related or neighboring rights to the source code in this file. 15 http://creativecommons.org/publicdomain/zero/1.0/ 16 17 --- 18 19 This file provides a first-order threshold implementation of Lilliput-TBC's 20 tweakey schedule, where the tweak and the key are split into two shares. 21 */ 22 23 #include <stdint.h> 24 #include <string.h> 25 26 #include "constants.h" 27 #include "multiplications.h" 28 #include "random.h" 29 #include "tweakey.h" 30 31 32 #define LANES_NB (TWEAKEY_BYTES/LANE_BYTES) 33 #define TWEAK_LANES_NB (TWEAK_BYTES/LANE_BYTES) 34 #define KEY_LANES_NB (KEY_BYTES/LANE_BYTES) 35 36 37 void tweakey_state_init( 38 uint8_t TK_X[TWEAKEY_BYTES], 39 uint8_t TK_Y[KEY_BYTES], 40 const uint8_t key[KEY_BYTES], 41 const uint8_t tweak[TWEAK_BYTES] 42 ) 43 { 44 uint8_t SHARES_0[KEY_BYTES]; 45 randombytes(sizeof(SHARES_0), SHARES_0); 46 47 memcpy(TK_Y, SHARES_0, KEY_BYTES); 48 memcpy(TK_X, tweak, TWEAK_BYTES); 49 50 for (size_t i=0; i<KEY_BYTES; i++){ 51 TK_X[i+TWEAK_BYTES] = key[i] ^ SHARES_0[i]; 52 } 53 } 54 55 56 void tweakey_state_extract( 57 const uint8_t TK_X[TWEAKEY_BYTES], 58 const uint8_t TK_Y[KEY_BYTES], 59 uint8_t round_constant, 60 uint8_t round_tweakey_X[ROUND_TWEAKEY_BYTES], 61 uint8_t round_tweakey_Y[ROUND_TWEAKEY_BYTES] 62 ) 63 { 64 memset(round_tweakey_X, 0, ROUND_TWEAKEY_BYTES); 65 memset(round_tweakey_Y, 0, ROUND_TWEAKEY_BYTES); 66 67 for (size_t j=0; j<LANES_NB; j++) 68 { 69 const uint8_t *TKj_X = TK_X + j*LANE_BYTES; 70 71 for (size_t k=0; k<LANE_BYTES; k++) 72 { 73 round_tweakey_X[k] ^= TKj_X[k]; 74 } 75 } 76 77 for (size_t j=0; j<KEY_LANES_NB; j++) 78 { 79 const uint8_t *TKj_Y = TK_Y + j*LANE_BYTES; 80 81 for (size_t k=0; k<LANE_BYTES; k++) 82 { 83 round_tweakey_Y[k] ^= TKj_Y[k]; 84 } 85 } 86 87 round_tweakey_X[0] ^= round_constant; 88 } 89 90 91 typedef void (*matrix_multiplication)(const uint8_t x[LANE_BYTES], uint8_t y[LANE_BYTES]); 92 93 static const matrix_multiplication ALPHAS[7] = { 94 _multiply_M, 95 _multiply_M2, 96 _multiply_M3, 97 _multiply_M4, 98 _multiply_MR, 99 _multiply_MR2, 100 _multiply_MR3 101 }; 102 103 104 void tweakey_state_update(uint8_t TK_X[TWEAKEY_BYTES], uint8_t TK_Y[KEY_BYTES]) 105 { 106 for (size_t j=0; j<TWEAK_LANES_NB; j++) 107 { 108 uint8_t *TKj_X = TK_X + j*LANE_BYTES; 109 110 uint8_t TKj_old_X[LANE_BYTES]; 111 memcpy(TKj_old_X, TKj_X, LANE_BYTES); 112 113 ALPHAS[j](TKj_old_X, TKj_X); 114 } 115 116 for (size_t j=0; j<KEY_LANES_NB; j++) 117 { 118 uint8_t *TKj_X = TK_X + (j + TWEAK_LANES_NB)*LANE_BYTES; 119 uint8_t *TKj_Y = TK_Y + j*LANE_BYTES; 120 121 uint8_t TKj_X_old[LANE_BYTES]; 122 uint8_t TKj_Y_old[LANE_BYTES]; 123 memcpy(TKj_X_old, TKj_X, LANE_BYTES); 124 memcpy(TKj_Y_old, TKj_Y, LANE_BYTES); 125 126 ALPHAS[j + TWEAK_LANES_NB](TKj_X_old, TKj_X); 127 ALPHAS[j + TWEAK_LANES_NB](TKj_Y_old, TKj_Y); 128 } 129 }