Merge commits '4494a369 3aef6ab8 0fa84f86 249c81ea 7966aee3 fb758fe8 3fc1de5c 0aacf643 9e6d1b0e 332af315 afd7eb4a c9ebca95 cc557575 0f7657d5 907a6721 b40e2d30 c545fdc3 2bd5f3e6 0e00fc7d c734c642 26392da2 ' into temp-merge-1386
This commit is contained in:
204
src/tests.c
204
src/tests.c
@@ -89,16 +89,6 @@ static void uncounting_illegal_callback_fn(const char* str, void* data) {
|
||||
(*p)--;
|
||||
}
|
||||
|
||||
static void random_field_element_test(secp256k1_fe *fe) {
|
||||
do {
|
||||
unsigned char b32[32];
|
||||
secp256k1_testrand256_test(b32);
|
||||
if (secp256k1_fe_set_b32_limit(fe, b32)) {
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
}
|
||||
|
||||
static void random_field_element_magnitude(secp256k1_fe *fe) {
|
||||
secp256k1_fe zero;
|
||||
int n = secp256k1_testrand_int(9);
|
||||
@@ -108,17 +98,33 @@ static void random_field_element_magnitude(secp256k1_fe *fe) {
|
||||
}
|
||||
secp256k1_fe_clear(&zero);
|
||||
secp256k1_fe_negate(&zero, &zero, 0);
|
||||
secp256k1_fe_mul_int(&zero, n - 1);
|
||||
secp256k1_fe_mul_int_unchecked(&zero, n - 1);
|
||||
secp256k1_fe_add(fe, &zero);
|
||||
#ifdef VERIFY
|
||||
CHECK(fe->magnitude == n);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void random_fe_test(secp256k1_fe *x) {
|
||||
unsigned char bin[32];
|
||||
do {
|
||||
secp256k1_testrand256_test(bin);
|
||||
if (secp256k1_fe_set_b32_limit(x, bin)) {
|
||||
return;
|
||||
}
|
||||
} while(1);
|
||||
}
|
||||
|
||||
static void random_fe_non_zero_test(secp256k1_fe *fe) {
|
||||
do {
|
||||
random_fe_test(fe);
|
||||
} while(secp256k1_fe_is_zero(fe));
|
||||
}
|
||||
|
||||
static void random_group_element_test(secp256k1_ge *ge) {
|
||||
secp256k1_fe fe;
|
||||
do {
|
||||
random_field_element_test(&fe);
|
||||
random_fe_test(&fe);
|
||||
if (secp256k1_ge_set_xo_var(ge, &fe, secp256k1_testrand_bits(1))) {
|
||||
secp256k1_fe_normalize(&ge->y);
|
||||
break;
|
||||
@@ -129,12 +135,7 @@ static void random_group_element_test(secp256k1_ge *ge) {
|
||||
|
||||
static void random_group_element_jacobian_test(secp256k1_gej *gej, const secp256k1_ge *ge) {
|
||||
secp256k1_fe z2, z3;
|
||||
do {
|
||||
random_field_element_test(&gej->z);
|
||||
if (!secp256k1_fe_is_zero(&gej->z)) {
|
||||
break;
|
||||
}
|
||||
} while(1);
|
||||
random_fe_non_zero_test(&gej->z);
|
||||
secp256k1_fe_sqr(&z2, &gej->z);
|
||||
secp256k1_fe_mul(&z3, &z2, &gej->z);
|
||||
secp256k1_fe_mul(&gej->x, &ge->x, &z2);
|
||||
@@ -226,6 +227,35 @@ static void run_util_tests(void) {
|
||||
}
|
||||
}
|
||||
|
||||
static void run_xoshiro256pp_tests(void) {
|
||||
{
|
||||
size_t i;
|
||||
/* Sanity check that we run before the actual seeding. */
|
||||
for (i = 0; i < sizeof(secp256k1_test_state)/sizeof(secp256k1_test_state[0]); i++) {
|
||||
CHECK(secp256k1_test_state[i] == 0);
|
||||
}
|
||||
}
|
||||
{
|
||||
int i;
|
||||
unsigned char buf32[32];
|
||||
unsigned char seed16[16] = {
|
||||
'C', 'H', 'I', 'C', 'K', 'E', 'N', '!',
|
||||
'C', 'H', 'I', 'C', 'K', 'E', 'N', '!',
|
||||
};
|
||||
unsigned char buf32_expected[32] = {
|
||||
0xAF, 0xCC, 0xA9, 0x16, 0xB5, 0x6C, 0xE3, 0xF0,
|
||||
0x44, 0x3F, 0x45, 0xE0, 0x47, 0xA5, 0x08, 0x36,
|
||||
0x4C, 0xCC, 0xC1, 0x18, 0xB2, 0xD8, 0x8F, 0xEF,
|
||||
0x43, 0x26, 0x15, 0x57, 0x37, 0x00, 0xEF, 0x30,
|
||||
};
|
||||
secp256k1_testrand_seed(seed16);
|
||||
for (i = 0; i < 17; i++) {
|
||||
secp256k1_testrand256(buf32);
|
||||
}
|
||||
CHECK(secp256k1_memcmp_var(buf32, buf32_expected, sizeof(buf32)) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void run_selftest_tests(void) {
|
||||
/* Test public API */
|
||||
secp256k1_selftest();
|
||||
@@ -869,78 +899,6 @@ static void run_tagged_sha256_tests(void) {
|
||||
CHECK(secp256k1_memcmp_var(hash32, hash_expected, sizeof(hash32)) == 0);
|
||||
}
|
||||
|
||||
/***** RANDOM TESTS *****/
|
||||
|
||||
static void test_rand_bits(int rand32, int bits) {
|
||||
/* (1-1/2^B)^rounds[B] < 1/10^9, so rounds is the number of iterations to
|
||||
* get a false negative chance below once in a billion */
|
||||
static const unsigned int rounds[7] = {1, 30, 73, 156, 322, 653, 1316};
|
||||
/* We try multiplying the results with various odd numbers, which shouldn't
|
||||
* influence the uniform distribution modulo a power of 2. */
|
||||
static const uint32_t mults[6] = {1, 3, 21, 289, 0x9999, 0x80402011};
|
||||
/* We only select up to 6 bits from the output to analyse */
|
||||
unsigned int usebits = bits > 6 ? 6 : bits;
|
||||
unsigned int maxshift = bits - usebits;
|
||||
/* For each of the maxshift+1 usebits-bit sequences inside a bits-bit
|
||||
number, track all observed outcomes, one per bit in a uint64_t. */
|
||||
uint64_t x[6][27] = {{0}};
|
||||
unsigned int i, shift, m;
|
||||
/* Multiply the output of all rand calls with the odd number m, which
|
||||
should not change the uniformity of its distribution. */
|
||||
for (i = 0; i < rounds[usebits]; i++) {
|
||||
uint32_t r = (rand32 ? secp256k1_testrand32() : secp256k1_testrand_bits(bits));
|
||||
CHECK((((uint64_t)r) >> bits) == 0);
|
||||
for (m = 0; m < sizeof(mults) / sizeof(mults[0]); m++) {
|
||||
uint32_t rm = r * mults[m];
|
||||
for (shift = 0; shift <= maxshift; shift++) {
|
||||
x[m][shift] |= (((uint64_t)1) << ((rm >> shift) & ((1 << usebits) - 1)));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (m = 0; m < sizeof(mults) / sizeof(mults[0]); m++) {
|
||||
for (shift = 0; shift <= maxshift; shift++) {
|
||||
/* Test that the lower usebits bits of x[shift] are 1 */
|
||||
CHECK(((~x[m][shift]) << (64 - (1 << usebits))) == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Subrange must be a whole divisor of range, and at most 64 */
|
||||
static void test_rand_int(uint32_t range, uint32_t subrange) {
|
||||
/* (1-1/subrange)^rounds < 1/10^9 */
|
||||
int rounds = (subrange * 2073) / 100;
|
||||
int i;
|
||||
uint64_t x = 0;
|
||||
CHECK((range % subrange) == 0);
|
||||
for (i = 0; i < rounds; i++) {
|
||||
uint32_t r = secp256k1_testrand_int(range);
|
||||
CHECK(r < range);
|
||||
r = r % subrange;
|
||||
x |= (((uint64_t)1) << r);
|
||||
}
|
||||
/* Test that the lower subrange bits of x are 1. */
|
||||
CHECK(((~x) << (64 - subrange)) == 0);
|
||||
}
|
||||
|
||||
static void run_rand_bits(void) {
|
||||
size_t b;
|
||||
test_rand_bits(1, 32);
|
||||
for (b = 1; b <= 32; b++) {
|
||||
test_rand_bits(0, b);
|
||||
}
|
||||
}
|
||||
|
||||
static void run_rand_int(void) {
|
||||
static const uint32_t ms[] = {1, 3, 17, 1000, 13771, 999999, 33554432};
|
||||
static const uint32_t ss[] = {1, 3, 6, 9, 13, 31, 64};
|
||||
unsigned int m, s;
|
||||
for (m = 0; m < sizeof(ms) / sizeof(ms[0]); m++) {
|
||||
for (s = 0; s < sizeof(ss) / sizeof(ss[0]); s++) {
|
||||
test_rand_int(ms[m] * ss[s], ss[s]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***** MODINV TESTS *****/
|
||||
|
||||
/* Compute the modular inverse of (odd) x mod 2^64. */
|
||||
@@ -3154,16 +3112,6 @@ static void random_fe(secp256k1_fe *x) {
|
||||
} while(1);
|
||||
}
|
||||
|
||||
static void random_fe_test(secp256k1_fe *x) {
|
||||
unsigned char bin[32];
|
||||
do {
|
||||
secp256k1_testrand256_test(bin);
|
||||
if (secp256k1_fe_set_b32_limit(x, bin)) {
|
||||
return;
|
||||
}
|
||||
} while(1);
|
||||
}
|
||||
|
||||
static void random_fe_non_zero(secp256k1_fe *nz) {
|
||||
int tries = 10;
|
||||
while (--tries >= 0) {
|
||||
@@ -3404,7 +3352,7 @@ static void run_field_misc(void) {
|
||||
CHECK(q.normalized && q.magnitude == 1);
|
||||
#endif
|
||||
for (j = 0; j < 6; j++) {
|
||||
secp256k1_fe_negate(&z, &z, j+1);
|
||||
secp256k1_fe_negate_unchecked(&z, &z, j+1);
|
||||
secp256k1_fe_normalize_var(&q);
|
||||
secp256k1_fe_cmov(&q, &z, (j&1));
|
||||
#ifdef VERIFY
|
||||
@@ -3990,18 +3938,14 @@ static void test_ge(void) {
|
||||
}
|
||||
|
||||
/* Generate random zf, and zfi2 = 1/zf^2, zfi3 = 1/zf^3 */
|
||||
do {
|
||||
random_field_element_test(&zf);
|
||||
} while(secp256k1_fe_is_zero(&zf));
|
||||
random_fe_non_zero_test(&zf);
|
||||
random_field_element_magnitude(&zf);
|
||||
secp256k1_fe_inv_var(&zfi3, &zf);
|
||||
secp256k1_fe_sqr(&zfi2, &zfi3);
|
||||
secp256k1_fe_mul(&zfi3, &zfi3, &zfi2);
|
||||
|
||||
/* Generate random r */
|
||||
do {
|
||||
random_field_element_test(&r);
|
||||
} while(secp256k1_fe_is_zero(&r));
|
||||
random_fe_non_zero_test(&r);
|
||||
|
||||
for (i1 = 0; i1 < 1 + 4 * runs; i1++) {
|
||||
int i2;
|
||||
@@ -4218,22 +4162,15 @@ static void test_add_neg_y_diff_x(void) {
|
||||
* which this test is a regression test for.
|
||||
*
|
||||
* These points were generated in sage as
|
||||
* # secp256k1 params
|
||||
* F = FiniteField (0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F)
|
||||
* C = EllipticCurve ([F (0), F (7)])
|
||||
* G = C.lift_x(0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798)
|
||||
* N = FiniteField(G.order())
|
||||
*
|
||||
* # endomorphism values (lambda is 1^{1/3} in N, beta is 1^{1/3} in F)
|
||||
* x = polygen(N)
|
||||
* lam = (1 - x^3).roots()[1][0]
|
||||
* load("secp256k1_params.sage")
|
||||
*
|
||||
* # random "bad pair"
|
||||
* P = C.random_element()
|
||||
* Q = -int(lam) * P
|
||||
* print " P: %x %x" % P.xy()
|
||||
* print " Q: %x %x" % Q.xy()
|
||||
* print "P + Q: %x %x" % (P + Q).xy()
|
||||
* Q = -int(LAMBDA) * P
|
||||
* print(" P: %x %x" % P.xy())
|
||||
* print(" Q: %x %x" % Q.xy())
|
||||
* print("P + Q: %x %x" % (P + Q).xy())
|
||||
*/
|
||||
secp256k1_gej aj = SECP256K1_GEJ_CONST(
|
||||
0x8d24cd95, 0x0a355af1, 0x3c543505, 0x44238d30,
|
||||
@@ -4318,10 +4255,7 @@ static void run_gej(void) {
|
||||
CHECK(!secp256k1_gej_eq_var(&a, &b));
|
||||
|
||||
b = a;
|
||||
random_field_element_test(&fe);
|
||||
if (secp256k1_fe_is_zero(&fe)) {
|
||||
continue;
|
||||
}
|
||||
random_fe_non_zero_test(&fe);
|
||||
secp256k1_gej_rescale(&a, &fe);
|
||||
CHECK(secp256k1_gej_eq_var(&a, &b));
|
||||
}
|
||||
@@ -4866,9 +4800,7 @@ static void ecmult_const_mult_xonly(void) {
|
||||
random_scalar_order_test(&q);
|
||||
/* If i is odd, n=d*base.x for random non-zero d */
|
||||
if (i & 1) {
|
||||
do {
|
||||
random_field_element_test(&d);
|
||||
} while (secp256k1_fe_normalizes_to_zero_var(&d));
|
||||
random_fe_non_zero_test(&d);
|
||||
secp256k1_fe_mul(&n, &base.x, &d);
|
||||
} else {
|
||||
n = base.x;
|
||||
@@ -4887,22 +4819,17 @@ static void ecmult_const_mult_xonly(void) {
|
||||
|
||||
/* Test that secp256k1_ecmult_const_xonly correctly rejects X coordinates not on curve. */
|
||||
for (i = 0; i < 2*COUNT; ++i) {
|
||||
secp256k1_fe x, n, d, c, r;
|
||||
secp256k1_fe x, n, d, r;
|
||||
int res;
|
||||
secp256k1_scalar q;
|
||||
random_scalar_order_test(&q);
|
||||
/* Generate random X coordinate not on the curve. */
|
||||
do {
|
||||
random_field_element_test(&x);
|
||||
secp256k1_fe_sqr(&c, &x);
|
||||
secp256k1_fe_mul(&c, &c, &x);
|
||||
secp256k1_fe_add_int(&c, SECP256K1_B);
|
||||
} while (secp256k1_fe_is_square_var(&c));
|
||||
random_fe_test(&x);
|
||||
} while (secp256k1_ge_x_on_curve_var(&x));
|
||||
/* If i is odd, n=d*x for random non-zero d. */
|
||||
if (i & 1) {
|
||||
do {
|
||||
random_field_element_test(&d);
|
||||
} while (secp256k1_fe_normalizes_to_zero_var(&d));
|
||||
random_fe_non_zero_test(&d);
|
||||
secp256k1_fe_mul(&n, &x, &d);
|
||||
} else {
|
||||
n = x;
|
||||
@@ -8073,6 +8000,9 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
printf("test count = %i\n", COUNT);
|
||||
|
||||
/* run test RNG tests (must run before we really initialize the test RNG) */
|
||||
run_xoshiro256pp_tests();
|
||||
|
||||
/* find random seed */
|
||||
secp256k1_testrand_init(argc > 2 ? argv[2] : NULL);
|
||||
|
||||
@@ -8110,9 +8040,7 @@ int main(int argc, char **argv) {
|
||||
/* scratch tests */
|
||||
run_scratch_tests();
|
||||
|
||||
/* randomness tests */
|
||||
run_rand_bits();
|
||||
run_rand_int();
|
||||
/* util tests */
|
||||
run_util_tests();
|
||||
|
||||
/* integer arithmetic tests */
|
||||
|
||||
Reference in New Issue
Block a user