]> git.cryptolib.org Git - avr-crypto-lib.git/blob - test_src/main-ecdsa-test.c
fixing and extending ecdsa
[avr-crypto-lib.git] / test_src / main-ecdsa-test.c
1 /* main-dsa-test.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  * ECDSA test-suit
21  *
22 */
23
24 #include "main-test-common.h"
25
26 #include "noekeon.h"
27 #include "noekeon_prng.h"
28 #include "bigint.h"
29 #include "bigint_io.h"
30 #include "nist_p192.h"
31 #include "ecc.h"
32 #include "ecdsa_sign.h"
33
34 #include "hfal_sha1.h"
35 #include "hfal_sha224.h"
36 #include "hfal_sha256.h"
37 #include "hfal_sha384.h"
38 #include "hfal_sha512.h"
39
40 #include "performance_test.h"
41 #include "hfal_sha1.h"
42 #include "base64_enc.h"
43 #include "base64_dec.h"
44
45 char* algo_name = "ECDSA";
46
47 /*****************************************************************************
48  *  additional validation-functions                                                                                      *
49  *****************************************************************************/
50
51 uint8_t prng_get_byte(void){
52     return random8();
53 }
54
55 void testrun_performance_invert_bigint(void){
56     printf_P(PSTR("\n=== performance measurement (invert) ===\n"));
57     unsigned i,j;
58     uint64_t time = 0;
59     bigint_t a, v;
60     bigint_word_t v_w[192 / BIGINT_WORD_SIZE];
61     bigint_word_t a_w[192 / BIGINT_WORD_SIZE];
62
63     a.wordv = a_w;
64     v.wordv = v_w;
65
66     for(j = 0; j < 32; ++j){
67         for(i = 0; i < 192 / BIGINT_WORD_SIZE; ++i){
68             ((uint8_t*)v_w)[i] = random();
69         }
70         v.length_W = 192 / BIGINT_WORD_SIZE;
71         v.info = 0;
72         bigint_adjust(&v);
73
74         for(i = 0; i < 16; ++i){
75             startTimer(1);
76             START_TIMER;
77             bigint_inverse(&a, &v, &nist_curve_p192_p);
78             STOP_TIMER;
79             time += stopTimer();
80         }
81     }
82
83     time >>= 8;
84     ++time;
85     time >>= 1;
86
87     printf_P(PSTR("  invert costs %"PRIu32" cycles\n"), (uint32_t)time);
88 }
89
90 void testrun_performance_multiply_bigint(void){
91     printf_P(PSTR("\n=== performance measurement (invert) ===\n"));
92     unsigned i,j;
93     uint64_t time_a = 0, time_b = 0;
94     uint32_t tmp;
95     bigint_t a, b, v;
96     bigint_word_t v_w[192 * 2 / BIGINT_WORD_SIZE];
97     bigint_word_t a_w[192 / BIGINT_WORD_SIZE];
98     bigint_word_t b_w[192 / BIGINT_WORD_SIZE];
99
100     a.wordv = a_w;
101     b.wordv = b_w;
102     v.wordv = v_w;
103
104     for(j = 0; j < 32; ++j){
105         for(i = 0; i < 192 / BIGINT_WORD_SIZE; ++i){
106             ((uint8_t*)a_w)[i] = random();
107         }
108         a.length_W = 192 / BIGINT_WORD_SIZE;
109         a.info = 0;
110         bigint_adjust(&a);
111
112         for(i = 0; i < 192 / BIGINT_WORD_SIZE; ++i){
113             ((uint8_t*)b_w)[i] = random();
114         }
115         b.length_W = 192 / BIGINT_WORD_SIZE;
116         b.info = 0;
117         bigint_adjust(&b);
118
119         for(i = 0; i < 16; ++i){
120             startTimer(1);
121             START_TIMER;
122             bigint_mul_u(&v,&a, &b);
123             STOP_TIMER;
124             tmp = stopTimer();
125             time_a += tmp;
126             time_b += tmp;
127
128             START_TIMER;
129             bigint_reduce_p192(&v);
130             STOP_TIMER;
131             tmp = stopTimer();
132             time_b += tmp;
133          }
134     }
135
136     time_a >>= 8;
137     ++time_a;
138     time_a >>= 1;
139
140     time_b >>= 8;
141     ++time_b;
142     time_b >>= 1;
143
144
145     printf_P(PSTR("  multiply          costs %7"PRIu32" cycles\n"), (uint32_t)time_a);
146     printf_P(PSTR("  multiply + reduce costs %7"PRIu32" cycles\n"), (uint32_t)time_b);
147 }
148
149 void testrun_performance_reduce_bigint(void){
150     printf_P(PSTR("\n=== performance measurement (reduce) ===\n"));
151     unsigned i, j;
152     bigint_t a,b,v;
153     bigint_word_t v_w[192 * 2 / BIGINT_WORD_SIZE];
154     bigint_word_t a_w[192 * 2 / BIGINT_WORD_SIZE];
155     bigint_word_t b_w[192 * 2 / BIGINT_WORD_SIZE];
156     uint32_t time_a, time_b;
157     int32_t time_diff;
158     int16_t faster_percent;
159     v.wordv = v_w;
160     for(j = 0; j < 32; ++j){
161         do{
162             for(i = 0; i < 192 * 2 / BIGINT_WORD_SIZE; ++i){
163                 ((uint8_t*)v_w)[i] = random();
164             }
165             v.length_W = 192 * 2 / BIGINT_WORD_SIZE;
166             v.info = 0;
167             bigint_adjust(&v);
168         }while(0);
169
170     //    printf_P(PSTR("candidate:\n"));
171     //    bigint_print_hex(&v);
172         a.wordv = a_w;
173         b.wordv = b_w;
174         calibrateTimer();
175
176     //    printf_P(PSTR("\n  going to test optimized version: ...\n"));
177         uart0_flush();
178         time_a = 0;
179         for(i = 0; i < 16; ++i){
180             bigint_copy(&a, &v);
181             startTimer(1);
182             START_TIMER;
183             bigint_reduce_p192(&a);
184             STOP_TIMER;
185             time_a += stopTimer();
186         }
187     //    printf_P(PSTR("    took: %"PRIu32" cycles\nresult:"), time);
188     //    bigint_print_hex(&a);
189
190
191     //    printf_P(PSTR("\n  going to test not-optimized version: ...\n"));
192     //    uart0_flush();
193         time_b = 0;
194         for(i = 0; i < 16; ++i){
195             bigint_copy(&b, &v);
196             startTimer(1);
197             START_TIMER;
198             bigint_reduce(&b, &nist_curve_p192_p);
199             STOP_TIMER;
200             time_b += stopTimer();
201         }
202     //    printf_P(PSTR("    took: %"PRIu32" cycles\nresult:"), time);
203     //    bigint_print_hex(&b);
204
205         time_diff = time_b - time_a;
206         faster_percent = (time_diff * 100) / time_b;
207
208         printf_P(PSTR("  delta: %7"PRId32"  (%3"PRId16"%%)  :-"), time_diff, faster_percent);
209         if(bigint_cmp_u(&a, &b)){
210             printf_P(PSTR("(\n"));
211         } else {
212             printf_P(PSTR(")\n"));
213         }
214         uart0_flush();
215     }
216 }
217
218 uint8_t ecc_affine_point_alloc(ecc_affine_point_t *p, uint16_t length_b){
219     size_t len = (length_b + BIGINT_WORD_SIZE - 1)/ BIGINT_WORD_SIZE;
220     if (! (p->x.wordv = malloc(len))){
221         return 1;
222     }
223     if (! (p->y.wordv = malloc(len))){
224         free(p->x.wordv);
225         return 2;
226     }
227     return 0;
228 }
229
230 void ecc_affine_point_free(ecc_affine_point_t *p){
231     free(p->x.wordv);
232     free(p->y.wordv);
233 }
234
235
236 void testrun_square(void){
237     bigint_word_t a_w[] = {
238         0x82, 0x6f, 0x79, 0x39, 0x47, 0x06, 0x26, 0x9f,
239         0x4b, 0xe2, 0x15, 0x61, 0x6f, 0xa1, 0xd4, 0x0c,
240         0x1f, 0x24, 0x3a, 0xd4, 0xc2, 0x6d, 0xe8, 0xb6
241     };
242
243     bigint_word_t b_w[2 * 192 / BIGINT_WORD_SIZE];
244     bigint_t a, b;
245
246     a.wordv = a_w;
247     a.length_W = sizeof(a_w);
248     a.info = 7;
249
250     b.wordv = b_w;
251     b.info = 0;
252     b.length_W = 0;
253
254     printf_P(PSTR("\n a = "));
255     bigint_print_hex(&a);
256     bigint_square(&b, &a);
257     printf_P(PSTR("\n a^2 = "));
258     bigint_print_hex(&b);
259     bigint_reduce_p192(&b);
260     printf_P(PSTR("\n a^2 %% p = "));
261     bigint_print_hex(&b);
262     putchar('\n');
263
264
265 }
266
267 #if 1
268 /*
269 0: b3cfed2634516540528622e16c396c229e50bbdf773f8423
270 1: b6e86dc2d43a241f0cd4a16f6115e24b9f26064739796f82
271 2: 563f557e41731f268f82fe81c8fed959600dd46649ebeeee
272 3: 5e45169bd87475db886b8a7833bb0845f5b011a7ce0c1766
273 4: 4abf34c505a73308a804dcefacbd8f7b10b59fa6ac6421a
274 */
275 uint8_t test_point_x_w[] = {
276     0x23, 0x84, 0x3f, 0x77, 0xdf, 0xbb, 0x50, 0x9e,
277     0x22, 0x6c, 0x39, 0x6c, 0xe1, 0x22, 0x86, 0x52,
278     0x40, 0x65, 0x51, 0x34, 0x26, 0xed, 0xcf, 0xb3
279 };
280
281 uint8_t test_point_y_w[] = {
282     0x82, 0x6f, 0x79, 0x39, 0x47, 0x06, 0x26, 0x9f,
283     0x4b, 0xe2, 0x15, 0x61, 0x6f, 0xa1, 0xd4, 0x0c,
284     0x1f, 0x24, 0x3a, 0xd4, 0xc2, 0x6d, 0xe8, 0xb6
285 };
286
287 uint8_t test_point_z1_w[] = {
288     0xee, 0xee, 0xeb, 0x49, 0x66, 0xd4, 0x0d, 0x60,
289     0x59, 0xd9, 0xfe, 0xc8, 0x81, 0xfe, 0x82, 0x8f,
290     0x26, 0x1f, 0x73, 0x41, 0x7e, 0x55, 0x3f, 0x56
291 };
292
293 uint8_t test_point_z2_w[] = {
294     0x66, 0x17, 0x0c, 0xce, 0xa7, 0x11, 0xb0, 0xf5,
295     0x45, 0x08, 0xbb, 0x33, 0x78, 0x8a, 0x6b, 0x88,
296     0xdb, 0x75, 0x74, 0xd8, 0x9b, 0x16, 0x45, 0x5e
297 };
298
299 uint8_t test_point_z3_w[] = {
300     0x1a, 0x42, 0xc6, 0x6a, 0xfa, 0x59, 0x0b, 0xb1,
301     0xf7, 0xd8, 0xcb, 0xfa, 0xce, 0x4d, 0x80, 0x8a,
302     0x30, 0x73, 0x5a, 0x50, 0x4c, 0xf3, 0xab, 0x04
303 };
304
305 ecc_combi_point_t test_point = {
306     .chudnovsky = {
307         .x = {
308             .wordv = test_point_x_w,
309             .length_W = sizeof(test_point_x_w),
310             .info = 7
311         },
312         .y = {
313             .wordv = test_point_y_w,
314             .length_W = sizeof(test_point_y_w),
315             .info = 7
316         },
317         .z1 = {
318             .wordv = test_point_z1_w,
319             .length_W = sizeof(test_point_z1_w),
320             .info = 6
321         },
322         .z2 = {
323             .wordv = test_point_z2_w,
324             .length_W = sizeof(test_point_z2_w),
325             .info = 6
326         },
327         .z3 = {
328             .wordv = test_point_z3_w,
329             .length_W = sizeof(test_point_z3_w),
330             .info = 2
331         }
332     }
333 };
334 void testrun_genkey2(void){
335     ecc_chudnovsky_point_t q;
336     ecc_affine_point_t qa;
337
338     printf_P(PSTR("\n== testing key generation (2) ==\n"));
339
340     if(ecc_chudnovsky_point_alloc(&q, 192)){
341         printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
342         return;
343     }
344     if(ecc_affine_point_alloc(&qa, 192)){
345         printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
346         return;
347     }
348
349     ecc_chudnovsky_point_print(&test_point.chudnovsky);
350     ecc_chudnovsky_to_affine_point(&qa, &test_point.chudnovsky, &nist_curve_p192);
351     printf_P(PSTR("\n  Qx: "));
352     bigint_print_hex(&qa.x);
353     printf_P(PSTR("\n  Qy: "));
354     bigint_print_hex(&qa.y);
355     printf_P(PSTR("\n================\n"));
356     ecc_chudnovsky_point_double_sp(&q, &test_point.chudnovsky, &nist_curve_p192);
357     ecc_chudnovsky_point_print(&q);
358
359     ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
360
361     printf_P(PSTR("\n  Qx: "));
362     bigint_print_hex(&qa.x);
363     printf_P(PSTR("\n  Qy: "));
364     bigint_print_hex(&qa.y);
365     puts("\n");
366
367 }
368
369 void testrun_genkey1(void){
370     ecc_chudnovsky_point_t q;
371     ecc_affine_point_t qa;
372
373     uint8_t k_w[] = {
374     //  e5ce89a34adddf25ff3bf1ffe6803f57d0220de3118798ea
375         0xea, 0x98, 0x87, 0x11, 0xe3, 0x0d, 0x22, 0xd0,
376         0x57, 0x3f, 0x80, 0xe6, 0xff, 0xf1, 0x3b, 0xff,
377         0x25, 0xdf, 0xdd, 0x4a, 0xa3, 0x89, 0xce, 0xe5
378     };
379
380     bigint_t k = {
381             .length_W = sizeof(k_w),
382             .wordv = k_w,
383             .info = 7
384     };
385
386     printf_P(PSTR("\n== testing key generation ==\n"));
387
388     if(ecc_chudnovsky_point_alloc(&q, 192)){
389         printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
390         return;
391     }
392     if(ecc_affine_point_alloc(&qa, 192)){
393         printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
394         return;
395     }
396
397     printf_P(PSTR("  k:  "));
398     bigint_print_hex(&k);
399     ecc_chudnovsky_multiplication(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
400     ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
401
402     printf_P(PSTR("\n  Qx: "));
403     bigint_print_hex(&qa.x);
404     printf_P(PSTR("\n  Qy: "));
405     bigint_print_hex(&qa.y);
406     puts("\n");
407 }
408
409 void testrun_genkey3(void){
410     ecc_chudnovsky_point_t q;
411     ecc_affine_point_t qa;
412
413     uint8_t k_w[] = {
414         0xb2, 0x51, 0x97, 0xc3, 0x7c, 0x61, 0xf8, 0x8f,
415         0x19, 0x91, 0xcc, 0x67, 0xb5, 0x1c, 0x34, 0x23,
416         0xff, 0x13, 0xad, 0x14, 0x57, 0x43, 0x14, 0x7d
417     };
418
419     bigint_t k = {
420             .length_W = sizeof(k_w),
421             .wordv = k_w,
422             .info = 6
423     };
424
425     printf_P(PSTR("\n== testing key generation ==\n"));
426
427     if(ecc_chudnovsky_point_alloc(&q, 192)){
428         printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
429         return;
430     }
431     if(ecc_affine_point_alloc(&qa, 192)){
432         printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
433         return;
434     }
435
436     printf_P(PSTR("  k:  "));
437     bigint_print_hex(&k);
438     ecc_chudnovsky_double_and_add(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
439     ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
440
441     printf_P(PSTR("\n  Qx: "));
442     bigint_print_hex(&qa.x);
443     printf_P(PSTR("\n  Qy: "));
444     bigint_print_hex(&qa.y);
445     puts("\n");
446 }
447
448 void testrun_genkey(void){
449     ecc_chudnovsky_point_t q;
450     ecc_affine_point_t qa;
451     uint32_t time;
452     bigint_t k;
453
454     printf_P(PSTR("\n== testing key generation ==\n"));
455
456     printf_P(PSTR("enter secret key d: "));
457     bigint_read_hex_echo(&k);
458     putchar('\n');
459
460     if(ecc_chudnovsky_point_alloc(&q, 192)){
461         printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
462         return;
463     }
464     if(ecc_affine_point_alloc(&qa, 192)){
465         ecc_chudnovsky_point_free(&q);
466         printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
467         return;
468     }
469
470     printf_P(PSTR("(naf)  k:  "));
471     bigint_print_hex(&k);
472     startTimer(1);
473     START_TIMER;
474     ecc_chudnovsky_naf_multiplication(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
475     STOP_TIMER;
476     time = stopTimer();
477     ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
478
479     printf_P(PSTR("\n  Qx: "));
480     bigint_print_hex(&qa.x);
481     printf_P(PSTR("\n  Qy: "));
482     bigint_print_hex(&qa.y);
483     printf_P(PSTR("\n time: %"PRIu32" cycles\n"), time);
484
485     printf_P(PSTR("(d&a)  k:  "));
486     bigint_print_hex(&k);
487     startTimer(1);
488     START_TIMER;
489     ecc_chudnovsky_double_and_add(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
490     STOP_TIMER;
491     time = stopTimer();
492     ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
493
494     printf_P(PSTR("\n  Qx: "));
495     bigint_print_hex(&qa.x);
496     printf_P(PSTR("\n  Qy: "));
497     bigint_print_hex(&qa.y);
498     printf_P(PSTR("\n time: %"PRIu32" cycles\n"), time);
499     free(k.wordv);
500     ecc_chudnovsky_point_free(&q);
501     ecc_affine_point_free(&qa);
502 }
503
504
505 #endif
506
507 const uint8_t ecdsa_test_1_msg[] PROGMEM = {
508     0xcf, 0x71, 0xa0, 0xe4, 0xce, 0x59, 0x43, 0x11,
509     0x77, 0x88, 0x50, 0x87, 0x53, 0x78, 0xd0, 0xee,
510     0xa3, 0xc0, 0x32, 0xa4, 0xbc, 0xc0, 0xdc, 0x1c,
511     0xf2, 0x9d, 0x01, 0xb9, 0xc5, 0x10, 0x78, 0x9c,
512     0xd5, 0x2f, 0xc3, 0x8c, 0x74, 0xe6, 0xa4, 0x27,
513     0x87, 0xd0, 0xf2, 0x7c, 0xe2, 0x93, 0x20, 0x7a,
514     0xfd, 0xd0, 0x11, 0x7a, 0xcc, 0x71, 0xb9, 0x16,
515     0x63, 0x06, 0xce, 0x56, 0xf1, 0xa7, 0xf1, 0xc6,
516     0x0a, 0x9d, 0x68, 0x7d, 0x12, 0x5e, 0xb0, 0x7e,
517     0x26, 0xe5, 0x51, 0xdc, 0x14, 0x0e, 0x8a, 0x04,
518     0xaf, 0xa2, 0xa1, 0x6f, 0x98, 0xb5, 0x1b, 0xa9,
519     0x18, 0x96, 0xbf, 0x32, 0x0f, 0xd4, 0xd6, 0xf1,
520     0xa4, 0x4b, 0x46, 0xf3, 0x3d, 0xae, 0x39, 0xcc,
521     0x24, 0xf0, 0x4a, 0x5d, 0x86, 0x0c, 0xb1, 0x4f,
522     0x6b, 0x6e, 0x8a, 0x69, 0x73, 0xb4, 0x9f, 0xd2,
523     0xa7, 0xbc, 0xeb, 0x48, 0xd7, 0x48, 0xf7, 0xeb
524 };
525
526 const uint8_t ecdsa_test_1_d[] PROGMEM = {
527     0xf3, 0xd7, 0x60, 0xd6, 0x75, 0xf2, 0xcc, 0xeb,
528     0xf0, 0xd2, 0xfd, 0xb3, 0xb9, 0x41, 0x3f, 0xb0,
529     0xf8, 0x4f, 0x37, 0xd1, 0xb3, 0x37, 0x4f, 0xe1
530 };
531
532 const uint8_t ecdsa_test_1_k[] PROGMEM = {
533     0x25, 0x5f, 0x68, 0x89, 0xa2, 0x31, 0xbc, 0x57,
534     0x4d, 0x15, 0xc4, 0x12, 0xfb, 0x56, 0x45, 0x68,
535     0x83, 0x07, 0xa1, 0x43, 0x70, 0xbc, 0x0a, 0xcb
536 };
537
538 void test_sign1(void){
539     bigint_word_t d_w[sizeof(ecdsa_test_1_d)];
540     uint8_t msg[sizeof(ecdsa_test_1_msg)];
541     uint8_t rnd[sizeof(ecdsa_test_1_k)];
542     bigint_t d;
543     ecc_combi_point_t q;
544     ecdsa_signature_t sign;
545     ecdsa_ctx_t ctx;
546     d.wordv = d_w;
547     memcpy_P(msg, ecdsa_test_1_msg, sizeof(ecdsa_test_1_msg));
548     memcpy_P(rnd, ecdsa_test_1_k, sizeof(ecdsa_test_1_k));
549     memcpy_P(d_w, ecdsa_test_1_d, sizeof(ecdsa_test_1_d) * sizeof(bigint_word_t));
550     d.length_W = sizeof(ecdsa_test_1_d) / sizeof(bigint_word_t);
551     d.info = 0;
552     bigint_adjust(&d);
553
554     ecc_chudnovsky_point_alloc(&q.chudnovsky, nist_curve_p192_p.length_W * sizeof(bigint_word_t));
555     ctx.basepoint = &nist_curve_p192_basepoint.chudnovsky;
556     ctx.priv = &d;
557     ctx.curve = &nist_curve_p192;
558
559     printf("\n  d:");
560     bigint_print_hex(&d);
561     printf_P(PSTR("\n  Gx: "));
562     bigint_print_hex(&nist_curve_p192_basepoint.affine.x);
563     printf_P(PSTR("\n  Gy: "));
564     bigint_print_hex(&nist_curve_p192_basepoint.affine.y);
565
566     ecc_chudnovsky_multiplication(&q.chudnovsky, &d, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
567     ecc_chudnovsky_to_affine_point(&q.affine, &q.chudnovsky, &nist_curve_p192);
568     printf_P(PSTR("\n  Qx: "));
569     bigint_print_hex(&q.affine.x);
570     printf_P(PSTR("\n  Qy: "));
571     bigint_print_hex(&q.affine.y);
572
573     ctx.pub = &q.affine;
574
575     ecdsa_signature_alloc(&sign, sizeof(ecdsa_test_1_d) * sizeof(bigint_word_t));
576
577     ecdsa_sign_message(&sign, msg, sizeof(msg) * 8, &sha1_desc, &ctx, rnd);
578
579     printf_P(PSTR("\n  r: "));
580     bigint_print_hex(&sign.r);
581     printf_P(PSTR("\n  r: "));
582     bigint_print_hex(&sign.s);
583
584
585     ecdsa_signature_free(&sign);
586     ecc_chudnovsky_point_free(&q.chudnovsky);
587 }
588
589 /*****************************************************************************
590  *  main                                                                                                                                         *
591  *****************************************************************************/
592
593 const char echo_test_str[]               PROGMEM = "echo-test";
594 const char reset_prng_str[]              PROGMEM = "reset-prng";
595 const char quick_test_str[]              PROGMEM = "quick-test";
596 const char performance_reduce_str[]      PROGMEM = "performance_reduce";
597 const char performance_invert_str[]      PROGMEM = "performance_invert";
598 const char performance_multiply_str[]    PROGMEM = "performance_multiply";
599 const char genkey1_str[]                 PROGMEM = "genkey1";
600 const char genkey2_str[]                 PROGMEM = "genkey2";
601 const char genkey3_str[]                 PROGMEM = "genkey3";
602 const char genkey_str[]                  PROGMEM = "genkey";
603 const char testsign1_str[]               PROGMEM = "testsign1";
604 const char square_str[]                  PROGMEM = "square";
605 const char echo_str[]                    PROGMEM = "echo";
606
607 const const cmdlist_entry_t cmdlist[] PROGMEM = {
608 //      { reset_prng_str,              NULL, reset_prng                           },
609 //      { quick_test_str,              NULL, quick_test                           },
610     { square_str,                  NULL, testrun_square                       },
611     { genkey_str,                  NULL, testrun_genkey                       },
612     { genkey1_str,                 NULL, testrun_genkey1                      },
613     { genkey2_str,                 NULL, testrun_genkey2                      },
614     { genkey3_str,                 NULL, testrun_genkey3                      },
615     { testsign1_str,               NULL, test_sign1                           },
616         { performance_reduce_str,      NULL, testrun_performance_reduce_bigint    },
617     { performance_invert_str,      NULL, testrun_performance_invert_bigint    },
618     { performance_multiply_str,    NULL, testrun_performance_multiply_bigint  },
619         { echo_str,                (void*)1, (void_fpt)echo_ctrl                  },
620         { NULL,                        NULL, NULL                                 }
621 };
622
623 int main (void){
624     int8_t r;
625     main_setup();
626     calibrateTimer();
627     for(;;){
628         welcome_msg(algo_name);
629         r = cmd_interface(cmdlist);
630         printf("r = %"PRId8"\n", r);
631         cli_putstr_P(PSTR("\r\nHello!\r\n"));
632         }
633 }