4 * email: daniel.otte@rub.de
7 * a suit for running the nessie-tests for hashes
12 #include "nessie_hash_test.h"
15 nessie_hash_ctx_t nessie_hash_ctx;
17 static void printblock(uint8_t* block, uint16_t blocksize_bit){
18 char tab [] = {'0', '1', '2', '3',
23 for(i=0; i<(blocksize_bit+7)/8; ++i){
24 uart_putc(tab[(block[i])>>4]);
25 uart_putc(tab[(block[i])&0xf]);
30 #define BYTESPERLINE 16
32 static void printitem(char* name, uint8_t* buffer, uint16_t size_B){
35 name_len=strlen(name);
36 if(name_len>SPACES-1){
37 uart_putstr_P(PSTR("\r\n!!! formatting error !!!\r\n"));
40 uart_putstr_P(PSTR("\r\n"));
41 for(i=0; i<SPACES-name_len-1; ++i){
46 /* now the data printing begins */
47 if(size_B<=BYTESPERLINE){
48 /* one line seems sufficient */
49 printblock(buffer, size_B*8);
51 /* we need more lines */
52 printblock(buffer, BYTESPERLINE*8); /* first line */
53 int16_t toprint = size_B - BYTESPERLINE;
54 buffer += BYTESPERLINE;
56 uart_putstr_P(PSTR("\r\n"));
57 for(i=0; i<SPACES; ++i){
60 printblock(buffer, ((toprint>BYTESPERLINE)?BYTESPERLINE:toprint)*8);
61 buffer += BYTESPERLINE;
62 toprint -= BYTESPERLINE;
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);
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====================="));
88 ********************************************************************************
89 *Project NESSIE - New European Schemes for Signature, Integrity, and Encryption*
90 ********************************************************************************
92 Primitive Name: Serpent
93 =======================
98 static void print_header(void){
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"
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){
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);
115 if(nessie_hash_ctx.hashsize_b>10){
116 uart_putc('0'+(nessie_hash_ctx.hashsize_b/10)%10);
118 uart_putc('0'+nessie_hash_ctx.hashsize_b%10);
119 uart_putstr_P(PSTR(" bits\r\n"));
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"));
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];
132 uart_putstr_P(PSTR("\r\n message="));
134 nessie_hash_ctx.hash_init(ctx);
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;
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);
146 // message=1 million times "a"
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;
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;
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);
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];
175 uart_putstr_P(PSTR("\r\n message="));
177 uart_putc('0'+n/10000);
179 uart_putc('0'+(n/1000)%10);
181 uart_putc('0'+(n/100)%10);
183 uart_putc('0'+(n/10)%10);
185 uart_putstr_P(PSTR(" zero bits"));
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;
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);
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];
204 char* tab[8]={"80", "40", "20", "10",
205 "08", "04", "02", "01" };
208 uart_putstr_P(PSTR("\r\n message="));
209 uart_putstr_P(PSTR("512-bit string: "));
211 uart_putc('0'+(pos/8/10)%10);
215 uart_putc('0'+(pos/8)%10);
216 uart_putstr_P(PSTR("*00,"));
217 uart_putstr(tab[pos&7]);
220 uart_putc('0'+((63-pos/8)/10)%10);
224 uart_putc('0'+(63-pos/8)%10);
225 uart_putstr_P(PSTR("*00"));
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;
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);
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];
248 uart_putstr_P(PSTR("\r\n message="));
249 uart_putstr(PSTR("256 zero bits"));
250 memset(block, 0, 256/8);
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;
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);
265 printitem("iterated 100000 times", hash, (nessie_hash_ctx.hashsize_b+7)/8);
272 message="message digest"
273 message="abcdefghijklmnopqrstuvwxyz"
274 message="abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
275 message="A...Za...z0...9"
276 message=8 times "1234567890"
280 void nessie_hash_run(void){
286 char* challange[8][2]= {
287 {"", "\"\" (empty string)"},
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\""}
302 print_setheader(set);
304 print_set_vector(set, i);
305 ascii_hash(challange[i][0], challange[i][1]);
307 print_set_vector(set, i);
311 print_setheader(set);
312 for(i=0; i<1024; ++i){
313 print_set_vector(set, i);
318 print_setheader(set);
319 for(i=0; i<512; ++i){
320 print_set_vector(set, i);
325 print_setheader(set);
326 print_set_vector(set, 0);