1*bdcc259dSMatthias Ringwald /* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ 2*bdcc259dSMatthias Ringwald 3*bdcc259dSMatthias Ringwald #include "uECC.h" 4*bdcc259dSMatthias Ringwald 5*bdcc259dSMatthias Ringwald #include <stdio.h> 6*bdcc259dSMatthias Ringwald #include <string.h> 7*bdcc259dSMatthias Ringwald 8*bdcc259dSMatthias Ringwald #include <stdio.h> 9*bdcc259dSMatthias Ringwald #include <string.h> 10*bdcc259dSMatthias Ringwald #include <stdint.h> 11*bdcc259dSMatthias Ringwald #include <stdlib.h> 12*bdcc259dSMatthias Ringwald 13*bdcc259dSMatthias Ringwald typedef uint8_t sm_key24_t[3]; 14*bdcc259dSMatthias Ringwald typedef uint8_t sm_key56_t[7]; 15*bdcc259dSMatthias Ringwald typedef uint8_t sm_key_t[16]; 16*bdcc259dSMatthias Ringwald typedef uint8_t sm_key256_t[32]; 17*bdcc259dSMatthias Ringwald 18*bdcc259dSMatthias Ringwald // P256 Set 1 19*bdcc259dSMatthias Ringwald static const char * set1_private_a_string = "3f49f6d4a3c55f3874c9b3e3d2103f504aff607beb40b7995899b8a6cd3c1abd"; 20*bdcc259dSMatthias Ringwald static const char * set1_private_b_string = "55188b3d32f6bb9a900afcfbeed4e72a59cb9ac2f19d7cfb6b4fdd49f47fc5fd"; 21*bdcc259dSMatthias Ringwald static const char * set1_public_a_string = \ 22*bdcc259dSMatthias Ringwald "20b003d2f297be2c5e2c83a7e9f9a5b9eff49111acf4fddbcc0301480e359de6" \ 23*bdcc259dSMatthias Ringwald "dc809c49652aeb6d63329abf5a52155c766345c28fed3024741c8ed01589d28b"; 24*bdcc259dSMatthias Ringwald static const char * set1_public_b_string = \ 25*bdcc259dSMatthias Ringwald "1ea1f0f01faf1d9609592284f19e4c0047b58afd8615a69f559077b22faaa190" \ 26*bdcc259dSMatthias Ringwald "4c55f33e429dad377356703a9ab85160472d1130e28e36765f89aff915b1214a"; 27*bdcc259dSMatthias Ringwald static const char * set1_dh_key_string = "ec0234a357c8ad05341010a60a397d9b99796b13b4f866f1868d34f373bfa698"; 28*bdcc259dSMatthias Ringwald 29*bdcc259dSMatthias Ringwald // P256 Set 1 30*bdcc259dSMatthias Ringwald static const char * set2_private_a_string = "06a516693c9aa31a6084545d0c5db641b48572b97203ddffb7ac73f7d0457663"; 31*bdcc259dSMatthias Ringwald static const char * set2_private_b_string = "529aa0670d72cd6497502ed473502b037e8803b5c60829a5a3caa219505530ba"; 32*bdcc259dSMatthias Ringwald static const char * set2_public_a_string = \ 33*bdcc259dSMatthias Ringwald "2c31a47b5779809ef44cb5eaaf5c3e43d5f8faad4a8794cb987e9b03745c78dd" \ 34*bdcc259dSMatthias Ringwald "919512183898dfbecd52e2408e43871fd021109117bd3ed4eaf8437743715d4f"; 35*bdcc259dSMatthias Ringwald static const char * set2_public_b_string = \ 36*bdcc259dSMatthias Ringwald "f465e43ff23d3f1b9dc7dfc04da8758184dbc966204796eccf0d6cf5e16500cc" \ 37*bdcc259dSMatthias Ringwald "0201d048bcbbd899eeefc424164e33c201c2b010ca6b4d43a8a155cad8ecb279"; 38*bdcc259dSMatthias Ringwald static const char * set2_dh_key_string = "ab85843a2f6d883f62e5684b38e307335fe6e1945ecd19604105c6f23221eb69"; 39*bdcc259dSMatthias Ringwald 40*bdcc259dSMatthias Ringwald uint32_t big_endian_read_32( const uint8_t * buffer, int pos) { 41*bdcc259dSMatthias Ringwald return ((uint32_t) buffer[(pos)+3]) | (((uint32_t)buffer[(pos)+2]) << 8) | (((uint32_t)buffer[(pos)+1]) << 16) | (((uint32_t) buffer[pos]) << 24); 42*bdcc259dSMatthias Ringwald } 43*bdcc259dSMatthias Ringwald 44*bdcc259dSMatthias Ringwald void big_endian_store_32(uint8_t *buffer, uint16_t pos, uint32_t value){ 45*bdcc259dSMatthias Ringwald buffer[pos++] = value >> 24; 46*bdcc259dSMatthias Ringwald buffer[pos++] = value >> 16; 47*bdcc259dSMatthias Ringwald buffer[pos++] = value >> 8; 48*bdcc259dSMatthias Ringwald buffer[pos++] = value; 49*bdcc259dSMatthias Ringwald } 50*bdcc259dSMatthias Ringwald 51*bdcc259dSMatthias Ringwald static void hexdump_key(void *data, int size){ 52*bdcc259dSMatthias Ringwald if (size <= 0) return; 53*bdcc259dSMatthias Ringwald int i; 54*bdcc259dSMatthias Ringwald for (i=0; i<size;i++){ 55*bdcc259dSMatthias Ringwald printf("%02X", ((uint8_t *)data)[i]); 56*bdcc259dSMatthias Ringwald } 57*bdcc259dSMatthias Ringwald printf("\n"); 58*bdcc259dSMatthias Ringwald } 59*bdcc259dSMatthias Ringwald 60*bdcc259dSMatthias Ringwald static int nibble_for_char(char c){ 61*bdcc259dSMatthias Ringwald if (c >= '0' && c <= '9') return c - '0'; 62*bdcc259dSMatthias Ringwald if (c >= 'a' && c <= 'f') return c - 'a' + 10; 63*bdcc259dSMatthias Ringwald if (c >= 'A' && c <= 'F') return c - 'F' + 10; 64*bdcc259dSMatthias Ringwald return -1; 65*bdcc259dSMatthias Ringwald } 66*bdcc259dSMatthias Ringwald 67*bdcc259dSMatthias Ringwald static int parse_hex(uint8_t * buffer, const char * hex_string){ 68*bdcc259dSMatthias Ringwald int len = 0; 69*bdcc259dSMatthias Ringwald while (*hex_string){ 70*bdcc259dSMatthias Ringwald if (*hex_string == ' '){ 71*bdcc259dSMatthias Ringwald hex_string++; 72*bdcc259dSMatthias Ringwald continue; 73*bdcc259dSMatthias Ringwald } 74*bdcc259dSMatthias Ringwald int high_nibble = nibble_for_char(*hex_string++); 75*bdcc259dSMatthias Ringwald int low_nibble = nibble_for_char(*hex_string++); 76*bdcc259dSMatthias Ringwald int value = (high_nibble << 4) | low_nibble; 77*bdcc259dSMatthias Ringwald buffer[len++] = value; 78*bdcc259dSMatthias Ringwald } 79*bdcc259dSMatthias Ringwald return len; 80*bdcc259dSMatthias Ringwald } 81*bdcc259dSMatthias Ringwald 82*bdcc259dSMatthias Ringwald 83*bdcc259dSMatthias Ringwald static int test_generate_f_rng(uint8_t * buffer, unsigned size){ 84*bdcc259dSMatthias Ringwald // printf("test_generate_f_rng: size %u\n", (int)size); 85*bdcc259dSMatthias Ringwald while (size) { 86*bdcc259dSMatthias Ringwald *buffer++ = rand() & 0xff; 87*bdcc259dSMatthias Ringwald size--; 88*bdcc259dSMatthias Ringwald } 89*bdcc259dSMatthias Ringwald return 1; 90*bdcc259dSMatthias Ringwald } 91*bdcc259dSMatthias Ringwald 92*bdcc259dSMatthias Ringwald int test_set1(void){ 93*bdcc259dSMatthias Ringwald uint8_t private1[uECC_BYTES]; 94*bdcc259dSMatthias Ringwald uint8_t private2[uECC_BYTES]; 95*bdcc259dSMatthias Ringwald uint8_t public1[uECC_BYTES * 2]; 96*bdcc259dSMatthias Ringwald uint8_t public1_computed[uECC_BYTES * 2]; 97*bdcc259dSMatthias Ringwald uint8_t public2[uECC_BYTES * 2]; 98*bdcc259dSMatthias Ringwald uint8_t secret1[uECC_BYTES]; 99*bdcc259dSMatthias Ringwald uint8_t secret2[uECC_BYTES]; 100*bdcc259dSMatthias Ringwald uint8_t secret[uECC_BYTES]; 101*bdcc259dSMatthias Ringwald 102*bdcc259dSMatthias Ringwald parse_hex(private1, set1_private_a_string); 103*bdcc259dSMatthias Ringwald parse_hex(public1, set1_public_a_string); 104*bdcc259dSMatthias Ringwald parse_hex(private2, set1_private_b_string); 105*bdcc259dSMatthias Ringwald parse_hex(public2, set1_public_b_string); 106*bdcc259dSMatthias Ringwald parse_hex(secret, set1_dh_key_string); 107*bdcc259dSMatthias Ringwald 108*bdcc259dSMatthias Ringwald if (!uECC_compute_public_key(private1, public1_computed)){ 109*bdcc259dSMatthias Ringwald printf("uECC_compute_public_key() failed\n"); 110*bdcc259dSMatthias Ringwald } 111*bdcc259dSMatthias Ringwald if (memcmp(public1, public1_computed, sizeof(public1_computed)) != 0) { 112*bdcc259dSMatthias Ringwald printf("Computed public key differs from test data!\n"); 113*bdcc259dSMatthias Ringwald printf("Computed key = "); 114*bdcc259dSMatthias Ringwald hexdump_key(public1_computed, uECC_BYTES * 2); 115*bdcc259dSMatthias Ringwald printf("Expected ke = "); 116*bdcc259dSMatthias Ringwald hexdump_key(public1, uECC_BYTES * 2); 117*bdcc259dSMatthias Ringwald return 0; 118*bdcc259dSMatthias Ringwald } 119*bdcc259dSMatthias Ringwald 120*bdcc259dSMatthias Ringwald if (!uECC_shared_secret(public2, private1, secret1)) { 121*bdcc259dSMatthias Ringwald printf("shared_secret() failed (1)\n"); 122*bdcc259dSMatthias Ringwald return 0; 123*bdcc259dSMatthias Ringwald } 124*bdcc259dSMatthias Ringwald 125*bdcc259dSMatthias Ringwald if (!uECC_shared_secret(public1, private2, secret2)) { 126*bdcc259dSMatthias Ringwald printf("shared_secret() failed (2)\n"); 127*bdcc259dSMatthias Ringwald return 0; 128*bdcc259dSMatthias Ringwald } 129*bdcc259dSMatthias Ringwald 130*bdcc259dSMatthias Ringwald if (memcmp(secret1, secret2, sizeof(secret1)) != 0) { 131*bdcc259dSMatthias Ringwald printf("Shared secrets are not identical!\n"); 132*bdcc259dSMatthias Ringwald printf("Shared secret 1 = "); 133*bdcc259dSMatthias Ringwald hexdump_key(secret1, uECC_BYTES); 134*bdcc259dSMatthias Ringwald printf("Shared secret 2 = "); 135*bdcc259dSMatthias Ringwald hexdump_key(secret2, uECC_BYTES); 136*bdcc259dSMatthias Ringwald printf("Expected secret = "); hexdump_key(secret1, uECC_BYTES); 137*bdcc259dSMatthias Ringwald return 0; 138*bdcc259dSMatthias Ringwald } 139*bdcc259dSMatthias Ringwald // printf("Shared secret = "); hexdump_key(secret1, uECC_BYTES); 140*bdcc259dSMatthias Ringwald return 1; 141*bdcc259dSMatthias Ringwald } 142*bdcc259dSMatthias Ringwald 143*bdcc259dSMatthias Ringwald int test_set2(void){ 144*bdcc259dSMatthias Ringwald uint8_t private1[uECC_BYTES]; 145*bdcc259dSMatthias Ringwald uint8_t private2[uECC_BYTES]; 146*bdcc259dSMatthias Ringwald uint8_t public1[uECC_BYTES * 2]; 147*bdcc259dSMatthias Ringwald uint8_t public1_computed[uECC_BYTES * 2]; 148*bdcc259dSMatthias Ringwald uint8_t public2[uECC_BYTES * 2]; 149*bdcc259dSMatthias Ringwald uint8_t secret1[uECC_BYTES]; 150*bdcc259dSMatthias Ringwald uint8_t secret2[uECC_BYTES]; 151*bdcc259dSMatthias Ringwald uint8_t secret[uECC_BYTES]; 152*bdcc259dSMatthias Ringwald 153*bdcc259dSMatthias Ringwald parse_hex(private1, set2_private_a_string); 154*bdcc259dSMatthias Ringwald parse_hex(public1, set2_public_a_string); 155*bdcc259dSMatthias Ringwald parse_hex(private2, set2_private_b_string); 156*bdcc259dSMatthias Ringwald parse_hex(public2, set2_public_b_string); 157*bdcc259dSMatthias Ringwald parse_hex(secret, set2_dh_key_string); 158*bdcc259dSMatthias Ringwald 159*bdcc259dSMatthias Ringwald if (!uECC_compute_public_key(private1, public1_computed)){ 160*bdcc259dSMatthias Ringwald printf("uECC_compute_public_key() failed\n"); 161*bdcc259dSMatthias Ringwald } 162*bdcc259dSMatthias Ringwald 163*bdcc259dSMatthias Ringwald if (memcmp(public1, public1_computed, sizeof(public1_computed)) != 0) { 164*bdcc259dSMatthias Ringwald printf("Computed public key differs from test data!\n"); 165*bdcc259dSMatthias Ringwald printf("Computed key = "); 166*bdcc259dSMatthias Ringwald hexdump_key(public1_computed, uECC_BYTES * 2); 167*bdcc259dSMatthias Ringwald printf("Expected key = "); 168*bdcc259dSMatthias Ringwald hexdump_key(public1, uECC_BYTES * 2); 169*bdcc259dSMatthias Ringwald return 0; 170*bdcc259dSMatthias Ringwald } 171*bdcc259dSMatthias Ringwald 172*bdcc259dSMatthias Ringwald if (!uECC_shared_secret(public2, private1, secret1)) { 173*bdcc259dSMatthias Ringwald printf("shared_secret() failed (1)\n"); 174*bdcc259dSMatthias Ringwald return 0; 175*bdcc259dSMatthias Ringwald } 176*bdcc259dSMatthias Ringwald 177*bdcc259dSMatthias Ringwald if (!uECC_shared_secret(public1, private2, secret2)) { 178*bdcc259dSMatthias Ringwald printf("shared_secret() failed (2)\n"); 179*bdcc259dSMatthias Ringwald return 0; 180*bdcc259dSMatthias Ringwald } 181*bdcc259dSMatthias Ringwald 182*bdcc259dSMatthias Ringwald if (memcmp(secret1, secret2, sizeof(secret1)) != 0) { 183*bdcc259dSMatthias Ringwald printf("Shared secrets are not identical!\n"); 184*bdcc259dSMatthias Ringwald printf("Shared secret 1 = "); 185*bdcc259dSMatthias Ringwald hexdump_key(secret1, uECC_BYTES); 186*bdcc259dSMatthias Ringwald printf("Shared secret 2 = "); 187*bdcc259dSMatthias Ringwald hexdump_key(secret2, uECC_BYTES); 188*bdcc259dSMatthias Ringwald printf("Expected secret = "); hexdump_key(secret1, uECC_BYTES); 189*bdcc259dSMatthias Ringwald return 0; 190*bdcc259dSMatthias Ringwald } 191*bdcc259dSMatthias Ringwald // printf("Shared secret = "); hexdump_key(secret1, uECC_BYTES); 192*bdcc259dSMatthias Ringwald return 1; 193*bdcc259dSMatthias Ringwald } 194*bdcc259dSMatthias Ringwald 195*bdcc259dSMatthias Ringwald int test_generate(void){ 196*bdcc259dSMatthias Ringwald // use stdlib rand with fixed seed for testing 197*bdcc259dSMatthias Ringwald srand(0); 198*bdcc259dSMatthias Ringwald 199*bdcc259dSMatthias Ringwald uint8_t d[uECC_BYTES]; 200*bdcc259dSMatthias Ringwald uint8_t q[uECC_BYTES * 2]; 201*bdcc259dSMatthias Ringwald 202*bdcc259dSMatthias Ringwald if (!uECC_make_key(q, d)) { 203*bdcc259dSMatthias Ringwald printf("uECC_make_key() failed\n"); 204*bdcc259dSMatthias Ringwald return 1; 205*bdcc259dSMatthias Ringwald } 206*bdcc259dSMatthias Ringwald 207*bdcc259dSMatthias Ringwald // print keypair 208*bdcc259dSMatthias Ringwald printf("d: "); hexdump_key(d, uECC_BYTES); 209*bdcc259dSMatthias Ringwald printf("X: "); hexdump_key(&q[00], uECC_BYTES); 210*bdcc259dSMatthias Ringwald printf("Y: "); hexdump_key(&q[16], uECC_BYTES); 211*bdcc259dSMatthias Ringwald 212*bdcc259dSMatthias Ringwald // verify public key 213*bdcc259dSMatthias Ringwald if (!uECC_valid_public_key(q)){ 214*bdcc259dSMatthias Ringwald printf("uECC_valid_public_key() == 0 -> generated public key invalid\n"); 215*bdcc259dSMatthias Ringwald return 1; 216*bdcc259dSMatthias Ringwald } 217*bdcc259dSMatthias Ringwald 218*bdcc259dSMatthias Ringwald // verify private key? 219*bdcc259dSMatthias Ringwald // TODO: 220*bdcc259dSMatthias Ringwald 221*bdcc259dSMatthias Ringwald return 0; 222*bdcc259dSMatthias Ringwald } 223*bdcc259dSMatthias Ringwald 224*bdcc259dSMatthias Ringwald int main(void){ 225*bdcc259dSMatthias Ringwald uECC_set_rng(&test_generate_f_rng); 226*bdcc259dSMatthias Ringwald test_set1(); 227*bdcc259dSMatthias Ringwald test_set2(); 228*bdcc259dSMatthias Ringwald test_generate(); 229*bdcc259dSMatthias Ringwald return 0; 230*bdcc259dSMatthias Ringwald } 231