Correct secp256k1_fe_verify and use it everywhere

This commit is contained in:
Pieter Wuille 2014-07-15 19:09:35 +02:00
parent 59447da38d
commit 21f81a8469
3 changed files with 40 additions and 28 deletions

View file

@ -42,10 +42,6 @@ void static secp256k1_fe_start(void);
/** Unload field element precomputation data. */ /** Unload field element precomputation data. */
void static secp256k1_fe_stop(void); void static secp256k1_fe_stop(void);
#ifdef VERIFY
int static secp256k1_fe_verify(const secp256k1_fe_t * a);
#endif
/** Normalize a field element. */ /** Normalize a field element. */
void static secp256k1_fe_normalize(secp256k1_fe_t *r); void static secp256k1_fe_normalize(secp256k1_fe_t *r);

View file

@ -34,9 +34,9 @@ void static secp256k1_fe_inner_start(void) {}
void static secp256k1_fe_inner_stop(void) {} void static secp256k1_fe_inner_stop(void) {}
#ifdef VERIFY #ifdef VERIFY
int static secp256k1_fe_verify(const secp256k1_fe_t * a) { void static secp256k1_fe_verify(const secp256k1_fe_t *a) {
const uint64_t *d = a->n; const uint64_t *d = a->n;
int m = a->magnitude, r = 1; int m = a->normalized ? 1 : 2 * a->magnitude, r = 1;
r &= (d[0] <= 0xFFFFFFFFFFFFFULL * m); r &= (d[0] <= 0xFFFFFFFFFFFFFULL * m);
r &= (d[1] <= 0xFFFFFFFFFFFFFULL * m); r &= (d[1] <= 0xFFFFFFFFFFFFFULL * m);
r &= (d[2] <= 0xFFFFFFFFFFFFFULL * m); r &= (d[2] <= 0xFFFFFFFFFFFFFULL * m);
@ -48,8 +48,10 @@ int static secp256k1_fe_verify(const secp256k1_fe_t * a) {
r &= (d[0] < 0xFFFFEFFFFFC2FULL); r &= (d[0] < 0xFFFFEFFFFFC2FULL);
} }
} }
return r; assert(r == 1);
} }
#else
void static secp256k1_fe_verify(const secp256k1_fe_t *a) {}
#endif #endif
void static secp256k1_fe_normalize(secp256k1_fe_t *r) { void static secp256k1_fe_normalize(secp256k1_fe_t *r) {
@ -91,6 +93,7 @@ void static secp256k1_fe_normalize(secp256k1_fe_t *r) {
#ifdef VERIFY #ifdef VERIFY
r->magnitude = 1; r->magnitude = 1;
r->normalized = 1; r->normalized = 1;
secp256k1_fe_verify(r);
#endif #endif
} }
@ -100,6 +103,7 @@ void static inline secp256k1_fe_set_int(secp256k1_fe_t *r, int a) {
#ifdef VERIFY #ifdef VERIFY
r->magnitude = 1; r->magnitude = 1;
r->normalized = 1; r->normalized = 1;
secp256k1_fe_verify(r);
#endif #endif
} }
@ -107,6 +111,7 @@ void static inline secp256k1_fe_set_int(secp256k1_fe_t *r, int a) {
int static inline secp256k1_fe_is_zero(const secp256k1_fe_t *a) { int static inline secp256k1_fe_is_zero(const secp256k1_fe_t *a) {
#ifdef VERIFY #ifdef VERIFY
assert(a->normalized); assert(a->normalized);
secp256k1_fe_verify(a);
#endif #endif
return (a->n[0] == 0 && a->n[1] == 0 && a->n[2] == 0 && a->n[3] == 0 && a->n[4] == 0); return (a->n[0] == 0 && a->n[1] == 0 && a->n[2] == 0 && a->n[3] == 0 && a->n[4] == 0);
} }
@ -114,6 +119,7 @@ int static inline secp256k1_fe_is_zero(const secp256k1_fe_t *a) {
int static inline secp256k1_fe_is_odd(const secp256k1_fe_t *a) { int static inline secp256k1_fe_is_odd(const secp256k1_fe_t *a) {
#ifdef VERIFY #ifdef VERIFY
assert(a->normalized); assert(a->normalized);
secp256k1_fe_verify(a);
#endif #endif
return a->n[0] & 1; return a->n[0] & 1;
} }
@ -123,6 +129,8 @@ int static inline secp256k1_fe_equal(const secp256k1_fe_t *a, const secp256k1_fe
#ifdef VERIFY #ifdef VERIFY
assert(a->normalized); assert(a->normalized);
assert(b->normalized); assert(b->normalized);
secp256k1_fe_verify(a);
secp256k1_fe_verify(b);
#endif #endif
return (a->n[0] == b->n[0] && a->n[1] == b->n[1] && a->n[2] == b->n[2] && a->n[3] == b->n[3] && a->n[4] == b->n[4]); return (a->n[0] == b->n[0] && a->n[1] == b->n[1] && a->n[2] == b->n[2] && a->n[3] == b->n[3] && a->n[4] == b->n[4]);
} }
@ -139,6 +147,7 @@ void static secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
#ifdef VERIFY #ifdef VERIFY
r->magnitude = 1; r->magnitude = 1;
r->normalized = 1; r->normalized = 1;
secp256k1_fe_verify(r);
#endif #endif
} }
@ -146,6 +155,7 @@ void static secp256k1_fe_set_b32(secp256k1_fe_t *r, const unsigned char *a) {
void static secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) { void static secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) {
#ifdef VERIFY #ifdef VERIFY
assert(a->normalized); assert(a->normalized);
secp256k1_fe_verify(a);
#endif #endif
for (int i=0; i<32; i++) { for (int i=0; i<32; i++) {
int c = 0; int c = 0;
@ -161,57 +171,71 @@ void static secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe_t *a) {
void static inline secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) { void static inline secp256k1_fe_negate(secp256k1_fe_t *r, const secp256k1_fe_t *a, int m) {
#ifdef VERIFY #ifdef VERIFY
assert(a->magnitude <= m); assert(a->magnitude <= m);
r->magnitude = m + 1; secp256k1_fe_verify(a);
r->normalized = 0;
#endif #endif
r->n[0] = 0xFFFFEFFFFFC2FULL * (m + 1) - a->n[0]; r->n[0] = 0xFFFFEFFFFFC2FULL * (m + 1) - a->n[0];
r->n[1] = 0xFFFFFFFFFFFFFULL * (m + 1) - a->n[1]; r->n[1] = 0xFFFFFFFFFFFFFULL * (m + 1) - a->n[1];
r->n[2] = 0xFFFFFFFFFFFFFULL * (m + 1) - a->n[2]; r->n[2] = 0xFFFFFFFFFFFFFULL * (m + 1) - a->n[2];
r->n[3] = 0xFFFFFFFFFFFFFULL * (m + 1) - a->n[3]; r->n[3] = 0xFFFFFFFFFFFFFULL * (m + 1) - a->n[3];
r->n[4] = 0x0FFFFFFFFFFFFULL * (m + 1) - a->n[4]; r->n[4] = 0x0FFFFFFFFFFFFULL * (m + 1) - a->n[4];
#ifdef VERIFY
r->magnitude = m + 1;
r->normalized = 0;
secp256k1_fe_verify(r);
#endif
} }
void static inline secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) { void static inline secp256k1_fe_mul_int(secp256k1_fe_t *r, int a) {
#ifdef VERIFY
r->magnitude *= a;
r->normalized = 0;
#endif
r->n[0] *= a; r->n[0] *= a;
r->n[1] *= a; r->n[1] *= a;
r->n[2] *= a; r->n[2] *= a;
r->n[3] *= a; r->n[3] *= a;
r->n[4] *= a; r->n[4] *= a;
#ifdef VERIFY
r->magnitude *= a;
r->normalized = 0;
secp256k1_fe_verify(r);
#endif
} }
void static inline secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) { void static inline secp256k1_fe_add(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
#ifdef VERIFY
r->magnitude += a->magnitude;
r->normalized = 0;
#endif
r->n[0] += a->n[0]; r->n[0] += a->n[0];
r->n[1] += a->n[1]; r->n[1] += a->n[1];
r->n[2] += a->n[2]; r->n[2] += a->n[2];
r->n[3] += a->n[3]; r->n[3] += a->n[3];
r->n[4] += a->n[4]; r->n[4] += a->n[4];
#ifdef VERIFY
r->magnitude += a->magnitude;
r->normalized = 0;
secp256k1_fe_verify(r);
secp256k1_fe_verify(a);
#endif
} }
void static secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t *b) { void static secp256k1_fe_mul(secp256k1_fe_t *r, const secp256k1_fe_t *a, const secp256k1_fe_t *b) {
#ifdef VERIFY #ifdef VERIFY
assert(a->magnitude <= 8); assert(a->magnitude <= 8);
assert(b->magnitude <= 8); assert(b->magnitude <= 8);
r->magnitude = 1; secp256k1_fe_verify(a);
r->normalized = 0; secp256k1_fe_verify(b);
#endif #endif
secp256k1_fe_mul_inner(a->n, b->n, r->n); secp256k1_fe_mul_inner(a->n, b->n, r->n);
#ifdef VERIFY
r->magnitude = 1;
r->normalized = 0;
secp256k1_fe_verify(r);
#endif
} }
void static secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) { void static secp256k1_fe_sqr(secp256k1_fe_t *r, const secp256k1_fe_t *a) {
#ifdef VERIFY #ifdef VERIFY
assert(a->magnitude <= 8); assert(a->magnitude <= 8);
#endif
secp256k1_fe_sqr_inner(a->n, r->n);
#ifdef VERIFY
r->magnitude = 1; r->magnitude = 1;
r->normalized = 0; r->normalized = 0;
#endif #endif
secp256k1_fe_sqr_inner(a->n, r->n);
} }
#endif #endif

