|
|
@ -217,18 +217,26 @@ void random_fe(secp256k1_fe_t *x) {
|
|
|
|
secp256k1_fe_set_b32(x, bin);
|
|
|
|
secp256k1_fe_set_b32(x, bin);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void random_fe_non_square(secp256k1_fe_t *ns) {
|
|
|
|
void random_fe_non_zero(secp256k1_fe_t *nz) {
|
|
|
|
secp256k1_fe_t r;
|
|
|
|
int tries = 10;
|
|
|
|
int tries = 100;
|
|
|
|
|
|
|
|
while (--tries >= 0) {
|
|
|
|
while (--tries >= 0) {
|
|
|
|
random_fe(ns);
|
|
|
|
random_fe(nz);
|
|
|
|
if (!secp256k1_fe_sqrt(&r, ns))
|
|
|
|
secp256k1_fe_normalize(nz);
|
|
|
|
|
|
|
|
if (!secp256k1_fe_is_zero(nz))
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// 2^-100 probability of spurious failure here
|
|
|
|
// Infinitesimal probability of spurious failure here
|
|
|
|
assert(tries >= 0);
|
|
|
|
assert(tries >= 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void random_fe_non_square(secp256k1_fe_t *ns) {
|
|
|
|
|
|
|
|
random_fe_non_zero(ns);
|
|
|
|
|
|
|
|
secp256k1_fe_t r;
|
|
|
|
|
|
|
|
if (secp256k1_fe_sqrt(&r, ns)) {
|
|
|
|
|
|
|
|
secp256k1_fe_negate(ns, ns, 1);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
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) {
|
|
|
|
secp256k1_fe_t r1, r2;
|
|
|
|
secp256k1_fe_t r1, r2;
|
|
|
|
int v = secp256k1_fe_sqrt(&r1, a);
|
|
|
|
int v = secp256k1_fe_sqrt(&r1, a);
|
|
|
@ -245,14 +253,34 @@ void test_sqrt(const secp256k1_fe_t *a, const secp256k1_fe_t *k) {
|
|
|
|
|
|
|
|
|
|
|
|
void run_sqrt() {
|
|
|
|
void run_sqrt() {
|
|
|
|
secp256k1_fe_t ns, x, s, t;
|
|
|
|
secp256k1_fe_t ns, x, s, t;
|
|
|
|
random_fe_non_square(&ns);
|
|
|
|
|
|
|
|
for (int i=0; i<10*count; i++) {
|
|
|
|
// Check sqrt(0) is 0
|
|
|
|
random_fe(&x);
|
|
|
|
secp256k1_fe_set_int(&x, 0);
|
|
|
|
|
|
|
|
secp256k1_fe_sqr(&s, &x);
|
|
|
|
|
|
|
|
test_sqrt(&s, &x);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Check sqrt of small squares (and their negatives)
|
|
|
|
|
|
|
|
for (int i=1; i<=100; i++) {
|
|
|
|
|
|
|
|
secp256k1_fe_set_int(&x, i);
|
|
|
|
secp256k1_fe_sqr(&s, &x);
|
|
|
|
secp256k1_fe_sqr(&s, &x);
|
|
|
|
test_sqrt(&s, &x);
|
|
|
|
test_sqrt(&s, &x);
|
|
|
|
secp256k1_fe_mul(&t, &s, &ns);
|
|
|
|
secp256k1_fe_negate(&t, &s, 1);
|
|
|
|
test_sqrt(&t, NULL);
|
|
|
|
test_sqrt(&t, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Consistency checks for large random values
|
|
|
|
|
|
|
|
for (int i=0; i<10; i++) {
|
|
|
|
|
|
|
|
random_fe_non_square(&ns);
|
|
|
|
|
|
|
|
for (int j=0; j<count; j++) {
|
|
|
|
|
|
|
|
random_fe(&x);
|
|
|
|
|
|
|
|
secp256k1_fe_sqr(&s, &x);
|
|
|
|
|
|
|
|
test_sqrt(&s, &x);
|
|
|
|
|
|
|
|
secp256k1_fe_negate(&t, &s, 1);
|
|
|
|
|
|
|
|
test_sqrt(&t, NULL);
|
|
|
|
|
|
|
|
secp256k1_fe_mul(&t, &s, &ns);
|
|
|
|
|
|
|
|
test_sqrt(&t, NULL);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/***** ECMULT TESTS *****/
|
|
|
|
/***** ECMULT TESTS *****/
|
|
|
|