mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-10 20:03:34 -03:00
Field storage type
This commit is contained in:
parent
7137be8110
commit
ff889f7d90
6 changed files with 134 additions and 0 deletions
|
@ -110,7 +110,14 @@ 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
|
||||
|
|
|
@ -1083,4 +1083,47 @@ static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int fl
|
|||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t *a) {
|
||||
#ifdef VERIFY
|
||||
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
|
||||
}
|
||||
|
||||
#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
|
||||
|
|
|
@ -413,4 +413,34 @@ static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_t *a, int fl
|
|||
#endif
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
static void secp256k1_fe_to_storage(secp256k1_fe_storage_t *r, const secp256k1_fe_t *a) {
|
||||
#ifdef VERIFY
|
||||
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
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
37
src/tests.c
37
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,
|
||||
|
@ -1668,6 +1704,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…
Reference in a new issue