Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/field.h
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,8 @@ static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe
*/
static void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a);

/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/
/** If flag is 1, set *r equal to *a; if flag is 0, leave it. Constant-time.
* Both *r and *a must be initialized. Flag must be 0 or 1. */
static void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag);

/** Conditionally move a field element in constant time.
Expand Down
2 changes: 2 additions & 0 deletions src/field_10x26_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -1014,6 +1014,7 @@ SECP256K1_INLINE static void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp25
SECP256K1_INLINE static void secp256k1_fe_impl_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) {
uint32_t mask0, mask1;
volatile int vflag = flag;
VERIFY_CHECK(flag == 0 || flag == 1);
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
mask0 = vflag + ~((uint32_t)0);
mask1 = ~mask0;
Expand Down Expand Up @@ -1097,6 +1098,7 @@ static SECP256K1_INLINE void secp256k1_fe_impl_half(secp256k1_fe *r) {
static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) {
uint32_t mask0, mask1;
volatile int vflag = flag;
VERIFY_CHECK(flag == 0 || flag == 1);
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
mask0 = vflag + ~((uint32_t)0);
mask1 = ~mask0;
Expand Down
2 changes: 2 additions & 0 deletions src/field_5x52_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ SECP256K1_INLINE static void secp256k1_fe_impl_sqr(secp256k1_fe *r, const secp25
SECP256K1_INLINE static void secp256k1_fe_impl_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) {
uint64_t mask0, mask1;
volatile int vflag = flag;
VERIFY_CHECK(flag == 0 || flag == 1);
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
mask0 = vflag + ~((uint64_t)0);
mask1 = ~mask0;
Expand Down Expand Up @@ -416,6 +417,7 @@ static SECP256K1_INLINE void secp256k1_fe_impl_half(secp256k1_fe *r) {
static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) {
uint64_t mask0, mask1;
volatile int vflag = flag;
VERIFY_CHECK(flag == 0 || flag == 1);
SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
mask0 = vflag + ~((uint64_t)0);
mask1 = ~mask0;
Expand Down
6 changes: 4 additions & 2 deletions src/group.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,10 +169,12 @@ static void secp256k1_ge_to_storage(secp256k1_ge_storage *r, const secp256k1_ge
/** Convert a group element back from the storage type. */
static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storage *a);

/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/
/** If flag is 1, set *r equal to *a; if flag is 0, leave it. Constant-time.
* Both *r and *a must be initialized. Flag must be 0 or 1. */
static void secp256k1_gej_cmov(secp256k1_gej *r, const secp256k1_gej *a, int flag);

/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/
/** If flag is 1, set *r equal to *a; if flag is 0, leave it. Constant-time.
* Both *r and *a must be initialized. Flag must be 0 or 1. */
static void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag);

/** Rescale a jacobian point by b which must be non-zero. Constant-time. */
Expand Down
2 changes: 2 additions & 0 deletions src/group_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,7 @@ static void secp256k1_ge_from_storage(secp256k1_ge *r, const secp256k1_ge_storag
static SECP256K1_INLINE void secp256k1_gej_cmov(secp256k1_gej *r, const secp256k1_gej *a, int flag) {
SECP256K1_GEJ_VERIFY(r);
SECP256K1_GEJ_VERIFY(a);
VERIFY_CHECK(flag == 0 || flag == 1);

secp256k1_fe_cmov(&r->x, &a->x, flag);
secp256k1_fe_cmov(&r->y, &a->y, flag);
Expand All @@ -908,6 +909,7 @@ static SECP256K1_INLINE void secp256k1_gej_cmov(secp256k1_gej *r, const secp256k
}

static SECP256K1_INLINE void secp256k1_ge_storage_cmov(secp256k1_ge_storage *r, const secp256k1_ge_storage *a, int flag) {
VERIFY_CHECK(flag == 0 || flag == 1);
secp256k1_fe_storage_cmov(&r->x, &a->x, flag);
secp256k1_fe_storage_cmov(&r->y, &a->y, flag);
}
Expand Down
6 changes: 3 additions & 3 deletions src/scalar.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar*
/** Add two scalars together (modulo the group order). Returns whether it overflowed. */
static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b);

/** Conditionally add a power of two to a scalar. The result is not allowed to overflow. */
/** Conditionally add a power of two to a scalar. The result is not allowed to overflow. Flag must be 0 or 1. */
static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag);

/** Multiply two scalars (modulo the group order). */
Expand Down Expand Up @@ -78,7 +78,7 @@ static int secp256k1_scalar_is_even(const secp256k1_scalar *a);
/** Check whether a scalar is higher than the group order divided by 2. */
static int secp256k1_scalar_is_high(const secp256k1_scalar *a);

/** Conditionally negate a number, in constant time.
/** Conditionally negate a number, in constant time. Flag must be 0 or 1.
* Returns -1 if the number was negated, 1 otherwise */
static int secp256k1_scalar_cond_negate(secp256k1_scalar *a, int flag);

