Example #1
0
void run_ecmult_chain(void) {
    /* random starting point A (on the curve) */
    secp256k1_fe_t ax; secp256k1_fe_set_hex(&ax, "8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004", 64);
    secp256k1_fe_t ay; secp256k1_fe_set_hex(&ay, "a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f", 64);
    secp256k1_gej_t a; secp256k1_gej_set_xy(&a, &ax, &ay);
    /* two random initial factors xn and gn */
    secp256k1_num_t xn;
    secp256k1_num_set_hex(&xn, "84cc5452f7fde1edb4d38a8ce9b1b84ccef31f146e569be9705d357a42985407", 64);
    secp256k1_num_t gn;
    secp256k1_num_set_hex(&gn, "a1e58d22553dcd42b23980625d4c57a96e9323d42b3152e5ca2c3990edc7c9de", 64);
    /* two small multipliers to be applied to xn and gn in every iteration: */
    secp256k1_num_t xf;
    secp256k1_num_set_hex(&xf, "1337", 4);
    secp256k1_num_t gf;
    secp256k1_num_set_hex(&gf, "7113", 4);
    /* accumulators with the resulting coefficients to A and G */
    secp256k1_num_t ae;
    secp256k1_num_set_int(&ae, 1);
    secp256k1_num_t ge;
    secp256k1_num_set_int(&ge, 0);
    /* the point being computed */
    secp256k1_gej_t x = a;
    const secp256k1_num_t *order = &secp256k1_ge_consts->order;
    for (int i=0; i<200*count; i++) {
        /* in each iteration, compute X = xn*X + gn*G; */
        secp256k1_ecmult(&x, &x, &xn, &gn);
        /* also compute ae and ge: the actual accumulated factors for A and G */
        /* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */
        secp256k1_num_mod_mul(&ae, &ae, &xn, order);
        secp256k1_num_mod_mul(&ge, &ge, &xn, order);
        secp256k1_num_add(&ge, &ge, &gn);
        secp256k1_num_mod(&ge, order);
        /* modify xn and gn */
        secp256k1_num_mod_mul(&xn, &xn, &xf, order);
        secp256k1_num_mod_mul(&gn, &gn, &gf, order);

        /* verify */
        if (i == 19999) {
            char res[132]; int resl = 132;
            secp256k1_gej_get_hex(res, &resl, &x);
            CHECK(strcmp(res, "(D6E96687F9B10D092A6F35439D86CEBEA4535D0D409F53586440BD74B933E830,B95CBCA2C77DA786539BE8FD53354D2D3B4F566AE658045407ED6015EE1B2A88)") == 0);
        }
    }
    /* redo the computation, but directly with the resulting ae and ge coefficients: */
    secp256k1_gej_t x2; secp256k1_ecmult(&x2, &a, &ae, &ge);
    char res[132]; int resl = 132;
    char res2[132]; int resl2 = 132;
    secp256k1_gej_get_hex(res, &resl, &x);
    secp256k1_gej_get_hex(res2, &resl2, &x2);
    CHECK(strcmp(res, res2) == 0);
    CHECK(strlen(res) == 131);
}
Example #2
0
int secp256k1_ecdsa_pubkey_tweak_mul(unsigned char *pubkey, int pubkeylen, const unsigned char *tweak) {
    int ret = 1;
    secp256k1_num_t factor;
    secp256k1_num_init(&factor);
    secp256k1_num_set_bin(&factor, tweak, 32);
    if (secp256k1_num_is_zero(&factor))
        ret = 0;
    if (secp256k1_num_cmp(&factor, &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_num_t zero;
        secp256k1_num_init(&zero);
        secp256k1_num_set_int(&zero, 0);
        secp256k1_gej_t pt;
        secp256k1_gej_set_ge(&pt, &p);
        secp256k1_ecmult(&pt, &pt, &factor, &zero);
        secp256k1_num_free(&zero);
        secp256k1_ge_set_gej(&p, &pt);
        int oldlen = pubkeylen;
        secp256k1_ecdsa_pubkey_serialize(&p, pubkey, &pubkeylen, oldlen <= 33);
        assert(pubkeylen == oldlen);
    }
    secp256k1_num_free(&factor);
    return ret;
}
Example #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;
}
Example #4
0
static void run_test(bench_data* data, size_t count, int includes_g) {
    char str[32];
    static const secp256k1_scalar zero = SECP256K1_SCALAR_CONST(0, 0, 0, 0, 0, 0, 0, 0);
    size_t iters = 1 + ITERS / count;
    size_t iter;

    data->count = count;
    data->includes_g = includes_g;

    /* Compute (the negation of) the expected results directly. */
    data->offset1 = (data->count * 0x537b7f6f + 0x8f66a481) % POINTS;
    data->offset2 = (data->count * 0x7f6f537b + 0x6a1a8f49) % POINTS;
    for (iter = 0; iter < iters; ++iter) {
        secp256k1_scalar tmp;
        secp256k1_scalar total = data->scalars[(data->offset1++) % POINTS];
        size_t i = 0;
        for (i = 0; i + 1 < count; ++i) {
            secp256k1_scalar_mul(&tmp, &data->seckeys[(data->offset2++) % POINTS], &data->scalars[(data->offset1++) % POINTS]);
            secp256k1_scalar_add(&total, &total, &tmp);
        }
        secp256k1_scalar_negate(&total, &total);
        secp256k1_ecmult(&data->ctx->ecmult_ctx, &data->expected_output[iter], NULL, &zero, &total);
    }

    /* Run the benchmark. */
    sprintf(str, includes_g ? "ecmult_%ig" : "ecmult_%i", (int)count);
    run_benchmark(str, bench_ecmult, bench_ecmult_setup, bench_ecmult_teardown, data, 10, count * (1 + ITERS / count));
}
Example #5
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);
}
Example #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_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));
}
Example #7
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);
}
void test_exhaustive_ecmult(const secp256k1_context *ctx, const secp256k1_ge *group, const secp256k1_gej *groupj, int order) {
    int i, j, r_log;
    for (r_log = 1; r_log < order; r_log++) {
        for (j = 0; j < order; j++) {
            for (i = 0; i < order; i++) {
                secp256k1_gej tmp;
                secp256k1_scalar na, ng;
                secp256k1_scalar_set_int(&na, i);
                secp256k1_scalar_set_int(&ng, j);

                secp256k1_ecmult(&ctx->ecmult_ctx, &tmp, &groupj[r_log], &na, &ng);
                ge_equals_gej(&group[(i * r_log + j) % order], &tmp);

                if (i > 0) {
                    secp256k1_ecmult_const(&tmp, &group[i], &ng, 256);
                    ge_equals_gej(&group[(i * j) % order], &tmp);
                }
            }
        }
    }
}
Example #9
0
void run_ecmult_chain(void) {
    /* random starting point A (on the curve) */
    secp256k1_fe_t ax; VERIFY_CHECK(secp256k1_fe_set_hex(&ax, "8b30bbe9ae2a990696b22f670709dff3727fd8bc04d3362c6c7bf458e2846004", 64));
    secp256k1_fe_t ay; VERIFY_CHECK(secp256k1_fe_set_hex(&ay, "a357ae915c4a65281309edf20504740f0eb3343990216b4f81063cb65f2f7e0f", 64));
    secp256k1_gej_t a; secp256k1_gej_set_xy(&a, &ax, &ay);
    /* two random initial factors xn and gn */
    static const unsigned char xni[32] = {
        0x84, 0xcc, 0x54, 0x52, 0xf7, 0xfd, 0xe1, 0xed,
        0xb4, 0xd3, 0x8a, 0x8c, 0xe9, 0xb1, 0xb8, 0x4c,
        0xce, 0xf3, 0x1f, 0x14, 0x6e, 0x56, 0x9b, 0xe9,
        0x70, 0x5d, 0x35, 0x7a, 0x42, 0x98, 0x54, 0x07
    };
    secp256k1_scalar_t xn;
    secp256k1_scalar_set_b32(&xn, xni, NULL);
    static const unsigned char gni[32] = {
        0xa1, 0xe5, 0x8d, 0x22, 0x55, 0x3d, 0xcd, 0x42,
        0xb2, 0x39, 0x80, 0x62, 0x5d, 0x4c, 0x57, 0xa9,
        0x6e, 0x93, 0x23, 0xd4, 0x2b, 0x31, 0x52, 0xe5,
        0xca, 0x2c, 0x39, 0x90, 0xed, 0xc7, 0xc9, 0xde
    };
    secp256k1_scalar_t gn;
    secp256k1_scalar_set_b32(&gn, gni, NULL);
    /* two small multipliers to be applied to xn and gn in every iteration: */
    static const unsigned char xfi[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x13,0x37};
    secp256k1_scalar_t xf;
    secp256k1_scalar_set_b32(&xf, xfi, NULL);
    static const unsigned char gfi[32] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0x71,0x13};
    secp256k1_scalar_t gf;
    secp256k1_scalar_set_b32(&gf, gfi, NULL);
    /* accumulators with the resulting coefficients to A and G */
    secp256k1_scalar_t ae;
    secp256k1_scalar_set_int(&ae, 1);
    secp256k1_scalar_t ge;
    secp256k1_scalar_set_int(&ge, 0);
    /* the point being computed */
    secp256k1_gej_t x = a;
    for (int i=0; i<200*count; i++) {
        /* in each iteration, compute X = xn*X + gn*G; */
        secp256k1_ecmult(&x, &x, &xn, &gn);
        /* also compute ae and ge: the actual accumulated factors for A and G */
        /* if X was (ae*A+ge*G), xn*X + gn*G results in (xn*ae*A + (xn*ge+gn)*G) */
        secp256k1_scalar_mul(&ae, &ae, &xn);
        secp256k1_scalar_mul(&ge, &ge, &xn);
        secp256k1_scalar_add(&ge, &ge, &gn);
        /* modify xn and gn */
        secp256k1_scalar_mul(&xn, &xn, &xf);
        secp256k1_scalar_mul(&gn, &gn, &gf);

        /* verify */
        if (i == 19999) {
            char res[132]; int resl = 132;
            secp256k1_gej_get_hex(res, &resl, &x);
            CHECK(strcmp(res, "(D6E96687F9B10D092A6F35439D86CEBEA4535D0D409F53586440BD74B933E830,B95CBCA2C77DA786539BE8FD53354D2D3B4F566AE658045407ED6015EE1B2A88)") == 0);
        }
    }
    /* redo the computation, but directly with the resulting ae and ge coefficients: */
    secp256k1_gej_t x2; secp256k1_ecmult(&x2, &a, &ae, &ge);
    char res[132]; int resl = 132;
    char res2[132]; int resl2 = 132;
    secp256k1_gej_get_hex(res, &resl, &x);
    secp256k1_gej_get_hex(res2, &resl2, &x2);
    CHECK(strcmp(res, res2) == 0);
    CHECK(strlen(res) == 131);
}