aboutsummaryrefslogtreecommitdiff
path: root/src/field_10x26_impl.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/field_10x26_impl.h')
-rw-r--r--src/field_10x26_impl.h45
1 files changed, 42 insertions, 3 deletions
diff --git a/src/field_10x26_impl.h b/src/field_10x26_impl.h
index c0f1be0b2d..c4403fba22 100644
--- a/src/field_10x26_impl.h
+++ b/src/field_10x26_impl.h
@@ -152,7 +152,21 @@ SECP256K1_INLINE static int secp256k1_fe_equal(const secp256k1_fe_t *a, const se
| (t[5]^u[5]) | (t[6]^u[6]) | (t[7]^u[7]) | (t[8]^u[8]) | (t[9]^u[9])) == 0;
}
-static void secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
+static int secp256k1_fe_cmp_var(const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
+#ifdef VERIFY
+ VERIFY_CHECK(a->normalized);
+ VERIFY_CHECK(b->normalized);
+ secp256k1_fe_verify(a);
+ secp256k1_fe_verify(b);
+#endif
+ for (int i = 9; i >= 0; i--) {
+ if (a->n[i] > b->n[i]) return 1;
+ if (a->n[i] < b->n[i]) return -1;
+ }
+ return 0;
+}
+
+static int secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
r->n[0] = r->n[1] = r->n[2] = r->n[3] = r->n[4] = 0;
r->n[5] = r->n[6] = r->n[7] = r->n[8] = r->n[9] = 0;
for (int i=0; i<32; i++) {
@@ -162,11 +176,15 @@ static void secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
r->n[limb] |= (uint32_t)((a[31-i] >> (2*j)) & 0x3) << shift;
}
}
+ if (r->n[9] == 0x3FFFFFUL && (r->n[8] & r->n[7] & r->n[6] & r->n[5] & r->n[4] & r->n[3] & r->n[2]) == 0x3FFFFFFUL && (r->n[1] + 0x40UL + ((r->n[0] + 0x3D1UL) >> 26)) > 0x3FFFFFFUL) {
+ return 0;
+ }
#ifdef VERIFY
r->magnitude = 1;
r->normalized = 1;
secp256k1_fe_verify(r);
#endif
+ return 1;
}
/** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */
@@ -253,7 +271,7 @@ SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1
#define VERIFY_BITS(x, n) do { } while(0)
#endif
-SECP256K1_INLINE static void secp256k1_fe_mul_inner(const uint32_t *a, const uint32_t *b, uint32_t *r) {
+SECP256K1_INLINE static void secp256k1_fe_mul_inner(const uint32_t *a, const uint32_t * SECP256K1_RESTRICT b, uint32_t *r) {
VERIFY_BITS(a[0], 30);
VERIFY_BITS(a[1], 30);
VERIFY_BITS(a[2], 30);
@@ -853,12 +871,13 @@ SECP256K1_INLINE static void secp256k1_fe_sqr_inner(const uint32_t *a, uint32_t
}
-static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
+static void secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t * SECP256K1_RESTRICT b) {
#ifdef VERIFY
VERIFY_CHECK(a->magnitude <= 8);
VERIFY_CHECK(b->magnitude <= 8);
secp256k1_fe_verify(a);
secp256k1_fe_verify(b);
+ VERIFY_CHECK(r != b);
#endif
secp256k1_fe_mul_inner(a->n, b->n, r->n);
#ifdef VERIFY
@@ -881,4 +900,24 @@ static void secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
#endif
}
+static void secp256k1_fe_cmov(secp256k1_fe_t *r, const secp256k1_fe_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);
+ r->n[8] = (r->n[8] & mask0) | (a->n[8] & mask1);
+ r->n[9] = (r->n[9] & mask0) | (a->n[9] & mask1);
+#ifdef VERIFY
+ if (flag) {
+ r->magnitude = a->magnitude;
+ r->normalized = a->normalized;
+ }
+#endif
+}
+
#endif