summaryrefslogtreecommitdiff
path: root/crypto_aead/lilliputaei128v1/ref/cipher.c
blob: 31f7f027c83013cb0f8c4e40a0721fddf2335384 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>              /* debug */
#include <string.h>

#include "cipher.h"
#include "parameters.h"
#include "tweakey.h"

#include "debug.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];
    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; i<ROUNDS; i++)
    {
        tweakey_state_update(&TK);
        tweakey_state_extract(&TK, RTK[i], i);
    }
}


static void _nonlinear_layer(__attribute__((unused)) cipher_state *X, __attribute__((unused)) const uint8_t RTK[ROUND_TWEAKEY_BYTES])
{

}

static void _linear_layer(__attribute__((unused)) cipher_state *X)
{

}

static void _permutation_layer(__attribute__((unused)) cipher_state *X, permutation p)
{
    if (p == PERMUTATION_NONE)
    {
        return;
    }
}

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);
    fprintf(debug, "\n");

    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<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);

    debug_dump_buffer(debug, "Ciphertext :", BLOCK_BYTES, ciphertext, 0);

}

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],
    FILE *debug
)
{
    cipher_state X;
    _state_init(&X, ciphertext, debug);

    uint8_t RTK[ROUNDS][ROUND_TWEAKEY_BYTES];
    _compute_round_tweakeys(key, tweak, RTK);

    _one_round_egfn(&X, RTK[ROUNDS-1], PERMUTATION_NONE);

    for (uint8_t i=0; i<ROUNDS-1; i++)
    {
        _one_round_egfn(&X, RTK[ROUNDS-1-i], PERMUTATION_DECRYPTION);
    }

    memcpy(message, X.X, BLOCK_BYTES);
}