mirror of
https://github.com/kmackay/micro-ecc.git
synced 2026-07-29 22:57:46 +00:00
Modified ecc_make_key() and ecdh_shared_secret() functions to produce/take uncompressed public keys. Added separate functions to compress and decompress public keys.
This commit is contained in:
@@ -4109,25 +4109,7 @@ static void vli_flip(uint8_t * RESTRICT p_dest, const uint8_t * RESTRICT p_src)
|
||||
}
|
||||
}
|
||||
|
||||
static void ecc_point_decompress(EccPoint *p_point, const uint8_t p_compressed[ECC_BYTES+1])
|
||||
{
|
||||
uint8_t _3[ECC_BYTES] = {3}; /* -a = 3 */
|
||||
vli_flip(p_point->x, p_compressed + 1);
|
||||
|
||||
vli_modSquare_fast(p_point->y, p_point->x); /* y = x^2 */
|
||||
vli_modSub(p_point->y, p_point->y, _3, curve_p); /* y = x^2 - 3 */
|
||||
vli_modMult_fast(p_point->y, p_point->y, p_point->x); /* y = x^3 - 3x */
|
||||
vli_modAdd(p_point->y, p_point->y, curve_b, curve_p); /* y = x^3 - 3x + b */
|
||||
|
||||
mod_sqrt(p_point->y);
|
||||
|
||||
if((p_point->y[0] & 0x01) != (p_compressed[0] & 0x01))
|
||||
{
|
||||
vli_sub(p_point->y, curve_p, p_point->y);
|
||||
}
|
||||
}
|
||||
|
||||
int ecc_make_key(uint8_t p_publicKey[ECC_BYTES+1], uint8_t p_privateKey[ECC_BYTES])
|
||||
int ecc_make_key(uint8_t p_publicKey[ECC_BYTES*2], uint8_t p_privateKey[ECC_BYTES])
|
||||
{
|
||||
EccPoint l_public;
|
||||
uint8_t l_private[ECC_BYTES];
|
||||
@@ -4157,24 +4139,22 @@ int ecc_make_key(uint8_t p_publicKey[ECC_BYTES+1], uint8_t p_privateKey[ECC_BYTE
|
||||
} while(EccPoint_isZero(&l_public));
|
||||
|
||||
vli_flip(p_privateKey, l_private);
|
||||
vli_flip(p_publicKey + 1, l_public.x);
|
||||
p_publicKey[0] = 2 + (l_public.y[0] & 0x01);
|
||||
vli_flip(p_publicKey, l_public.x);
|
||||
vli_flip(p_publicKey + ECC_BYTES, l_public.y);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ecdh_shared_secret(const uint8_t p_publicKey[ECC_BYTES+1], const uint8_t p_privateKey[ECC_BYTES], uint8_t p_secret[ECC_BYTES])
|
||||
int ecdh_shared_secret(const uint8_t p_publicKey[ECC_BYTES*2], const uint8_t p_privateKey[ECC_BYTES], uint8_t p_secret[ECC_BYTES])
|
||||
{
|
||||
EccPoint l_public;
|
||||
uint8_t l_private[ECC_BYTES];
|
||||
uint8_t l_random[ECC_BYTES];
|
||||
|
||||
if(!g_rng(l_random, ECC_BYTES))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
g_rng(l_random, ECC_BYTES);
|
||||
|
||||
vli_flip(l_private, p_privateKey);
|
||||
ecc_point_decompress(&l_public, p_publicKey);
|
||||
vli_flip(l_public.x, p_publicKey);
|
||||
vli_flip(l_public.y, p_publicKey + ECC_BYTES);
|
||||
|
||||
EccPoint l_product;
|
||||
EccPoint_mult(&l_product, &l_public, l_private, l_random);
|
||||
@@ -4183,3 +4163,31 @@ int ecdh_shared_secret(const uint8_t p_publicKey[ECC_BYTES+1], const uint8_t p_p
|
||||
|
||||
return !EccPoint_isZero(&l_product);
|
||||
}
|
||||
|
||||
void ecc_compress(uint8_t p_publicKey[ECC_BYTES*2], uint8_t p_compressed[ECC_BYTES+1])
|
||||
{
|
||||
vli_set(p_compressed + 1, p_publicKey);
|
||||
p_compressed[0] = 2 + (p_publicKey[ECC_BYTES * 2 - 1] & 0x01);
|
||||
}
|
||||
|
||||
void ecc_decompress(uint8_t p_compressed[ECC_BYTES+1], uint8_t p_publicKey[ECC_BYTES*2])
|
||||
{
|
||||
EccPoint l_point;
|
||||
uint8_t _3[ECC_BYTES] = {3}; /* -a = 3 */
|
||||
vli_flip(l_point.x, p_compressed + 1);
|
||||
|
||||
vli_modSquare_fast(l_point.y, l_point.x); /* y = x^2 */
|
||||
vli_modSub(l_point.y, l_point.y, _3, curve_p); /* y = x^2 - 3 */
|
||||
vli_modMult_fast(l_point.y, l_point.y, l_point.x); /* y = x^3 - 3x */
|
||||
vli_modAdd(l_point.y, l_point.y, curve_b, curve_p); /* y = x^3 - 3x + b */
|
||||
|
||||
mod_sqrt(l_point.y);
|
||||
|
||||
if((l_point.y[0] & 0x01) != (p_compressed[0] & 0x01))
|
||||
{
|
||||
vli_sub(l_point.y, curve_p, l_point.y);
|
||||
}
|
||||
|
||||
vli_flip(p_publicKey, l_point.x);
|
||||
vli_flip(p_publicKey + ECC_BYTES, l_point.y);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@ Outputs:
|
||||
|
||||
Returns 1 if the key pair was generated successfully, 0 if an error occurred.
|
||||
*/
|
||||
int ecc_make_key(uint8_t p_publicKey[ECC_BYTES+1], uint8_t p_privateKey[ECC_BYTES]);
|
||||
int ecc_make_key(uint8_t p_publicKey[ECC_BYTES*2], uint8_t p_privateKey[ECC_BYTES]);
|
||||
|
||||
/* ecdh_shared_secret() function.
|
||||
Compute a shared secret given your secret key and someone else's public key.
|
||||
@@ -84,10 +84,32 @@ Outputs:
|
||||
|
||||
Returns 1 if the shared secret was generated successfully, 0 if an error occurred.
|
||||
*/
|
||||
int ecdh_shared_secret(const uint8_t p_publicKey[ECC_BYTES+1], const uint8_t p_privateKey[ECC_BYTES], uint8_t p_secret[ECC_BYTES]);
|
||||
int ecdh_shared_secret(const uint8_t p_publicKey[ECC_BYTES*2], const uint8_t p_privateKey[ECC_BYTES], uint8_t p_secret[ECC_BYTES]);
|
||||
|
||||
/* ecc_compress() function.
|
||||
Compress a public key.
|
||||
|
||||
Inputs:
|
||||
p_publicKey - The public key to compress.
|
||||
|
||||
Outputs:
|
||||
p_compressed - Will be filled in with the compressed public key.
|
||||
*/
|
||||
void ecc_compress(uint8_t p_publicKey[ECC_BYTES*2], uint8_t p_compressed[ECC_BYTES+1]);
|
||||
|
||||
/* ecc_decompress() function.
|
||||
Decompress a compressed public key.
|
||||
|
||||
Inputs:
|
||||
p_compressed - The compressed public key.
|
||||
|
||||
Outputs:
|
||||
p_publicKey - Will be filled in with the decompressed public key.
|
||||
*/
|
||||
void ecc_decompress(uint8_t p_compressed[ECC_BYTES+1], uint8_t p_publicKey[ECC_BYTES*2]);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* _EASY_ECC_H_ */
|
||||
#endif /* _AVR_ECC_H_ */
|
||||
|
||||
@@ -20,8 +20,8 @@ void setup() {
|
||||
uint8_t l_private1[ECC_BYTES];
|
||||
uint8_t l_private2[ECC_BYTES];
|
||||
|
||||
uint8_t l_public1[ECC_BYTES + 1];
|
||||
uint8_t l_public2[ECC_BYTES + 1];
|
||||
uint8_t l_public1[ECC_BYTES * 2];
|
||||
uint8_t l_public2[ECC_BYTES * 2];
|
||||
|
||||
uint8_t l_secret1[ECC_BYTES];
|
||||
uint8_t l_secret2[ECC_BYTES];
|
||||
|
||||
Reference in New Issue
Block a user