mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 10:43:19 -03:00
weak normalization
This commit is contained in:
parent
cf0c48bea5
commit
0295f0a33d
7 changed files with 65 additions and 17 deletions
|
@ -73,7 +73,7 @@ static void secp256k1_ecmult_gen_start(void) {
|
|||
secp256k1_gej_double_var(&numsbase, &numsbase);
|
||||
if (j == 62) {
|
||||
/* In the last iteration, numsbase is (1 - 2^j) * nums instead. */
|
||||
secp256k1_gej_neg_var(&numsbase, &numsbase);
|
||||
secp256k1_gej_neg(&numsbase, &numsbase);
|
||||
secp256k1_gej_add_var(&numsbase, &numsbase, &nums_gej);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,8 +70,8 @@ static void secp256k1_ecmult_table_precomp_ge_var(secp256k1_ge_t *pre, const sec
|
|||
(neg)((r), &(pre)[(-(n)-1)/2]); \
|
||||
} while(0)
|
||||
|
||||
#define ECMULT_TABLE_GET_GEJ(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_gej_neg_var)
|
||||
#define ECMULT_TABLE_GET_GE(r,pre,n,w) ECMULT_TABLE_GET((r),(pre),(n),(w),secp256k1_ge_neg_var)
|
||||
#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: */
|
||||
|
|
|
@ -48,6 +48,9 @@ static void secp256k1_fe_stop(void);
|
|||
/** Normalize a field element. */
|
||||
static void secp256k1_fe_normalize(secp256k1_fe_t *r);
|
||||
|
||||
/** Weakly normalize a field element: reduce it magnitude to 1, but don't fully normalize. */
|
||||
static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r);
|
||||
|
||||
/** Normalize a field element, without constant-time guarantee. */
|
||||
static void secp256k1_fe_normalize_var(secp256k1_fe_t *r);
|
||||
|
||||
|
|
|
@ -103,6 +103,34 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) {
|
||||
uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
|
||||
t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
|
||||
|
||||
/* Reduce t9 at the start so there will be at most a single carry from the first pass */
|
||||
uint32_t x = t9 >> 22; t9 &= 0x03FFFFFUL;
|
||||
|
||||
/* The first pass ensures the magnitude is 1, ... */
|
||||
t0 += x * 0x3D1UL; t1 += (x << 6);
|
||||
t1 += (t0 >> 26); t0 &= 0x3FFFFFFUL;
|
||||
t2 += (t1 >> 26); t1 &= 0x3FFFFFFUL;
|
||||
t3 += (t2 >> 26); t2 &= 0x3FFFFFFUL;
|
||||
t4 += (t3 >> 26); t3 &= 0x3FFFFFFUL;
|
||||
t5 += (t4 >> 26); t4 &= 0x3FFFFFFUL;
|
||||
t6 += (t5 >> 26); t5 &= 0x3FFFFFFUL;
|
||||
t7 += (t6 >> 26); t6 &= 0x3FFFFFFUL;
|
||||
t8 += (t7 >> 26); t7 &= 0x3FFFFFFUL;
|
||||
t9 += (t8 >> 26); t8 &= 0x3FFFFFFUL;
|
||||
|
||||
r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
|
||||
r->n[5] = t5; r->n[6] = t6; r->n[7] = t7; r->n[8] = t8; r->n[9] = t9;
|
||||
|
||||
#ifdef VERIFY
|
||||
r->magnitude = 1;
|
||||
secp256k1_fe_verify(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) {
|
||||
uint32_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4],
|
||||
t5 = r->n[5], t6 = r->n[6], t7 = r->n[7], t8 = r->n[8], t9 = r->n[9];
|
||||
|
|
|
@ -100,6 +100,30 @@ static void secp256k1_fe_normalize(secp256k1_fe_t *r) {
|
|||
#endif
|
||||
}
|
||||
|
||||
static void secp256k1_fe_normalize_weak(secp256k1_fe_t *r) {
|
||||
uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
|
||||
|
||||
/* Reduce t4 at the start so there will be at most a single carry from the first pass */
|
||||
uint64_t x = t4 >> 48; t4 &= 0x0FFFFFFFFFFFFULL;
|
||||
|
||||
/* The first pass ensures the magnitude is 1, ... */
|
||||
t0 += x * 0x1000003D1ULL;
|
||||
t1 += (t0 >> 52); t0 &= 0xFFFFFFFFFFFFFULL;
|
||||
t2 += (t1 >> 52); t1 &= 0xFFFFFFFFFFFFFULL;
|
||||
t3 += (t2 >> 52); t2 &= 0xFFFFFFFFFFFFFULL;
|
||||
t4 += (t3 >> 52); t3 &= 0xFFFFFFFFFFFFFULL;
|
||||
|
||||
/* ... except for a possible carry at bit 48 of t4 (i.e. bit 256 of the field element) */
|
||||
VERIFY_CHECK(t4 >> 49 == 0);
|
||||
|
||||
r->n[0] = t0; r->n[1] = t1; r->n[2] = t2; r->n[3] = t3; r->n[4] = t4;
|
||||
|
||||
#ifdef VERIFY
|
||||
r->magnitude = 1;
|
||||
secp256k1_fe_verify(r);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void secp256k1_fe_normalize_var(secp256k1_fe_t *r) {
|
||||
uint64_t t0 = r->n[0], t1 = r->n[1], t2 = r->n[2], t3 = r->n[3], t4 = r->n[4];
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a);
|
|||
static int secp256k1_ge_is_valid_var(const secp256k1_ge_t *a);
|
||||
|
||||
static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a);
|
||||
static void secp256k1_ge_neg_var(secp256k1_ge_t *r, const secp256k1_ge_t *a);
|
||||
|
||||
/** Get a hex representation of a point. *rlen will be overwritten with the real length. */
|
||||
static void secp256k1_ge_get_hex(char *r, int *rlen, const secp256k1_ge_t *a);
|
||||
|
@ -85,7 +84,7 @@ static void secp256k1_gej_set_ge(secp256k1_gej_t *r, const secp256k1_ge_t *a);
|
|||
static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t *a);
|
||||
|
||||
/** Set r equal to the inverse of a (i.e., mirrored around the X axis) */
|
||||
static void secp256k1_gej_neg_var(secp256k1_gej_t *r, const secp256k1_gej_t *a);
|
||||
static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a);
|
||||
|
||||
/** Check whether a group element is the point at infinity. */
|
||||
static int secp256k1_gej_is_infinity(const secp256k1_gej_t *a);
|
||||
|
|
|
@ -29,13 +29,7 @@ static int secp256k1_ge_is_infinity(const secp256k1_ge_t *a) {
|
|||
|
||||
static void secp256k1_ge_neg(secp256k1_ge_t *r, const secp256k1_ge_t *a) {
|
||||
*r = *a;
|
||||
secp256k1_fe_normalize(&r->y);
|
||||
secp256k1_fe_negate(&r->y, &r->y, 1);
|
||||
}
|
||||
|
||||
static void secp256k1_ge_neg_var(secp256k1_ge_t *r, const secp256k1_ge_t *a) {
|
||||
*r = *a;
|
||||
secp256k1_fe_normalize_var(&r->y);
|
||||
secp256k1_fe_normalize_weak(&r->y);
|
||||
secp256k1_fe_negate(&r->y, &r->y, 1);
|
||||
}
|
||||
|
||||
|
@ -172,12 +166,12 @@ static int secp256k1_gej_eq_x_var(const secp256k1_fe_t *x, const secp256k1_gej_t
|
|||
return secp256k1_fe_equal(&r, &r2);
|
||||
}
|
||||
|
||||
static void secp256k1_gej_neg_var(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
|
||||
static void secp256k1_gej_neg(secp256k1_gej_t *r, const secp256k1_gej_t *a) {
|
||||
r->infinity = a->infinity;
|
||||
r->x = a->x;
|
||||
r->y = a->y;
|
||||
r->z = a->z;
|
||||
secp256k1_fe_normalize_var(&r->y);
|
||||
secp256k1_fe_normalize_weak(&r->y);
|
||||
secp256k1_fe_negate(&r->y, &r->y, 1);
|
||||
}
|
||||
|
||||
|
@ -359,9 +353,9 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c
|
|||
*/
|
||||
|
||||
secp256k1_fe_t zz; secp256k1_fe_sqr(&zz, &a->z); /* z = Z1^2 */
|
||||
secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize(&u1); /* u1 = U1 = X1*Z2^2 (1) */
|
||||
secp256k1_fe_t u1 = a->x; secp256k1_fe_normalize_weak(&u1); /* u1 = U1 = X1*Z2^2 (1) */
|
||||
secp256k1_fe_t u2; secp256k1_fe_mul(&u2, &b->x, &zz); /* u2 = U2 = X2*Z1^2 (1) */
|
||||
secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize(&s1); /* s1 = S1 = Y1*Z2^3 (1) */
|
||||
secp256k1_fe_t s1 = a->y; secp256k1_fe_normalize_weak(&s1); /* s1 = S1 = Y1*Z2^3 (1) */
|
||||
secp256k1_fe_t s2; secp256k1_fe_mul(&s2, &b->y, &zz); /* s2 = Y2*Z2^2 (1) */
|
||||
secp256k1_fe_mul(&s2, &s2, &a->z); /* s2 = S2 = Y2*Z1^3 (1) */
|
||||
secp256k1_fe_t z = a->z; /* z = Z = Z1*Z2 (8) */
|
||||
|
@ -388,7 +382,7 @@ static void secp256k1_gej_add_ge(secp256k1_gej_t *r, const secp256k1_gej_t *a, c
|
|||
secp256k1_fe_mul(&t, &t, &rr); /* t = R*(2*R^2-3*Q) (1) */
|
||||
secp256k1_fe_add(&t, &n); /* t = R*(2*R^2-3*Q)+M^4 (2) */
|
||||
secp256k1_fe_negate(&r->y, &t, 2); /* r->y = R*(3*Q-2*R^2)-M^4 (3) */
|
||||
secp256k1_fe_normalize(&r->y);
|
||||
secp256k1_fe_normalize_weak(&r->y);
|
||||
secp256k1_fe_mul_int(&r->x, 4 * (1 - a->infinity)); /* r->x = X3 = 4*(R^2-Q) */
|
||||
secp256k1_fe_mul_int(&r->y, 4 * (1 - a->infinity)); /* r->y = Y3 = 4*R*(3*Q-2*R^2)-4*M^4 (4) */
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue