void test_exhaustive_addition(const secp256k1_ge *group, const secp256k1_gej *groupj, int order) {
    int i, j;

    /* Sanity-check (and check infinity functions) */
    CHECK(secp256k1_ge_is_infinity(&group[0]));
    CHECK(secp256k1_gej_is_infinity(&groupj[0]));
    for (i = 1; i < order; i++) {
        CHECK(!secp256k1_ge_is_infinity(&group[i]));
        CHECK(!secp256k1_gej_is_infinity(&groupj[i]));
    }

    /* Check all addition formulae */
    for (j = 0; j < order; j++) {
        secp256k1_fe fe_inv;
        secp256k1_fe_inv(&fe_inv, &groupj[j].z);
        for (i = 0; i < order; i++) {
            secp256k1_ge zless_gej;
            secp256k1_gej tmp;
            /* add_var */
            secp256k1_gej_add_var(&tmp, &groupj[i], &groupj[j], NULL);
            ge_equals_gej(&group[(i + j) % order], &tmp);
            /* add_ge */
            if (j > 0) {
                secp256k1_gej_add_ge(&tmp, &groupj[i], &group[j]);
                ge_equals_gej(&group[(i + j) % order], &tmp);
            }
            /* add_ge_var */
            secp256k1_gej_add_ge_var(&tmp, &groupj[i], &group[j], NULL);
            ge_equals_gej(&group[(i + j) % order], &tmp);
            /* add_zinv_var */
            zless_gej.infinity = groupj[j].infinity;
            zless_gej.x = groupj[j].x;
            zless_gej.y = groupj[j].y;
            secp256k1_gej_add_zinv_var(&tmp, &groupj[i], &zless_gej, &fe_inv);
            ge_equals_gej(&group[(i + j) % order], &tmp);
        }
    }

    /* Check doubling */
    for (i = 0; i < order; i++) {
        secp256k1_gej tmp;
        if (i > 0) {
            secp256k1_gej_double_nonzero(&tmp, &groupj[i], NULL);
            ge_equals_gej(&group[(2 * i) % order], &tmp);
        }
        secp256k1_gej_double_var(&tmp, &groupj[i], NULL);
        ge_equals_gej(&group[(2 * i) % order], &tmp);
    }

    /* Check negation */
    for (i = 1; i < order; i++) {
        secp256k1_ge tmp;
        secp256k1_gej tmpj;
        secp256k1_ge_neg(&tmp, &group[i]);
        ge_equals_ge(&group[order - i], &tmp);
        secp256k1_gej_neg(&tmpj, &groupj[i]);
        ge_equals_gej(&group[order - i], &tmpj);
    }
}
Beispiel #2
0
int secp256k1_ecdsa_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) {
    int ret = 1;
    secp256k1_num_t term;
    secp256k1_num_init(&term);
    secp256k1_num_set_bin(&term, tweak, 32);
    if (secp256k1_num_cmp(&term, &secp256k1_ge_consts->order) >= 0)
        ret = 0;
    secp256k1_ge_t p;
    if (ret) {
        if (!secp256k1_ecdsa_pubkey_parse(&p, pubkey, pubkeylen))
            ret = 0;
    }
    if (ret) {
        secp256k1_gej_t pt;
        secp256k1_ecmult_gen(&pt, &term);
        secp256k1_gej_add_ge(&pt, &pt, &p);
        if (secp256k1_gej_is_infinity(&pt))
            ret = 0;
        secp256k1_ge_set_gej(&p, &pt);
        int oldlen = pubkeylen;
        secp256k1_ecdsa_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33);
        assert(pubkeylen == oldlen);
    }
    secp256k1_num_free(&term);
    return ret;
}
Beispiel #3
0
int secp256k1_ecdsa_pubkey_tweak_add(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) {
    DEBUG_CHECK(secp256k1_ecmult_consts != NULL);
    DEBUG_CHECK(pubkey != NULL);
    DEBUG_CHECK(tweak != NULL);

    int ret = 1;
    secp256k1_num_t term;
    secp256k1_num_init(&term);
    secp256k1_num_set_bin(&term, tweak, 32);
    if (secp256k1_num_cmp(&term, &secp256k1_ge_consts->order) >= 0)
        ret = 0;
    secp256k1_ge_t p;
    if (ret) {
        if (!secp256k1_ecdsa_pubkey_parse(&p, pubkey, pubkeylen))
            ret = 0;
    }
    if (ret) {
        secp256k1_gej_t pt;
        secp256k1_gej_set_ge(&pt, &p);
        secp256k1_num_t one;
        secp256k1_num_init(&one);
        secp256k1_num_set_int(&one, 1);
        secp256k1_ecmult(&pt, &pt, &one, &term);
        secp256k1_num_free(&one);
        if (secp256k1_gej_is_infinity(&pt))
            ret = 0;
        secp256k1_ge_set_gej(&p, &pt);
        int oldlen = pubkeylen;
        secp256k1_ecdsa_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33);
        VERIFY_CHECK(pubkeylen == oldlen);
    }
    secp256k1_num_free(&term);
    return ret;
}
Beispiel #4
0
void test_point_times_order(const secp256k1_gej_t *point) {
    /* multiplying a point by the order results in O */
    const secp256k1_num_t *order = &secp256k1_ge_consts->order;
    secp256k1_num_t zero;
    secp256k1_num_set_int(&zero, 0);
    secp256k1_gej_t res;
    secp256k1_ecmult(&res, point, order, order); /* calc res = order * point + order * G; */
    CHECK(secp256k1_gej_is_infinity(&res));
}
static void bench_ecmult_teardown(void* arg) {
    bench_data* data = (bench_data*)arg;
    size_t iters = 1 + ITERS / data->count;
    size_t iter;
    /* Verify the results in teardown, to avoid doing comparisons while benchmarking. */
    for (iter = 0; iter < iters; ++iter) {
        secp256k1_gej tmp;
        secp256k1_gej_add_var(&tmp, &data->output[iter], &data->expected_output[iter], NULL);
        CHECK(secp256k1_gej_is_infinity(&tmp));
    }
}
Beispiel #6
0
void test_point_times_order(const secp256k1_gej_t *point) {
    // multiplying a point by the order results in O
    const secp256k1_num_t *order = &secp256k1_ge_consts->order;
    secp256k1_num_t zero;
    secp256k1_num_init(&zero);
    secp256k1_num_set_int(&zero, 0);
    secp256k1_gej_t res;
    secp256k1_ecmult(&res, point, order, order); // calc res = order * point + order * G;
    assert(secp256k1_gej_is_infinity(&res));
    secp256k1_num_free(&zero);
}
Beispiel #7
0
void test_point_times_order(const secp256k1_gej_t *point) {
    /* X * (point + G) + (order-X) * (pointer + G) = 0 */
    secp256k1_scalar_t x;
    random_scalar_order_test(&x);
    secp256k1_scalar_t nx;
    secp256k1_scalar_negate(&nx, &x);
    secp256k1_gej_t res1, res2;
    secp256k1_ecmult(&res1, point, &x, &x); /* calc res1 = x * point + x * G; */
    secp256k1_ecmult(&res2, point, &nx, &nx); /* calc res2 = (order - x) * point + (order - x) * G; */
    secp256k1_gej_add_var(&res1, &res1, &res2);
    CHECK(secp256k1_gej_is_infinity(&res1));
    CHECK(secp256k1_gej_is_valid(&res1) == 0);
    secp256k1_ge_t res3;
    secp256k1_ge_set_gej(&res3, &res1);
    CHECK(secp256k1_ge_is_infinity(&res3));
    CHECK(secp256k1_ge_is_valid(&res3) == 0);
}
Beispiel #8
0
int secp256k1_ec_pubkey_combine(const secp256k1_context* ctx, secp256k1_pubkey *pubnonce, const secp256k1_pubkey * const *pubnonces, size_t n)
{
    size_t i; secp256k1_gej Qj; secp256k1_ge Q;
    ARG_CHECK(pubnonce != NULL);
    memset(pubnonce, 0, sizeof(*pubnonce));
    ARG_CHECK(n >= 1);
    ARG_CHECK(pubnonces != NULL);
    secp256k1_gej_set_infinity(&Qj);
    for (i = 0; i < n; i++)
    {
        secp256k1_pubkey_load(ctx, &Q, pubnonces[i]);
        secp256k1_gej_add_ge(&Qj, &Qj, &Q);
    }
    if (secp256k1_gej_is_infinity(&Qj))
        return 0;
    secp256k1_ge_set_gej(&Q, &Qj);
    secp256k1_pubkey_save(pubnonce, &Q);
    return 1;
}
Beispiel #9
0
void test_ge(void) {
    char ca[135];
    char cb[68];
    int rlen;
    secp256k1_ge_t a, b, i, n;
    random_group_element_test(&a);
    random_group_element_test(&b);
    rlen = sizeof(ca);
    secp256k1_ge_get_hex(ca,&rlen,&a);
    CHECK(rlen > 4 && rlen <= (int)sizeof(ca));
    rlen = sizeof(cb);
    secp256k1_ge_get_hex(cb,&rlen,&b); /* Intentionally undersized buffer. */
    n = a;
    secp256k1_fe_normalize(&a.y);
    secp256k1_fe_negate(&n.y, &a.y, 1);
    secp256k1_ge_set_infinity(&i);
    random_field_element_magnitude(&a.x);
    random_field_element_magnitude(&a.y);
    random_field_element_magnitude(&b.x);
    random_field_element_magnitude(&b.y);
    random_field_element_magnitude(&n.x);
    random_field_element_magnitude(&n.y);

    secp256k1_gej_t aj, bj, ij, nj;
    random_group_element_jacobian_test(&aj, &a);
    random_group_element_jacobian_test(&bj, &b);
    secp256k1_gej_set_infinity(&ij);
    random_group_element_jacobian_test(&nj, &n);
    random_field_element_magnitude(&aj.x);
    random_field_element_magnitude(&aj.y);
    random_field_element_magnitude(&aj.z);
    random_field_element_magnitude(&bj.x);
    random_field_element_magnitude(&bj.y);
    random_field_element_magnitude(&bj.z);
    random_field_element_magnitude(&nj.x);
    random_field_element_magnitude(&nj.y);
    random_field_element_magnitude(&nj.z);

    /* gej + gej adds */
    secp256k1_gej_t aaj; secp256k1_gej_add_var(&aaj, &aj, &aj);
    secp256k1_gej_t abj; secp256k1_gej_add_var(&abj, &aj, &bj);
    secp256k1_gej_t aij; secp256k1_gej_add_var(&aij, &aj, &ij);
    secp256k1_gej_t anj; secp256k1_gej_add_var(&anj, &aj, &nj);
    secp256k1_gej_t iaj; secp256k1_gej_add_var(&iaj, &ij, &aj);
    secp256k1_gej_t iij; secp256k1_gej_add_var(&iij, &ij, &ij);

    /* gej + ge adds */
    secp256k1_gej_t aa; secp256k1_gej_add_ge_var(&aa, &aj, &a);
    secp256k1_gej_t ab; secp256k1_gej_add_ge_var(&ab, &aj, &b);
    secp256k1_gej_t ai; secp256k1_gej_add_ge_var(&ai, &aj, &i);
    secp256k1_gej_t an; secp256k1_gej_add_ge_var(&an, &aj, &n);
    secp256k1_gej_t ia; secp256k1_gej_add_ge_var(&ia, &ij, &a);
    secp256k1_gej_t ii; secp256k1_gej_add_ge_var(&ii, &ij, &i);

    /* const gej + ge adds */
    secp256k1_gej_t aac; secp256k1_gej_add_ge(&aac, &aj, &a);
    secp256k1_gej_t abc; secp256k1_gej_add_ge(&abc, &aj, &b);
    secp256k1_gej_t anc; secp256k1_gej_add_ge(&anc, &aj, &n);
    secp256k1_gej_t iac; secp256k1_gej_add_ge(&iac, &ij, &a);

    CHECK(secp256k1_gej_is_infinity(&an));
    CHECK(secp256k1_gej_is_infinity(&anj));
    CHECK(secp256k1_gej_is_infinity(&anc));
    gej_equals_gej(&aa, &aaj);
    gej_equals_gej(&aa, &aac);
    gej_equals_gej(&ab, &abj);
    gej_equals_gej(&ab, &abc);
    gej_equals_gej(&an, &anj);
    gej_equals_gej(&an, &anc);
    gej_equals_gej(&ia, &iaj);
    gej_equals_gej(&ai, &aij);
    gej_equals_gej(&ii, &iij);
    ge_equals_gej(&a, &ai);
    ge_equals_gej(&a, &ai);
    ge_equals_gej(&a, &iaj);
    ge_equals_gej(&a, &iaj);
    ge_equals_gej(&a, &iac);
}
Beispiel #10
0
void test_ge(void) {
    secp256k1_ge_t a, b, i, n;
    random_group_element_test(&a);
    random_group_element_test(&b);
    n = a;
    secp256k1_fe_normalize(&a.y);
    secp256k1_fe_negate(&n.y, &a.y, 1);
    secp256k1_ge_set_infinity(&i);
    random_field_element_magnitude(&a.x);
    random_field_element_magnitude(&a.y);
    random_field_element_magnitude(&b.x);
    random_field_element_magnitude(&b.y);
    random_field_element_magnitude(&n.x);
    random_field_element_magnitude(&n.y);

    secp256k1_gej_t aj, bj, ij, nj;
    random_group_element_jacobian_test(&aj, &a);
    random_group_element_jacobian_test(&bj, &b);
    secp256k1_gej_set_infinity(&ij);
    random_group_element_jacobian_test(&nj, &n);
    random_field_element_magnitude(&aj.x);
    random_field_element_magnitude(&aj.y);
    random_field_element_magnitude(&aj.z);
    random_field_element_magnitude(&bj.x);
    random_field_element_magnitude(&bj.y);
    random_field_element_magnitude(&bj.z);
    random_field_element_magnitude(&nj.x);
    random_field_element_magnitude(&nj.y);
    random_field_element_magnitude(&nj.z);

    /* gej + gej adds */
    secp256k1_gej_t aaj; secp256k1_gej_add_var(&aaj, &aj, &aj);
    secp256k1_gej_t abj; secp256k1_gej_add_var(&abj, &aj, &bj);
    secp256k1_gej_t aij; secp256k1_gej_add_var(&aij, &aj, &ij);
    secp256k1_gej_t anj; secp256k1_gej_add_var(&anj, &aj, &nj);
    secp256k1_gej_t iaj; secp256k1_gej_add_var(&iaj, &ij, &aj);
    secp256k1_gej_t iij; secp256k1_gej_add_var(&iij, &ij, &ij);

    /* gej + ge adds */
    secp256k1_gej_t aa; secp256k1_gej_add_ge_var(&aa, &aj, &a);
    secp256k1_gej_t ab; secp256k1_gej_add_ge_var(&ab, &aj, &b);
    secp256k1_gej_t ai; secp256k1_gej_add_ge_var(&ai, &aj, &i);
    secp256k1_gej_t an; secp256k1_gej_add_ge_var(&an, &aj, &n);
    secp256k1_gej_t ia; secp256k1_gej_add_ge_var(&ia, &ij, &a);
    secp256k1_gej_t ii; secp256k1_gej_add_ge_var(&ii, &ij, &i);

    /* const gej + ge adds */
    secp256k1_gej_t aac; secp256k1_gej_add_ge(&aac, &aj, &a);
    secp256k1_gej_t abc; secp256k1_gej_add_ge(&abc, &aj, &b);
    secp256k1_gej_t anc; secp256k1_gej_add_ge(&anc, &aj, &n);
    secp256k1_gej_t iac; secp256k1_gej_add_ge(&iac, &ij, &a);

    CHECK(secp256k1_gej_is_infinity(&an));
    CHECK(secp256k1_gej_is_infinity(&anj));
    CHECK(secp256k1_gej_is_infinity(&anc));
    gej_equals_gej(&aa, &aaj);
    gej_equals_gej(&aa, &aac);
    gej_equals_gej(&ab, &abj);
    gej_equals_gej(&ab, &abc);
    gej_equals_gej(&an, &anj);
    gej_equals_gej(&an, &anc);
    gej_equals_gej(&ia, &iaj);
    gej_equals_gej(&ai, &aij);
    gej_equals_gej(&ii, &iij);
    ge_equals_gej(&a, &ai);
    ge_equals_gej(&a, &ai);
    ge_equals_gej(&a, &iaj);
    ge_equals_gej(&a, &iaj);
    ge_equals_gej(&a, &iac);
}