Skip to content

Commit

Permalink
Merge bitcoin-core/secp256k1#1303: ct: Use more volatile
Browse files Browse the repository at this point in the history
17fa217 ct: Be cautious and use volatile trick in more "conditional" paths (Tim Ruffing)
5fb336f ct: Use volatile trick in scalar_cond_negate (Tim Ruffing)

Pull request description:

ACKs for top commit:
  sipa:
    ACK 17fa217
  jonasnick:
    ACK 17fa217

Tree-SHA512: 4a0fbee7b1cce4f4647bff697c0e645d93aa8fb49777feef5eb1e1eadce2116bafdcc6175c066ee4fe4bf1340047311e2d7d2c48bb288867a837ecd6c8687121
  • Loading branch information
jonasnick committed May 11, 2023
2 parents 9eb6934 + 17fa217 commit ab5a917
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 34 deletions.
2 changes: 1 addition & 1 deletion src/ecmult_const_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ static void secp256k1_ecmult_odd_multiples_table_globalz_windowa(secp256k1_ge *p
#define ECMULT_CONST_TABLE_GET_GE(r,pre,n,w) do { \
int m = 0; \
/* Extract the sign-bit for a constant time absolute-value. */ \
int mask = (n) >> (sizeof(n) * CHAR_BIT - 1); \
int volatile mask = (n) >> (sizeof(n) * CHAR_BIT - 1); \
int abs_n = ((n) + mask) ^ mask; \
int idx_n = abs_n >> 1; \
secp256k1_fe neg_y; \
Expand Down
33 changes: 18 additions & 15 deletions src/modinv32_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static void secp256k1_modinv32_normalize_30(secp256k1_modinv32_signed30 *r, int3
const int32_t M30 = (int32_t)(UINT32_MAX >> 2);
int32_t r0 = r->v[0], r1 = r->v[1], r2 = r->v[2], r3 = r->v[3], r4 = r->v[4],
r5 = r->v[5], r6 = r->v[6], r7 = r->v[7], r8 = r->v[8];
int32_t cond_add, cond_negate;
volatile int32_t cond_add, cond_negate;

#ifdef VERIFY
/* Verify that all limbs are in range (-2^30,2^30). */
Expand Down Expand Up @@ -186,7 +186,8 @@ static int32_t secp256k1_modinv32_divsteps_30(int32_t zeta, uint32_t f0, uint32_
* being inside [-2^31,2^31) means that casting to signed works correctly.
*/
uint32_t u = 1, v = 0, q = 0, r = 1;
uint32_t c1, c2, f = f0, g = g0, x, y, z;
volatile uint32_t c1, c2;
uint32_t mask1, mask2, f = f0, g = g0, x, y, z;
int i;

for (i = 0; i < 30; ++i) {
Expand All @@ -195,23 +196,25 @@ static int32_t secp256k1_modinv32_divsteps_30(int32_t zeta, uint32_t f0, uint32_
VERIFY_CHECK((q * f0 + r * g0) == g << i);
/* Compute conditional masks for (zeta < 0) and for (g & 1). */
c1 = zeta >> 31;
c2 = -(g & 1);
mask1 = c1;
c2 = g & 1;
mask2 = -c2;
/* Compute x,y,z, conditionally negated versions of f,u,v. */
x = (f ^ c1) - c1;
y = (u ^ c1) - c1;
z = (v ^ c1) - c1;
x = (f ^ mask1) - mask1;
y = (u ^ mask1) - mask1;
z = (v ^ mask1) - mask1;
/* Conditionally add x,y,z to g,q,r. */
g += x & c2;
q += y & c2;
r += z & c2;
/* In what follows, c1 is a condition mask for (zeta < 0) and (g & 1). */
c1 &= c2;
g += x & mask2;
q += y & mask2;
r += z & mask2;
/* In what follows, mask1 is a condition mask for (zeta < 0) and (g & 1). */
mask1 &= mask2;
/* Conditionally change zeta into -zeta-2 or zeta-1. */
zeta = (zeta ^ c1) - 1;
zeta = (zeta ^ mask1) - 1;
/* Conditionally add g,q,r to f,u,v. */
f += g & c1;
u += q & c1;
v += r & c1;
f += g & mask1;
u += q & mask1;
v += r & mask1;
/* Shifts */
g >>= 1;
u <<= 1;
Expand Down
31 changes: 17 additions & 14 deletions src/modinv64_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ static int secp256k1_modinv64_det_check_pow2(const secp256k1_modinv64_trans2x2 *
static void secp256k1_modinv64_normalize_62(secp256k1_modinv64_signed62 *r, int64_t sign, const secp256k1_modinv64_modinfo *modinfo) {
const int64_t M62 = (int64_t)(UINT64_MAX >> 2);
int64_t r0 = r->v[0], r1 = r->v[1], r2 = r->v[2], r3 = r->v[3], r4 = r->v[4];
int64_t cond_add, cond_negate;
volatile int64_t cond_add, cond_negate;

#ifdef VERIFY
/* Verify that all limbs are in range (-2^62,2^62). */
Expand Down Expand Up @@ -175,7 +175,8 @@ static int64_t secp256k1_modinv64_divsteps_59(int64_t zeta, uint64_t f0, uint64_
* being inside [-2^63,2^63) means that casting to signed works correctly.
*/
uint64_t u = 8, v = 0, q = 0, r = 8;
uint64_t c1, c2, f = f0, g = g0, x, y, z;
volatile uint64_t c1, c2;
uint64_t mask1, mask2, f = f0, g = g0, x, y, z;
int i;

for (i = 3; i < 62; ++i) {
Expand All @@ -184,23 +185,25 @@ static int64_t secp256k1_modinv64_divsteps_59(int64_t zeta, uint64_t f0, uint64_
VERIFY_CHECK((q * f0 + r * g0) == g << i);
/* Compute conditional masks for (zeta < 0) and for (g & 1). */
c1 = zeta >> 63;
c2 = -(g & 1);
mask1 = c1;
c2 = g & 1;
mask2 = -c2;
/* Compute x,y,z, conditionally negated versions of f,u,v. */
x = (f ^ c1) - c1;
y = (u ^ c1) - c1;
z = (v ^ c1) - c1;
x = (f ^ mask1) - mask1;
y = (u ^ mask1) - mask1;
z = (v ^ mask1) - mask1;
/* Conditionally add x,y,z to g,q,r. */
g += x & c2;
q += y & c2;
r += z & c2;
g += x & mask2;
q += y & mask2;
r += z & mask2;
/* In what follows, c1 is a condition mask for (zeta < 0) and (g & 1). */
c1 &= c2;
mask1 &= mask2;
/* Conditionally change zeta into -zeta-2 or zeta-1. */
zeta = (zeta ^ c1) - 1;
zeta = (zeta ^ mask1) - 1;
/* Conditionally add g,q,r to f,u,v. */
f += g & c1;
u += q & c1;
v += r & c1;
f += g & mask1;
u += q & mask1;
v += r & mask1;
/* Shifts */
g >>= 1;
u <<= 1;
Expand Down
6 changes: 4 additions & 2 deletions src/scalar_4x64_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,8 +111,9 @@ static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a,

static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) {
secp256k1_uint128 t;
volatile int vflag = flag;
VERIFY_CHECK(bit < 256);
bit += ((uint32_t) flag - 1) & 0x100; /* forcing (bit >> 6) > 3 makes this a noop */
bit += ((uint32_t) vflag - 1) & 0x100; /* forcing (bit >> 6) > 3 makes this a noop */
secp256k1_u128_from_u64(&t, r->d[0]);
secp256k1_u128_accum_u64(&t, ((uint64_t)((bit >> 6) == 0)) << (bit & 0x3F));
r->d[0] = secp256k1_u128_to_u64(&t); secp256k1_u128_rshift(&t, 64);
Expand Down Expand Up @@ -189,7 +190,8 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar *a) {
static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) {
/* If we are flag = 0, mask = 00...00 and this is a no-op;
* if we are flag = 1, mask = 11...11 and this is identical to secp256k1_scalar_negate */
uint64_t mask = !flag - 1;
volatile int vflag = flag;
uint64_t mask = -vflag;
uint64_t nonzero = (secp256k1_scalar_is_zero(r) != 0) - 1;
secp256k1_uint128 t;
secp256k1_u128_from_u64(&t, r->d[0] ^ mask);
Expand Down
6 changes: 4 additions & 2 deletions src/scalar_8x32_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,8 +142,9 @@ static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a,

static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) {
uint64_t t;
volatile int vflag = flag;
VERIFY_CHECK(bit < 256);
bit += ((uint32_t) flag - 1) & 0x100; /* forcing (bit >> 5) > 7 makes this a noop */
bit += ((uint32_t) vflag - 1) & 0x100; /* forcing (bit >> 5) > 7 makes this a noop */
t = (uint64_t)r->d[0] + (((uint32_t)((bit >> 5) == 0)) << (bit & 0x1F));
r->d[0] = t & 0xFFFFFFFFULL; t >>= 32;
t += (uint64_t)r->d[1] + (((uint32_t)((bit >> 5) == 1)) << (bit & 0x1F));
Expand Down Expand Up @@ -242,7 +243,8 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar *a) {
static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) {
/* If we are flag = 0, mask = 00...00 and this is a no-op;
* if we are flag = 1, mask = 11...11 and this is identical to secp256k1_scalar_negate */
uint32_t mask = !flag - 1;
volatile int vflag = flag;
uint32_t mask = -vflag;
uint32_t nonzero = 0xFFFFFFFFUL * (secp256k1_scalar_is_zero(r) == 0);
uint64_t t = (uint64_t)(r->d[0] ^ mask) + ((SECP256K1_N_0 + 1) & mask);
r->d[0] = t & nonzero; t >>= 32;
Expand Down

0 comments on commit ab5a917

Please sign in to comment.