Alien-libsecp256k1

 view release on metacpan or  search on metacpan

libsecp256k1/src/tests.c  view on Meta::CPAN

    CHECK(secp256k1_ecmult_multi_batch_size_helper(&n_batches, &n_batch_points, max_n_batch_points, n) == 1);
    CHECK(n_batches == 2);
    CHECK(n_batch_points == ECMULT_MAX_POINTS_PER_BATCH/2 + 1);

    max_n_batch_points = 1;
    n = SIZE_MAX;
    CHECK(secp256k1_ecmult_multi_batch_size_helper(&n_batches, &n_batch_points, max_n_batch_points, n) == 1);
    CHECK(n_batches == SIZE_MAX);
    CHECK(n_batch_points == 1);

    max_n_batch_points = 2;
    n = SIZE_MAX;
    CHECK(secp256k1_ecmult_multi_batch_size_helper(&n_batches, &n_batch_points, max_n_batch_points, n) == 1);
    CHECK(n_batches == SIZE_MAX/2 + 1);
    CHECK(n_batch_points == 2);
}

/**
 * Run secp256k1_ecmult_multi_var with num points and a scratch space restricted to
 * 1 <= i <= num points.
 */
static void test_ecmult_multi_batching(void) {
    static const int n_points = 2*ECMULT_PIPPENGER_THRESHOLD;
    secp256k1_scalar scG;
    secp256k1_scalar *sc = (secp256k1_scalar *)checked_malloc(&CTX->error_callback, sizeof(secp256k1_scalar) * n_points);
    secp256k1_ge *pt = (secp256k1_ge *)checked_malloc(&CTX->error_callback, sizeof(secp256k1_ge) * n_points);
    secp256k1_gej r;
    secp256k1_gej r2;
    ecmult_multi_data data;
    int i;
    secp256k1_scratch *scratch;

    secp256k1_gej_set_infinity(&r2);

    /* Get random scalars and group elements and compute result */
    testutil_random_scalar_order(&scG);
    secp256k1_ecmult(&r2, &r2, &secp256k1_scalar_zero, &scG);
    for(i = 0; i < n_points; i++) {
        secp256k1_ge ptg;
        secp256k1_gej ptgj;
        testutil_random_ge_test(&ptg);
        secp256k1_gej_set_ge(&ptgj, &ptg);
        pt[i] = ptg;
        testutil_random_scalar_order(&sc[i]);
        secp256k1_ecmult(&ptgj, &ptgj, &sc[i], NULL);
        secp256k1_gej_add_var(&r2, &r2, &ptgj, NULL);
    }
    data.sc = sc;
    data.pt = pt;
    secp256k1_gej_neg(&r2, &r2);

    /* Test with empty scratch space. It should compute the correct result using
     * ecmult_mult_simple algorithm which doesn't require a scratch space. */
    scratch = secp256k1_scratch_create(&CTX->error_callback, 0);
    CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &r, &scG, ecmult_multi_callback, &data, n_points));
    secp256k1_gej_add_var(&r, &r, &r2, NULL);
    CHECK(secp256k1_gej_is_infinity(&r));
    secp256k1_scratch_destroy(&CTX->error_callback, scratch);

    /* Test with space for 1 point in pippenger. That's not enough because
     * ecmult_multi selects strauss which requires more memory. It should
     * therefore select the simple algorithm. */
    scratch = secp256k1_scratch_create(&CTX->error_callback, secp256k1_pippenger_scratch_size(1, 1) + PIPPENGER_SCRATCH_OBJECTS*ALIGNMENT);
    CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &r, &scG, ecmult_multi_callback, &data, n_points));
    secp256k1_gej_add_var(&r, &r, &r2, NULL);
    CHECK(secp256k1_gej_is_infinity(&r));
    secp256k1_scratch_destroy(&CTX->error_callback, scratch);

    for(i = 1; i <= n_points; i++) {
        if (i > ECMULT_PIPPENGER_THRESHOLD) {
            int bucket_window = secp256k1_pippenger_bucket_window(i);
            size_t scratch_size = secp256k1_pippenger_scratch_size(i, bucket_window);
            scratch = secp256k1_scratch_create(&CTX->error_callback, scratch_size + PIPPENGER_SCRATCH_OBJECTS*ALIGNMENT);
        } else {
            size_t scratch_size = secp256k1_strauss_scratch_size(i);
            scratch = secp256k1_scratch_create(&CTX->error_callback, scratch_size + STRAUSS_SCRATCH_OBJECTS*ALIGNMENT);
        }
        CHECK(secp256k1_ecmult_multi_var(&CTX->error_callback, scratch, &r, &scG, ecmult_multi_callback, &data, n_points));
        secp256k1_gej_add_var(&r, &r, &r2, NULL);
        CHECK(secp256k1_gej_is_infinity(&r));
        secp256k1_scratch_destroy(&CTX->error_callback, scratch);
    }
    free(sc);
    free(pt);
}

static void run_ecmult_multi_tests(void) {
    secp256k1_scratch *scratch;
    int64_t todo = (int64_t)320 * COUNT;

    test_secp256k1_pippenger_bucket_window_inv();
    test_ecmult_multi_pippenger_max_points();
    scratch = secp256k1_scratch_create(&CTX->error_callback, 819200);
    test_ecmult_multi(scratch, secp256k1_ecmult_multi_var);
    test_ecmult_multi(NULL, secp256k1_ecmult_multi_var);
    test_ecmult_multi(scratch, secp256k1_ecmult_pippenger_batch_single);
    test_ecmult_multi_batch_single(secp256k1_ecmult_pippenger_batch_single);
    test_ecmult_multi(scratch, secp256k1_ecmult_strauss_batch_single);
    test_ecmult_multi_batch_single(secp256k1_ecmult_strauss_batch_single);
    while (todo > 0) {
        todo -= test_ecmult_multi_random(scratch);
    }
    secp256k1_scratch_destroy(&CTX->error_callback, scratch);

    /* Run test_ecmult_multi with space for exactly one point */
    scratch = secp256k1_scratch_create(&CTX->error_callback, secp256k1_strauss_scratch_size(1) + STRAUSS_SCRATCH_OBJECTS*ALIGNMENT);
    test_ecmult_multi(scratch, secp256k1_ecmult_multi_var);
    secp256k1_scratch_destroy(&CTX->error_callback, scratch);

    test_ecmult_multi_batch_size_helper();
    test_ecmult_multi_batching();
}

static void test_wnaf(const secp256k1_scalar *number, int w) {
    secp256k1_scalar x, two, t;
    int wnaf[256];
    int zeroes = -1;
    int i;
    int bits;
    secp256k1_scalar_set_int(&x, 0);
    secp256k1_scalar_set_int(&two, 2);
    bits = secp256k1_ecmult_wnaf(wnaf, 256, number, w);



( run in 1.146 second using v1.01-cache-2.11-cpan-5a3173703d6 )