@@ -285,6 +285,177 @@ static int s_ecc_issue443_447(void)
285
285
return CRYPT_OK ;
286
286
}
287
287
288
+ /* https://github.com/libtom/libtomcrypt/issues/446 */
289
+ static int s_ecc_issue446 (void )
290
+ {
291
+ const ltc_ecc_curve * cu ;
292
+ ecc_key key1 , key2 , key3 , key4 ;
293
+ int err , stat = 0 ;
294
+ unsigned char hash [64 ];
295
+ unsigned long hashlen ;
296
+ const unsigned char msg1 [] = { 0x31 ,0x32 ,0x33 ,0x34 ,0x30 ,0x30 };
297
+ const unsigned char msg2 [] = { 0x36 ,0x39 ,0x38 ,0x31 ,0x39 };
298
+ const unsigned char msg3 [] = { 0x4d ,0x73 ,0x67 };
299
+ const unsigned char msg4 [] = { 0x54 ,0x65 ,0x73 ,0x74 };
300
+ const unsigned char pub1 [] = {
301
+ 0x04 , /* secp256r1 */
302
+ 0x29 ,0x27 ,0xb1 ,0x05 ,0x12 ,0xba ,0xe3 ,0xed ,0xdc ,0xfe ,0x46 ,0x78 ,0x28 ,0x12 ,0x8b ,0xad ,
303
+ 0x29 ,0x03 ,0x26 ,0x99 ,0x19 ,0xf7 ,0x08 ,0x60 ,0x69 ,0xc8 ,0xc4 ,0xdf ,0x6c ,0x73 ,0x28 ,0x38 ,
304
+ 0xc7 ,0x78 ,0x79 ,0x64 ,0xea ,0xac ,0x00 ,0xe5 ,0x92 ,0x1f ,0xb1 ,0x49 ,0x8a ,0x60 ,0xf4 ,0x60 ,
305
+ 0x67 ,0x66 ,0xb3 ,0xd9 ,0x68 ,0x50 ,0x01 ,0x55 ,0x8d ,0x1a ,0x97 ,0x4e ,0x73 ,0x41 ,0x51 ,0x3e
306
+ };
307
+ const unsigned char pub2 [] = {
308
+ 0x04 , /* secp224r1 */
309
+ 0x53 ,0x88 ,0x35 ,0x38 ,0xd8 ,0x66 ,0x09 ,0x21 ,0x7a ,0x4d ,0x9c ,0x27 ,0x99 ,0x2e ,
310
+ 0x2b ,0xd7 ,0x04 ,0xa4 ,0xbb ,0x12 ,0xfb ,0x91 ,0x25 ,0x3c ,0xd4 ,0xf4 ,0x96 ,0xfa ,
311
+ 0x00 ,0xb3 ,0x2f ,0x3a ,0x2d ,0x15 ,0x3a ,0x52 ,0xbb ,0x57 ,0x76 ,0x50 ,0xcd ,0xf1 ,
312
+ 0xb7 ,0x3a ,0x34 ,0x05 ,0x35 ,0xc7 ,0xe7 ,0x3d ,0xeb ,0x59 ,0x9a ,0xa9 ,0x50 ,0x88
313
+ };
314
+ const unsigned char pub3 [] = {
315
+ 0x04 , /* brainpoolP256r1 */
316
+ 0x30 ,0x29 ,0x1b ,0xca ,0x4e ,0xb9 ,0x3c ,0x41 ,0x99 ,0x1d ,0xae ,0xc0 ,0xfd ,0x2e ,0x87 ,0xc2 ,
317
+ 0x77 ,0x8d ,0x95 ,0x8d ,0x9a ,0x8e ,0x2f ,0xa4 ,0xe6 ,0xd3 ,0x83 ,0x5d ,0x48 ,0x5b ,0xc2 ,0x3e ,
318
+ 0x42 ,0x17 ,0xf6 ,0x84 ,0xcf ,0xdd ,0x83 ,0x6d ,0x7c ,0xf6 ,0x09 ,0x9a ,0x34 ,0xc6 ,0x82 ,0x61 ,
319
+ 0xe5 ,0xa0 ,0x94 ,0xad ,0xb5 ,0xb3 ,0xe4 ,0xa9 ,0x26 ,0x2f ,0xf5 ,0x95 ,0x7c ,0x1b ,0x1b ,0xa8
320
+ };
321
+ const unsigned char pub4 [] = {
322
+ 0x04 , /* brainpoolP256t1 */
323
+ 0x44 ,0x24 ,0xf0 ,0x9e ,0x4f ,0x86 ,0x92 ,0x31 ,0xe4 ,0x7b ,0x1e ,0x34 ,0x26 ,0xec ,0x26 ,0x9e ,
324
+ 0x5b ,0xef ,0x19 ,0xec ,0x64 ,0xcc ,0x96 ,0xda ,0x5b ,0x2e ,0xfd ,0xd2 ,0x11 ,0x6b ,0x83 ,0xf0 ,
325
+ 0x7a ,0x86 ,0x3d ,0x25 ,0x74 ,0x3b ,0xb2 ,0x60 ,0xa6 ,0x38 ,0xde ,0x64 ,0x97 ,0x96 ,0xc6 ,0x76 ,
326
+ 0xe1 ,0x38 ,0x05 ,0x86 ,0x5c ,0x8b ,0xb9 ,0xda ,0xc3 ,0x8e ,0x16 ,0xfa ,0xe5 ,0x4b ,0x0c ,0xef
327
+ };
328
+ /* msg1+pub1+sig1 test vector is from wycheproof/ecdsa_test VALID */
329
+ const unsigned char sig1 [] = {
330
+ 0x30 ,0x45 ,0x02 ,0x20 ,0x2b ,0xa3 ,0xa8 ,0xbe ,0x6b ,0x94 ,0xd5 ,0xec ,0x80 ,0xa6 ,0xd9 ,0xd1 ,0x19 ,0x0a ,
331
+ 0x43 ,0x6e ,0xff ,0xe5 ,0x0d ,0x85 ,0xa1 ,0xee ,0xe8 ,0x59 ,0xb8 ,0xcc ,0x6a ,0xf9 ,0xbd ,0x5c ,0x2e ,0x18 ,
332
+ 0x02 ,0x21 ,0x00 ,0xb3 ,0x29 ,0xf4 ,0x79 ,0xa2 ,0xbb ,0xd0 ,0xa5 ,0xc3 ,0x84 ,0xee ,0x14 ,0x93 ,0xb1 ,0xf5 ,
333
+ 0x18 ,0x6a ,0x87 ,0x13 ,0x9c ,0xac ,0x5d ,0xf4 ,0x08 ,0x7c ,0x13 ,0x4b ,0x49 ,0x15 ,0x68 ,0x47 ,0xdb
334
+ };
335
+ /* msg1+pub1+sig2 test vector is from wycheproof/ecdsa_test INVALID (changing tag value of sequence) */
336
+ const unsigned char sig2 [] = {
337
+ 0x31 ,0x45 ,0x02 ,0x20 ,0x2b ,0xa3 ,0xa8 ,0xbe ,0x6b ,0x94 ,0xd5 ,0xec ,0x80 ,0xa6 ,0xd9 ,0xd1 ,0x19 ,0x0a ,
338
+ 0x43 ,0x6e ,0xff ,0xe5 ,0x0d ,0x85 ,0xa1 ,0xee ,0xe8 ,0x59 ,0xb8 ,0xcc ,0x6a ,0xf9 ,0xbd ,0x5c ,0x2e ,0x18 ,
339
+ 0x02 ,0x21 ,0x00 ,0xb3 ,0x29 ,0xf4 ,0x79 ,0xa2 ,0xbb ,0xd0 ,0xa5 ,0xc3 ,0x84 ,0xee ,0x14 ,0x93 ,0xb1 ,0xf5 ,
340
+ 0x18 ,0x6a ,0x87 ,0x13 ,0x9c ,0xac ,0x5d ,0xf4 ,0x08 ,0x7c ,0x13 ,0x4b ,0x49 ,0x15 ,0x68 ,0x47 ,0xdb
341
+ };
342
+ /* msg2+pub1+sig3 test vector is from wycheproof/ecdsa_test VALID (Edge case for Shamir multiplication) */
343
+ const unsigned char sig3 [] = {
344
+ 0x30 ,0x44 ,0x02 ,0x20 ,0x64 ,0xa1 ,0xaa ,0xb5 ,0x00 ,0x0d ,0x0e ,0x80 ,0x4f ,0x3e ,0x2f ,0xc0 ,0x2b ,0xde ,
345
+ 0xe9 ,0xbe ,0x8f ,0xf3 ,0x12 ,0x33 ,0x4e ,0x2b ,0xa1 ,0x6d ,0x11 ,0x54 ,0x7c ,0x97 ,0x71 ,0x1c ,0x89 ,0x8e ,
346
+ 0x02 ,0x20 ,0x6a ,0xf0 ,0x15 ,0x97 ,0x1c ,0xc3 ,0x0b ,0xe6 ,0xd1 ,0xa2 ,0x06 ,0xd4 ,0xe0 ,0x13 ,0xe0 ,0x99 ,
347
+ 0x77 ,0x72 ,0xa2 ,0xf9 ,0x1d ,0x73 ,0x28 ,0x6f ,0xfd ,0x68 ,0x3b ,0x9b ,0xb2 ,0xcf ,0x4f ,0x1b
348
+ };
349
+ /* msg1+pub1+sig4 test vector is from wycheproof/ecdsa_test INVALID (long form encoding of length) */
350
+ const unsigned char sig4 [] = {
351
+ 0x30 ,0x81 ,0x45 ,0x02 ,0x20 ,0x2b ,0xa3 ,0xa8 ,0xbe ,0x6b ,0x94 ,0xd5 ,0xec ,0x80 ,0xa6 ,0xd9 ,0xd1 ,0x19 ,
352
+ 0x0a ,0x43 ,0x6e ,0xff ,0xe5 ,0x0d ,0x85 ,0xa1 ,0xee ,0xe8 ,0x59 ,0xb8 ,0xcc ,0x6a ,0xf9 ,0xbd ,0x5c ,0x2e ,
353
+ 0x18 ,0x02 ,0x21 ,0x00 ,0xb3 ,0x29 ,0xf4 ,0x79 ,0xa2 ,0xbb ,0xd0 ,0xa5 ,0xc3 ,0x84 ,0xee ,0x14 ,0x93 ,0xb1 ,
354
+ 0xf5 ,0x18 ,0x6a ,0x87 ,0x13 ,0x9c ,0xac ,0x5d ,0xf4 ,0x08 ,0x7c ,0x13 ,0x4b ,0x49 ,0x15 ,0x68 ,0x47 ,0xdb
355
+ };
356
+ /* msg1+pub1+sig5 test vector is from wycheproof/ecdsa_test INVALID (length contains leading 0) */
357
+ const unsigned char sig5 [] = {
358
+ 0x30 ,0x82 ,0x00 ,0x45 ,0x02 ,0x20 ,0x2b ,0xa3 ,0xa8 ,0xbe ,0x6b ,0x94 ,0xd5 ,0xec ,0x80 ,0xa6 ,0xd9 ,0xd1 ,
359
+ 0x19 ,0x0a ,0x43 ,0x6e ,0xff ,0xe5 ,0x0d ,0x85 ,0xa1 ,0xee ,0xe8 ,0x59 ,0xb8 ,0xcc ,0x6a ,0xf9 ,0xbd ,0x5c ,
360
+ 0x2e ,0x18 ,0x02 ,0x21 ,0x00 ,0xb3 ,0x29 ,0xf4 ,0x79 ,0xa2 ,0xbb ,0xd0 ,0xa5 ,0xc3 ,0x84 ,0xee ,0x14 ,0x93 ,
361
+ 0xb1 ,0xf5 ,0x18 ,0x6a ,0x87 ,0x13 ,0x9c ,0xac ,0x5d ,0xf4 ,0x08 ,0x7c ,0x13 ,0x4b ,0x49 ,0x15 ,0x68 ,0x47 ,0xdb
362
+ };
363
+ /* msg3+pub2+sig6 test vector is from wycheproof/ecdsa_test VALID (extreme value for k and edgecase s) */
364
+ const unsigned char sig6 [] = {
365
+ 0x30 ,0x3c ,0x02 ,0x1c ,0x70 ,0x6a ,0x46 ,0xdc ,0x76 ,0xdc ,0xb7 ,0x67 ,0x98 ,0xe6 ,0x0e ,0x6d ,0x89 ,0x47 ,0x47 ,0x88 ,0xd1 ,
366
+ 0x6d ,0xc1 ,0x80 ,0x32 ,0xd2 ,0x68 ,0xfd ,0x1a ,0x70 ,0x4f ,0xa6 ,0x02 ,0x1c ,0x55 ,0x55 ,0x55 ,0x55 ,0x55 ,0x55 ,0x55 ,0x55 ,
367
+ 0x55 ,0x55 ,0x55 ,0x55 ,0x55 ,0x55 ,0x07 ,0x8b ,0xa0 ,0x3d ,0xa5 ,0x6a ,0x06 ,0x9f ,0x0d ,0xc1 ,0xc9 ,0x74 ,0x0e ,0x14
368
+ };
369
+ /* msg4+pub3+sig7 test vector is from wycheproof/ecdsa_test VALID (extreme value for k) */
370
+ const unsigned char sig7 [] = {
371
+ 0x30 ,0x44 ,0x02 ,0x20 ,0x74 ,0x3c ,0xf1 ,0xb8 ,0xb5 ,0xcd ,0x4f ,0x2e ,0xb5 ,0x5f ,0x8a ,0xa3 ,0x69 ,0x59 ,
372
+ 0x3a ,0xc4 ,0x36 ,0xef ,0x04 ,0x41 ,0x66 ,0x69 ,0x9e ,0x37 ,0xd5 ,0x1a ,0x14 ,0xc2 ,0xce ,0x13 ,0xea ,0x0e ,
373
+ 0x02 ,0x20 ,0x77 ,0x47 ,0x2d ,0x9a ,0x28 ,0xb4 ,0xec ,0xe7 ,0x1c ,0xf4 ,0x13 ,0xa6 ,0x8e ,0xac ,0x0e ,0xb4 ,
374
+ 0x23 ,0xa1 ,0x6f ,0xb4 ,0x62 ,0xb1 ,0xf4 ,0x87 ,0x06 ,0xfe ,0xd4 ,0x8c ,0xa4 ,0x37 ,0xbd ,0x2d
375
+ };
376
+ /* msg4+pub4+sig8 test vector is from wycheproof/ecdsa_test VALID (extreme value for k and s^-1) */
377
+ const unsigned char sig8 [] = {
378
+ 0x30 ,0x45 ,0x02 ,0x21 ,0x00 ,0x83 ,0x38 ,0x42 ,0x7c ,0x7c ,0xf4 ,0xd1 ,0x1c ,0xb9 ,0x81 ,0xd9 ,0xb1 ,0x87 ,
379
+ 0x93 ,0xe3 ,0x77 ,0x9c ,0x49 ,0x4c ,0x50 ,0x2c ,0x75 ,0xbd ,0x73 ,0x9e ,0x57 ,0x8d ,0xe2 ,0xa7 ,0x00 ,0x57 ,
380
+ 0x8d ,0x02 ,0x20 ,0x30 ,0x90 ,0xf4 ,0x87 ,0xe5 ,0x1f ,0x9e ,0x35 ,0xc8 ,0xaf ,0x70 ,0xbb ,0x9a ,0xb7 ,0xdf ,
381
+ 0x45 ,0x03 ,0x7e ,0x23 ,0x0a ,0x33 ,0xd2 ,0xc1 ,0xfd ,0x96 ,0xe4 ,0x04 ,0x25 ,0x4f ,0xcb ,0x86 ,0x79
382
+ };
383
+
384
+ DO (ecc_find_curve ("secp256r1" , & cu ));
385
+ DO (ecc_set_curve (cu , & key1 ));
386
+ DO (ecc_set_key (pub1 , sizeof (pub1 ), PK_PUBLIC , & key1 ));
387
+
388
+ DO (ecc_find_curve ("secp224r1" , & cu ));
389
+ DO (ecc_set_curve (cu , & key2 ));
390
+ DO (ecc_set_key (pub2 , sizeof (pub2 ), PK_PUBLIC , & key2 ));
391
+
392
+ DO (ecc_find_curve ("brainpoolP256r1" , & cu ));
393
+ DO (ecc_set_curve (cu , & key3 ));
394
+ DO (ecc_set_key (pub3 , sizeof (pub3 ), PK_PUBLIC , & key3 ));
395
+
396
+ DO (ecc_find_curve ("brainpoolP256t1" , & cu ));
397
+ DO (ecc_set_curve (cu , & key4 ));
398
+ DO (ecc_set_key (pub4 , sizeof (pub4 ), PK_PUBLIC , & key4 ));
399
+
400
+ hashlen = sizeof (hash );
401
+ DO (hash_memory (find_hash ("sha256" ), msg1 , sizeof (msg1 ), hash , & hashlen ));
402
+ DO (ecc_verify_hash (sig1 , sizeof (sig1 ), hash , hashlen , & stat , & key1 ));
403
+ if (stat != 1 ) return CRYPT_FAIL_TESTVECTOR ; /* expected result: VALID */
404
+
405
+ err = ecc_verify_hash (sig2 , sizeof (sig2 ), hash , hashlen , & stat , & key1 );
406
+ if (err == CRYPT_OK && stat == 1 ) {
407
+ fprintf (stderr , "XXX-TODO should fail - wycheproof / changing tag value of sequence\n" );
408
+ /* return CRYPT_FAIL_TESTVECTOR; / * expected result: INVALID */
409
+ }
410
+
411
+ err = ecc_verify_hash (sig4 , sizeof (sig4 ), hash , hashlen , & stat , & key1 );
412
+ if (err == CRYPT_OK && stat == 1 ) {
413
+ fprintf (stderr , "XXX-TODO should fail - wycheproof / long form encoding of length\n" );
414
+ /* return CRYPT_FAIL_TESTVECTOR; / * expected result: INVALID */
415
+ }
416
+
417
+ err = ecc_verify_hash (sig5 , sizeof (sig5 ), hash , hashlen , & stat , & key1 );
418
+ if (err == CRYPT_OK && stat == 1 ) {
419
+ fprintf (stderr , "XXX-TODO should fail - wycheproof / length contains leading 0\n" );
420
+ /* return CRYPT_FAIL_TESTVECTOR; / * expected result: INVALID */
421
+ }
422
+
423
+ hashlen = sizeof (hash );
424
+ DO (hash_memory (find_hash ("sha256" ), msg2 , sizeof (msg2 ), hash , & hashlen ));
425
+ DO (ecc_verify_hash (sig3 , sizeof (sig3 ), hash , hashlen , & stat , & key1 ));
426
+ if (stat != 1 ) {
427
+ fprintf (stderr , "XXX-TODO should be valid - wycheproof / Edge case for Shamir multiplication\n" );
428
+ /* return CRYPT_FAIL_TESTVECTOR; / * expected result: VALID */
429
+ }
430
+
431
+ hashlen = sizeof (hash );
432
+ DO (hash_memory (find_hash ("sha224" ), msg3 , sizeof (msg3 ), hash , & hashlen ));
433
+ DO (ecc_verify_hash (sig6 , sizeof (sig6 ), hash , hashlen , & stat , & key2 ));
434
+ if (stat != 1 ) {
435
+ fprintf (stderr , "XXX-TODO should be valid - wycheproof / extreme value for k and edgecase s\n" );
436
+ /* return CRYPT_FAIL_TESTVECTOR; / * expected result: VALID */
437
+ }
438
+
439
+ hashlen = sizeof (hash );
440
+ DO (hash_memory (find_hash ("sha256" ), msg4 , sizeof (msg4 ), hash , & hashlen ));
441
+ DO (ecc_verify_hash (sig7 , sizeof (sig7 ), hash , hashlen , & stat , & key3 ));
442
+ if (stat != 1 ) {
443
+ fprintf (stderr , "XXX-TODO should be valid - wycheproof / extreme value for k\n" );
444
+ /* return CRYPT_FAIL_TESTVECTOR; / * expected result: VALID */
445
+ }
446
+ DO (ecc_verify_hash (sig8 , sizeof (sig8 ), hash , hashlen , & stat , & key4 ));
447
+ if (stat != 1 ) {
448
+ fprintf (stderr , "XXX-TODO should be valid - wycheproof / extreme value for k and s^-1\n" );
449
+ /* return CRYPT_FAIL_TESTVECTOR; / * expected result: VALID */
450
+ }
451
+
452
+ ecc_free (& key1 );
453
+ ecc_free (& key2 );
454
+ ecc_free (& key3 );
455
+ ecc_free (& key4 );
456
+ return CRYPT_OK ;
457
+ }
458
+
288
459
static int s_ecc_test_mp (void )
289
460
{
290
461
void * a , * modulus , * order ;
@@ -1591,6 +1762,7 @@ int ecc_test(void)
1591
1762
DO (s_ecc_test_mp ());
1592
1763
DO (s_ecc_issue108 ());
1593
1764
DO (s_ecc_issue443_447 ());
1765
+ DO (s_ecc_issue446 ());
1594
1766
#ifdef LTC_ECC_SHAMIR
1595
1767
DO (s_ecc_test_shamir ());
1596
1768
DO (s_ecc_test_recovery ());
0 commit comments