mirror of
https://github.com/kmackay/micro-ecc.git
synced 2026-09-14 13:10:05 +00:00
Added point compression and decompression functions (for issue #2).
This commit is contained in:
@@ -1260,9 +1260,19 @@ int ecc_make_key(EccPoint *p_publicKey, uint32_t p_privateKey[NUM_ECC_DIGITS], u
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Compute p_result = x^3 - 3x + b */
|
||||||
|
static void curve_x_side(uint32_t p_result[NUM_ECC_DIGITS], uint32_t x[NUM_ECC_DIGITS])
|
||||||
|
{
|
||||||
|
uint32_t _3[NUM_ECC_DIGITS] = {3}; /* -a = 3 */
|
||||||
|
|
||||||
|
vli_modSquare_fast(p_result, x); /* r = x^2 */
|
||||||
|
vli_modSub(p_result, p_result, _3, curve_p); /* r = x^2 - 3 */
|
||||||
|
vli_modMult_fast(p_result, p_result, x); /* r = x^3 - 3x */
|
||||||
|
vli_modAdd(p_result, p_result, curve_b, curve_p); /* r = x^3 - 3x + b */
|
||||||
|
}
|
||||||
|
|
||||||
int ecc_valid_public_key(EccPoint *p_publicKey)
|
int ecc_valid_public_key(EccPoint *p_publicKey)
|
||||||
{
|
{
|
||||||
uint32_t na[NUM_ECC_DIGITS] = {3}; /* -a = 3 */
|
|
||||||
uint32_t l_tmp1[NUM_ECC_DIGITS];
|
uint32_t l_tmp1[NUM_ECC_DIGITS];
|
||||||
uint32_t l_tmp2[NUM_ECC_DIGITS];
|
uint32_t l_tmp2[NUM_ECC_DIGITS];
|
||||||
|
|
||||||
@@ -1278,10 +1288,7 @@ int ecc_valid_public_key(EccPoint *p_publicKey)
|
|||||||
|
|
||||||
vli_modSquare_fast(l_tmp1, p_publicKey->y); /* tmp1 = y^2 */
|
vli_modSquare_fast(l_tmp1, p_publicKey->y); /* tmp1 = y^2 */
|
||||||
|
|
||||||
vli_modSquare_fast(l_tmp2, p_publicKey->x); /* tmp2 = x^2 */
|
curve_x_side(l_tmp2, p_publicKey->x); /* tmp2 = x^3 - 3x + b */
|
||||||
vli_modSub(l_tmp2, l_tmp2, na, curve_p); /* tmp2 = x^2 + a = x^2 - 3 */
|
|
||||||
vli_modMult_fast(l_tmp2, l_tmp2, p_publicKey->x); /* tmp2 = x^3 + ax */
|
|
||||||
vli_modAdd(l_tmp2, l_tmp2, curve_b, curve_p); /* tmp2 = x^3 + ax + b */
|
|
||||||
|
|
||||||
/* Make sure that y^2 == x^3 + ax + b */
|
/* Make sure that y^2 == x^3 + ax + b */
|
||||||
if(vli_cmp(l_tmp1, l_tmp2) != 0)
|
if(vli_cmp(l_tmp1, l_tmp2) != 0)
|
||||||
@@ -1517,3 +1524,41 @@ void ecc_native2bytes(uint8_t p_bytes[NUM_ECC_DIGITS*4], uint32_t p_native[NUM_E
|
|||||||
p_digit[3] = p_native[i];
|
p_digit[3] = p_native[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Compute a = sqrt(a) (mod curve_p). */
|
||||||
|
static void mod_sqrt(uint32_t a[NUM_ECC_DIGITS])
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
uint32_t p1[NUM_ECC_DIGITS] = {1};
|
||||||
|
uint32_t l_result[NUM_ECC_DIGITS] = {1};
|
||||||
|
|
||||||
|
/* Since curve_p == 3 (mod 4) for all supported curves, we can
|
||||||
|
compute sqrt(a) = a^((curve_p + 1) / 4) (mod curve_p). */
|
||||||
|
vli_add(p1, curve_p, p1); /* p1 = curve_p + 1 */
|
||||||
|
for(i = vli_numBits(p1) - 1; i > 1; --i)
|
||||||
|
{
|
||||||
|
vli_modSquare_fast(l_result, l_result);
|
||||||
|
if(vli_testBit(p1, i))
|
||||||
|
{
|
||||||
|
vli_modMult_fast(l_result, l_result, a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vli_set(a, l_result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ecc_point_compress(uint8_t p_compressed[NUM_ECC_DIGITS*4 + 1], EccPoint *p_point)
|
||||||
|
{
|
||||||
|
p_compressed[0] = 2 + (p_point->y[0] & 0x01);
|
||||||
|
ecc_native2bytes(p_compressed + 1, p_point->x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ecc_point_decompress(EccPoint *p_point, uint8_t p_compressed[NUM_ECC_DIGITS*4 + 1])
|
||||||
|
{
|
||||||
|
ecc_bytes2native(p_point->x, p_compressed + 1);
|
||||||
|
curve_x_side(p_point->y, p_point->x);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -152,4 +152,26 @@ Inputs:
|
|||||||
*/
|
*/
|
||||||
void ecc_native2bytes(uint8_t p_bytes[NUM_ECC_DIGITS*4], uint32_t p_native[NUM_ECC_DIGITS]);
|
void ecc_native2bytes(uint8_t p_bytes[NUM_ECC_DIGITS*4], uint32_t p_native[NUM_ECC_DIGITS]);
|
||||||
|
|
||||||
|
/* ecc_point_compress() function.
|
||||||
|
Compress a point from native format into the standard compressed octet representation.
|
||||||
|
|
||||||
|
Outputs:
|
||||||
|
p_compressed - Will be filled in with the compressed point representation.
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
p_point - The point to compress.
|
||||||
|
*/
|
||||||
|
void ecc_point_compress(uint8_t p_compressed[NUM_ECC_DIGITS*4 + 1], EccPoint *p_point);
|
||||||
|
|
||||||
|
/* ecc_point_compress() function.
|
||||||
|
Decompress a point from the standard compressed octet representation to native format.
|
||||||
|
|
||||||
|
Outputs:
|
||||||
|
p_point - Will be filled in with the native point representation.
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
p_compressed - The standard compressed octet representation of the point.
|
||||||
|
*/
|
||||||
|
void ecc_point_decompress(EccPoint *p_point, uint8_t p_compressed[NUM_ECC_DIGITS*4 + 1]);
|
||||||
|
|
||||||
#endif /* _MICRO_ECC_H_ */
|
#endif /* _MICRO_ECC_H_ */
|
||||||
|
|||||||
Reference in New Issue
Block a user