| /* Copyright 2020, Kenneth MacKay. Licensed under the BSD 2-clause license. */ |
| |
| #include "uECC.h" |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| typedef struct { |
| const char* k; |
| const char* Q; |
| int success; |
| } Test; |
| |
| Test secp160r1_tests[] = { |
| /* Note, I couldn't find any test vectors for secp160r1 online, so these are just |
| generated on my desktop using uECC. */ |
| { |
| "000000000000000000000000000000000000000000", |
| "00000000000000000000000000000000000000000000000000000000000000000000000000000000", |
| 0 |
| }, |
| { |
| "000000000000000000000000000000000000000001", |
| "00000000000000000000000000000000000000000000000000000000000000000000000000000000", |
| 0 |
| }, |
| { |
| "000000000000000000000000000000000000000002", |
| "02F997F33C5ED04C55D3EDF8675D3E92E8F46686F083A323482993E9440E817E21CFB7737DF8797B", |
| 1 |
| }, |
| { |
| "000000000000000000000000000000000000000003", |
| "7B76FF541EF363F2DF13DE1650BD48DAA958BC59C915CA790D8C8877B55BE0079D12854FFE9F6F5A", |
| 1 |
| }, |
| { /* n - 4 */ |
| "0100000000000000000001F4C8F927AED3CA752253", |
| "B4041D8683BE99F0AFE01C307B1AD4C100CF2A88C0CD35127BE0F73FF99F338B350B5A42864112F7", |
| 1 |
| }, |
| { /* n - 3 */ |
| "0100000000000000000001F4C8F927AED3CA752254", |
| "7B76FF541EF363F2DF13DE1650BD48DAA958BC5936EA3586F27377884AA41FF862ED7AAF816090A5", |
| 1 |
| }, |
| { /* n - 2 */ |
| "0100000000000000000001F4C8F927AED3CA752255", |
| "00000000000000000000000000000000000000000000000000000000000000000000000000000000", |
| 0 |
| }, |
| { /* n - 1 */ |
| "0100000000000000000001F4C8F927AED3CA752256", |
| "00000000000000000000000000000000000000000000000000000000000000000000000000000000", |
| 0 |
| }, |
| { /* n */ |
| "0100000000000000000001F4C8F927AED3CA752257", |
| "00000000000000000000000000000000000000000000000000000000000000000000000000000000", |
| 0 |
| }, |
| }; |
| |
| |
| Test secp192r1_tests[] = { |
| { |
| "000000000000000000000000000000000000000000000000", |
| "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
| 0 |
| }, |
| { |
| "000000000000000000000000000000000000000000000001", |
| "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF101207192B95FFC8DA78631011ED6B24CDD573F977A11E794811", |
| 0 |
| }, |
| { |
| "000000000000000000000000000000000000000000000002", |
| "DAFEBF5828783F2AD35534631588A3F629A70FB16982A888DD6BDA0D993DA0FA46B27BBC141B868F59331AFA5C7E93AB", |
| 1 |
| }, |
| { |
| "000000000000000000000000000000000000000000000003", |
| "76E32A2557599E6EDCD283201FB2B9AADFD0D359CBB263DA782C37E372BA4520AA62E0FED121D49EF3B543660CFD05FD", |
| 1 |
| }, |
| { /* n - 4 */ |
| "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D2282D", |
| "35433907297CC378B0015703374729D7A4FE46647084E4BA5D9B667B0DECA3CFE15C534F88932B0DDAC764CEE24C41CD", |
| 1 |
| }, |
| { /* n - 3 */ |
| "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D2282E", |
| "76E32A2557599E6EDCD283201FB2B9AADFD0D359CBB263DA87D3C81C8D45BADF559D1F012EDE2B600C4ABC99F302FA02", |
| 1 |
| }, |
| { /* n - 2 */ |
| "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D2282F", |
| "DAFEBF5828783F2AD35534631588A3F629A70FB16982A888229425F266C25F05B94D8443EBE4796FA6CCE505A3816C54", |
| 0 |
| }, |
| { /* n - 1 */ |
| "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22830", |
| "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012F8E6D46A003725879CEFEE1294DB32298C06885EE186B7EE", |
| 0 |
| }, |
| { /* n */ |
| "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831", |
| "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
| 0 |
| }, |
| }; |
| |
| Test secp224r1_tests[] = { |
| { |
| "00000000000000000000000000000000000000000000000000000000", |
| "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
| 0 |
| }, |
| { |
| "00000000000000000000000000000000000000000000000000000001", |
| "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", |
| 0 |
| }, |
| { |
| "00000000000000000000000000000000000000000000000000000002", |
| "706A46DC76DCB76798E60E6D89474788D16DC18032D268FD1A704FA61C2B76A7BC25E7702A704FA986892849FCA629487ACF3709D2E4E8BB", |
| 1 |
| }, |
| { |
| "00000000000000000000000000000000000000000000000000000003", |
| "DF1B1D66A551D0D31EFF822558B9D2CC75C2180279FE0D08FD896D04A3F7F03CADD0BE444C0AA56830130DDF77D317344E1AF3591981A925", |
| 1 |
| }, |
| { /* n - 4 */ |
| "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A39", |
| "AE99FEEBB5D26945B54892092A8AEE02912930FA41CD114E40447301FB7DA7F5F13A43B81774373C879CD32D6934C05FA758EEB14FCFAB38", |
| 1 |
| }, |
| { /* n - 3 */ |
| "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3A", |
| "DF1B1D66A551D0D31EFF822558B9D2CC75C2180279FE0D08FD896D045C080FC3522F41BBB3F55A97CFECF21F882CE8CBB1E50CA6E67E56DC", |
| 1 |
| }, |
| { /* n - 2 */ |
| "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3B", |
| "706A46DC76DCB76798E60E6D89474788D16DC18032D268FD1A704FA6E3D4895843DA188FD58FB0567976D7B50359D6B78530C8F62D1B1746", |
| 0 |
| }, |
| { /* n - 1 */ |
| "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3C", |
| "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D2142C89C774A08DC04B3DD201932BC8A5EA5F8B89BBB2A7E667AFF81CD", |
| 0 |
| }, |
| { /* n */ |
| "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", |
| "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
| 0 |
| }, |
| }; |
| |
| Test secp256r1_tests[] = { |
| { |
| "0000000000000000000000000000000000000000000000000000000000000000", |
| "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
| 0 |
| }, |
| { |
| "0000000000000000000000000000000000000000000000000000000000000001", |
| "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", |
| 0 |
| }, |
| { |
| "0000000000000000000000000000000000000000000000000000000000000002", |
| "7CF27B188D034F7E8A52380304B51AC3C08969E277F21B35A60B48FC4766997807775510DB8ED040293D9AC69F7430DBBA7DADE63CE982299E04B79D227873D1", |
| 1 |
| }, |
| { |
| "0000000000000000000000000000000000000000000000000000000000000003", |
| "5ECBE4D1A6330A44C8F7EF951D4BF165E6C6B721EFADA985FB41661BC6E7FD6C8734640C4998FF7E374B06CE1A64A2ECD82AB036384FB83D9A79B127A27D5032", |
| 1 |
| }, |
| { /* n - 4 */ |
| "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC63254D", |
| "E2534A3532D08FBBA02DDE659EE62BD0031FE2DB785596EF509302446B0308521F0EA8A4B39CC339E62011A02579D289B103693D0CF11FFAA3BD3DC0E7B12739", |
| 1 |
| }, |
| { /* n - 3 */ |
| "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC63254E", |
| "5ECBE4D1A6330A44C8F7EF951D4BF165E6C6B721EFADA985FB41661BC6E7FD6C78CB9BF2B6670082C8B4F931E59B5D1327D54FCAC7B047C265864ED85D82AFCD", |
| 1 |
| }, |
| { /* n - 2 */ |
| "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC63254F", |
| "7CF27B188D034F7E8A52380304B51AC3C08969E277F21B35A60B48FC47669978F888AAEE24712FC0D6C26539608BCF244582521AC3167DD661FB4862DD878C2E", |
| 0 |
| }, |
| { /* n - 1 */ |
| "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632550", |
| "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296B01CBD1C01E58065711814B583F061E9D431CCA994CEA1313449BF97C840AE0A", |
| 0 |
| }, |
| { /* n */ |
| "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", |
| "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
| 0 |
| }, |
| }; |
| |
| Test secp256k1_tests[] = { |
| { |
| "0000000000000000000000000000000000000000000000000000000000000000", |
| "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
| 0 |
| }, |
| { |
| "0000000000000000000000000000000000000000000000000000000000000001", |
| "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", |
| 0 |
| }, |
| { |
| "0000000000000000000000000000000000000000000000000000000000000002", |
| "C6047F9441ED7D6D3045406E95C07CD85C778E4B8CEF3CA7ABAC09B95C709EE51AE168FEA63DC339A3C58419466CEAEEF7F632653266D0E1236431A950CFE52A", |
| 1 |
| }, |
| { |
| "0000000000000000000000000000000000000000000000000000000000000003", |
| "F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9388F7B0F632DE8140FE337E62A37F3566500A99934C2231B6CB9FD7584B8E672", |
| 1 |
| }, |
| { /* n - 4 */ |
| "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD036413D", |
| "E493DBF1C10D80F3581E4904930B1404CC6C13900EE0758474FA94ABE8C4CD13AE1266C15F2BAA48A9BD1DF6715AEBB7269851CC404201BF30168422B88C630D", |
| 1 |
| }, |
| { /* n - 3 */ |
| "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD036413E", |
| "F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9C77084F09CD217EBF01CC819D5C80CA99AFF5666CB3DDCE4934602897B4715BD", |
| 1 |
| }, |
| { /* n - 2 */ |
| "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD036413F", |
| "C6047F9441ED7D6D3045406E95C07CD85C778E4B8CEF3CA7ABAC09B95C709EE5E51E970159C23CC65C3A7BE6B99315110809CD9ACD992F1EDC9BCE55AF301705", |
| 0 |
| }, |
| { /* n - 1 */ |
| "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364140", |
| "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798B7C52588D95C3B9AA25B0403F1EEF75702E84BB7597AABE663B82F6F04EF2777", |
| 0 |
| }, |
| { /* n */ |
| "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", |
| "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", |
| 0 |
| }, |
| }; |
| |
| |
| void vli_print(uint8_t *vli, unsigned int size) { |
| for(unsigned i=0; i<size; ++i) { |
| printf("%02X ", (unsigned)vli[i]); |
| } |
| printf("\n"); |
| } |
| |
| void strtobytes(const char* str, uint8_t* bytes, int count) { |
| for (int c = 0; c < count; ++c) { |
| if (sscanf(str, "%2hhx", &bytes[c]) != 1) { |
| printf("Failed to read string to bytes"); |
| exit(1); |
| } |
| str += 2; |
| } |
| } |
| |
| int run(Test* tests, int num_tests, uECC_Curve curve) { |
| uint8_t private[32] = {0}; |
| uint8_t public[64] = {0}; |
| uint8_t expected[64] = {0}; |
| int result; |
| int i; |
| int private_key_size; |
| int public_key_size; |
| int all_success = 1; |
| |
| private_key_size = uECC_curve_private_key_size(curve); |
| public_key_size = uECC_curve_public_key_size(curve); |
| |
| for (i = 0; i < num_tests; ++i) { |
| strtobytes(tests[i].k, private, private_key_size); |
| result = uECC_compute_public_key(private, public, curve); |
| if (result != tests[i].success) { |
| all_success = 0; |
| printf(" Got unexpected result from test %d: %d\n", i, result); |
| } |
| if (result) { |
| strtobytes(tests[i].Q, expected, public_key_size); |
| if (memcmp(public, expected, public_key_size) != 0) { |
| all_success = 0; |
| printf(" Got incorrect public key for test %d\n", i); |
| printf(" Expected: "); |
| vli_print(expected, public_key_size); |
| printf(" Calculated: "); |
| vli_print(public, public_key_size); |
| } |
| } |
| } |
| |
| return all_success; |
| } |
| |
| #define RUN_TESTS(curve) \ |
| printf(#curve ":\n"); \ |
| if (run(curve##_tests, sizeof(curve##_tests) / sizeof(curve##_tests[0]), uECC_##curve()) ) { \ |
| printf(" All passed\n"); \ |
| } else { \ |
| printf(" Failed\n"); \ |
| } |
| |
| int main() { |
| #if uECC_SUPPORTS_secp160r1 |
| RUN_TESTS(secp160r1) |
| #endif |
| #if uECC_SUPPORTS_secp192r1 |
| RUN_TESTS(secp192r1) |
| #endif |
| #if uECC_SUPPORTS_secp224r1 |
| RUN_TESTS(secp224r1) |
| #endif |
| #if uECC_SUPPORTS_secp256r1 |
| RUN_TESTS(secp256r1) |
| #endif |
| #if uECC_SUPPORTS_secp256k1 |
| RUN_TESTS(secp256k1) |
| #endif |
| |
| return 0; |
| } |