]> git.cryptolib.org Git - avr-crypto-lib.git/blob - echo/echo.c
now with Echo (hashfunction), tests are running ...
[avr-crypto-lib.git] / echo / echo.c
1 /* echo.c */
2 /*
3     This file is part of the AVR-Crypto-Lib.
4     Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
5
6     This program is free software: you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation, either version 3 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20
21 #include "echo.h"
22 #include "gf256mul.h"
23 #include "memxor.h"
24 #include <stdint.h>
25 #include <string.h>
26
27 #ifdef DEBUG
28 #undef DEBUG
29 #endif
30
31 #define DEBUG 0
32
33 #if DEBUG
34 #define DEBUG_DEPTH 2
35 #include "cli.h"
36 #endif
37
38 void aes_encrypt_round(void* state, void* key);
39
40 #define INDEX(c,r) ((r)*16*4+(c)*16)
41
42 #define GF256MUL_1(a) (a)
43 #define GF256MUL_2(a) (gf256mul(2, (a), 0x1b))
44 #define GF256MUL_3(a) (gf256mul(3, (a), 0x1b))
45
46 /*
47 static void mixcol_2(uint8_t* s){
48         uint8_t t, tmp[4];
49         memcpy(tmp, s, 4);
50         t = tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3];
51         s[0] =
52                   GF256MUL_2(tmp[0]^tmp[1])
53                 ^ tmp[0]
54                 ^ t;
55         s[1] =
56                   GF256MUL_2(tmp[1]^tmp[2])
57                 ^ tmp[1]
58                 ^ t;
59         s[2] =
60                   GF256MUL_2(tmp[2]^tmp[3])
61                 ^ tmp[2]
62                 ^ t;
63         s[3] =
64                   GF256MUL_2(tmp[3]^tmp[0])
65                 ^ tmp[3]
66                 ^ t;
67 }
68 */
69
70 static void mixcol(uint8_t* a, uint8_t* b, uint8_t* c, uint8_t* d){
71         uint8_t t, tmp[4];
72         tmp[0] = *a;
73         tmp[1] = *b;
74         tmp[2] = *c;
75         tmp[3] = *d;
76
77         t = tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3];
78         *a =
79                   GF256MUL_2(tmp[0]^tmp[1])
80                 ^ tmp[0]
81                 ^ t;
82         *b =
83                   GF256MUL_2(tmp[1]^tmp[2])
84                 ^ tmp[1]
85                 ^ t;
86         *c =
87                   GF256MUL_2(tmp[2]^tmp[3])
88                 ^ tmp[2]
89                 ^ t;
90         *d =
91                   GF256MUL_2(tmp[3]^tmp[0])
92                 ^ tmp[3]
93                 ^ t;
94 }
95
96 #if DEBUG
97 static void dump_state(void* s){
98         uint8_t row, col;
99         for(col=0; col<4; col++){
100                 for(row=0; row<4; row++){
101                         cli_putstr_P(PSTR("\r\nrow "));
102                         cli_putc('0'+row);
103                         cli_putstr_P(PSTR(", col "));
104                         cli_putc('0'+col);
105                         cli_putstr_P(PSTR(": "));
106                         cli_hexdump((uint8_t*)s+col*16+row*16*4, 4);
107                         cli_putc(' ');
108                         cli_hexdump((uint8_t*)s+col*16+row*16*4+ 4, 4);
109                         cli_putc(' ');
110                         cli_hexdump((uint8_t*)s+col*16+row*16*4+ 8, 4);
111                         cli_putc(' ');
112                         cli_hexdump((uint8_t*)s+col*16+row*16*4+12, 4);
113                 }
114         }
115 }
116 #endif
117
118 static void compress512(void* v, void* m, uint64_t* c, void* salt){
119         uint8_t i, j, l;
120         uint8_t s[16*16];
121         uint8_t k[16];
122 /*
123         memcpy(s, v, 16*4);           / * load v into state * /
124         memcpy(s+16*4, m, 16*12);     / * load m into state * /
125 */
126         for(i=0; i<4; ++i){
127                 memcpy(s+4*16*i, (uint8_t*)v+16*i, 16);
128         }
129         for(i=1; i<4; ++i){
130                 for(j=0; j<4; ++j){
131                         memcpy(s+i*16+j*16*4, m, 16);
132                         m = (uint8_t*)m + 16;
133                 }
134         }
135         memcpy(k, c, 8);
136         memset(k+8, 0, 8);
137         for(i=0; i<8; ++i){
138                 /* BIG.SubWords */
139 #if DEBUG
140         cli_putstr_P(PSTR("\r\n === ROUND "));
141         cli_putc('1'+i);
142         cli_putstr_P(PSTR(" ==="));
143         if(i<DEBUG_DEPTH){
144                 dump_state(s);
145         }
146 #endif
147                 for(j=0; j<4; ++j){
148                         for(l=0; l<4; ++l){
149                                 aes_encrypt_round(s+16*l*4+16*j, k);
150                                 aes_encrypt_round(s+16*l*4+16*j, salt);
151                                 *((uint64_t*)(k)) += 1;
152                         }
153                 }
154 #if DEBUG
155                 if(i<DEBUG_DEPTH){
156                         cli_putstr_P(PSTR("\r\nAfter SubWords"));
157                         dump_state(s);
158                 }
159 #endif
160                 /* BIG.ShiftRows */
161                 uint8_t t[16];
162                 /* "Row" 1 */
163                 memcpy(t,             s+INDEX(0, 1), 16);
164                 memcpy(s+INDEX(0, 1), s+INDEX(1, 1), 16);
165                 memcpy(s+INDEX(1, 1), s+INDEX(2, 1), 16);
166                 memcpy(s+INDEX(2, 1), s+INDEX(3, 1), 16);
167                 memcpy(s+INDEX(3, 1), t,             16);
168                 /* "Row" 2 */
169                 memcpy(t,             s+INDEX(0, 2), 16);
170                 memcpy(s+INDEX(0, 2), s+INDEX(2, 2), 16);
171                 memcpy(s+INDEX(2, 2), t,             16);
172                 memcpy(t,             s+INDEX(1, 2), 16);
173                 memcpy(s+INDEX(1, 2), s+INDEX(3, 2), 16);
174                 memcpy(s+INDEX(3, 2), t,             16);
175                 /* "Row" 3 */
176                 memcpy(t,             s+INDEX(0, 3), 16);
177                 memcpy(s+INDEX(0, 3), s+INDEX(3, 3), 16);
178                 memcpy(s+INDEX(3, 3), s+INDEX(2, 3), 16);
179                 memcpy(s+INDEX(2, 3), s+INDEX(1, 3), 16);
180                 memcpy(s+INDEX(1, 3), t,             16);
181 #if DEBUG
182                 if(i<DEBUG_DEPTH){
183                         cli_putstr_P(PSTR("\r\nAfter ShiftRows"));
184                         dump_state(s);
185                 }
186 #endif
187                 /* BIG.MixColumns */
188                 /*
189                 for(j=0; j<64; ++j){
190                         mixcol(s+j*4);
191                 }
192                 */
193                 for(j=0; j<64; ++j){
194                         mixcol(s+j, s+j+64, s+j+64*2, s+j+64*3);
195                 }
196 #if DEBUG
197                 if(i<DEBUG_DEPTH){
198                         cli_putstr_P(PSTR("\r\nAfter MixColumns"));
199                         dump_state(s);
200                 }
201 #endif
202         }
203
204         /* BIG.Final */
205         /*
206         for(i=0; i<3; ++i){
207                 memxor(v, (uint8_t*)m+4*16*i, 4*16);
208         }
209         for(i=0; i<4; ++i){
210                 memxor(v, s+4*16*i, 4*16);
211         }
212         */
213         m = (uint8_t*)m - ECHO_SMALL_BLOCKSIZE_B;
214         for(i=0; i<3; ++i){
215                 memxor(v, (uint8_t*)m+4*16*i, 4*16);
216         }
217
218         for(i=0; i<4; ++i){
219                 for(j=0; j<4; ++j){
220                         memxor((uint8_t*)v+16*i, s+4*16*i+16*j, 16);
221                 }
222         }
223
224 }
225
226 void echo_small_nextBlock(echo_small_ctx_t* ctx, void* block){
227         ctx->counter += ECHO_SMALL_BLOCKSIZE;
228         compress512(ctx->v, block, &(ctx->counter), ctx->salt);
229 }
230
231 void echo_small_lastBlock(echo_small_ctx_t* ctx, void* block, uint16_t length_b){
232         while(length_b>=ECHO_SMALL_BLOCKSIZE){
233                 echo_small_nextBlock(ctx, block);
234                 block = (uint8_t*)block + ECHO_SMALL_BLOCKSIZE_B;
235                 length_b -= ECHO_SMALL_BLOCKSIZE;
236         }
237         uint8_t buffer[ECHO_SMALL_BLOCKSIZE_B];
238         uint64_t total_len;
239         memset(buffer, 0, ECHO_SMALL_BLOCKSIZE_B);
240         memcpy(buffer, block, (length_b+7)/8);
241         buffer[length_b/8] |= 0x80 >> (length_b&7);
242         total_len = (ctx->counter += length_b);
243         if(length_b>=ECHO_SMALL_BLOCKSIZE-144){
244                 compress512(ctx->v, buffer, &total_len, ctx->salt);
245                 memset(buffer, 0, ECHO_SMALL_BLOCKSIZE_B);
246                 ctx->counter = 0;
247         }
248         if(length_b==0){
249                 ctx->counter = 0;
250         }
251         memcpy(buffer+ECHO_SMALL_BLOCKSIZE_B-18, &(ctx->id), 2);
252         memcpy(buffer+ECHO_SMALL_BLOCKSIZE_B-16, &total_len, 8);
253         compress512(ctx->v, buffer, &(ctx->counter), ctx->salt);
254 }
255
256 /******************************************************************************/
257
258 void echo_small_ctx2hash(void* dest, uint16_t length_b, echo_small_ctx_t* ctx){
259         memcpy(dest, ctx->v, (length_b+7)/8);
260 }
261
262 void echo224_ctx2hash(void* dest, echo_small_ctx_t* ctx){
263         memcpy(dest, ctx->v, 224/8);
264 }
265
266 void echo256_ctx2hash(void* dest, echo_small_ctx_t* ctx){
267         memcpy(dest, ctx->v, 256/8);
268 }
269
270 /******************************************************************************/
271
272 void echo224_init(echo_small_ctx_t* ctx){
273         memset(ctx->v, 0, 4*16);
274         ctx->counter = 0;
275         memset(ctx->salt, 0, 16);
276         ctx->id = 0x00E0;
277         ctx->v[0+16*0] = 0xE0;
278         ctx->v[0+16*1] = 0xE0;
279         ctx->v[0+16*2] = 0xE0;
280         ctx->v[0+16*3] = 0xE0;
281 }
282
283 void echo256_init(echo_small_ctx_t* ctx){
284         memset(ctx->v, 0, 4*16);
285         ctx->counter = 0;
286         memset(ctx->salt, 0, 16);
287         ctx->id = 0x0100;
288         ctx->v[1+16*0] = 0x01;
289         ctx->v[1+16*1] = 0x01;
290         ctx->v[1+16*2] = 0x01;
291         ctx->v[1+16*3] = 0x01;
292 }
293
294 /******************************************************************************/
295