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);
496 ecc_affine_point_free(&qa);
497 ecc_chudnovsky_point_free(&q);
500 void testrun_genkey3(void){
501 ecc_chudnovsky_point_t q;
502 ecc_affine_point_t qa;
505 0xb2, 0x51, 0x97, 0xc3, 0x7c, 0x61, 0xf8, 0x8f,
506 0x19, 0x91, 0xcc, 0x67, 0xb5, 0x1c, 0x34, 0x23,
507 0xff, 0x13, 0xad, 0x14, 0x57, 0x43, 0x14, 0x7d
511 .length_W = sizeof(k_w),
516 printf_P(PSTR("\n== testing key generation ==\n"));
518 if(ecc_chudnovsky_point_alloc(&q, 192)){
519 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
522 if(ecc_affine_point_alloc(&qa, 192)){
523 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
527 printf_P(PSTR(" k: "));
528 bigint_print_hex(&k);
529 ecc_chudnovsky_double_and_add(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
530 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
532 printf_P(PSTR("\n Qx: "));
533 bigint_print_hex(&qa.x);
534 printf_P(PSTR("\n Qy: "));
535 bigint_print_hex(&qa.y);
538 ecc_affine_point_free(&qa);
539 ecc_chudnovsky_point_free(&q);
543 void testrun_genkey(void){
544 ecc_chudnovsky_point_t q;
545 ecc_affine_point_t qa;
550 printf_P(PSTR("\n== testing key generation ==\n"));
552 printf_P(PSTR("enter secret key d: "));
553 bigint_read_hex_echo(&k);
556 if(ecc_chudnovsky_point_alloc(&q, 192)){
557 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
560 if(ecc_affine_point_alloc(&qa, 192)){
561 ecc_chudnovsky_point_free(&q);
562 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
566 printf_P(PSTR("(naf) k: "));
567 bigint_print_hex(&k);
570 r = ecc_chudnovsky_naf_multiplication(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
573 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
575 printf_P(PSTR("\n Qx: "));
576 bigint_print_hex(&qa.x);
577 printf_P(PSTR("\n Qy: "));
578 bigint_print_hex(&qa.y);
579 printf_P(PSTR("\n time: %"PRIu32" cycles (r code: %"PRIu8")\n"), time, r);
581 printf_P(PSTR("(d&a) k: "));
582 bigint_print_hex(&k);
585 r = ecc_chudnovsky_double_and_add(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
588 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
590 printf_P(PSTR("\n Qx: "));
591 bigint_print_hex(&qa.x);
592 printf_P(PSTR("\n Qy: "));
593 bigint_print_hex(&qa.y);
594 printf_P(PSTR("\n time: %"PRIu32" cycles (r code: %"PRIu8")\n"), time, r);
596 ecc_chudnovsky_point_free(&q);
597 ecc_affine_point_free(&qa);
601 3128D2B4 B1C96B14 36F8DE99 FFFFFFFF FFFFFFFF FFFFFFFF 99DEF836 146BC9B1 B4D22831
602 --------------------------------------------------------------
604 78916860 32FD8057 F636B44B 1F47CCE5 64D25099 23A7465A
605 --------------------------------------------------------------
607 78916860 32FD8057 F636B44B 1F47CCE5 64D25099 23A7465B
609 FBA2AAC6 47884B50 4EB8CD5A 0A1287BA BCC62163 F606A9A2
611 DAE6D4CC 05EF4F27 D79EE38B 71C9C8EF 4865D988 50D84AA5
614 void testrun_interm(void){
615 ecc_chudnovsky_point_t q;
616 ecc_affine_point_t qa;
621 printf_P(PSTR("\n== testing key generation ==\n"));
623 printf_P(PSTR("enter secret key d: "));
624 bigint_read_hex_echo(&k);
627 if(ecc_chudnovsky_point_alloc(&q, 192)){
628 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
631 if(ecc_affine_point_alloc(&qa, 192)){
632 ecc_chudnovsky_point_free(&q);
633 printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
637 printf_P(PSTR("(naf) k: "));
638 bigint_print_hex(&k);
641 r = ecc_chudnovsky_naf_multiplication(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
644 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
646 printf_P(PSTR("\n Qx: "));
647 bigint_print_hex(&qa.x);
648 printf_P(PSTR("\n Qy: "));
649 bigint_print_hex(&qa.y);
650 printf_P(PSTR("\n time: %"PRIu32" cycles (r code: %"PRIu8")\n"), time, r);
652 printf_P(PSTR("(d&a) k: "));
653 bigint_print_hex(&k);
656 r = ecc_chudnovsky_double_and_add(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
659 ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);
661 printf_P(PSTR("\n Qx: "));
662 bigint_print_hex(&qa.x);
663 printf_P(PSTR("\n Qy: "));
664 bigint_print_hex(&qa.y);
665 printf_P(PSTR("\n time: %"PRIu32" cycles (r code: %"PRIu8")\n"), time, r);
667 ecc_chudnovsky_point_free(&q);
668 ecc_affine_point_free(&qa);
675 const uint8_t ecdsa_test_1_msg[] PROGMEM = {
677 0xcf, 0x71, 0xa0, 0xe4, 0xce, 0x59, 0x43, 0x11,
678 0x77, 0x88, 0x50, 0x87, 0x53, 0x78, 0xd0, 0xee,
679 0xa3, 0xc0, 0x32, 0xa4, 0xbc, 0xc0, 0xdc, 0x1c,
680 0xf2, 0x9d, 0x01, 0xb9, 0xc5, 0x10, 0x78, 0x9c,
681 0xd5, 0x2f, 0xc3, 0x8c, 0x74, 0xe6, 0xa4, 0x27,
682 0x87, 0xd0, 0xf2, 0x7c, 0xe2, 0x93, 0x20, 0x7a,
683 0xfd, 0xd0, 0x11, 0x7a, 0xcc, 0x71, 0xb9, 0x16,
684 0x63, 0x06, 0xce, 0x56, 0xf1, 0xa7, 0xf1, 0xc6,
685 0x0a, 0x9d, 0x68, 0x7d, 0x12, 0x5e, 0xb0, 0x7e,
686 0x26, 0xe5, 0x51, 0xdc, 0x14, 0x0e, 0x8a, 0x04,
687 0xaf, 0xa2, 0xa1, 0x6f, 0x98, 0xb5, 0x1b, 0xa9,
688 0x18, 0x96, 0xbf, 0x32, 0x0f, 0xd4, 0xd6, 0xf1,
689 0xa4, 0x4b, 0x46, 0xf3, 0x3d, 0xae, 0x39, 0xcc,
690 0x24, 0xf0, 0x4a, 0x5d, 0x86, 0x0c, 0xb1, 0x4f,
691 0x6b, 0x6e, 0x8a, 0x69, 0x73, 0xb4, 0x9f, 0xd2,
692 0xa7, 0xbc, 0xeb, 0x48, 0xd7, 0x48, 0xf7, 0xeb
694 0xeb, 0xf7, 0x48, 0xd7, 0x48, 0xeb, 0xbc, 0xa7,
695 0xd2, 0x9f, 0xb4, 0x73, 0x69, 0x8a, 0x6e, 0x6b,
696 0x4f, 0xb1, 0x0c, 0x86, 0x5d, 0x4a, 0xf0, 0x24,
697 0xcc, 0x39, 0xae, 0x3d, 0xf3, 0x46, 0x4b, 0xa4,
698 0xf1, 0xd6, 0xd4, 0x0f, 0x32, 0xbf, 0x96, 0x18,
699 0xa9, 0x1b, 0xb5, 0x98, 0x6f, 0xa1, 0xa2, 0xaf,
700 0x04, 0x8a, 0x0e, 0x14, 0xdc, 0x51, 0xe5, 0x26,
701 0x7e, 0xb0, 0x5e, 0x12, 0x7d, 0x68, 0x9d, 0x0a,
702 0xc6, 0xf1, 0xa7, 0xf1, 0x56, 0xce, 0x06, 0x63,
703 0x16, 0xb9, 0x71, 0xcc, 0x7a, 0x11, 0xd0, 0xfd,
704 0x7a, 0x20, 0x93, 0xe2, 0x7c, 0xf2, 0xd0, 0x87,
705 0x27, 0xa4, 0xe6, 0x74, 0x8c, 0xc3, 0x2f, 0xd5,
706 0x9c, 0x78, 0x10, 0xc5, 0xb9, 0x01, 0x9d, 0xf2,
707 0x1c, 0xdc, 0xc0, 0xbc, 0xa4, 0x32, 0xc0, 0xa3,
708 0xee, 0xd0, 0x78, 0x53, 0x87, 0x50, 0x88, 0x77,
709 0x11, 0x43, 0x59, 0xce, 0xe4, 0xa0, 0x71, 0xcf
712 const uint8_t ecdsa_test_1_d[] PROGMEM = {
713 0xf3, 0xd7, 0x60, 0xd6, 0x75, 0xf2, 0xcc, 0xeb,
714 0xf0, 0xd2, 0xfd, 0xb3, 0xb9, 0x41, 0x3f, 0xb0,
715 0xf8, 0x4f, 0x37, 0xd1, 0xb3, 0x37, 0x4f, 0xe1
718 const uint8_t ecdsa_test_1_k[] PROGMEM = {
719 0x25, 0x5f, 0x68, 0x89, 0xa2, 0x31, 0xbc, 0x57,
720 0x4d, 0x15, 0xc4, 0x12, 0xfb, 0x56, 0x45, 0x68,
721 0x83, 0x07, 0xa1, 0x43, 0x70, 0xbc, 0x0a, 0xcb
724 void hash_mem_P(const hfdesc_t *hfdesc, void *dest, const void *msg, uint16_t msg_len_b){
725 uint16_t blocksize = hfal_hash_getBlocksize(hfdesc);
726 uint8_t block[blocksize / 8];
728 hfal_hash_init(hfdesc, &ctx);
729 while(msg_len_b > blocksize){
730 memcpy_P(block, msg, blocksize / 8);
731 msg = (uint8_t*)msg + blocksize / 8;
732 msg_len_b -= blocksize;
733 hfal_hash_nextBlock(&ctx, block);
735 memcpy_P(block, msg, (msg_len_b + 7) / 8);
736 hfal_hash_lastBlock(&ctx, block, msg_len_b);
737 hfal_hash_ctx2hash(dest, &ctx);
738 hfal_hash_free(&ctx);
741 const uint8_t ecdsa_test_2_msg[] PROGMEM = {
742 0x66, 0xa2, 0x51, 0x3d, 0x7b, 0x60, 0x45, 0xe5,
743 0x66, 0x79, 0xb0, 0x32, 0xca, 0xd4, 0x5f, 0xb1,
744 0x82, 0x28, 0x9c, 0xa7, 0x6a, 0x88, 0xc0, 0x6d,
745 0x78, 0xc8, 0x5f, 0x3d, 0xd3, 0x80, 0x45, 0x90,
746 0x20, 0x5b, 0x73, 0xa7, 0x84, 0x24, 0x9a, 0x0a,
747 0x0c, 0x8b, 0xf2, 0xf2, 0x21, 0x45, 0xd1, 0x05,
748 0x21, 0x9b, 0x48, 0x0d, 0x74, 0x60, 0x7c, 0x02,
749 0xb8, 0xa6, 0xb6, 0xb4, 0x59, 0x25, 0x9e, 0x4f,
750 0xdf, 0xe2, 0xbd, 0xb4, 0xab, 0x22, 0x38, 0x01,
751 0x75, 0x35, 0x29, 0x1d, 0x7a, 0xc1, 0xab, 0xda,
752 0x66, 0xc4, 0xf6, 0xdc, 0xea, 0x9e, 0x5d, 0x0b,
753 0xf0, 0x5a, 0x93, 0x06, 0xf3, 0x33, 0xb0, 0x0e,
754 0x56, 0x34, 0x2f, 0x75, 0x53, 0x40, 0x21, 0x1a,
755 0xc2, 0x94, 0xac, 0x21, 0xa7, 0xc2, 0xb2, 0x67,
756 0x12, 0xb8, 0x79, 0x95, 0x1b, 0x2e, 0x23, 0xf6,
757 0x48, 0x7e, 0x4d, 0x39, 0x89, 0x9f, 0xe3, 0x74
760 const uint8_t ecdsa_test_2_d[] PROGMEM = {
761 0xeb, 0x8e, 0x9f, 0x04, 0x7d, 0xb5, 0x9a, 0x80,
762 0x34, 0x6f, 0xcd, 0xf1, 0xcc, 0x33, 0xbb, 0x78,
763 0xbe, 0xc6, 0xb8, 0x76, 0xaf, 0x9f, 0x4b, 0x69
766 const uint8_t ecdsa_test_2_k[] PROGMEM = {
767 0x8e, 0xd5, 0x00, 0x34, 0x08, 0x09, 0x60, 0x36,
768 0x2e, 0xfe, 0x16, 0xd0, 0x53, 0x37, 0xa2, 0xf5,
769 0x47, 0xfa, 0x11, 0xbc, 0xb1, 0xc2, 0xe8, 0x41
772 void test_sign1(void){
773 bigint_word_t d_w[sizeof(ecdsa_test_1_d)];
774 uint8_t rnd[sizeof(ecdsa_test_1_k)];
777 const hfdesc_t *hash_desc;
779 ecdsa_signature_t sign;
785 memcpy_P(rnd, ecdsa_test_1_k, sizeof(ecdsa_test_1_k));
786 memcpy_P(d_w, ecdsa_test_1_d, sizeof(ecdsa_test_1_d) * sizeof(bigint_word_t));
787 d.length_W = sizeof(ecdsa_test_1_d) / sizeof(bigint_word_t);
791 hash_desc = &sha1_desc; //hash_select();
792 hash = malloc(hfal_hash_getHashsize(hash_desc) / 8);
794 printf_P(PSTR("DBG: XXX <%S %s %d>\n"), PSTR(__FILE__), __func__, __LINE__);
796 hash_mem_P(hash_desc, hash, ecdsa_test_1_msg, sizeof(ecdsa_test_1_msg) * 8);
797 printf_P(PSTR("msg hash: "));
798 cli_hexdump(hash, hfal_hash_getHashsize(hash_desc) / 8);
801 ecc_chudnovsky_point_alloc(&q.chudnovsky, nist_curve_p192_p.length_W * sizeof(bigint_word_t));
802 ctx.basepoint = &nist_curve_p192_basepoint.chudnovsky;
804 ctx.curve = &nist_curve_p192;
807 bigint_print_hex(&d);
808 printf_P(PSTR("\n Gx: "));
809 bigint_print_hex(&nist_curve_p192_basepoint.affine.x);
810 printf_P(PSTR("\n Gy: "));
811 bigint_print_hex(&nist_curve_p192_basepoint.affine.y);
813 r = ecc_chudnovsky_multiplication(&q.chudnovsky, &d, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
815 printf_P(PSTR("ERROR: ecc_chudnovsky_multiplication() returned: %"PRIu8"\n"), r);
817 r = ecc_chudnovsky_to_affine_point(&q.affine, &q.chudnovsky, &nist_curve_p192);
819 printf_P(PSTR("ERROR: ecc_chudnovsky_to_affine_point() returned: %"PRIu8"\n"), r);
822 printf_P(PSTR("\n Qx: "));
823 bigint_print_hex(&q.affine.x);
824 printf_P(PSTR("\n Qy: "));
825 bigint_print_hex(&q.affine.y);
829 ecdsa_signature_alloc(&sign, sizeof(ecdsa_test_1_d) * sizeof(bigint_word_t));
831 r = ecdsa_sign_hash(&sign, hash, hfal_hash_getHashsize(hash_desc) / 8, &ctx, rnd);
833 printf_P(PSTR("ERROR: ecdsa_sign_message() returned: %"PRIu8"\n"), r);
835 printf_P(PSTR(" r: "));
836 bigint_print_hex(&sign.r);
837 printf_P(PSTR("\n s: "));
838 bigint_print_hex(&sign.s);
841 ecdsa_signature_free(&sign);
842 ecc_chudnovsky_point_free(&q.chudnovsky);
845 void test_sign2(void){
846 bigint_word_t d_w[sizeof(ecdsa_test_2_d)];
847 uint8_t rnd[sizeof(ecdsa_test_2_k)];
850 const hfdesc_t *hash_desc;
852 ecdsa_signature_t sign;
858 memcpy_P(rnd, ecdsa_test_2_k, sizeof(ecdsa_test_2_k));
859 memcpy_P(d_w, ecdsa_test_2_d, sizeof(ecdsa_test_2_d) * sizeof(bigint_word_t));
860 d.length_W = sizeof(ecdsa_test_2_d) / sizeof(bigint_word_t);
864 hash_desc = &sha224_desc; //hash_select();
865 hash = malloc(hfal_hash_getHashsize(hash_desc) / 8);
867 printf_P(PSTR("DBG: XXX <%S %s %d>\n"), PSTR(__FILE__), __func__, __LINE__);
869 hash_mem_P(hash_desc, hash, ecdsa_test_2_msg, sizeof(ecdsa_test_1_msg) * 8);
870 printf_P(PSTR("msg hash: "));
871 cli_hexdump(hash, hfal_hash_getHashsize(hash_desc) / 8);
874 ecc_chudnovsky_point_alloc(&q.chudnovsky, nist_curve_p192_p.length_W * sizeof(bigint_word_t));
875 ctx.basepoint = &nist_curve_p192_basepoint.chudnovsky;
877 ctx.curve = &nist_curve_p192;
880 bigint_print_hex(&d);
881 printf_P(PSTR("\n Gx: "));
882 bigint_print_hex(&nist_curve_p192_basepoint.affine.x);
883 printf_P(PSTR("\n Gy: "));
884 bigint_print_hex(&nist_curve_p192_basepoint.affine.y);
886 r = ecc_chudnovsky_multiplication(&q.chudnovsky, &d, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
888 printf_P(PSTR("ERROR: ecc_chudnovsky_multiplication() returned: %"PRIu8"\n"), r);
890 r = ecc_chudnovsky_to_affine_point(&q.affine, &q.chudnovsky, &nist_curve_p192);
892 printf_P(PSTR("ERROR: ecc_chudnovsky_to_affine_point() returned: %"PRIu8"\n"), r);
895 printf_P(PSTR("\n Qx: "));
896 bigint_print_hex(&q.affine.x);
897 printf_P(PSTR("\n Qy: "));
898 bigint_print_hex(&q.affine.y);
902 ecdsa_signature_alloc(&sign, sizeof(ecdsa_test_2_d) * sizeof(bigint_word_t));
904 r = ecdsa_sign_hash(&sign, hash, hfal_hash_getHashsize(hash_desc) / 8, &ctx, rnd);
906 printf_P(PSTR("ERROR: ecdsa_sign_message() returned: %"PRIu8"\n"), r);
908 printf_P(PSTR(" r: "));
909 bigint_print_hex(&sign.r);
910 printf_P(PSTR("\n s: "));
911 bigint_print_hex(&sign.s);
914 ecdsa_signature_free(&sign);
915 ecc_chudnovsky_point_free(&q.chudnovsky);
917 /*****************************************************************************
919 *****************************************************************************/
921 const char echo_test_str[] PROGMEM = "echo-test";
922 const char reset_prng_str[] PROGMEM = "reset-prng";
923 const char quick_test_str[] PROGMEM = "quick-test";
924 const char performance_reduce_str[] PROGMEM = "performance_reduce";
925 const char performance_invert_str[] PROGMEM = "performance_invert";
926 const char performance_multiply_str[] PROGMEM = "performance_multiply";
927 const char genkey1_str[] PROGMEM = "genkey1";
928 const char genkey2_str[] PROGMEM = "genkey2";
929 const char genkey3_str[] PROGMEM = "genkey3";
930 const char genkey_str[] PROGMEM = "genkey";
931 const char testsign1_str[] PROGMEM = "testsign1";
932 const char testsign2_str[] PROGMEM = "testsign2";
933 const char square_str[] PROGMEM = "square";
934 const char echo_str[] PROGMEM = "echo";
936 const const cmdlist_entry_t cmdlist[] PROGMEM = {
937 // { reset_prng_str, NULL, reset_prng },
938 // { quick_test_str, NULL, quick_test },
939 { square_str, NULL, testrun_square },
940 { genkey_str, NULL, testrun_genkey },
941 { genkey1_str, NULL, testrun_genkey1 },
942 { genkey2_str, NULL, testrun_genkey2 },
943 { genkey3_str, NULL, testrun_genkey3 },
944 { testsign1_str, NULL, test_sign1 },
945 { testsign2_str, NULL, test_sign2 },
946 { performance_reduce_str, NULL, testrun_performance_reduce_bigint },
947 { performance_invert_str, NULL, testrun_performance_invert_bigint },
948 { performance_multiply_str, NULL, testrun_performance_multiply_bigint },
949 { echo_str, (void*)1, (void_fpt)echo_ctrl },
958 welcome_msg(algo_name);
959 r = cmd_interface(cmdlist);
960 printf("r = %"PRId8"\n", r);
961 cli_putstr_P(PSTR("\r\nHello!\r\n"));