View file

@ -315,9 +315,6 @@ void run_field_inv_all_var() {
void run_sqr() { void run_sqr() {
secp256k1_fe_t x, s; secp256k1_fe_t x, s;
#if defined(USE_FIELD_5X52)
// Known issue with reduction part of sqr. For simplicity, we trigger the problem here
// with "negative" powers of 2, but the problem exists for large ranges of values.
{ {
secp256k1_fe_set_int(&x, 1); secp256k1_fe_set_int(&x, 1);
secp256k1_fe_negate(&x, &x, 1); secp256k1_fe_negate(&x, &x, 1);
@ -326,13 +323,8 @@ void run_sqr() {
secp256k1_fe_mul_int(&x, 2); secp256k1_fe_mul_int(&x, 2);
secp256k1_fe_normalize(&x); secp256k1_fe_normalize(&x);
secp256k1_fe_sqr(&s, &x); secp256k1_fe_sqr(&s, &x);
if (!secp256k1_fe_verify(&s)) {
printf("%4i: %016llx %016llx %016llx %016llx %016llx\n",
i, s.n[4], s.n[3], s.n[2], s.n[1], s.n[0]);
} }
} }
}
#endif
} }
void test_sqrt(const secp256k1_fe_t *a, const secp256k1_fe_t *k) { void test_sqrt(const secp256k1_fe_t *a, const secp256k1_fe_t *k) {