3 This file is part of the AVR-Crypto-Lib.
4 Copyright (C) 2010 Daniel Otte (daniel.otte@rub.de)
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.
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.
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/>.
26 #include "main-test-common.h"
29 #include "noekeon_prng.h"
31 #include "bigint_io.h"
32 #include "nist_p192.h"
34 #include "ecdsa_sign.h"
36 #include "hfal_sha1.h"
37 #include "hfal_sha224.h"
38 #include "hfal_sha256.h"
39 #include "hfal_sha384.h"
40 #include "hfal_sha512.h"
41 #include "hfal-basic.h"
43 #include "performance_test.h"
44 #include "hfal_sha1.h"
45 #include "base64_enc.h"
46 #include "base64_dec.h"
48 char *algo_name = "ECDSA";
50 /*****************************************************************************
51 * additional validation-functions *
52 *****************************************************************************/
54 uint8_t prng_get_byte(void){
58 const hfdesc_t *hash_select(void){
59 const hfdesc_t *hashes[] = { &sha1_desc, &sha224_desc, &sha256_desc, &sha384_desc, &sha512_desc };
62 printf_P(PSTR("Please select one of the following hash functions:\n"));
63 for(index = 0; index < sizeof(hashes) / sizeof(hashes[0]); ++index){
64 printf_P(PSTR(" %c: %S\n"), index + 'a', pgm_read_word(&(hashes[index]->name)));
67 printf_P(PSTR("[a]: "));
68 selection = getchar();
70 if(selection == '\n' || selection == '\r'){
76 }while(selection > sizeof(hashes) / sizeof(hashes[0]));
77 return hashes[selection];
80 uint8_t convert_hexchar_to_value(char a){
84 if(a >= 'a' && a <= 'f'){
87 if(a >= 'A' && a <= 'F'){
94 uint8_t convert_hex_to_byte(char a, char b){
95 return (convert_hexchar_to_value(a) << 4) | convert_hexchar_to_value(b);
98 void *hash_message(hfdesc_t *hash_function){
99 uint8_t *block, *hash_value;
102 if(hash_function == NULL){
105 block = malloc(hfal_hash_getBlocksize(hash_function) / 8);
109 hash_value = malloc(hfal_hash_getHashsize(hash_function) / 8);
110 if(hash_value == NULL){
114 hfal_hash_init(hash_function, &ctx);
119 hfal_hash_lastBlock(&ctx, block, index * 8);
125 printf_P(PSTR("*** invalid ***\n"));
126 hfal_hash_free(&ctx);
132 block[index++] = convert_hex_to_byte(a, b);
133 if(index == hfal_hash_getBlocksize(hash_function) / 8){
134 hfal_hash_nextBlock(&ctx, block);
137 hfal_hash_ctx2hash(hash_value, &ctx);
138 hfal_hash_free(&ctx);
143 void testrun_performance_invert_bigint(void){
144 printf_P(PSTR("\n=== performance measurement (invert) ===\n"));
148 bigint_word_t v_w[192 / BIGINT_WORD_SIZE];
149 bigint_word_t a_w[192 / BIGINT_WORD_SIZE];
154 for(j = 0; j < 32; ++j){
155 for(i = 0; i < 192 / BIGINT_WORD_SIZE; ++i){
156 ((uint8_t*)v_w)[i] = random();
158 v.length_W = 192 / BIGINT_WORD_SIZE;
162 for(i = 0; i < 16; ++i){
165 bigint_inverse(&a, &v, &nist_curve_p192_p);
175 printf_P(PSTR(" invert costs %"PRIu32" cycles\n"), (uint32_t)time);
178 void testrun_performance_multiply_bigint(void){
179 printf_P(PSTR("\n=== performance measurement (invert) ===\n"));
181 uint64_t time_a = 0, time_b = 0;
184 bigint_word_t v_w[192 * 2 / BIGINT_WORD_SIZE];
185 bigint_word_t a_w[192 / BIGINT_WORD_SIZE];
186 bigint_word_t b_w[192 / BIGINT_WORD_SIZE];
192 for(j = 0; j < 32; ++j){
193 for(i = 0; i < 192 / BIGINT_WORD_SIZE; ++i){
194 ((uint8_t*)a_w)[i] = random();
196 a.length_W = 192 / BIGINT_WORD_SIZE;
200 for(i = 0; i < 192 / BIGINT_WORD_SIZE; ++i){
201 ((uint8_t*)b_w)[i] = random();
203 b.length_W = 192 / BIGINT_WORD_SIZE;
207 for(i = 0; i < 16; ++i){
210 bigint_mul_u(&v,&a, &b);
217 bigint_reduce_p192(&v);
233 printf_P(PSTR(" multiply costs %7"PRIu32" cycles\n"), (uint32_t)time_a);
234 printf_P(PSTR(" multiply + reduce costs %7"PRIu32" cycles\n"), (uint32_t)time_b);
237 void testrun_performance_reduce_bigint(void){
238 printf_P(PSTR("\n=== performance measurement (reduce) ===\n"));
241 bigint_word_t v_w[192 * 2 / BIGINT_WORD_SIZE];
242 bigint_word_t a_w[192 * 2 / BIGINT_WORD_SIZE];
243 bigint_word_t b_w[192 * 2 / BIGINT_WORD_SIZE];
244 uint32_t time_a, time_b;
246 int16_t faster_percent;
248 for(j = 0; j < 32; ++j){
250 for(i = 0; i < 192 * 2 / BIGINT_WORD_SIZE; ++i){
251 ((uint8_t*)v_w)[i] = random();
253 v.length_W = 192 * 2 / BIGINT_WORD_SIZE;
258 // printf_P(PSTR("candidate:\n"));
259 // bigint_print_hex(&v);
264 // printf_P(PSTR("\n going to test optimized version: ...\n"));
267 for(i = 0; i < 16; ++i){
271 bigint_reduce_p192(&a);
273 time_a += stopTimer();
275 // printf_P(PSTR(" took: %"PRIu32" cycles\nresult:"), time);
276 // bigint_print_hex(&a);
279 // printf_P(PSTR("\n going to test not-optimized version: ...\n"));
282 for(i = 0; i < 16; ++i){
286 bigint_reduce(&b, &nist_curve_p192_p);
288 time_b += stopTimer();
290 // printf_P(PSTR(" took: %"PRIu32" cycles\nresult:"), time);
291 // bigint_print_hex(&b);
293 time_diff = time_b - time_a;
294 faster_percent = (time_diff * 100) / time_b;
296 printf_P(PSTR(" delta: %7"PRId32" (%3"PRId16"%%) :-"), time_diff, faster_percent);
297 if(bigint_cmp_u(&a, &b)){
298 printf_P(PSTR("(\n"));
300 printf_P(PSTR(")\n"));
306 uint8_t ecc_affine_point_alloc(ecc_affine_point_t *p, uint16_t length_b){
307 size_t len = (length_b + BIGINT_WORD_SIZE - 1)/ BIGINT_WORD_SIZE;
308 if (! (p->x.wordv = malloc(len))){
311 if (! (p->y.wordv = malloc(len))){
318 void ecc_affine_point_free(ecc_affine_point_t *p){
324 void testrun_square(void){
325 bigint_word_t a_w[] = {
326 0x82, 0x6f, 0x79, 0x39, 0x47, 0x06, 0x26, 0x9f,
327 0x4b, 0xe2, 0x15, 0x61, 0x6f, 0xa1, 0xd4, 0x0c,
328 0x1f, 0x24, 0x3a, 0xd4, 0xc2, 0x6d, 0xe8, 0xb6
331 bigint_word_t b_w[2 * 192 / BIGINT_WORD_SIZE];
335 a.length_W = sizeof(a_w);
342 printf_P(PSTR("\n a = "));
343 bigint_print_hex(&a);
344 bigint_square(&b, &a);
345 printf_P(PSTR("\n a^2 = "));
346 bigint_print_hex(&b);
347 bigint_reduce_p192(&b);
348 printf_P(PSTR("\n a^2 %% p = "));
349 bigint_print_hex(&b);
357 0: b3cfed2634516540528622e16c396c229e50bbdf773f8423
358 1: b6e86dc2d43a241f0cd4a16f6115e24b9f26064739796f82
359 2: 563f557e41731f268f82fe81c8fed959600dd46649ebeeee
360 3: 5e45169bd87475db886b8a7833bb0845f5b011a7ce0c1766
361 4: 4abf34c505a73308a804dcefacbd8f7b10b59fa6ac6421a
363 uint8_t test_point_x_w[] = {
364 0x23, 0x84, 0x3f, 0x77, 0xdf, 0xbb, 0x50, 0x9e,
365 0x22, 0x6c, 0x39, 0x6c, 0xe1, 0x22, 0x86, 0x52,
366 0x40, 0x65, 0x51, 0x34, 0x26, 0xed, 0xcf, 0xb3
369 uint8_t test_point_y_w[] = {
370 0x82, 0x6f, 0x79, 0x39, 0x47, 0x06, 0x26, 0x9f,
371 0x4b, 0xe2, 0x15, 0x61, 0x6f, 0xa1, 0xd4, 0x0c,
372 0x1f, 0x24, 0x3a, 0xd4, 0xc2, 0x6d, 0xe8, 0xb6
375 uint8_t test_point_z1_w[] = {
376 0xee, 0xee, 0xeb, 0x49, 0x66, 0xd4, 0x0d, 0x60,
377 0x59, 0xd9, 0xfe, 0xc8, 0x81, 0xfe, 0x82, 0x8f,
378 0x26, 0x1f, 0x73, 0x41, 0x7e, 0x55, 0x3f, 0x56
381 uint8_t test_point_z2_w[] = {
382 0x66, 0x17, 0x0c, 0xce, 0xa7, 0x11, 0xb0, 0xf5,
383 0x45, 0x08, 0xbb, 0x33, 0x78, 0x8a, 0x6b, 0x88,
384 0xdb, 0x75, 0x74, 0xd8, 0x9b, 0x16, 0x45, 0x5e
387 uint8_t test_point_z3_w[] = {
388 0x1a, 0x42, 0xc6, 0x6a, 0xfa, 0x59, 0x0b, 0xb1,
389 0xf7, 0xd8, 0xcb, 0xfa, 0xce, 0x4d, 0x80, 0x8a,
390 0x30, 0x73, 0x5a, 0x50, 0x4c, 0xf3, 0xab, 0x04
393 ecc_combi_point_t test_point = {
396 .wordv = test_point_x_w,
397 .length_W = sizeof(test_point_x_w),
401 .wordv = test_point_y_w,
402 .length_W = sizeof(test_point_y_w),
406 .wordv = test_point_z1_w,
407 .length_W = sizeof(test_point_z1_w),
411 .wordv = test_point_z2_w,
412 .length_W = sizeof(test_point_z2_w),
416 .wordv = test_point_z3_w,
417 .length_W = sizeof(test_point_z3_w),
422 void testrun_genkey2(void){
423 ecc_chudnovsky_point_t q;
424 ecc_affine_point_t qa;
426 printf_P(PSTR("\n== testing key generation (2) ==\n"));
428 if(ecc_chudnovsky_point_alloc(&q, 192)){
429 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
432 if(ecc_affine_point_alloc(&qa, 192)){
433 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
437 ecc_chudnovsky_point_print(&test_point.chudnovsky);
438 ecc_chudnovsky_to_affine_point(&qa, &test_point.chudnovsky, &nist_curve_p192);
439 printf_P(PSTR("\n Qx: "));
440 bigint_print_hex(&qa.x);
441 printf_P(PSTR("\n Qy: "));
442 bigint_print_hex(&qa.y);
443 printf_P(PSTR("\n================\n"));
444 ecc_chudnovsky_point_double_sp(&q, &test_point.chudnovsky, &nist_curve_p192);
445 ecc_chudnovsky_point_print(&q);
447 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
449 printf_P(PSTR("\n Qx: "));
450 bigint_print_hex(&qa.x);
451 printf_P(PSTR("\n Qy: "));
452 bigint_print_hex(&qa.y);
457 void testrun_genkey1(void){
458 ecc_chudnovsky_point_t q;
459 ecc_affine_point_t qa;
462 // e5ce89a34adddf25ff3bf1ffe6803f57d0220de3118798ea
463 0xea, 0x98, 0x87, 0x11, 0xe3, 0x0d, 0x22, 0xd0,
464 0x57, 0x3f, 0x80, 0xe6, 0xff, 0xf1, 0x3b, 0xff,
465 0x25, 0xdf, 0xdd, 0x4a, 0xa3, 0x89, 0xce, 0xe5
469 .length_W = sizeof(k_w),
474 printf_P(PSTR("\n== testing key generation ==\n"));
476 if(ecc_chudnovsky_point_alloc(&q, 192)){
477 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
480 if(ecc_affine_point_alloc(&qa, 192)){
481 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
485 printf_P(PSTR(" k: "));
486 bigint_print_hex(&k);
487 ecc_chudnovsky_multiplication(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
488 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
490 printf_P(PSTR("\n Qx: "));
491 bigint_print_hex(&qa.x);
492 printf_P(PSTR("\n Qy: "));
493 bigint_print_hex(&qa.y);
497 void testrun_genkey3(void){
498 ecc_chudnovsky_point_t q;
499 ecc_affine_point_t qa;
502 0xb2, 0x51, 0x97, 0xc3, 0x7c, 0x61, 0xf8, 0x8f,
503 0x19, 0x91, 0xcc, 0x67, 0xb5, 0x1c, 0x34, 0x23,
504 0xff, 0x13, 0xad, 0x14, 0x57, 0x43, 0x14, 0x7d
508 .length_W = sizeof(k_w),
513 printf_P(PSTR("\n== testing key generation ==\n"));
515 if(ecc_chudnovsky_point_alloc(&q, 192)){
516 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
519 if(ecc_affine_point_alloc(&qa, 192)){
520 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
524 printf_P(PSTR(" k: "));
525 bigint_print_hex(&k);
526 ecc_chudnovsky_double_and_add(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
527 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
529 printf_P(PSTR("\n Qx: "));
530 bigint_print_hex(&qa.x);
531 printf_P(PSTR("\n Qy: "));
532 bigint_print_hex(&qa.y);
536 void testrun_genkey(void){
537 ecc_chudnovsky_point_t q;
538 ecc_affine_point_t qa;
543 printf_P(PSTR("\n== testing key generation ==\n"));
545 printf_P(PSTR("enter secret key d: "));
546 bigint_read_hex_echo(&k);
549 if(ecc_chudnovsky_point_alloc(&q, 192)){
550 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
553 if(ecc_affine_point_alloc(&qa, 192)){
554 ecc_chudnovsky_point_free(&q);
555 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
559 printf_P(PSTR("(naf) k: "));
560 bigint_print_hex(&k);
563 r = ecc_chudnovsky_naf_multiplication(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
566 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
568 printf_P(PSTR("\n Qx: "));
569 bigint_print_hex(&qa.x);
570 printf_P(PSTR("\n Qy: "));
571 bigint_print_hex(&qa.y);
572 printf_P(PSTR("\n time: %"PRIu32" cycles (r code: %"PRIu8")\n"), time, r);
574 printf_P(PSTR("(d&a) k: "));
575 bigint_print_hex(&k);
578 r = ecc_chudnovsky_double_and_add(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
581 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
583 printf_P(PSTR("\n Qx: "));
584 bigint_print_hex(&qa.x);
585 printf_P(PSTR("\n Qy: "));
586 bigint_print_hex(&qa.y);
587 printf_P(PSTR("\n time: %"PRIu32" cycles (r code: %"PRIu8")\n"), time, r);
589 ecc_chudnovsky_point_free(&q);
590 ecc_affine_point_free(&qa);
596 const uint8_t ecdsa_test_1_msg[] PROGMEM = {
598 0xcf, 0x71, 0xa0, 0xe4, 0xce, 0x59, 0x43, 0x11,
599 0x77, 0x88, 0x50, 0x87, 0x53, 0x78, 0xd0, 0xee,
600 0xa3, 0xc0, 0x32, 0xa4, 0xbc, 0xc0, 0xdc, 0x1c,
601 0xf2, 0x9d, 0x01, 0xb9, 0xc5, 0x10, 0x78, 0x9c,
602 0xd5, 0x2f, 0xc3, 0x8c, 0x74, 0xe6, 0xa4, 0x27,
603 0x87, 0xd0, 0xf2, 0x7c, 0xe2, 0x93, 0x20, 0x7a,
604 0xfd, 0xd0, 0x11, 0x7a, 0xcc, 0x71, 0xb9, 0x16,
605 0x63, 0x06, 0xce, 0x56, 0xf1, 0xa7, 0xf1, 0xc6,
606 0x0a, 0x9d, 0x68, 0x7d, 0x12, 0x5e, 0xb0, 0x7e,
607 0x26, 0xe5, 0x51, 0xdc, 0x14, 0x0e, 0x8a, 0x04,
608 0xaf, 0xa2, 0xa1, 0x6f, 0x98, 0xb5, 0x1b, 0xa9,
609 0x18, 0x96, 0xbf, 0x32, 0x0f, 0xd4, 0xd6, 0xf1,
610 0xa4, 0x4b, 0x46, 0xf3, 0x3d, 0xae, 0x39, 0xcc,
611 0x24, 0xf0, 0x4a, 0x5d, 0x86, 0x0c, 0xb1, 0x4f,
612 0x6b, 0x6e, 0x8a, 0x69, 0x73, 0xb4, 0x9f, 0xd2,
613 0xa7, 0xbc, 0xeb, 0x48, 0xd7, 0x48, 0xf7, 0xeb
615 0xeb, 0xf7, 0x48, 0xd7, 0x48, 0xeb, 0xbc, 0xa7,
616 0xd2, 0x9f, 0xb4, 0x73, 0x69, 0x8a, 0x6e, 0x6b,
617 0x4f, 0xb1, 0x0c, 0x86, 0x5d, 0x4a, 0xf0, 0x24,
618 0xcc, 0x39, 0xae, 0x3d, 0xf3, 0x46, 0x4b, 0xa4,
619 0xf1, 0xd6, 0xd4, 0x0f, 0x32, 0xbf, 0x96, 0x18,
620 0xa9, 0x1b, 0xb5, 0x98, 0x6f, 0xa1, 0xa2, 0xaf,
621 0x04, 0x8a, 0x0e, 0x14, 0xdc, 0x51, 0xe5, 0x26,
622 0x7e, 0xb0, 0x5e, 0x12, 0x7d, 0x68, 0x9d, 0x0a,
623 0xc6, 0xf1, 0xa7, 0xf1, 0x56, 0xce, 0x06, 0x63,
624 0x16, 0xb9, 0x71, 0xcc, 0x7a, 0x11, 0xd0, 0xfd,
625 0x7a, 0x20, 0x93, 0xe2, 0x7c, 0xf2, 0xd0, 0x87,
626 0x27, 0xa4, 0xe6, 0x74, 0x8c, 0xc3, 0x2f, 0xd5,
627 0x9c, 0x78, 0x10, 0xc5, 0xb9, 0x01, 0x9d, 0xf2,
628 0x1c, 0xdc, 0xc0, 0xbc, 0xa4, 0x32, 0xc0, 0xa3,
629 0xee, 0xd0, 0x78, 0x53, 0x87, 0x50, 0x88, 0x77,
630 0x11, 0x43, 0x59, 0xce, 0xe4, 0xa0, 0x71, 0xcf
633 const uint8_t ecdsa_test_1_d[] PROGMEM = {
634 0xf3, 0xd7, 0x60, 0xd6, 0x75, 0xf2, 0xcc, 0xeb,
635 0xf0, 0xd2, 0xfd, 0xb3, 0xb9, 0x41, 0x3f, 0xb0,
636 0xf8, 0x4f, 0x37, 0xd1, 0xb3, 0x37, 0x4f, 0xe1
639 const uint8_t ecdsa_test_1_k[] PROGMEM = {
640 0x25, 0x5f, 0x68, 0x89, 0xa2, 0x31, 0xbc, 0x57,
641 0x4d, 0x15, 0xc4, 0x12, 0xfb, 0x56, 0x45, 0x68,
642 0x83, 0x07, 0xa1, 0x43, 0x70, 0xbc, 0x0a, 0xcb
645 void hash_mem_P(const hfdesc_t *hfdesc, void *dest, const void *msg, uint16_t msg_len_b){
646 uint16_t blocksize = hfal_hash_getBlocksize(hfdesc);
647 uint8_t block[blocksize / 8];
649 hfal_hash_init(hfdesc, &ctx);
650 while(msg_len_b > blocksize){
651 memcpy_P(block, msg, blocksize / 8);
652 msg = (uint8_t*)msg + blocksize / 8;
653 msg_len_b -= blocksize;
654 hfal_hash_nextBlock(&ctx, block);
656 memcpy_P(block, msg, (msg_len_b + 7) / 8);
657 hfal_hash_lastBlock(&ctx, block, msg_len_b);
658 hfal_hash_ctx2hash(dest, &ctx);
659 hfal_hash_free(&ctx);
662 const uint8_t ecdsa_test_2_msg[] PROGMEM = {
663 0x66, 0xa2, 0x51, 0x3d, 0x7b, 0x60, 0x45, 0xe5,
664 0x66, 0x79, 0xb0, 0x32, 0xca, 0xd4, 0x5f, 0xb1,
665 0x82, 0x28, 0x9c, 0xa7, 0x6a, 0x88, 0xc0, 0x6d,
666 0x78, 0xc8, 0x5f, 0x3d, 0xd3, 0x80, 0x45, 0x90,
667 0x20, 0x5b, 0x73, 0xa7, 0x84, 0x24, 0x9a, 0x0a,
668 0x0c, 0x8b, 0xf2, 0xf2, 0x21, 0x45, 0xd1, 0x05,
669 0x21, 0x9b, 0x48, 0x0d, 0x74, 0x60, 0x7c, 0x02,
670 0xb8, 0xa6, 0xb6, 0xb4, 0x59, 0x25, 0x9e, 0x4f,
671 0xdf, 0xe2, 0xbd, 0xb4, 0xab, 0x22, 0x38, 0x01,
672 0x75, 0x35, 0x29, 0x1d, 0x7a, 0xc1, 0xab, 0xda,
673 0x66, 0xc4, 0xf6, 0xdc, 0xea, 0x9e, 0x5d, 0x0b,
674 0xf0, 0x5a, 0x93, 0x06, 0xf3, 0x33, 0xb0, 0x0e,
675 0x56, 0x34, 0x2f, 0x75, 0x53, 0x40, 0x21, 0x1a,
676 0xc2, 0x94, 0xac, 0x21, 0xa7, 0xc2, 0xb2, 0x67,
677 0x12, 0xb8, 0x79, 0x95, 0x1b, 0x2e, 0x23, 0xf6,
678 0x48, 0x7e, 0x4d, 0x39, 0x89, 0x9f, 0xe3, 0x74
681 const uint8_t ecdsa_test_2_d[] PROGMEM = {
682 0xeb, 0x8e, 0x9f, 0x04, 0x7d, 0xb5, 0x9a, 0x80,
683 0x34, 0x6f, 0xcd, 0xf1, 0xcc, 0x33, 0xbb, 0x78,
684 0xbe, 0xc6, 0xb8, 0x76, 0xaf, 0x9f, 0x4b, 0x69
687 const uint8_t ecdsa_test_2_k[] PROGMEM = {
688 0x8e, 0xd5, 0x00, 0x34, 0x08, 0x09, 0x60, 0x36,
689 0x2e, 0xfe, 0x16, 0xd0, 0x53, 0x37, 0xa2, 0xf5,
690 0x47, 0xfa, 0x11, 0xbc, 0xb1, 0xc2, 0xe8, 0x41
693 void test_sign1(void){
694 bigint_word_t d_w[sizeof(ecdsa_test_1_d)];
695 uint8_t rnd[sizeof(ecdsa_test_1_k)];
698 const hfdesc_t *hash_desc;
700 ecdsa_signature_t sign;
706 memcpy_P(rnd, ecdsa_test_1_k, sizeof(ecdsa_test_1_k));
707 memcpy_P(d_w, ecdsa_test_1_d, sizeof(ecdsa_test_1_d) * sizeof(bigint_word_t));
708 d.length_W = sizeof(ecdsa_test_1_d) / sizeof(bigint_word_t);
712 hash_desc = &sha1_desc; //hash_select();
713 hash = malloc(hfal_hash_getHashsize(hash_desc) / 8);
715 printf_P(PSTR("DBG: XXX <%S %s %d>\n"), PSTR(__FILE__), __func__, __LINE__);
717 hash_mem_P(hash_desc, hash, ecdsa_test_1_msg, sizeof(ecdsa_test_1_msg) * 8);
718 printf_P(PSTR("msg hash: "));
719 cli_hexdump(hash, hfal_hash_getHashsize(hash_desc) / 8);
722 ecc_chudnovsky_point_alloc(&q.chudnovsky, nist_curve_p192_p.length_W * sizeof(bigint_word_t));
723 ctx.basepoint = &nist_curve_p192_basepoint.chudnovsky;
725 ctx.curve = &nist_curve_p192;
728 bigint_print_hex(&d);
729 printf_P(PSTR("\n Gx: "));
730 bigint_print_hex(&nist_curve_p192_basepoint.affine.x);
731 printf_P(PSTR("\n Gy: "));
732 bigint_print_hex(&nist_curve_p192_basepoint.affine.y);
734 r = ecc_chudnovsky_multiplication(&q.chudnovsky, &d, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
736 printf_P(PSTR("ERROR: ecc_chudnovsky_multiplication() returned: %"PRIu8"\n"), r);
738 r = ecc_chudnovsky_to_affine_point(&q.affine, &q.chudnovsky, &nist_curve_p192);
740 printf_P(PSTR("ERROR: ecc_chudnovsky_to_affine_point() returned: %"PRIu8"\n"), r);
743 printf_P(PSTR("\n Qx: "));
744 bigint_print_hex(&q.affine.x);
745 printf_P(PSTR("\n Qy: "));
746 bigint_print_hex(&q.affine.y);
750 ecdsa_signature_alloc(&sign, sizeof(ecdsa_test_1_d) * sizeof(bigint_word_t));
752 r = ecdsa_sign_hash(&sign, hash, hfal_hash_getHashsize(hash_desc) / 8, &ctx, rnd);
754 printf_P(PSTR("ERROR: ecdsa_sign_message() returned: %"PRIu8"\n"), r);
756 printf_P(PSTR(" r: "));
757 bigint_print_hex(&sign.r);
758 printf_P(PSTR("\n s: "));
759 bigint_print_hex(&sign.s);
762 ecdsa_signature_free(&sign);
763 ecc_chudnovsky_point_free(&q.chudnovsky);
766 void test_sign2(void){
767 bigint_word_t d_w[sizeof(ecdsa_test_2_d)];
768 uint8_t rnd[sizeof(ecdsa_test_2_k)];
771 const hfdesc_t *hash_desc;
773 ecdsa_signature_t sign;
779 memcpy_P(rnd, ecdsa_test_2_k, sizeof(ecdsa_test_2_k));
780 memcpy_P(d_w, ecdsa_test_2_d, sizeof(ecdsa_test_2_d) * sizeof(bigint_word_t));
781 d.length_W = sizeof(ecdsa_test_2_d) / sizeof(bigint_word_t);
785 hash_desc = &sha224_desc; //hash_select();
786 hash = malloc(hfal_hash_getHashsize(hash_desc) / 8);
788 printf_P(PSTR("DBG: XXX <%S %s %d>\n"), PSTR(__FILE__), __func__, __LINE__);
790 hash_mem_P(hash_desc, hash, ecdsa_test_2_msg, sizeof(ecdsa_test_1_msg) * 8);
791 printf_P(PSTR("msg hash: "));
792 cli_hexdump(hash, hfal_hash_getHashsize(hash_desc) / 8);
795 ecc_chudnovsky_point_alloc(&q.chudnovsky, nist_curve_p192_p.length_W * sizeof(bigint_word_t));
796 ctx.basepoint = &nist_curve_p192_basepoint.chudnovsky;
798 ctx.curve = &nist_curve_p192;
801 bigint_print_hex(&d);
802 printf_P(PSTR("\n Gx: "));
803 bigint_print_hex(&nist_curve_p192_basepoint.affine.x);
804 printf_P(PSTR("\n Gy: "));
805 bigint_print_hex(&nist_curve_p192_basepoint.affine.y);
807 r = ecc_chudnovsky_multiplication(&q.chudnovsky, &d, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
809 printf_P(PSTR("ERROR: ecc_chudnovsky_multiplication() returned: %"PRIu8"\n"), r);
811 r = ecc_chudnovsky_to_affine_point(&q.affine, &q.chudnovsky, &nist_curve_p192);
813 printf_P(PSTR("ERROR: ecc_chudnovsky_to_affine_point() returned: %"PRIu8"\n"), r);
816 printf_P(PSTR("\n Qx: "));
817 bigint_print_hex(&q.affine.x);
818 printf_P(PSTR("\n Qy: "));
819 bigint_print_hex(&q.affine.y);
823 ecdsa_signature_alloc(&sign, sizeof(ecdsa_test_2_d) * sizeof(bigint_word_t));
825 r = ecdsa_sign_hash(&sign, hash, hfal_hash_getHashsize(hash_desc) / 8, &ctx, rnd);
827 printf_P(PSTR("ERROR: ecdsa_sign_message() returned: %"PRIu8"\n"), r);
829 printf_P(PSTR(" r: "));
830 bigint_print_hex(&sign.r);
831 printf_P(PSTR("\n s: "));
832 bigint_print_hex(&sign.s);
835 ecdsa_signature_free(&sign);
836 ecc_chudnovsky_point_free(&q.chudnovsky);
838 /*****************************************************************************
840 *****************************************************************************/
842 const char echo_test_str[] PROGMEM = "echo-test";
843 const char reset_prng_str[] PROGMEM = "reset-prng";
844 const char quick_test_str[] PROGMEM = "quick-test";
845 const char performance_reduce_str[] PROGMEM = "performance_reduce";
846 const char performance_invert_str[] PROGMEM = "performance_invert";
847 const char performance_multiply_str[] PROGMEM = "performance_multiply";
848 const char genkey1_str[] PROGMEM = "genkey1";
849 const char genkey2_str[] PROGMEM = "genkey2";
850 const char genkey3_str[] PROGMEM = "genkey3";
851 const char genkey_str[] PROGMEM = "genkey";
852 const char testsign1_str[] PROGMEM = "testsign1";
853 const char testsign2_str[] PROGMEM = "testsign2";
854 const char square_str[] PROGMEM = "square";
855 const char echo_str[] PROGMEM = "echo";
857 const const cmdlist_entry_t cmdlist[] PROGMEM = {
858 // { reset_prng_str, NULL, reset_prng },
859 // { quick_test_str, NULL, quick_test },
860 { square_str, NULL, testrun_square },
861 { genkey_str, NULL, testrun_genkey },
862 { genkey1_str, NULL, testrun_genkey1 },
863 { genkey2_str, NULL, testrun_genkey2 },
864 { genkey3_str, NULL, testrun_genkey3 },
865 { testsign1_str, NULL, test_sign1 },
866 { testsign2_str, NULL, test_sign2 },
867 { performance_reduce_str, NULL, testrun_performance_reduce_bigint },
868 { performance_invert_str, NULL, testrun_performance_invert_bigint },
869 { performance_multiply_str, NULL, testrun_performance_multiply_bigint },
870 { echo_str, (void*)1, (void_fpt)echo_ctrl },
879 welcome_msg(algo_name);
880 r = cmd_interface(cmdlist);
881 printf("r = %"PRId8"\n", r);
882 cli_putstr_P(PSTR("\r\nHello!\r\n"));