From a46621eb5789749e0e54e97fb6d95390c712a27d Mon Sep 17 00:00:00 2001 From: Richard Moore Date: Tue, 19 May 2015 13:26:24 -0400 Subject: [PATCH] Added uECC_compute_public_key. --- test/test_compute.c | 58 +++++++++++++++++++++++++++++++++++++++++++++ uECC.c | 12 ++++++++++ uECC.h | 12 ++++++++++ 3 files changed, 82 insertions(+) create mode 100644 test/test_compute.c diff --git a/test/test_compute.c b/test/test_compute.c new file mode 100644 index 0000000..160fac5 --- /dev/null +++ b/test/test_compute.c @@ -0,0 +1,58 @@ +/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */ + +#include "uECC.h" + +#include +#include + +void vli_print(uint8_t *p_vli, unsigned int p_size) +{ + while(p_size) + { + printf("%02X ", (unsigned)p_vli[p_size - 1]); + --p_size; + } +} + +int main() +{ + int i; + + uint8_t l_private[uECC_BYTES]; + + uint8_t l_public[uECC_BYTES * 2]; + uint8_t l_public_computed[uECC_BYTES * 2]; + + printf("Testing 256 random private key pairs\n"); + + for(i=0; i<256; ++i) + { + printf("."); + fflush(stdout); + + int success = uECC_make_key(l_public, l_private); + if (!success) { + printf("uECC_make_key() failed\n"); + return 1; + } + + uECC_compute_public_key(l_private, l_public_computed); + + if(memcmp(l_public, l_public_computed, sizeof(l_public)) != 0) + { + printf("Computed and provided public keys are not identical!\n"); + printf("Computed public key = "); + vli_print(l_public_computed, uECC_BYTES); + printf("\n"); + printf("Provided public key = "); + vli_print(l_public, uECC_BYTES); + printf("\n"); + printf("Private key = "); + vli_print(l_private, uECC_BYTES); + printf("\n"); + } + } + printf("\n"); + + return 0; +} diff --git a/uECC.c b/uECC.c index 96726a9..33cae0c 100644 --- a/uECC.c +++ b/uECC.c @@ -2380,6 +2380,18 @@ int uECC_verify(const uint8_t p_publicKey[uECC_BYTES*2], const uint8_t p_hash[uE return vli_equal(rx, r); } +void uECC_compute_public_key(const uint8_t p_privateKey[uECC_BYTES], uint8_t p_publicKey[uECC_BYTES * 2]) { + EccPoint l_public; + uECC_word_t l_private[uECC_WORDS]; + + vli_bytesToNative(l_private, p_privateKey); + + EccPoint_mult(&l_public, &curve_G, l_private, 0, vli_numBits(l_private, uECC_WORDS)); + + vli_nativeToBytes(p_publicKey, l_public.x); + vli_nativeToBytes(p_publicKey + uECC_BYTES, l_public.y); +} + int uECC_bytes(void) { return uECC_BYTES; diff --git a/uECC.h b/uECC.h index 18c1adb..e1a4fa8 100644 --- a/uECC.h +++ b/uECC.h @@ -178,6 +178,18 @@ Returns 1 if the public key is valid, 0 if it is invalid. */ int uECC_valid_public_key(const uint8_t p_publicKey[uECC_BYTES*2]); +/* uECC_compute_public_key() function. +Compute the corresponding public key for a private key. + +Inputs: + p_privateKey - The private key to compute the public key for + +Outputs: + p_publicKey - Will be filled in with the corresponding public key +*/ +void uECC_compute_public_key(const uint8_t p_privateKey[uECC_BYTES], uint8_t p_publicKey[uECC_BYTES * 2]); + + /* uECC_bytes() function. Returns the value of uECC_BYTES. Helpful for foreign-interfaces to higher-level languages. */