mirror of
https://github.com/neocturne/libuecc.git
synced 2025-03-04 09:03:31 +01:00
Check points for validity on load
This commit is contained in:
parent
131597e511
commit
a88af14481
2 changed files with 38 additions and 12 deletions
|
@ -65,10 +65,10 @@ typedef struct _ecc_25519_work {
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void ecc_25519_load_xy(ecc_25519_work_t *out, const ecc_int256_t *x, const ecc_int256_t *y);
|
int ecc_25519_load_xy(ecc_25519_work_t *out, const ecc_int256_t *x, const ecc_int256_t *y);
|
||||||
void ecc_25519_store_xy(ecc_int256_t *x, ecc_int256_t *y, const ecc_25519_work_t *in);
|
void ecc_25519_store_xy(ecc_int256_t *x, ecc_int256_t *y, const ecc_25519_work_t *in);
|
||||||
|
|
||||||
void ecc_25519_load_packed(ecc_25519_work_t *out, const ecc_int256_t *in);
|
int ecc_25519_load_packed(ecc_25519_work_t *out, const ecc_int256_t *in);
|
||||||
void ecc_25519_store_packed(ecc_int256_t *out, const ecc_25519_work_t *in);
|
void ecc_25519_store_packed(ecc_int256_t *out, const ecc_25519_work_t *in);
|
||||||
|
|
||||||
int ecc_25519_is_identity(const ecc_25519_work_t *in);
|
int ecc_25519_is_identity(const ecc_25519_work_t *in);
|
||||||
|
|
|
@ -40,6 +40,10 @@
|
||||||
#include <libuecc/ecc.h>
|
#include <libuecc/ecc.h>
|
||||||
|
|
||||||
|
|
||||||
|
static const unsigned int zero[32] = {0};
|
||||||
|
static const unsigned int one[32] = {1};
|
||||||
|
|
||||||
|
|
||||||
/** Adds two unpacked integers (modulo p) */
|
/** Adds two unpacked integers (modulo p) */
|
||||||
static void add(unsigned int out[32], const unsigned int a[32], const unsigned int b[32]) {
|
static void add(unsigned int out[32], const unsigned int a[32], const unsigned int b[32]) {
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
|
@ -114,7 +118,7 @@ static void mult(unsigned int out[32], const unsigned int a[32], const unsigned
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Multiplies an unpacked integer with a small integer (modulo p) */
|
/** Multiplies an unpacked integer with a small integer (modulo p) */
|
||||||
static void mult_int(unsigned int out[32], const unsigned int n, const unsigned int a[32]) {
|
static void mult_int(unsigned int out[32], unsigned int n, const unsigned int a[32]) {
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
unsigned int u;
|
unsigned int u;
|
||||||
|
|
||||||
|
@ -165,7 +169,6 @@ static int check_equal(const unsigned int x[32], const unsigned int y[32]) {
|
||||||
* The intergers must be must be \ref squeeze "squeezed" before.
|
* The intergers must be must be \ref squeeze "squeezed" before.
|
||||||
*/
|
*/
|
||||||
static int check_zero(const unsigned int x[32]) {
|
static int check_zero(const unsigned int x[32]) {
|
||||||
static const unsigned int zero[32] = {0};
|
|
||||||
static const unsigned int p[32] = {
|
static const unsigned int p[32] = {
|
||||||
0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
0xed, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
@ -214,9 +217,9 @@ static void select(unsigned int out[32], const unsigned int r[32], const unsigne
|
||||||
/**
|
/**
|
||||||
* Computes the square root of an unpacked integer (in the prime field modulo p)
|
* Computes the square root of an unpacked integer (in the prime field modulo p)
|
||||||
*
|
*
|
||||||
* If the given integer has no square root, the result is undefined.
|
* If the given integer has no square root, 0 is returned, 1 otherwise.
|
||||||
*/
|
*/
|
||||||
static void square_root(unsigned int out[32], const unsigned int z[32]) {
|
static int square_root(unsigned int out[32], const unsigned int z[32]) {
|
||||||
static const unsigned int minus1[32] = {
|
static const unsigned int minus1[32] = {
|
||||||
0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
0xec, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||||
|
@ -303,6 +306,10 @@ static void square_root(unsigned int out[32], const unsigned int z[32]) {
|
||||||
mult(z2_252_1_rho_s, z2_252_1, rho_s);
|
mult(z2_252_1_rho_s, z2_252_1, rho_s);
|
||||||
|
|
||||||
select(out, z2_252_1, z2_252_1_rho_s, check_equal(t1, minus1));
|
select(out, z2_252_1, z2_252_1_rho_s, check_equal(t1, minus1));
|
||||||
|
|
||||||
|
/* Check the root */
|
||||||
|
square(t0, out);
|
||||||
|
return check_equal(t0, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Computes the reciprocal of an unpacked integer (in the prime field modulo p) */
|
/** Computes the reciprocal of an unpacked integer (in the prime field modulo p) */
|
||||||
|
@ -373,8 +380,9 @@ static void recip(unsigned int out[32], const unsigned int z[32]) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Loads a point with given coordinates into its unpacked representation */
|
/** Loads a point with given coordinates into its unpacked representation */
|
||||||
void ecc_25519_load_xy(ecc_25519_work_t *out, const ecc_int256_t *x, const ecc_int256_t *y) {
|
int ecc_25519_load_xy(ecc_25519_work_t *out, const ecc_int256_t *x, const ecc_int256_t *y) {
|
||||||
int i;
|
int i;
|
||||||
|
unsigned int X2[32], Y2[32], aX2[32], dX2[32], dX2Y2[32], aX2_Y2[32], _1_dX2Y2[32], r[32];
|
||||||
|
|
||||||
for (i = 0; i < 32; i++) {
|
for (i = 0; i < 32; i++) {
|
||||||
out->X[i] = x->p[i];
|
out->X[i] = x->p[i];
|
||||||
|
@ -382,7 +390,23 @@ void ecc_25519_load_xy(ecc_25519_work_t *out, const ecc_int256_t *x, const ecc_i
|
||||||
out->Z[i] = (i == 0);
|
out->Z[i] = (i == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check validity */
|
||||||
|
square(X2, out->X);
|
||||||
|
square(Y2, out->Y);
|
||||||
|
mult_int(aX2, 486664, X2);
|
||||||
|
mult_int(dX2, 486660, X2);
|
||||||
|
mult(dX2Y2, dX2, Y2);
|
||||||
|
add(aX2_Y2, aX2, Y2);
|
||||||
|
add(_1_dX2Y2, one, dX2Y2);
|
||||||
|
sub(r, aX2_Y2, _1_dX2Y2);
|
||||||
|
squeeze(r);
|
||||||
|
|
||||||
|
if (!check_zero(r))
|
||||||
|
return 0;
|
||||||
|
|
||||||
mult(out->T, out->X, out->Y);
|
mult(out->T, out->X, out->Y);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -414,10 +438,7 @@ void ecc_25519_store_xy(ecc_int256_t *x, ecc_int256_t *y, const ecc_25519_work_t
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Loads a packed point into its unpacked representation */
|
/** Loads a packed point into its unpacked representation */
|
||||||
void ecc_25519_load_packed(ecc_25519_work_t *out, const ecc_int256_t *in) {
|
int ecc_25519_load_packed(ecc_25519_work_t *out, const ecc_int256_t *in) {
|
||||||
static const unsigned int zero[32] = {0};
|
|
||||||
static const unsigned int one[32] = {1};
|
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
unsigned int X2[32] /* X^2 */, aX2[32] /* aX^2 */, dX2[32] /* dX^2 */, _1_aX2[32] /* 1-aX^2 */, _1_dX2[32] /* 1-aX^2 */;
|
unsigned int X2[32] /* X^2 */, aX2[32] /* aX^2 */, dX2[32] /* dX^2 */, _1_aX2[32] /* 1-aX^2 */, _1_dX2[32] /* 1-aX^2 */;
|
||||||
unsigned int _1_1_dX2[32] /* 1/(1-aX^2) */, Y2[32] /* Y^2 */, Y[32], Yt[32];
|
unsigned int _1_1_dX2[32] /* 1/(1-aX^2) */, Y2[32] /* Y^2 */, Y[32], Yt[32];
|
||||||
|
@ -436,12 +457,17 @@ void ecc_25519_load_packed(ecc_25519_work_t *out, const ecc_int256_t *in) {
|
||||||
sub(_1_dX2, one, dX2);
|
sub(_1_dX2, one, dX2);
|
||||||
recip(_1_1_dX2, _1_dX2);
|
recip(_1_1_dX2, _1_dX2);
|
||||||
mult(Y2, _1_aX2, _1_1_dX2);
|
mult(Y2, _1_aX2, _1_1_dX2);
|
||||||
square_root(Y, Y2);
|
|
||||||
|
if (!square_root(Y, Y2))
|
||||||
|
return 0;
|
||||||
|
|
||||||
sub(Yt, zero, Y);
|
sub(Yt, zero, Y);
|
||||||
|
|
||||||
select(out->Y, Y, Yt, (in->p[31] >> 7) ^ (Y[0] & 1));
|
select(out->Y, Y, Yt, (in->p[31] >> 7) ^ (Y[0] & 1));
|
||||||
|
|
||||||
mult(out->T, out->X, out->Y);
|
mult(out->T, out->X, out->Y);
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Stores a point into its packed representation */
|
/** Stores a point into its packed representation */
|
||||||
|
|
Loading…
Add table
Reference in a new issue