summaryrefslogtreecommitdiff
path: root/src/cipher.c
diff options
context:
space:
mode:
authorKévin Le Gouguec <kevin.legouguec@airbus.com>2018-11-27 08:58:46 +0100
committerKévin Le Gouguec <kevin.legouguec@airbus.com>2018-11-27 08:58:46 +0100
commitd14739644394986cb584acb45ed9b214dff1c501 (patch)
tree3bd49b3feeafcd3aeb23a779d161f67664a1eaec /src/cipher.c
parent89ff89643cf6682742730c3f65b572debe2c2ab1 (diff)
downloadlilliput-ae-implem-d14739644394986cb584acb45ed9b214dff1c501.tar.xz
Mise en commun du code TBC et ΘCB3
Il ne devrait pas varier selon les paramètres AFAICT.
Diffstat (limited to 'src/cipher.c')
-rw-r--r--src/cipher.c170
1 files changed, 170 insertions, 0 deletions
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 <stdint.h>
+#include <string.h>
+
+#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; i<ROUNDS; i++)
+ {
+ tweakey_state_update(&TK);
+ tweakey_state_extract(&TK, RTK[i], i);
+ }
+}
+
+
+static void _nonlinear_layer(cipher_state *X, const uint8_t RTK[ROUND_TWEAKEY_BYTES])
+{
+ uint8_t F[ROUND_TWEAKEY_BYTES];
+ for (size_t j=0; j<sizeof(F); j++)
+ {
+ F[j] = X->X[j] ^ RTK[j];
+ }
+
+ for (size_t j=0; j<sizeof(F); j++)
+ {
+ F[j] = S[F[j]];
+ }
+
+ for (size_t j=0; j<8; j++)
+ {
+ size_t dest_j = 15-j;
+ X->X[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; j<BLOCK_BYTES; j++)
+ {
+ X->X[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<ROUNDS-1; i++)
+ {
+ _one_round_egfn(&X, RTK[i], PERMUTATION_ENCRYPTION);
+ }
+
+ _one_round_egfn(&X, RTK[ROUNDS-1], PERMUTATION_NONE);
+
+ memcpy(ciphertext, X.X, BLOCK_BYTES);
+}
+
+void lilliput_tbc_decrypt(
+ const uint8_t key[KEY_BYTES],
+ const uint8_t tweak[TWEAK_BYTES],
+ const uint8_t ciphertext[BLOCK_BYTES],
+ uint8_t message[BLOCK_BYTES]
+)
+{
+ cipher_state X;
+ _state_init(&X, ciphertext);
+
+ uint8_t RTK[ROUNDS][ROUND_TWEAKEY_BYTES];
+ _compute_round_tweakeys(key, tweak, RTK);
+
+ for (uint8_t i=0; i<ROUNDS-1; i++)
+ {
+ _one_round_egfn(&X, RTK[ROUNDS-1-i], PERMUTATION_DECRYPTION);
+ }
+
+ _one_round_egfn(&X, RTK[0], PERMUTATION_NONE);
+
+ memcpy(message, X.X, BLOCK_BYTES);
+}