]> git.cryptolib.org Git - avr-crypto-lib.git/blob - nessie_hash_test.c
footer got two newlines at the end
[avr-crypto-lib.git] / nessie_hash_test.c
1 /**
2  * 
3  * author: Daniel Otte
4  * email:  daniel.otte@rub.de
5  * license: GPLv3
6  * 
7  * a suit for running the nessie-tests for hashes
8  * 
9  * */
10 #include <stdint.h>
11 #include <string.h>
12 #include "nessie_hash_test.h"
13 #include "uart.h"
14
15 nessie_hash_ctx_t nessie_hash_ctx;
16
17 static void printblock(uint8_t* block, uint16_t blocksize_bit){
18         char tab [] = {'0', '1', '2', '3', 
19                                    '4', '5', '6', '7', 
20                                    '8', '9', 'A', 'B', 
21                                    'C', 'D', 'E', 'F'};
22         uint16_t i;
23         for(i=0; i<(blocksize_bit+7)/8; ++i){
24                 uart_putc(tab[(block[i])>>4]);
25                 uart_putc(tab[(block[i])&0xf]);
26         }                                  
27 }
28
29 #define SPACES 31
30 #define BYTESPERLINE 16
31
32 static void printitem(char* name, uint8_t* buffer, uint16_t size_B){
33         uint8_t name_len;
34         uint8_t i;
35         name_len=strlen(name);
36         if(name_len>SPACES-1){
37                 uart_putstr_P(PSTR("\r\n!!! formatting error !!!\r\n"));
38                 return;
39         }
40         uart_putstr_P(PSTR("\r\n"));
41         for(i=0; i<SPACES-name_len-1; ++i){
42                 uart_putc(' ');
43         }
44         uart_putstr(name);
45         uart_putc('=');
46         /* now the data printing begins */
47         if(size_B<=BYTESPERLINE){
48                 /* one line seems sufficient */
49                 printblock(buffer, size_B*8);
50         } else {
51                 /* we need more lines */
52                 printblock(buffer, BYTESPERLINE*8); /* first line */
53                 int16_t toprint = size_B - BYTESPERLINE;
54                 buffer += BYTESPERLINE;
55                 while(toprint > 0){
56                         uart_putstr_P(PSTR("\r\n"));
57                         for(i=0; i<SPACES; ++i){
58                                 uart_putc(' ');
59                         }
60                         printblock(buffer, ((toprint>BYTESPERLINE)?BYTESPERLINE:toprint)*8);
61                         buffer  += BYTESPERLINE;
62                         toprint -= BYTESPERLINE;
63                 }
64         }
65
66
67 static void print_set_vector(uint8_t set, uint16_t vector){
68         uart_putstr_P(PSTR("\r\n\r\nSet "));
69         uart_putc('0'+set%10);
70         uart_putstr_P(PSTR(", vector#"));
71         uart_putc((vector<100)?' ':'0'+vector/100);
72         uart_putc((vector<10 )?' ':'0'+(vector/10)%10);
73         uart_putc('0'+vector%10);
74         uart_putc(':');
75 }
76
77 /* example:
78 Test vectors -- set 3
79 =====================
80  */ 
81 static void print_setheader(uint8_t set){
82         uart_putstr_P(PSTR("\r\n\r\nTest vectors -- set "));
83         uart_putc('0'+set%10);
84         uart_putstr_P(PSTR("\r\n====================="));
85 }
86
87 /* example:
88 ********************************************************************************
89 *Project NESSIE - New European Schemes for Signature, Integrity, and Encryption*
90 ********************************************************************************
91
92 Primitive Name: Serpent
93 =======================
94 Key size: 256 bits
95 Block size: 128 bits
96 */
97
98 static void print_header(void){
99         uint16_t i;
100         uart_putstr_P(PSTR("\r\n\r\n"
101         "********************************************************************************\r\n"
102         "* micro-cryt - crypto primitives for microcontrolles by Daniel Otte            *\r\n"
103         "********************************************************************************\r\n"
104         "\r\n"));
105         uart_putstr_P(PSTR("Primitive Name: "));
106         uart_putstr(nessie_hash_ctx.name);
107         uart_putstr_P(PSTR("\r\n"));
108         for(i=0; i<16+strlen(nessie_hash_ctx.name); ++i){
109                 uart_putc('=');
110         }
111         uart_putstr_P(PSTR("\r\nHash size: "));
112         if(nessie_hash_ctx.hashsize_b >100){
113                 uart_putc('0'+nessie_hash_ctx.hashsize_b/100);
114         }
115         if(nessie_hash_ctx.hashsize_b>10){
116                 uart_putc('0'+(nessie_hash_ctx.hashsize_b/10)%10);
117         }
118         uart_putc('0'+nessie_hash_ctx.hashsize_b%10);
119         uart_putstr_P(PSTR(" bits\r\n"));
120 }
121
122 static void print_footer(void){
123         uart_putstr_P(PSTR("\r\n\r\n\r\n\r\nEnd of test vectors\r\n\r\n"));
124 }
125
126 static
127 void ascii_hash(char* data, char* desc){
128         uint8_t ctx[nessie_hash_ctx.ctx_size_B];
129         uint8_t hash[(nessie_hash_ctx.hashsize_b+7)/8];
130         uint16_t sl;
131         
132         uart_putstr_P(PSTR("\r\n                       message="));
133         uart_putstr(desc);
134         nessie_hash_ctx.hash_init(ctx);
135         sl = strlen(data);
136         while(sl>=nessie_hash_ctx.blocksize_B){
137                 nessie_hash_ctx.hash_next(data, ctx);
138                 data += nessie_hash_ctx.blocksize_B;
139                 sl   -= nessie_hash_ctx.blocksize_B;
140         }
141         nessie_hash_ctx.hash_last(data, sl*8, ctx);
142         nessie_hash_ctx.hash_conv(hash, ctx);
143         printitem("hash", hash, (nessie_hash_ctx.hashsize_b+7)/8);
144 }
145
146 // message=1 million times "a"
147
148 static
149 void amillion_hash(void){
150         uint8_t ctx[nessie_hash_ctx.ctx_size_B];
151         uint8_t hash[(nessie_hash_ctx.hashsize_b+7)/8];
152         uint8_t block[nessie_hash_ctx.blocksize_B];
153         uint32_t n=1000000LL;
154         
155         uart_putstr_P(PSTR("\r\n                       message="));
156         uart_putstr_P(PSTR("1 million times \"a\""));
157         memset(block, 'a', nessie_hash_ctx.blocksize_B);
158         nessie_hash_ctx.hash_init(ctx);
159         while(n>=nessie_hash_ctx.blocksize_B){
160                 nessie_hash_ctx.hash_next(block, ctx);
161                 n    -= nessie_hash_ctx.blocksize_B;
162         }
163         nessie_hash_ctx.hash_last(block, n*8, ctx);
164         nessie_hash_ctx.hash_conv(hash, ctx);
165         printitem("hash", hash, (nessie_hash_ctx.hashsize_b+7)/8);
166 }
167
168
169 static
170 void zero_hash(uint16_t n){
171         uint8_t ctx[nessie_hash_ctx.ctx_size_B];
172         uint8_t hash[(nessie_hash_ctx.hashsize_b+7)/8];
173         uint8_t block[nessie_hash_ctx.blocksize_B];
174         
175         uart_putstr_P(PSTR("\r\n                       message="));
176         if(n>=10000)
177                 uart_putc('0'+n/10000);
178         if(n>=1000)
179                 uart_putc('0'+(n/1000)%10);
180         if(n>=100)
181                 uart_putc('0'+(n/100)%10);
182         if(n>=10)
183                 uart_putc('0'+(n/10)%10);
184         uart_putc('0'+n%10);
185         uart_putstr_P(PSTR(" zero bits"));
186         
187         memset(block, 0, nessie_hash_ctx.blocksize_B); 
188         nessie_hash_ctx.hash_init(ctx);
189         while(n>=nessie_hash_ctx.blocksize_B*8){
190                 nessie_hash_ctx.hash_next(block, ctx);
191                 n   -= nessie_hash_ctx.blocksize_B*8;
192         }
193         nessie_hash_ctx.hash_last(block, n, ctx);
194         nessie_hash_ctx.hash_conv(hash, ctx);
195         printitem("hash", hash, (nessie_hash_ctx.hashsize_b+7)/8);
196 }
197
198 static
199 void one_in512_hash(uint16_t pos){
200         uint8_t ctx[nessie_hash_ctx.ctx_size_B];
201         uint8_t hash[(nessie_hash_ctx.hashsize_b+7)/8];
202         uint8_t block[nessie_hash_ctx.blocksize_B];
203         uint16_t n=512;
204         char* tab[8]={"80", "40", "20", "10", 
205                       "08", "04", "02", "01" };
206
207         pos&=511;
208         uart_putstr_P(PSTR("\r\n                       message="));
209         uart_putstr_P(PSTR("512-bit string: "));
210         if((pos/8) >=10){
211                 uart_putc('0'+(pos/8/10)%10);
212         } else {
213                 uart_putc(' ');
214         }
215         uart_putc('0'+(pos/8)%10);
216         uart_putstr_P(PSTR("*00,"));
217         uart_putstr(tab[pos&7]);
218         uart_putc(',');
219         if(63-(pos/8) >=10){
220                 uart_putc('0'+((63-pos/8)/10)%10);
221         } else {
222                 uart_putc(' ');
223         }
224         uart_putc('0'+(63-pos/8)%10);
225         uart_putstr_P(PSTR("*00"));
226         
227         /* now the real stuff */
228         memset(block, 0, 512/8);
229         block[pos>>3] = 0x80>>(pos&0x7);
230         nessie_hash_ctx.hash_init(ctx);
231         while(n>=nessie_hash_ctx.blocksize_B*8){
232                 nessie_hash_ctx.hash_next(block, ctx);
233                 n   -= nessie_hash_ctx.blocksize_B*8;
234         }
235         nessie_hash_ctx.hash_last(block, n, ctx);
236         nessie_hash_ctx.hash_conv(hash, ctx);
237         printitem("hash", hash, (nessie_hash_ctx.hashsize_b+7)/8);
238 }
239
240 static
241 void tv4_hash(void){
242         uint8_t ctx[nessie_hash_ctx.ctx_size_B];
243         uint8_t hash[(nessie_hash_ctx.hashsize_b+7)/8];
244         uint8_t block[256/8];
245         uint16_t n=256;
246         uint32_t i;
247         
248         uart_putstr_P(PSTR("\r\n                       message="));
249         uart_putstr(PSTR("256 zero bits"));
250         memset(block, 0, 256/8);
251         
252         nessie_hash_ctx.hash_init(ctx);
253         while(n>=nessie_hash_ctx.blocksize_B*8){
254                 nessie_hash_ctx.hash_next(block, ctx);
255                 n    -= nessie_hash_ctx.blocksize_B*8;
256         }
257         nessie_hash_ctx.hash_last(block, n, ctx);
258         nessie_hash_ctx.hash_conv(hash, ctx);
259         printitem("hash", hash, (nessie_hash_ctx.hashsize_b+7)/8);
260         for(i=1; i<100000L; ++i){ /* this assumes BLOCKSIZE >= HASHSIZE */
261                 nessie_hash_ctx.hash_init(ctx);
262                 nessie_hash_ctx.hash_last(hash, nessie_hash_ctx.hashsize_b, ctx);
263                 nessie_hash_ctx.hash_conv(hash, ctx);
264         }
265         printitem("iterated 100000 times", hash, (nessie_hash_ctx.hashsize_b+7)/8);
266 }
267
268 /*
269    "" (empty string)
270    message="a"
271    message="abc"
272    message="message digest"
273    message="abcdefghijklmnopqrstuvwxyz"
274    message="abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
275    message="A...Za...z0...9"
276    message=8 times "1234567890"
277 */
278
279
280 void nessie_hash_run(void){
281         uint16_t i;
282         uint8_t set;
283         
284         print_header();
285         /* test set 1 */
286         char* challange[8][2]= {
287                 {"", "\"\" (empty string)"},
288                 {"a", "\"a\""},
289                 {"abc", "\"abc\""},
290                 {"message digest", "\"message digest\""},
291                 {"abcdefghijklmnopqrstuvwxyz","\"abcdefghijklmnopqrstuvwxyz\""},
292                 {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
293                         "\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\""},
294                 {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
295                  "abcdefghijklmnopqrstuvwxyz"
296                  "0123456789"   , "\"A...Za...z0...9\""},
297                 {"1234567890" "1234567890" "1234567890" "1234567890" 
298                  "1234567890" "1234567890" "1234567890" "1234567890",
299                  "8 times \"1234567890\""}      
300         };
301         set=1;
302         print_setheader(set);
303         for(i=0; i<8; ++i){
304                 print_set_vector(set, i);
305                 ascii_hash(challange[i][0], challange[i][1]);
306         }
307         print_set_vector(set, i);
308         amillion_hash();
309         /* test set 2 */
310         set=2;
311         print_setheader(set);
312         for(i=0; i<1024; ++i){
313                 print_set_vector(set, i);
314                 zero_hash(i);
315         }
316         /* test set 3 */
317         set=3;
318         print_setheader(set);
319         for(i=0; i<512; ++i){
320                 print_set_vector(set, i);
321                 one_in512_hash(i);
322         }
323         /* test set 4 */
324         set=4;
325         print_setheader(set);
326         print_set_vector(set, 0);
327         tv4_hash();
328
329         print_footer();
330 }