]> AND Private Git Repository - Cipher_code.git/blob - Grain-128AEAD-sw-ref/grain128aead.c
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
new
[Cipher_code.git] / Grain-128AEAD-sw-ref / grain128aead.c
1 #include <stdio.h>
2 #include <stdint.h>
3 #include <stdlib.h>
4
5 #include "grain128aead.h"
6 #include <string.h>
7 #include <sys/time.h>
8
9
10
11
12
13
14
15 /*
16  * Define "PRE" to print the pre-output instead of keystream.
17  * Define "INIT" to also print the bits during the initialization part.
18  * Do this either here or during compilation with -D flag.
19  */
20
21 uint8_t grain_round;
22
23
24 double TimeStart()
25 {
26   struct timeval tstart;
27   gettimeofday(&tstart,0);
28   return( (double) (tstart.tv_sec + tstart.tv_usec*1e-6) );
29 }
30
31 double TimeStop(double t)
32 {
33   struct timeval tend;
34
35   gettimeofday(&tend,0);
36   t = (double) (tend.tv_sec + tend.tv_usec*1e-6) - t;
37   return (t);
38 }
39
40
41 void init_grain(grain_state *grain, uint8_t *key, uint8_t *iv)
42 {
43         // expand the packed bytes and place one bit per array cell (like a flip flop in HW)
44         for (int i = 0; i < 12; i++) {
45                 for (int j = 0; j < 8; j++) {
46                         grain->lfsr[8 * i + j] = (iv[i] & (1 << (7-j))) >> (7-j);
47
48                 }
49         }
50
51         for (int i = 96; i < 127; i++) {
52                 grain->lfsr[i] = 1;
53         }
54
55         grain->lfsr[127] = 0;
56
57         for (int i = 0; i < 16; i++) {
58                 for (int j = 0; j < 8; j++) {
59                         grain->nfsr[8 * i + j] = (key[i] & (1 << (7-j))) >> (7-j);
60                 }
61         }
62
63         for (int i = 0; i < 64; i++) {
64                 grain->auth_acc[i] = 0;
65                 grain->auth_sr[i] = 0;
66         }
67 }
68
69 void init_data(grain_data *data, uint8_t *msg, uint32_t msg_len)
70 {
71         // allocate enough space for message, including the padding byte, 0x80
72   data->message = (uint8_t *) calloc(msg_len+8,1);//8 * STREAM_BYTES + 8, 1);
73         for (uint32_t i = 0; i < msg_len; i++) {
74                 data->message[i] = msg[i];
75         }
76
77         // always pad data with the byte 0x80
78         data->message[msg_len] = 1;
79 }
80
81 uint8_t next_lfsr_fb(grain_state *grain)
82 {
83         /* f(x) = 1 + x^32 + x^47 + x^58 + x^90 + x^121 + x^128 */
84         return grain->lfsr[96] ^ grain->lfsr[81] ^ grain->lfsr[70] ^ grain->lfsr[38] ^ grain->lfsr[7] ^ grain->lfsr[0];
85 }
86
87 uint8_t next_nfsr_fb(grain_state *grain)
88 {
89         return grain->nfsr[96] ^ grain->nfsr[91] ^ grain->nfsr[56] ^ grain->nfsr[26] ^ grain->nfsr[0] ^ (grain->nfsr[84] & grain->nfsr[68]) ^
90                         (grain->nfsr[67] & grain->nfsr[3]) ^ (grain->nfsr[65] & grain->nfsr[61]) ^ (grain->nfsr[59] & grain->nfsr[27]) ^
91                         (grain->nfsr[48] & grain->nfsr[40]) ^ (grain->nfsr[18] & grain->nfsr[17]) ^ (grain->nfsr[13] & grain->nfsr[11]) ^
92                         (grain->nfsr[82] & grain->nfsr[78] & grain->nfsr[70]) ^ (grain->nfsr[25] & grain->nfsr[24] & grain->nfsr[22]) ^
93                         (grain->nfsr[95] & grain->nfsr[93] & grain->nfsr[92] & grain->nfsr[88]);
94 }
95
96 uint8_t next_h(grain_state *grain)
97 {
98         // h(x) = x0x1 + x2x3 + x4x5 + x6x7 + x0x4x8
99         #define x0 grain->nfsr[12]      // bi+12
100         #define x1 grain->lfsr[8]               // si+8
101         #define x2 grain->lfsr[13]      // si+13
102         #define x3 grain->lfsr[20]      // si+20
103         #define x4 grain->nfsr[95]      // bi+95
104         #define x5 grain->lfsr[42]      // si+42
105         #define x6 grain->lfsr[60]      // si+60
106         #define x7 grain->lfsr[79]      // si+79
107         #define x8 grain->lfsr[94]      // si+94
108
109         uint8_t h_out = (x0 & x1) ^ (x2 & x3) ^ (x4 & x5) ^ (x6 & x7) ^ (x0 & x4 & x8);
110         return h_out;
111 }
112
113 uint8_t shift(uint8_t fsr[128], uint8_t fb)
114 {
115         uint8_t out = fsr[0];
116         for (int i = 0; i < 127; i++) {
117                 fsr[i] = fsr[i+1];
118         }
119         fsr[127] = fb;
120
121         return out;
122 }
123
124 void auth_shift(uint8_t sr[64], uint8_t fb)
125 {
126         for (int i = 0; i < 63; i++) {
127                 sr[i] = sr[i+1];
128         }
129         sr[63] = fb;
130 }
131
132 void accumulate(grain_state *grain)
133 {
134         for (int i = 0; i < 64; i++) {
135                 grain->auth_acc[i] ^= grain->auth_sr[i];
136         }
137 }
138
139 uint8_t next_z(grain_state *grain, uint8_t keybit)
140 {
141         uint8_t lfsr_fb = next_lfsr_fb(grain);
142         uint8_t nfsr_fb = next_nfsr_fb(grain);
143         uint8_t h_out = next_h(grain);
144
145         /* y = h + s_{i+93} + sum(b_{i+j}), j \in A */
146         uint8_t A[] = {2, 15, 36, 45, 64, 73, 89};
147
148         uint8_t nfsr_tmp = 0;
149         for (int i = 0; i < 7; i++) {
150                 nfsr_tmp ^= grain->nfsr[A[i]];
151         }
152
153         uint8_t y = h_out ^ grain->lfsr[93] ^ nfsr_tmp;
154         
155         uint8_t lfsr_out;
156
157         /* feedback y if we are in the initialization instance */
158         if (grain_round == INIT) {
159                 lfsr_out = shift(grain->lfsr, lfsr_fb ^ y);
160                 shift(grain->nfsr, nfsr_fb ^ lfsr_out ^ y);
161         } else if (grain_round == FP1) {
162                 lfsr_out = shift(grain->lfsr, lfsr_fb ^ keybit);
163                 shift(grain->nfsr, nfsr_fb ^ lfsr_out);
164         } else if (grain_round == NORMAL) {
165                 lfsr_out = shift(grain->lfsr, lfsr_fb);
166                 shift(grain->nfsr, nfsr_fb ^ lfsr_out);
167         }
168
169         return y;
170 }
171
172 void print_state(grain_state *grain)
173 {
174         printf("LFSR: ");
175         for (int i = 0; i < 128; i++) {
176                 printf("%d", grain->lfsr[i]);
177         }
178         printf("\nNFSR: ");
179         for (int i = 0; i < 128; i++) {
180                 printf("%d", grain->nfsr[i]);
181         }
182         printf("\n");
183 }
184
185 void print_stream(uint8_t *stream, uint8_t byte_size)
186 {
187         for (int i = 0; i < byte_size; i++) {
188                 uint8_t yi = 0;
189                 for (int j = 0; j < 8; j++) {
190                         yi = (yi << 1) ^ stream[i * 8 + j];
191                 }
192                 printf("%02x", yi);
193         }
194         printf("\n");
195 }
196
197 void generate_keystream(grain_state *grain, grain_data *data, uint8_t *key)
198 {
199         grain_round = FP1;
200
201         uint8_t key_idx = 0;
202         /* inititalize the accumulator and shift reg. using the first 64 bits */
203         for (int i = 0; i < 8; i++) {
204                 for (int j = 0; j < 8; j++) {
205                         uint8_t fp1_fb = (key[key_idx] & (1 << (7-j))) >> (7-j);
206                         grain->auth_acc[8 * i + j] = next_z(grain, fp1_fb);
207                 }
208                 key_idx++;
209         }
210
211         for (int i = 0; i < 8; i++) {
212                 for (int j = 0; j < 8; j++) {
213                         uint8_t fp1_fb = (key[key_idx] & (1 << (7-j))) >> (7-j);
214                         grain->auth_sr[8 * i + j] = next_z(grain, fp1_fb);
215                 }
216                 key_idx++;
217         }
218
219         grain_round = NORMAL;
220
221         /*      printf("accum init:\t");
222         print_stream(grain->auth_acc, 8);
223
224         printf("register init:\t");
225         print_stream(grain->auth_sr, 8);
226         */
227         uint8_t ks[STREAM_BYTES * 8];           // keystream array
228         uint16_t ks_cnt = 0;
229         uint8_t ms[STREAM_BYTES * 8];           // macstream array
230         uint16_t ms_cnt = 0;
231         uint8_t pre[2 * STREAM_BYTES * 8];      // pre-output
232         uint16_t pre_cnt = 0;
233
234         /* generate keystream */
235         for (int i = 0; i < STREAM_BYTES; i++) {
236                 /* every second bit is used for keystream, the others for MAC */
237                 for (int j = 0; j < 16; j++) {
238                         uint8_t z_next = next_z(grain, 0);
239                         if (j % 2 == 0) {
240                                 ks[ks_cnt] = z_next;
241                                 ks_cnt++;
242                         } else {
243                                 ms[ms_cnt] = z_next;
244                                 if (data->message[ms_cnt] == 1) {
245                                         accumulate(grain);
246                                 }
247                                 auth_shift(grain->auth_sr, z_next);
248                                 ms_cnt++;
249                         }
250                         pre[pre_cnt++] = z_next;        // pre-output includes all bits
251                 }
252         }
253
254         /*      printf("pre-output:\t");
255         print_stream(pre, 2 * STREAM_BYTES);
256
257         printf("keystream:\t");
258         print_stream(ks, STREAM_BYTES);
259
260         printf("macstream:\t");
261         print_stream(ms, STREAM_BYTES);
262
263         printf("tag:\t\t");
264         print_stream(grain->auth_acc, 8);
265         */
266 }
267
268
269 int main(int argc, char** argv)
270 {
271         grain_state grain;
272         grain_data data;
273         
274         //uint8_t key[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0};
275         //uint8_t iv[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x12, 0x34, 0x56, 0x78};
276
277
278         uint8_t key[] = {0x81, 0x27, 0x73, 0x35, 0x11, 0xe9, 0x4c, 0x32, 0x9f, 0x77, 0x1f, 0xe8, 0x31, 0xec, 0x95, 0x55};
279         uint8_t iv[] = {0xcc, 0xb5, 0x2f, 0xe4, 0x3e, 0x68, 0xc4, 0x5e, 0x78, 0xb1, 0x96, 0xb2};
280
281         //uint8_t key[16] = { 0 };
282         //uint8_t iv[12] = { 0 };
283         //iv[0] = 0x80;
284
285         //uint8_t msg[0];
286         //uint8_t msg[8] = {0, 0, 0, 0, 0, 0, 0, 0};
287         //uint8_t msg[8] = {1, 0, 0, 0, 0, 0, 0, 0};
288         //uint8_t msg[8] = {0, 0, 0, 0, 0, 0, 0, 1};
289
290         int size_buf=1;
291         int nb_test=1;
292          
293         for(int i=1; i<argc; i++){
294           if(strncmp(argv[i],"nb",2)==0)    nb_test = atoi(&(argv[i][2]));    //nb of test         
295           if(strncmp(argv[i],"sizebuf",7)==0) size_buf = atoi(&(argv[i][7]));          //SIZE of the buffer
296         }
297
298
299
300
301         size_buf=size_buf*size_buf;
302
303         //      printf("size %d\n",size_buf); //sizeof(msg));
304         
305         uint8_t *msg = (uint8_t*)malloc(size_buf+8);
306
307
308
309         /*      
310         printf("key:\t\t");
311         for (int i = 0; i < 16; i++) {
312                 printf("%02x", key[i]);
313         }
314         printf("\n");
315
316         printf("iv:\t\t");
317         for (int i = 0; i < 12; i++) {
318                 printf("%02x", iv[i]);
319         }
320         printf("\n");
321
322         printf("size %d\n",size_buf); //sizeof(msg));
323         */
324         
325         init_grain(&grain, key, iv);
326         init_data(&data, msg, size_buf);//sizeof(msg));
327         
328         /* initialize grain and skip output */
329         grain_round = INIT;
330 #ifdef INIT
331         printf("init bits: ");
332 #endif
333         for (int i = 0; i < 256; i++) {
334 #ifdef INIT
335                 printf("%d", next_z(&grain));
336 #else
337                 next_z(&grain, 0);
338 #endif
339         }
340 #ifdef INIT
341         printf("\n");
342 #endif
343         grain_round = NORMAL;
344
345
346         double time_encrypt=0;
347         double t=TimeStart();
348
349         for(int i=0;i<nb_test;i++)
350           {
351             generate_keystream(&grain, &data, key);
352           }
353
354         time_encrypt=TimeStop(t);
355
356         printf("%e \t",(double)size_buf*nb_test/time_encrypt);  
357         free(data.message);
358
359         return 0;
360 }