Expand All @@ -95,7 +95,7 @@ static void secp256k1_scalar_split_lambda(secp256k1_scalar * SECP256K1_RESTRICT
/** Multiply a and b (without taking the modulus!), divide by 2**shift, and round to the nearest integer. Shift must be at least 256. */
static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift);

/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized.*/
/** If flag is 1, set *r equal to *a; if flag is 0, leave it. Constant-time. Both *r and *a must be initialized. Flag must be 0 or 1. */
static void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag);

/** Check invariants on a scalar (no-op unless VERIFY is enabled). */
Expand Down
3 changes: 3 additions & 0 deletions src/scalar_4x64_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ 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(flag == 0 || flag == 1);
SECP256K1_SCALAR_VERIFY(r);
VERIFY_CHECK(bit < 256);

Expand Down Expand Up @@ -259,6 +260,7 @@ static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) {
uint64_t mask = -vflag;
uint64_t nonzero = (secp256k1_scalar_is_zero(r) != 0) - 1;
secp256k1_uint128 t;
VERIFY_CHECK(flag == 0 || flag == 1);
SECP256K1_SCALAR_VERIFY(r);

secp256k1_u128_from_u64(&t, r->d[0] ^ mask);
Expand Down Expand Up @@ -911,6 +913,7 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r,
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) {
uint64_t mask0, mask1;
volatile int vflag = flag;
VERIFY_CHECK(flag == 0 || flag == 1);
SECP256K1_SCALAR_VERIFY(a);
SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d));

Expand Down
3 changes: 3 additions & 0 deletions src/scalar_8x32_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ 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(flag == 0 || flag == 1);
SECP256K1_SCALAR_VERIFY(r);
VERIFY_CHECK(bit < 256);

Expand Down Expand Up @@ -314,6 +315,7 @@ static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int 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);
VERIFY_CHECK(flag == 0 || flag == 1);
SECP256K1_SCALAR_VERIFY(r);

r->d[0] = t & nonzero; t >>= 32;
Expand Down Expand Up @@ -709,6 +711,7 @@ SECP256K1_INLINE static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r,
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) {
uint32_t mask0, mask1;
volatile int vflag = flag;
VERIFY_CHECK(flag == 0 || flag == 1);
SECP256K1_SCALAR_VERIFY(a);
SECP256K1_CHECKMEM_CHECK_VERIFY(r->d, sizeof(r->d));

Expand Down
3 changes: 3 additions & 0 deletions src/scalar_low_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ 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_SCALAR_VERIFY(r);
VERIFY_CHECK(flag == 0 || flag == 1);

if (flag && bit < 32)
*r += ((uint32_t)1 << bit);
Expand Down Expand Up @@ -121,6 +122,7 @@ static int secp256k1_scalar_is_high(const secp256k1_scalar *a) {

static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) {
SECP256K1_SCALAR_VERIFY(r);
VERIFY_CHECK(flag == 0 || flag == 1);

if (flag) secp256k1_scalar_negate(r, r);

Expand Down Expand Up @@ -157,6 +159,7 @@ SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const
static SECP256K1_INLINE void secp256k1_scalar_cmov(secp256k1_scalar *r, const secp256k1_scalar *a, int flag) {
uint32_t mask0, mask1;
volatile int vflag = flag;
VERIFY_CHECK(flag == 0 || flag == 1);
SECP256K1_SCALAR_VERIFY(a);
SECP256K1_CHECKMEM_CHECK_VERIFY(r, sizeof(*r));

Expand Down
5 changes: 4 additions & 1 deletion src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ static SECP256K1_INLINE void secp256k1_memczero(void *s, size_t len, int flag) {
take only be 0 or 1, which leads to variable time code. */
volatile int vflag = flag;
unsigned char mask = -(unsigned char) vflag;
VERIFY_CHECK(flag == 0 || flag == 1);
while (len) {
*p &= ~mask;
p++;
Expand Down Expand Up @@ -294,14 +295,16 @@ static SECP256K1_INLINE int secp256k1_is_zero_array(const unsigned char *s, size
return ret;
}

/** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. Both *r and *a must be initialized and non-negative.*/
/** If flag is 1, set *r equal to *a; if flag is 0, leave it. Constant-time.
* Both *r and *a must be initialized and non-negative. Flag must be 0 or 1. */
static SECP256K1_INLINE void secp256k1_int_cmov(int *r, const int *a, int flag) {
unsigned int mask0, mask1, r_masked, a_masked;
/* Access flag with a volatile-qualified lvalue.
This prevents clang from figuring out (after inlining) that flag can
take only be 0 or 1, which leads to variable time code. */
volatile int vflag = flag;

VERIFY_CHECK(flag == 0 || flag == 1);
/* Casting a negative int to unsigned and back to int is implementation defined behavior */
VERIFY_CHECK(*r >= 0 && *a >= 0);

Expand Down