mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 10:43:19 -03:00
Merge pull request #199
fcc48c4
Remove the non-storage cmov (Pieter Wuille) 55422b6 Switch ecmult_gen to use storage types (Pieter Wuille)41f8455
Use group element storage type in EC multiplications (Pieter Wuille)e68d720
Add group element storage type (Pieter Wuille)ff889f7
Field storage type (Pieter Wuille)
This commit is contained in:
commit
fc8285f18a
10 changed files with 193 additions and 41 deletions
|
@ -24,7 +24,7 @@ typedef struct {
|
|||
* None of the resulting prec group elements have a known scalar, and neither do any of
|
||||
* the intermediate sums while computing a*G.
|
||||
*/
|
||||
secp256k1_fe_t prec[64][16][2]; /* prec[j][i] = (16^j * i * G + U_i).{x,y} */
|
||||
secp256k1_ge_storage_t prec[64][16]; /* prec[j][i] = 16^j * i * G + U_i */
|
||||
} secp256k1_ecmult_gen_consts_t;
|
||||
|
||||
static const secp256k1_ecmult_gen_consts_t *secp256k1_ecmult_gen_consts = NULL;
|
||||
|
@ -80,9 +80,7 @@ static void secp256k1_ecmult_gen_start(void) {
|
|||
}
|
||||
for (int j=0; j<64; j++) {
|
||||
for (int i=0; i<16; i++) {
|
||||
VERIFY_CHECK(!secp256k1_ge_is_infinity(&prec[j*16 + i]));
|
||||
ret->prec[j][i][0] = prec[j*16 + i].x;
|
||||
ret->prec[j][i][1] = prec[j*16 + i].y;
|
||||
secp256k1_ge_to_storage(&ret->prec[j][i], &prec[j*16 + i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,16 +99,17 @@ static void secp256k1_ecmult_gen_stop(void) {
|
|||
|
||||
static void secp256k1_ecmult_gen(secp256k1_gej_t *r, const secp256k1_scalar_t *gn) {
|
||||
const secp256k1_ecmult_gen_consts_t *c = secp256k1_ecmult_gen_consts;
|
||||
secp256k1_gej_set_infinity(r);
|
||||
secp256k1_ge_t add;
|
||||
secp256k1_ge_storage_t adds;
|
||||
secp256k1_gej_set_infinity(r);
|
||||
add.infinity = 0;
|
||||
int bits;
|
||||
for (int j=0; j<64; j++) {
|
||||
bits = secp256k1_scalar_get_bits(gn, j * 4, 4);
|
||||
for (int i=0; i<16; i++) {
|
||||
secp256k1_fe_cmov(&add.x, &c->prec[j][i][0], i == bits);
|
||||
secp256k1_fe_cmov(&add.y, &c->prec[j][i][1], i == bits);
|
||||
secp256k1_ge_storage_cmov(&adds, &c->prec[j][i], i == bits);
|
||||
}
|
||||
secp256k1_ge_from_storage(&add, &adds);
|
||||
secp256k1_gej_add_ge(r, r, &add);
|
||||
}
|
||||
bits = 0;
|
||||
|
|
|
@ -43,16 +43,21 @@ static void secp256k1_ecmult_table_precomp_gej_var(secp256k1_gej_t *pre, const s
|
|||
secp256k1_gej_add_var(&pre[i], &d, &pre[i-1]);
|
||||
}
|
||||
|
||||
static void secp256k1_ecmult_table_precomp_ge_var(secp256k1_ge_t *pre, const secp256k1_gej_t *a, int w) {
|
||||
static void secp256k1_ecmult_table_precomp_ge_storage_var(secp256k1_ge_storage_t *pre, const secp256k1_gej_t *a, int w) {
|
||||
const int table_size = 1 << (w-2);
|
||||
secp256k1_gej_t *prej = checked_malloc(sizeof(secp256k1_gej_t) * table_size);
|
||||
secp256k1_ge_t *prea = checked_malloc(sizeof(secp256k1_ge_t) * table_size);
|
||||
prej[0] = *a;
|
||||
secp256k1_gej_t d; secp256k1_gej_double_var(&d, a);
|
||||
for (int i=1; i<table_size; i++) {
|
||||
secp256k1_gej_add_var(&prej[i], &d, &prej[i-1]);
|
||||
}
|
||||
secp256k1_ge_set_all_gej_var(table_size, pre, prej);
|
||||
secp256k1_ge_set_all_gej_var(table_size, prea, prej);
|
||||
for (int i=0; i<table_size; i++) {
|
||||
secp256k1_ge_to_storage(&pre[i], &prea[i]);
|
||||
}
|
||||
free(prej);
|
||||
free(prea);
|
||||
}
|
||||
|
||||
/** The number of entries a table with precomputed multiples needs to have. */
|
||||
|
@ -60,24 +65,32 @@ static void secp256k1_ecmult_table_precomp_ge_var(secp256k1_ge_t *pre, const sec
|
|||
|
||||
/** The following two macro retrieves a particular odd multiple from a table
|
||||
* of precomputed multiples. */
|
||||
#define ECMULT_TABLE_GET(r,pre,n,w,neg) do { \
|
||||
#define ECMULT_TABLE_GET_GEJ(r,pre,n,w) do { \
|
||||
VERIFY_CHECK(((n) & 1) == 1); \
|
||||
VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \
|
||||
VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \
|
||||
if ((n) > 0) \
|
||||
*(r) = (pre)[((n)-1)/2]; \
|
||||
else \
|
||||
(neg)((r), &(pre)[(-(n)-1)/2]); \
|
||||
secp256k1_gej_neg((r), &(pre)[(-(n)-1)/2]); \
|
||||
} while(0)
|
||||
#define ECMULT_TABLE_GET_GE_STORAGE(r,pre,n,w) do { \
|
||||
VERIFY_CHECK(((n) & 1) == 1); \
|
||||
VERIFY_CHECK((n) >= -((1 << ((w)-1)) - 1)); \
|
||||
VERIFY_CHECK((n) <= ((1 << ((w)-1)) - 1)); \
|
||||
if ((n) > 0) \
|
||||
secp256k1_ge_from_storage((r), &(pre)[((n)-1)/2]); \
|
||||
else {\
|
||||
secp256k1_ge_from_storage((r), &(pre)[(-(n)-1)/2]); \
|
||||
secp256k1_ge_neg((r), (r)); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define ECMULT_TABLE_GET_GEJ(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_gej_neg)
|
||||
#define ECMULT_TABLE_GET_GE(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_ge_neg)
|
||||
|
||||
typedef struct {
|
||||
/* For accelerating the computation of a*P + b*G: */
|
||||
secp256k1_ge_t pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of the generator */
|
||||
secp256k1_ge_storage_t pre_g[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of the generator */
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
secp256k1_ge_t pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of 2^128*generator */
|
||||
secp256k1_ge_storage_t pre_g_128[ECMULT_TABLE_SIZE(WINDOW_G)]; /* odd multiples of 2^128*generator */
|
||||
#endif
|
||||
} secp256k1_ecmult_consts_t;
|
||||
|
||||
|
@ -101,9 +114,9 @@ static void secp256k1_ecmult_start(void) {
|
|||
#endif
|
||||
|
||||
/* precompute the tables with odd multiples */
|
||||
secp256k1_ecmult_table_precomp_ge_var(ret->pre_g, &gj, WINDOW_G);
|
||||
secp256k1_ecmult_table_precomp_ge_storage_var(ret->pre_g, &gj, WINDOW_G);
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
secp256k1_ecmult_table_precomp_ge_var(ret->pre_g_128, &g_128j, WINDOW_G);
|
||||
secp256k1_ecmult_table_precomp_ge_storage_var(ret->pre_g_128, &g_128j, WINDOW_G);
|
||||
#endif
|
||||
|
||||
/* Set the global pointer to the precomputation table. */
|
||||
|
@ -224,11 +237,11 @@ static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const
|
|||
secp256k1_gej_add_var(r, r, &tmpj);
|
||||
}
|
||||
if (i < bits_ng_1 && (n = wnaf_ng_1[i])) {
|
||||
ECMULT_TABLE_GET_GE(&tmpa, c->pre_g, n, WINDOW_G);
|
||||
ECMULT_TABLE_GET_GE_STORAGE(&tmpa, c->pre_g, n, WINDOW_G);
|
||||
secp256k1_gej_add_ge_var(r, r, &tmpa);
|
||||
}
|
||||
if (i < bits_ng_128 && (n = wnaf_ng_128[i])) {
|
||||
ECMULT_TABLE_GET_GE(&tmpa, c->pre_g_128, n, WINDOW_G);
|
||||
ECMULT_TABLE_GET_GE_STORAGE(&tmpa, c->pre_g_128, n, WINDOW_G);
|
||||
secp256k1_gej_add_ge_var(r, r, &tmpa);
|
||||
}
|
||||
#else
|
||||
|
@ -237,7 +250,7 @@ static void secp256k1_ecmult(secp256k1_gej_t *r, const secp256k1_gej_t *a, const
|
|||
secp256k1_gej_add_var(r, r, &tmpj);
|
||||
}
|
||||
if (i < bits_ng && (n = wnaf_ng[i])) {
|
||||
ECMULT_TABLE_GET_GE(&tmpa, c->pre_g, n, WINDOW_G);
|
||||
ECMULT_TABLE_GET_GE_STORAGE(&tmpa, c->pre_g, n, WINDOW_G);
|
||||
secp256k1_gej_add_ge_var(r, r, &tmpa);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -110,7 +110,13 @@ static void secp256k1_fe_get_hex(char *r64, const secp256k1_fe_t *a);
|
|||
/** Convert a 64-character hexadecimal string to a field element. */
|
||||
static int secp256k1_fe_set_hex(secp256k1_fe_t *r, const char *a64);
|
||||
|
||||
/** Convert a field element to the storage type. */
|
||||
static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t*);
|
||||
|
||||
/** Convert a field element back from the storage type. */
|
||||
static void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t*);
|
||||
|
||||
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */
|
||||
static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag);
|
||||
static void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -37,4 +37,10 @@ typedef struct {
|
|||
#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))}
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint32_t n[8];
|
||||
} secp256k1_fe_storage_t;
|
||||
|
||||
#define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1063,7 +1063,7 @@ static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) {
|
||||
static inline void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag) {
|
||||
uint32_t mask0 = flag + ~((uint32_t)0), mask1 = ~mask0;
|
||||
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
|
||||
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
|
||||
|
@ -1073,13 +1073,36 @@ static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int fl
|
|||
r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1);
|
||||
r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1);
|
||||
r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1);
|
||||
r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1);
|
||||
r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1);
|
||||
}
|
||||
|
||||
static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t *a) {
|
||||
#ifdef VERIFY
|
||||
if (flag) {
|
||||
r->magnitude = a->magnitude;
|
||||
r->normalized = a->normalized;
|
||||
}
|
||||
VERIFY_CHECK(a->normalized);
|
||||
#endif
|
||||
r->n[0] = a->n[0] | a->n[1] << 26;
|
||||
r->n[1] = a->n[1] >> 6 | a->n[2] << 20;
|
||||
r->n[2] = a->n[2] >> 12 | a->n[3] << 14;
|
||||
r->n[3] = a->n[3] >> 18 | a->n[4] << 8;
|
||||
r->n[4] = a->n[4] >> 24 | a->n[5] << 2 | a->n[6] << 28;
|
||||
r->n[5] = a->n[6] >> 4 | a->n[7] << 22;
|
||||
r->n[6] = a->n[7] >> 10 | a->n[8] << 16;
|
||||
r->n[7] = a->n[8] >> 16 | a->n[9] << 10;
|
||||
}
|
||||
|
||||
static inline void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t *a) {
|
||||
r->n[0] = a->n[0] & 0x3FFFFFFUL;
|
||||
r->n[1] = a->n[0] >> 26 | ((a->n[1] << 6) & 0x3FFFFFFUL);
|
||||
r->n[2] = a->n[1] >> 20 | ((a->n[2] << 12) & 0x3FFFFFFUL);
|
||||
r->n[3] = a->n[2] >> 14 | ((a->n[3] << 18) & 0x3FFFFFFUL);
|
||||
r->n[4] = a->n[3] >> 8 | ((a->n[4] << 24) & 0x3FFFFFFUL);
|
||||
r->n[5] = (a->n[4] >> 2) & 0x3FFFFFFUL;
|
||||
r->n[6] = a->n[4] >> 28 | ((a->n[5] << 4) & 0x3FFFFFFUL);
|
||||
r->n[7] = a->n[5] >> 22 | ((a->n[6] << 10) & 0x3FFFFFFUL);
|
||||
r->n[8] = a->n[6] >> 16 | ((a->n[7] << 16) & 0x3FFFFFFUL);
|
||||
r->n[9] = a->n[7] >> 10;
|
||||
#ifdef VERIFY
|
||||
r->magnitude = 1;
|
||||
r->normalized = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -32,4 +32,15 @@ typedef struct {
|
|||
#define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))}
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
uint64_t n[4];
|
||||
} secp256k1_fe_storage_t;
|
||||
|
||||
#define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ \
|
||||
(d0) | ((uint64_t)(d1)) << 32, \
|
||||
(d2) | ((uint64_t)(d3)) << 32, \
|
||||
(d4) | ((uint64_t)(d5)) << 32, \
|
||||
(d6) | ((uint64_t)(d7)) << 32 \
|
||||
}}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -398,18 +398,33 @@ static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int flag) {
|
||||
static inline void secp256k1_fe_storage_cmov(secp256k1_fe_storage_t *r, const secp256k1_fe_storage_t *a, int flag) {
|
||||
uint64_t mask0 = flag + ~((uint64_t)0), mask1 = ~mask0;
|
||||
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
|
||||
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
|
||||
r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1);
|
||||
r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1);
|
||||
r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1);
|
||||
}
|
||||
|
||||
static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t *a) {
|
||||
#ifdef VERIFY
|
||||
if (flag) {
|
||||
r->magnitude = a->magnitude;
|
||||
r->normalized = a->normalized;
|
||||
}
|
||||
VERIFY_CHECK(a->normalized);
|
||||
#endif
|
||||
r->n[0] = a->n[0] | a->n[1] << 52;
|
||||
r->n[1] = a->n[1] >> 12 | a->n[2] << 40;
|
||||
r->n[2] = a->n[2] >> 24 | a->n[3] << 28;
|
||||
r->n[3] = a->n[3] >> 36 | a->n[4] << 16;
|
||||
}
|
||||
|
||||
static inline void secp256k1_fe_from_storage(secp256k1_fe_t *r, const secp256k1_fe_storage_t *a) {
|
||||
r->n[0] = a->n[0] & 0xFFFFFFFFFFFFFULL;
|
||||
r->n[1] = a->n[0] >> 52 | ((a->n[1] << 12) & 0xFFFFFFFFFFFFFULL);
|
||||
r->n[2] = a->n[1] >> 40 | ((a->n[2] << 24) & 0xFFFFFFFFFFFFFULL);
|
||||
r->n[3] = a->n[2] >> 28 | ((a->n[3] << 36) & 0xFFFFFFFFFFFFFULL);
|
||||
r->n[4] = a->n[3] >> 16;
|
||||
#ifdef VERIFY
|
||||
r->magnitude = 1;
|
||||
r->normalized = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
14
src/group.h
14
src/group.h
|
@ -25,6 +25,11 @@ typedef struct {
|
|||
int infinity; /* whether this represents the point at infinity */
|
||||
} secp256k1_gej_t;
|
||||
|
||||
typedef struct {
|
||||
secp256k1_fe_storage_t x;
|
||||
secp256k1_fe_storage_t y;
|
||||
} secp256k1_ge_storage_t;
|
||||
|
||||
/** Set a group element equal to the point at infinity */
|
||||
static void secp256k1_ge_set_infinity(secp256k1_ge_t *r);
|
||||
|
||||
|
@ -99,4 +104,13 @@ static void secp256k1_gej_clear(secp256k1_gej_t *r);
|
|||
/** Clear a secp256k1_ge_t to prevent leaking sensitive information. */
|
||||
static void secp256k1_ge_clear(secp256k1_ge_t *r);
|
||||
|
||||
/** Convert a group element to the storage type. */
|
||||
static void secp256k1_ge_to_storage(secp256k1_ge_storage_t *r, const secp256k1_ge_t*);
|
||||
|
||||
/** Convert a group element back from the storage type. */
|
||||
static void secp256k1_ge_from_storage(secp256k1_ge_t *r, const secp256k1_ge_storage_t*);
|
||||
|
||||
/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */
|
||||
static void secp256k1_ge_storage_cmov(secp256k1_ge_storage_t *r, const secp256k1_ge_storage_t *a, int flag);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -392,6 +392,28 @@ static void secp256k1_gej_get_hex(char *r131, const secp256k1_gej_t *a) {
|
|||
secp256k1_ge_get_hex(r131, &t);
|
||||
}
|
||||
|
||||
static void secp256k1_ge_to_storage(secp256k1_ge_storage_t *r, const secp256k1_ge_t *a) {
|
||||
secp256k1_fe_t x, y;
|
||||
VERIFY_CHECK(!a->infinity);
|
||||
x = a->x;
|
||||
secp256k1_fe_normalize(&x);
|
||||
y = a->y;
|
||||
secp256k1_fe_normalize(&y);
|
||||
secp256k1_fe_to_storage(&r->x, &x);
|
||||
secp256k1_fe_to_storage(&r->y, &y);
|
||||
}
|
||||
|
||||
static void secp256k1_ge_from_storage(secp256k1_ge_t *r, const secp256k1_ge_storage_t *a) {
|
||||
secp256k1_fe_from_storage(&r->x, &a->x);
|
||||
secp256k1_fe_from_storage(&r->y, &a->y);
|
||||
r->infinity = 0;
|
||||
}
|
||||
|
||||
static SECP256K1_INLINE void secp256k1_ge_storage_cmov(secp256k1_ge_storage_t *r, const secp256k1_ge_storage_t *a, int flag) {
|
||||
secp256k1_fe_storage_cmov(&r->x, &a->x, flag);
|
||||
secp256k1_fe_storage_cmov(&r->y, &a->y, flag);
|
||||
}
|
||||
|
||||
#ifdef USE_ENDOMORPHISM
|
||||
static void secp256k1_gej_mul_lambda(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
|
||||
static const secp256k1_fe_t beta = SECP256K1_FE_CONST(
|
||||
|
|
55
src/tests.c
55
src/tests.c
|
@ -627,6 +627,42 @@ int check_fe_inverse(const secp256k1_fe_t *a, const secp256k1_fe_t *ai) {
|
|||
return check_fe_equal(&x, &one);
|
||||
}
|
||||
|
||||
void run_field_convert(void) {
|
||||
static const unsigned char b32[32] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||
0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
|
||||
0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x40
|
||||
};
|
||||
static const char *c64 = "0001020304050607111213141516171822232425262728293334353637383940";
|
||||
static const secp256k1_fe_storage_t fes = SECP256K1_FE_STORAGE_CONST(
|
||||
0x00010203UL, 0x04050607UL, 0x11121314UL, 0x15161718UL,
|
||||
0x22232425UL, 0x26272829UL, 0x33343536UL, 0x37383940UL
|
||||
);
|
||||
static const secp256k1_fe_t fe = SECP256K1_FE_CONST(
|
||||
0x00010203UL, 0x04050607UL, 0x11121314UL, 0x15161718UL,
|
||||
0x22232425UL, 0x26272829UL, 0x33343536UL, 0x37383940UL
|
||||
);
|
||||
secp256k1_fe_t fe2;
|
||||
unsigned char b322[32];
|
||||
char c642[64];
|
||||
secp256k1_fe_storage_t fes2;
|
||||
/* Check conversions to fe. */
|
||||
CHECK(secp256k1_fe_set_b32(&fe2, b32));
|
||||
CHECK(secp256k1_fe_equal_var(&fe, &fe2));
|
||||
CHECK(secp256k1_fe_set_hex(&fe2, c64));
|
||||
CHECK(secp256k1_fe_equal_var(&fe, &fe2));
|
||||
secp256k1_fe_from_storage(&fe2, &fes);
|
||||
CHECK(secp256k1_fe_equal_var(&fe, &fe2));
|
||||
/* Check conversion from fe. */
|
||||
secp256k1_fe_get_b32(b322, &fe);
|
||||
CHECK(memcmp(b322, b32, 32) == 0);
|
||||
secp256k1_fe_get_hex(c642, &fe);
|
||||
CHECK(memcmp(c642, c64, 64) == 0);
|
||||
secp256k1_fe_to_storage(&fes2, &fe);
|
||||
CHECK(memcmp(&fes2, &fes, sizeof(fes)) == 0);
|
||||
}
|
||||
|
||||
void run_field_misc(void) {
|
||||
const unsigned char f32_5[32] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
|
@ -649,12 +685,18 @@ void run_field_misc(void) {
|
|||
z = x;
|
||||
secp256k1_fe_add(&z,&y);
|
||||
secp256k1_fe_normalize(&z);
|
||||
/* Test the conditional move. */
|
||||
secp256k1_fe_cmov(&z, &x, 0);
|
||||
CHECK(secp256k1_fe_equal_var(&x, &z) == 0);
|
||||
CHECK(secp256k1_fe_cmp_var(&x, &z) != 0);
|
||||
secp256k1_fe_cmov(&y, &x, 1);
|
||||
CHECK(secp256k1_fe_equal_var(&x, &y));
|
||||
/* Test storage conversion and conditional moves. */
|
||||
secp256k1_fe_storage_t xs, ys, zs;
|
||||
secp256k1_fe_to_storage(&xs, &x);
|
||||
secp256k1_fe_to_storage(&ys, &y);
|
||||
secp256k1_fe_to_storage(&zs, &z);
|
||||
secp256k1_fe_storage_cmov(&zs, &xs, 0);
|
||||
CHECK(memcmp(&xs, &zs, sizeof(xs)) != 0);
|
||||
secp256k1_fe_storage_cmov(&ys, &xs, 1);
|
||||
CHECK(memcmp(&xs, &ys, sizeof(xs)) == 0);
|
||||
secp256k1_fe_from_storage(&x, &xs);
|
||||
secp256k1_fe_from_storage(&y, &ys);
|
||||
secp256k1_fe_from_storage(&z, &zs);
|
||||
/* Test that mul_int, mul, and add agree. */
|
||||
secp256k1_fe_add(&y, &x);
|
||||
secp256k1_fe_add(&y, &x);
|
||||
|
@ -1668,6 +1710,7 @@ int main(int argc, char **argv) {
|
|||
run_field_inv_var();
|
||||
run_field_inv_all_var();
|
||||
run_field_misc();
|
||||
run_field_convert();
|
||||
run_sqr();
|
||||
run_sqrt();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue