mirror of
https://github.com/kmackay/micro-ecc.git
synced 2026-08-01 16:17:46 +00:00
Merge pull request #39 from ricmoo/master
Added uECC_compute_public_key.
This commit is contained in:
@@ -0,0 +1,71 @@
|
||||
/* Copyright 2014, Kenneth MacKay. Licensed under the BSD 2-clause license. */
|
||||
|
||||
#include "uECC.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
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;
|
||||
int success;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
success = uECC_compute_public_key(l_private, l_public_computed);
|
||||
if (!success) {
|
||||
printf("uECC_compute_public_key() failed\n");
|
||||
}
|
||||
|
||||
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");
|
||||
|
||||
printf("Testing private key = 0\n");
|
||||
|
||||
memset(l_private, 0, uECC_BYTES);
|
||||
success = uECC_compute_public_key(l_private, l_public_computed);
|
||||
if (success) {
|
||||
printf("uECC_compute_public_key() should have failed\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1696,6 +1696,32 @@ static void EccPoint_mult(EccPoint * RESTRICT p_result, const EccPoint * RESTRIC
|
||||
vli_set(p_result->y, Ry[0]);
|
||||
}
|
||||
|
||||
static int EccPoint_compute_public_key(EccPoint *p_result, const uECC_word_t *p_private) {
|
||||
|
||||
/* Make sure the private key is in the range [1, n-1]. */
|
||||
if(vli_isZero(p_private))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if uECC_CURVE != uECC_secp160r1
|
||||
if(vli_cmp(curve_n, p_private) != 1)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Compute the public point */
|
||||
EccPoint_mult(p_result, &curve_G, p_private, 0, vli_numBits(p_private, uECC_WORDS));
|
||||
|
||||
if (EccPoint_isZero(p_result))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Compute a = sqrt(a) (mod curve_p). */
|
||||
static void mod_sqrt(uECC_word_t *a)
|
||||
{
|
||||
@@ -1789,36 +1815,28 @@ static void vli_bytesToNative(uint64_t *p_native, const uint8_t *p_bytes)
|
||||
|
||||
int uECC_make_key(uint8_t p_publicKey[uECC_BYTES*2], uint8_t p_privateKey[uECC_BYTES])
|
||||
{
|
||||
EccPoint l_public;
|
||||
uECC_word_t l_private[uECC_WORDS];
|
||||
uECC_word_t l_tries = 0;
|
||||
|
||||
do
|
||||
|
||||
EccPoint l_public;
|
||||
|
||||
while (1)
|
||||
{
|
||||
repeat:
|
||||
if(!g_rng((uint8_t *)l_private, sizeof(l_private)) || (l_tries++ >= MAX_TRIES))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if(vli_isZero(l_private))
|
||||
{
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
/* Make sure the private key is in the range [1, n-1]. */
|
||||
#if uECC_CURVE != uECC_secp160r1
|
||||
if(vli_cmp(curve_n, l_private) != 1)
|
||||
{
|
||||
goto repeat;
|
||||
}
|
||||
#endif
|
||||
|
||||
EccPoint_mult(&l_public, &curve_G, l_private, 0, vli_numBits(l_private, uECC_WORDS));
|
||||
} while(EccPoint_isZero(&l_public));
|
||||
|
||||
if (EccPoint_compute_public_key(&l_public, l_private)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vli_nativeToBytes(p_privateKey, l_private);
|
||||
|
||||
vli_nativeToBytes(p_publicKey, l_public.x);
|
||||
vli_nativeToBytes(p_publicKey + uECC_BYTES, l_public.y);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2380,6 +2398,22 @@ int uECC_verify(const uint8_t p_publicKey[uECC_BYTES*2], const uint8_t p_hash[uE
|
||||
return vli_equal(rx, r);
|
||||
}
|
||||
|
||||
int uECC_compute_public_key(const uint8_t p_privateKey[uECC_BYTES], uint8_t p_publicKey[uECC_BYTES * 2])
|
||||
{
|
||||
uECC_word_t l_private[uECC_WORDS];
|
||||
vli_bytesToNative(l_private, p_privateKey);
|
||||
|
||||
EccPoint l_public;
|
||||
if (!EccPoint_compute_public_key(&l_public, l_private)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
vli_nativeToBytes(p_publicKey, l_public.x);
|
||||
vli_nativeToBytes(p_publicKey + uECC_BYTES, l_public.y);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int uECC_bytes(void)
|
||||
{
|
||||
return uECC_BYTES;
|
||||
|
||||
@@ -78,7 +78,7 @@ return 1 if the random data was generated, or 0 if the random data could not be
|
||||
|
||||
On platforms where there is no predefined RNG function (eg embedded platforms), this must
|
||||
be called before uECC_make_key() or uECC_sign() are used.
|
||||
|
||||
|
||||
Inputs:
|
||||
p_rng - The function that will be used to generate random bytes.
|
||||
*/
|
||||
@@ -86,7 +86,7 @@ void uECC_set_rng(uECC_RNG_Function p_rng);
|
||||
|
||||
/* uECC_make_key() function.
|
||||
Create a public/private key pair.
|
||||
|
||||
|
||||
Outputs:
|
||||
p_publicKey - Will be filled in with the public key.
|
||||
p_privateKey - Will be filled in with the private key.
|
||||
@@ -178,6 +178,20 @@ 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
|
||||
|
||||
Returns 1 if the key was computed successfully, 0 if an error occurred.
|
||||
*/
|
||||
int 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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user