4 * email: daniel.otte@rub.de
7 * a suit for running the nessie-tests for MACs
12 #include "nessie_mac_test.h"
15 nessie_mac_ctx_t nessie_mac_ctx;
17 #define KEYSIZE_B ((nessie_mac_ctx.keysize_b+7)/8)
18 #define MACSIZE_B ((nessie_mac_ctx.macsize_b+7)/8)
20 #define PRINTKEY printitem("key", key, KEYSIZE_B)
21 #define PRINTMAC printitem("MAC", mac, MACSIZE_B)
23 static void printblock(uint8_t* block, uint16_t blocksize_bit){
24 char tab [] = {'0', '1', '2', '3',
29 for(i=0; i<(blocksize_bit+7)/8; ++i){
30 uart_putc(tab[(block[i])>>4]);
31 uart_putc(tab[(block[i])&0xf]);
36 #define BYTESPERLINE 16
38 static void printitem(char* name, uint8_t* buffer, uint16_t size_B){
41 name_len=strlen(name);
42 if(name_len>SPACES-1){
43 uart_putstr_P(PSTR("\r\n!!! formatting error !!!\r\n"));
46 uart_putstr_P(PSTR("\r\n"));
47 for(i=0; i<SPACES-name_len-1; ++i){
52 /* now the data printing begins */
53 if(size_B<=BYTESPERLINE){
54 /* one line seems sufficient */
55 printblock(buffer, size_B*8);
57 /* we need more lines */
58 printblock(buffer, BYTESPERLINE*8); /* first line */
59 int16_t toprint = size_B - BYTESPERLINE;
60 buffer += BYTESPERLINE;
62 uart_putstr_P(PSTR("\r\n"));
63 for(i=0; i<SPACES; ++i){
66 printblock(buffer, ((toprint>BYTESPERLINE)?BYTESPERLINE:toprint)*8);
67 buffer += BYTESPERLINE;
68 toprint -= BYTESPERLINE;
73 static void print_set_vector(uint8_t set, uint16_t vector){
74 uart_putstr_P(PSTR("\r\n\r\nSet "));
75 uart_putc('0'+set%10);
76 uart_putstr_P(PSTR(", vector#"));
77 uart_putc((vector<100)?' ':'0'+vector/100);
78 uart_putc((vector<10 )?' ':'0'+(vector/10)%10);
79 uart_putc('0'+vector%10);
87 static void print_setheader(uint8_t set){
88 uart_putstr_P(PSTR("\r\n\r\nTest vectors -- set "));
89 uart_putc('0'+set%10);
90 uart_putstr_P(PSTR("\r\n====================="));
94 ********************************************************************************
95 *Project NESSIE - New European Schemes for Signature, Integrity, and Encryption*
96 ********************************************************************************
98 Primitive Name: Serpent
99 =======================
104 static void print_header(void){
106 uart_putstr_P(PSTR("\r\n\r\n"
107 "********************************************************************************\r\n"
108 "* micro-cryt - crypto primitives for microcontrolles by Daniel Otte *\r\n"
109 "********************************************************************************\r\n"
111 uart_putstr_P(PSTR("Primitive Name: "));
112 uart_putstr(nessie_mac_ctx.name);
113 uart_putstr_P(PSTR("\r\n"));
114 for(i=0; i<16+strlen(nessie_mac_ctx.name); ++i){
117 uart_putstr_P(PSTR("\r\nHash size: "));
118 if(nessie_mac_ctx.macsize_b >100){
119 uart_putc('0'+nessie_mac_ctx.macsize_b/100);
121 if(nessie_mac_ctx.macsize_b>10){
122 uart_putc('0'+(nessie_mac_ctx.macsize_b/10)%10);
124 uart_putc('0'+nessie_mac_ctx.macsize_b%10);
125 uart_putstr_P(PSTR(" bits\r\n"));
128 static void print_footer(void){
129 uart_putstr_P(PSTR("\r\n\r\n\r\n\r\nEnd of test vectors\r\n\r\n"));
133 void ascii_mac(char* data, char* desc, uint8_t* key){
134 uint8_t ctx[nessie_mac_ctx.ctx_size_B];
135 uint8_t mac[MACSIZE_B];
138 uart_putstr_P(PSTR("\r\n message="));
141 nessie_mac_ctx.mac_init(key, nessie_mac_ctx.keysize_b, ctx);
143 while(sl>=nessie_mac_ctx.blocksize_B){
144 nessie_mac_ctx.mac_next(data, ctx);
145 data += nessie_mac_ctx.blocksize_B;
146 sl -= nessie_mac_ctx.blocksize_B;
148 nessie_mac_ctx.mac_last(data, sl*8, key, nessie_mac_ctx.keysize_b, ctx);
149 nessie_mac_ctx.mac_conv(mac, ctx);
153 // message=1 million times "a"
156 void amillion_mac(uint8_t* key){
157 uint8_t ctx[nessie_mac_ctx.ctx_size_B];
158 uint8_t mac[MACSIZE_B];
159 uint8_t block[nessie_mac_ctx.blocksize_B];
160 uint32_t n=1000000LL;
162 uart_putstr_P(PSTR("\r\n message="));
163 uart_putstr_P(PSTR("1 million times \"a\""));
166 memset(block, 'a', nessie_mac_ctx.blocksize_B);
167 nessie_mac_ctx.mac_init(key, nessie_mac_ctx.keysize_b, ctx);
168 while(n>=nessie_mac_ctx.blocksize_B){
169 nessie_mac_ctx.mac_next(block, ctx);
170 n -= nessie_mac_ctx.blocksize_B;
172 nessie_mac_ctx.mac_last(block, n*8, key, nessie_mac_ctx.keysize_b, ctx);
173 nessie_mac_ctx.mac_conv(mac, ctx);
179 void zero_mac(uint16_t n, uint8_t* key){
180 uint8_t ctx[nessie_mac_ctx.ctx_size_B];
181 uint8_t mac[MACSIZE_B];
182 uint8_t block[nessie_mac_ctx.blocksize_B];
184 uart_putstr_P(PSTR("\r\n message="));
186 uart_putc('0'+n/10000);
188 uart_putc('0'+(n/1000)%10);
190 uart_putc('0'+(n/100)%10);
192 uart_putc('0'+(n/10)%10);
194 uart_putstr_P(PSTR(" zero bits"));
197 memset(block, 0, nessie_mac_ctx.blocksize_B);
198 nessie_mac_ctx.mac_init(key, nessie_mac_ctx.keysize_b,ctx);;
199 while(n>=nessie_mac_ctx.blocksize_B*8){
200 nessie_mac_ctx.mac_next(block, ctx);
201 n -= nessie_mac_ctx.blocksize_B*8;
203 nessie_mac_ctx.mac_last(block, n, key, nessie_mac_ctx.keysize_b, ctx);
204 nessie_mac_ctx.mac_conv(mac, ctx);
209 void one_in512_mac(uint16_t pos, uint8_t* key){
210 uint8_t ctx[nessie_mac_ctx.ctx_size_B];
211 uint8_t mac[MACSIZE_B];
212 uint8_t block[nessie_mac_ctx.blocksize_B];
214 char* tab[8]={"80", "40", "20", "10",
215 "08", "04", "02", "01" };
218 uart_putstr_P(PSTR("\r\n message="));
219 uart_putstr_P(PSTR("512-bit string: "));
221 uart_putc('0'+(pos/8/10)%10);
225 uart_putc('0'+(pos/8)%10);
226 uart_putstr_P(PSTR("*00,"));
227 uart_putstr(tab[pos&7]);
230 uart_putc('0'+((63-pos/8)/10)%10);
234 uart_putc('0'+(63-pos/8)%10);
235 uart_putstr_P(PSTR("*00"));
238 /* now the real stuff */
239 memset(block, 0, 512/8);
240 block[pos>>3] = 0x80>>(pos&0x7);
241 nessie_mac_ctx.mac_init(key, nessie_mac_ctx.keysize_b, ctx);;
242 while(n>=nessie_mac_ctx.blocksize_B*8){
243 nessie_mac_ctx.mac_next(block, ctx);
244 n -= nessie_mac_ctx.blocksize_B*8;
246 nessie_mac_ctx.mac_last(block, n, key, nessie_mac_ctx.keysize_b, ctx);
247 nessie_mac_ctx.mac_conv(mac, ctx);
252 void tv4_mac(uint8_t* key){
253 uint8_t ctx[nessie_mac_ctx.ctx_size_B];
254 uint8_t mac[MACSIZE_B];
255 uint8_t block[256/8];
259 uart_putstr_P(PSTR("\r\n message="));
260 uart_putstr(PSTR("256 zero bits"));
261 memset(block, 0, 256/8);
263 nessie_mac_ctx.mac_init(key, nessie_mac_ctx.keysize_b, ctx);;
264 while(n>=nessie_mac_ctx.blocksize_B*8){
265 nessie_mac_ctx.mac_next(block, ctx);
266 n -= nessie_mac_ctx.blocksize_B*8;
268 nessie_mac_ctx.mac_last(block, n, key, nessie_mac_ctx.keysize_b, ctx);
269 nessie_mac_ctx.mac_conv(mac, ctx);
271 for(i=1; i<100000L; ++i){ /* this assumes BLOCKSIZE >= HASHSIZE */
272 nessie_mac_ctx.mac_init(key, nessie_mac_ctx.keysize_b, ctx);;
273 nessie_mac_ctx.mac_last(mac, nessie_mac_ctx.macsize_b, key, nessie_mac_ctx.keysize_b, ctx);
274 nessie_mac_ctx.mac_conv(mac, ctx);
276 printitem("iterated 100000 times", mac, MACSIZE_B);
280 void nessie_mac_run(void){
283 uint8_t keyproto[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
284 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
285 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef };
286 uint8_t key[KEYSIZE_B];
290 char* challange[10][2]= {
291 {"", "\"\" (empty string)"},
294 {"message digest", "\"message digest\""},
295 {"abcdefghijklmnopqrstuvwxyz","\"abcdefghijklmnopqrstuvwxyz\""},
296 {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
297 "\"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\""},
298 {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
299 "abcdefghijklmnopqrstuvwxyz"
300 "0123456789" , "\"A...Za...z0...9\""},
301 {"1234567890" "1234567890" "1234567890" "1234567890"
302 "1234567890" "1234567890" "1234567890" "1234567890",
303 "8 times \"1234567890\""},
304 {"Now is the time for all ", "\"Now is the time for all \""},
305 {"Now is the time for it", "\"Now is the time for it\""}
308 print_setheader(set);
309 for(i=0; i<KEYSIZE_B; ++i){
310 key[i] = keyproto[i%sizeof(keyproto)];
313 print_set_vector(set, i);
314 ascii_mac(challange[i][0], challange[i][1], key);
316 print_set_vector(set, i);
318 for(i=0; i<KEYSIZE_B; ++i){
319 key[i] = keyproto[16+i%8];
322 print_set_vector(set, 11+i);
323 ascii_mac(challange[i][0], challange[i][1], key);
325 print_set_vector(set, 11+i);
329 for(i=0; i<KEYSIZE_B; ++i){
330 key[i] = keyproto[i%sizeof(keyproto)];
332 print_setheader(set);
333 for(i=0; i<1024; ++i){
334 print_set_vector(set, i);
339 print_setheader(set);
340 /* we use the same key as above */
341 for(i=0; i<512; ++i){
342 print_set_vector(set, i);
343 one_in512_mac(i, key);
347 print_setheader(set);
348 /* we use the same key as above */
349 print_set_vector(set, 0);
352 for(i=0; i<nessie_mac_ctx.keysize_b; ++i){
353 print_set_vector(set, i);
354 memset(key, 0, KEYSIZE_B);
355 key[i>>3]=0x80>>(i&0x7);
356 ascii_mac("ABC", "\"ABC\"", key);