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.h46
1 files changed, 44 insertions, 2 deletions
diff --git a/src/field_10x26_impl.h b/src/field_10x26_impl.h
index 21742bf6eb..46b72ce78d 100644
--- a/src/field_10x26_impl.h
+++ b/src/field_10x26_impl.h
@@ -7,6 +7,7 @@
#ifndef SECP256K1_FIELD_REPR_IMPL_H
#define SECP256K1_FIELD_REPR_IMPL_H
+#include "checkmem.h"
#include "util.h"
#include "field.h"
#include "modinv32_impl.h"
@@ -481,6 +482,20 @@ SECP256K1_INLINE static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_f
#endif
}
+SECP256K1_INLINE static void secp256k1_fe_add_int(secp256k1_fe *r, int a) {
+#ifdef VERIFY
+ secp256k1_fe_verify(r);
+ VERIFY_CHECK(a >= 0);
+ VERIFY_CHECK(a <= 0x7FFF);
+#endif
+ r->n[0] += a;
+#ifdef VERIFY
+ r->magnitude += 1;
+ r->normalized = 0;
+ secp256k1_fe_verify(r);
+#endif
+}
+
#if defined(USE_EXTERNAL_ASM)
/* External assembler implementation */
@@ -1132,7 +1147,7 @@ static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a) {
static SECP256K1_INLINE void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag) {
uint32_t mask0, mask1;
- VG_CHECK_VERIFY(r->n, sizeof(r->n));
+ SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
mask0 = flag + ~((uint32_t)0);
mask1 = ~mask0;
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
@@ -1231,7 +1246,7 @@ static SECP256K1_INLINE void secp256k1_fe_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;
- VG_CHECK_VERIFY(r->n, sizeof(r->n));
+ SECP256K1_CHECKMEM_CHECK_VERIFY(r->n, sizeof(r->n));
mask0 = flag + ~((uint32_t)0);
mask1 = ~mask0;
r->n[0] = (r->n[0] & mask0) | (a->n[0] & mask1);
@@ -1364,4 +1379,31 @@ static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *x) {
VERIFY_CHECK(secp256k1_fe_normalizes_to_zero(r) == secp256k1_fe_normalizes_to_zero(&tmp));
}
+static int secp256k1_fe_is_square_var(const secp256k1_fe *x) {
+ secp256k1_fe tmp;
+ secp256k1_modinv32_signed30 s;
+ int jac, ret;
+
+ tmp = *x;
+ secp256k1_fe_normalize_var(&tmp);
+ /* secp256k1_jacobi32_maybe_var cannot deal with input 0. */
+ if (secp256k1_fe_is_zero(&tmp)) return 1;
+ secp256k1_fe_to_signed30(&s, &tmp);
+ jac = secp256k1_jacobi32_maybe_var(&s, &secp256k1_const_modinfo_fe);
+ if (jac == 0) {
+ /* secp256k1_jacobi32_maybe_var failed to compute the Jacobi symbol. Fall back
+ * to computing a square root. This should be extremely rare with random
+ * input (except in VERIFY mode, where a lower iteration count is used). */
+ secp256k1_fe dummy;
+ ret = secp256k1_fe_sqrt(&dummy, &tmp);
+ } else {
+#ifdef VERIFY
+ secp256k1_fe dummy;
+ VERIFY_CHECK(jac == 2*secp256k1_fe_sqrt(&dummy, &tmp) - 1);
+#endif
+ ret = jac >= 0;
+ }
+ return ret;
+}
+
#endif /* SECP256K1_FIELD_REPR_IMPL_H */