Skip to content

Commit 42b6b42

Browse files
committed
Alternative cmov implementation
1 parent 84973d3 commit 42b6b42

File tree

2 files changed

+34
-39
lines changed

2 files changed

+34
-39
lines changed

src/field_10x26_impl.h

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,21 @@
1111
#include "num.h"
1212
#include "field.h"
1313

14+
static SECP256K1_INLINE void secp256k1_fe_cmov_limbs(uint32_t *r, const uint32_t *a, int len, int flag) {
15+
int i;
16+
uint32_t diff, rest, r_i;
17+
static const uint32_t half = 0x55555555UL;
18+
VERIFY_CHECK(flag == 0 || flag == 1);
19+
rest = half << flag;
20+
for (i=0; i<len; i++) {
21+
r_i = r[i];
22+
diff = r_i ^ a[i];
23+
r_i ^= (diff & half);
24+
r_i ^= (diff & rest);
25+
r[i] = r_i;
26+
}
27+
}
28+
1429
#ifdef VERIFY
1530
static void secp256k1_fe_verify(const secp256k1_fe *a) {
1631
const uint32_t *d = a->n;
@@ -1092,19 +1107,7 @@ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) {
10921107
}
10931108

10941109
static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) {
1095-
uint32_t mask0, mask1;
1096-
mask0 = flag + ~((uint32_t)0);
1097-
mask1 = ~mask0;
1098-
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
1099-
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
1100-
r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1);
1101-
r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1);
1102-
r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1);
1103-
r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1);
1104-
r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1);
1105-
r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1);
1106-
r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1);
1107-
r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1);
1110+
secp256k1_fe_cmov_limbs(r->n, a->n, 10, flag);
11081111
#ifdef VERIFY
11091112
if (a->magnitude > r->magnitude) {
11101113
r->magnitude = a->magnitude;
@@ -1114,17 +1117,7 @@ static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_
11141117
}
11151118

11161119
static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) {
1117-
uint32_t mask0, mask1;
1118-
mask0 = flag + ~((uint32_t)0);
1119-
mask1 = ~mask0;
1120-
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
1121-
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
1122-
r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1);
1123-
r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1);
1124-
r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1);
1125-
r->n[5] = (r->n[5] & mask0) | (a->n[5] & mask1);
1126-
r->n[6] = (r->n[6] & mask0) | (a->n[6] & mask1);
1127-
r->n[7] = (r->n[7] & mask0) | (a->n[7] & mask1);
1120+
secp256k1_fe_cmov_limbs(r->n, a->n, 8, flag);
11281121
}
11291122

11301123
static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) {

src/field_5x52_impl.h

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,21 @@
2929
* output.
3030
*/
3131

32+
static SECP256K1_INLINE void secp256k1_fe_cmov_limbs(uint64_t *r, const uint64_t *a, int len, int flag) {
33+
int i;
34+
uint64_t diff, rest, r_i;
35+
static const uint64_t half = 0x5555555555555555ULL;
36+
VERIFY_CHECK(flag == 0 || flag == 1);
37+
rest = half << flag;
38+
for (i=0; i<len; i++) {
39+
r_i = r[i];
40+
diff = r_i ^ a[i];
41+
r_i ^= (diff & half);
42+
r_i ^= (diff & rest);
43+
r[i] = r_i;
44+
}
45+
}
46+
3247
#ifdef VERIFY
3348
static void secp256k1_fe_verify(const secp256k1_fe *a) {
3449
const uint64_t *d = a->n;
@@ -445,14 +460,7 @@ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) {
445460
}
446461

447462
static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) {
448-
uint64_t mask0, mask1;
449-
mask0 = flag + ~((uint64_t)0);
450-
mask1 = ~mask0;
451-
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
452-
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
453-
r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1);
454-
r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1);
455-
r->n[4] = (r->n[4] & mask0) | (a->n[4] & mask1);
463+
secp256k1_fe_cmov_limbs(r->n, a->n, 5, flag);
456464
#ifdef VERIFY
457465
if (a->magnitude > r->magnitude) {
458466
r->magnitude = a->magnitude;
@@ -462,13 +470,7 @@ static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_
462470
}
463471

464472
static SECP256K1_INLINE void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag) {
465-
uint64_t mask0, mask1;
466-
mask0 = flag + ~((uint64_t)0);
467-
mask1 = ~mask0;
468-
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
469-
r->n[1] = (r->n[1] & mask0) | (a->n[1] & mask1);
470-
r->n[2] = (r->n[2] & mask0) | (a->n[2] & mask1);
471-
r->n[3] = (r->n[3] & mask0) | (a->n[3] & mask1);
473+
secp256k1_fe_cmov_limbs(r->n, a->n, 4, flag);
472474
}
473475

474476
static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a) {

0 commit comments

Comments
 (0)