예제 #1
0
void test_reduce_bigint(void){
	bigint_t a, b;
	cli_putstr_P(PSTR("\r\nreduce test\r\n"));
	for(;;){
		cli_putstr_P(PSTR("\r\nenter a:"));
		if(bigint_read_hex_echo(&a)){
			cli_putstr_P(PSTR("\r\n end reduce test"));
			return;
		}
		cli_putstr_P(PSTR("\r\nenter b:"));
		if(bigint_read_hex_echo(&b)){
			free(a.wordv);
			cli_putstr_P(PSTR("\r\n end reduce test"));
			return;
		}
		cli_putstr_P(PSTR("\r\n "));
		bigint_print_hex(&a);
		cli_putstr_P(PSTR(" % "));
		bigint_print_hex(&b);
		cli_putstr_P(PSTR(" = "));
		bigint_reduce(&a, &b);
		bigint_print_hex(&a);
		cli_putstr_P(PSTR("\r\n"));
		free(a.wordv);
		free(b.wordv);
	}
}
예제 #2
0
void test_sub_bigint(void){
    bigint_t a, b, c;
    printf_P(PSTR("\nadd test\n"));
    for (;;) {
        printf_P(PSTR("\nenter a:"));
        if (bigint_read_hex_echo(&a, 512)) {
            printf_P(PSTR("\n end add test"));
            return;
        }
        printf_P(PSTR("\nenter b:"));
        if (bigint_read_hex_echo(&b, 512)) {
            free(a.wordv);
            printf_P(PSTR("\n end add test"));
            return;
        }
        printf_P(PSTR("\n "));
        bigint_print_hex(&a);
        printf_P(PSTR(" - "));
        bigint_print_hex(&b);
        printf_P(PSTR(" = "));
        memset(&c, 0, sizeof(c));
        bigint_sub_u(&c, &a, &b);
        bigint_print_hex(&c);
        cli_putstr_P(PSTR("\r\n"));
        free(a.wordv);
        free(b.wordv);
        bigint_free(&c);
    }
}
예제 #3
0
void test_div_bigint(void){
    bigint_t a, b, c, d;
    printf_P(PSTR("\ndiv test\n"));
    for (;;) {
        printf_P(PSTR("\nenter a:"));
        if (bigint_read_hex_echo(&a, 0)) {
            printf_P(PSTR("\n end div test"));
            return;
        }
        printf_P(PSTR("\nenter b:"));
        if (bigint_read_hex_echo(&b, 0)) {
            free(a.wordv);
            printf_P(PSTR("\n end div test"));
            return;
        }
        printf_P(PSTR("\n "));
        bigint_print_hex(&a);
        printf_P(PSTR(" / "));
        bigint_print_hex(&b);
        printf_P(PSTR(" = "));
        memset(&c, 0, sizeof(c));
        memset(&d, 0, sizeof(d));
        bigint_divide(&d, &c, &a, &b);
        bigint_print_hex(&d);
        printf_P(PSTR("; R = "));
        bigint_print_hex(&c);
        printf_P(PSTR("\n"));
        bigint_free(&d);
        bigint_free(&c);
        bigint_free(&b);
        bigint_free(&a);
    }
}
예제 #4
0
void test_reduce_bigint(void){
	bigint_t a, b, c;
	cli_putstr_P(PSTR("\r\nreduce test\r\n"));
	for (;;) {
		cli_putstr_P(PSTR("\r\nenter a:"));
		if (bigint_read_hex_echo(&a, 0)) {
			cli_putstr_P(PSTR("\r\n end reduce test"));
			return;
		}
		cli_putstr_P(PSTR("\r\nenter b:"));
		if (bigint_read_hex_echo(&b, 0)) {
			free(a.wordv);
			cli_putstr_P(PSTR("\r\n end reduce test"));
			return;
		}
		cli_putstr_P(PSTR("\r\n "));
		bigint_print_hex(&a);
		cli_putstr_P(PSTR(" % "));
		bigint_print_hex(&b);
		cli_putstr_P(PSTR(" = "));
		memset(&c, 0, sizeof(c));
		bigint_divide(NULL, &c, &a, &b);
		bigint_print_hex(&c);
		cli_putstr_P(PSTR("\r\n"));
        bigint_free(&c);
        bigint_free(&b);
		bigint_free(&a);
	}
}
예제 #5
0
void test_add_scale_bigint(void){
	bigint_t a, b, c;
	uint16_t scale;
	cli_putstr_P(PSTR("\r\nadd-scale test\r\n"));
	for(;;){
		cli_putstr_P(PSTR("\r\nenter a:"));
		if(bigint_read_hex_echo(&a)){
			cli_putstr_P(PSTR("\r\n end add-scale test"));
			return;
		}
		cli_putstr_P(PSTR("\r\nenter b:"));
		if(bigint_read_hex_echo(&b)){
			cli_putstr_P(PSTR("\r\n end add-scale test"));
			return;
		}
		cli_putstr_P(PSTR("\r\nenter scale:"));
		{
			char str[8];
			cli_getsn_cecho(str, 7);
			scale = atoi(str);
		}
	/*
		if(bigint_read_hex_echo(&scale)){
			free(scale.wordv);
			cli_putstr_P(PSTR("\r\n end add test"));
			return;
		}
	*/
		uint8_t *c_b;
		c_b = malloc(((a.length_B>(b.length_B+scale))?a.length_B:(b.length_B+scale))+2);
		if(c_b==NULL){
			cli_putstr_P(PSTR("\n\rERROR: Out of memory!"));
			free(a.wordv);
			free(b.wordv);
			continue;
		}
		c.wordv = c_b;
		bigint_copy(&c, &a);
		bigint_add_scale_u(&c, &b, scale);
		cli_putstr_P(PSTR("\r\n "));
		bigint_print_hex(&a);
		cli_putstr_P(PSTR(" + "));
		bigint_print_hex(&b);
		cli_putstr_P(PSTR("<<8*"));
		cli_hexdump_rev(&scale, 2);
		cli_putstr_P(PSTR(" = "));
		bigint_print_hex(&c);
		cli_putstr_P(PSTR("\r\n"));
		free(a.wordv);
		free(b.wordv);
		free(c_b);
	}
}
예제 #6
0
/* d = a**b % c */
void test_expmod_bigint(void){
	bigint_t a, b, c, d;
	uint8_t *d_b;
	cli_putstr_P(PSTR("\r\nreduce test\r\n"));
	for(;;){
		cli_putstr_P(PSTR("\r\nenter a:"));
		if(bigint_read_hex_echo(&a)){
			cli_putstr_P(PSTR("\r\n end expmod test"));
			return;
		}
		cli_putstr_P(PSTR("\r\nenter b:"));
		if(bigint_read_hex_echo(&b)){
			free(a.wordv);
			cli_putstr_P(PSTR("\r\n end expmod test"));
			return;
		}
		cli_putstr_P(PSTR("\r\nenter c:"));
		if(bigint_read_hex_echo(&c)){
			free(a.wordv);
			free(b.wordv);
			cli_putstr_P(PSTR("\r\n end expmod test"));
			return;
		}
		d_b = malloc(c.length_B);
		if(d_b==NULL){
			cli_putstr_P(PSTR("\n\rERROR: Out of memory!"));
			free(a.wordv);
			free(b.wordv);
			free(c.wordv);
			continue;
		}
		d.wordv = d_b;
		cli_putstr_P(PSTR("\r\n "));
		bigint_print_hex(&a);
		cli_putstr_P(PSTR("**"));
		bigint_print_hex(&b);
		cli_putstr_P(PSTR(" % "));
		bigint_print_hex(&c);
		cli_putstr_P(PSTR(" = "));
		bigint_expmod_u(&d, &a, &b, &c);
		bigint_print_hex(&d);
		cli_putstr_P(PSTR("\r\n"));
		free(a.wordv);
		free(b.wordv);
		free(c.wordv);
		free(d.wordv);

	}
}
예제 #7
0
/* d = a**b % c */
void test_expmod_mont_bigint(void){
    bigint_t a, b, c, d;
    bigint_word_t *d_b;
    cli_putstr_P(PSTR("\r\nexpnonentiation-modulo-montgomory test\r\n"));
    for (;;) {
        cli_putstr_P(PSTR("\r\nenter a:"));
        if (bigint_read_hex_echo(&a)) {
            cli_putstr_P(PSTR("\r\n end expmod test"));
            return;
        }
        cli_putstr_P(PSTR("\r\nenter b:"));
        if (bigint_read_hex_echo(&b)) {
            free(a.wordv);
            cli_putstr_P(PSTR("\r\n end expmod test"));
            return;
        }
        cli_putstr_P(PSTR("\r\nenter c:"));
        if (bigint_read_hex_echo(&c)) {
            free(a.wordv);
            free(b.wordv);
            cli_putstr_P(PSTR("\r\n end expmod test"));
            return;
        }
        d_b = malloc(c.length_W * sizeof(bigint_word_t));
        if (d_b == NULL) {
            cli_putstr_P(PSTR("\n\rERROR: Out of memory!"));
            free(a.wordv);
            free(b.wordv);
            free(c.wordv);
            continue;
        }
        d.wordv = d_b;
        cli_putstr_P(PSTR("\r\n "));
        bigint_print_hex(&a);
        cli_putstr_P(PSTR("**"));
        bigint_print_hex(&b);
        cli_putstr_P(PSTR(" % "));
        bigint_print_hex(&c);
        cli_putstr_P(PSTR(" = "));
        bigint_expmod_u_mont_sam(&d, &a, &b, &c);
        bigint_print_hex(&d);
        cli_putstr_P(PSTR("\r\n"));
        free(a.wordv);
        free(b.wordv);
        free(c.wordv);
        free(d.wordv);

    }
}
예제 #8
0
void test_mul_mont_bigint(void){
    bigint_t a, b, c, a_, b_, m_, res;
    bigint_length_t s;
    cli_putstr_P(PSTR("\r\nmul-mont test ( (a * b) % c )\r\n"));
    for (;;) {
        cli_putstr_P(PSTR("\r\nenter a:"));
        if (bigint_read_hex_echo(&a)) {
            cli_putstr_P(PSTR("\r\n end mul test"));
            return;
        }
        cli_putstr_P(PSTR("\r\nenter b:"));
        if (bigint_read_hex_echo(&b)) {
            free(a.wordv);
            cli_putstr_P(PSTR("\r\n end mul test"));
            return;
        }
        cli_putstr_P(PSTR("\r\nenter c:"));
        if (bigint_read_hex_echo(&c)) {
            free(a.wordv);
            free(b.wordv);
            cli_putstr_P(PSTR("\r\n end mul test"));
            return;
        }
        s = c.length_W;
        cli_putstr_P(PSTR("\r\n ("));
        bigint_print_hex(&a);
        cli_putstr_P(PSTR(" * "));
        bigint_print_hex(&b);
        cli_putstr_P(PSTR(") % "));
        bigint_print_hex(&c);
        cli_putstr_P(PSTR(" = "));
        bigint_word_t res_w[s], a_w_[s], b_w_[s], m_w_[s + 1];
        res.wordv = res_w;
        a_.wordv = a_w_;
        b_.wordv = b_w_;
        m_.wordv = m_w_;
        bigint_mont_gen_m_(&m_, &c);
        bigint_mont_trans(&a_, &a, &c);
        bigint_mont_trans(&b_, &b, &c);
        bigint_mont_mul(&res, &a_, &b_, &c, &m_);
        bigint_mont_red(&res, &res, &c, &m_);
        bigint_print_hex(&res);
        putchar('\n');
        free(a.wordv);
        free(b.wordv);
        free(c.wordv);
    }
}
예제 #9
0
void test_square_bigint(void){
	bigint_t a, c;
	cli_putstr_P(PSTR("\r\nsquare test\r\n"));
	for(;;){
		cli_putstr_P(PSTR("\r\nenter a:"));
		if(bigint_read_hex_echo(&a)){
			cli_putstr_P(PSTR("\r\n end square test"));
			return;
		}
		cli_putstr_P(PSTR("\r\n "));
		bigint_print_hex(&a);
		cli_putstr_P(PSTR("**2 = "));
		uint8_t *c_b;
		c_b = malloc(a.length_B*2);
		if(c_b==NULL){
			cli_putstr_P(PSTR("\n\rERROR: Out of memory!"));
			free(a.wordv);
			continue;
		}
		c.wordv = c_b;
		bigint_square(&c, &a);
		bigint_print_hex(&c);
		cli_putstr_P(PSTR("\r\n"));
		free(a.wordv);
		free(c_b);
	}
}
예제 #10
0
void testrun_interm(void){
    ecc_chudnovsky_point_t q;
    ecc_affine_point_t qa;
    uint32_t time;
    bigint_t k;
    uint8_t r;

    printf_P(PSTR("\n== testing key generation ==\n"));

    printf_P(PSTR("enter secret key d: "));
    bigint_read_hex_echo(&k);
    putchar('\n');

    if(ecc_chudnovsky_point_alloc(&q, 192)){
        printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
        return;
    }
    if(ecc_affine_point_alloc(&qa, 192)){
        ecc_chudnovsky_point_free(&q);
        printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
        return;
    }

    printf_P(PSTR("(naf)  k:  "));
    bigint_print_hex(&k);
    startTimer(1);
    START_TIMER;
    r = ecc_chudnovsky_naf_multiplication(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
    STOP_TIMER;
    time = stopTimer();
    ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);

    printf_P(PSTR("\n  Qx: "));
    bigint_print_hex(&qa.x);
    printf_P(PSTR("\n  Qy: "));
    bigint_print_hex(&qa.y);
    printf_P(PSTR("\n time: %"PRIu32" cycles (r code: %"PRIu8")\n"), time, r);

    printf_P(PSTR("(d&a)  k:  "));
    bigint_print_hex(&k);
    startTimer(1);
    START_TIMER;
    r = ecc_chudnovsky_double_and_add(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
    STOP_TIMER;
    time = stopTimer();
    ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);

    printf_P(PSTR("\n  Qx: "));
    bigint_print_hex(&qa.x);
    printf_P(PSTR("\n  Qy: "));
    bigint_print_hex(&qa.y);
    printf_P(PSTR("\n time: %"PRIu32" cycles (r code: %"PRIu8")\n"), time, r);
    free(k.wordv);
    ecc_chudnovsky_point_free(&q);
    ecc_affine_point_free(&qa);
}
예제 #11
0
void test_mul_word_bigint(void){
    bigint_t a, b;
    bigint_word_t *t;
    cli_putstr_P(PSTR("\r\nmul test\r\n"));
    for (;;) {
        cli_putstr_P(PSTR("\r\nenter a:"));
        if (bigint_read_hex_echo(&a, 0)) {
            cli_putstr_P(PSTR("\r\n end mul test"));
            return;
        }
        cli_putstr_P(PSTR("\r\nenter b:"));
        if (bigint_read_hex_echo(&b, 0)) {
            free(a.wordv);
            cli_putstr_P(PSTR("\r\n end mul test"));
            return;
        }
        cli_putstr_P(PSTR("\r\n "));
        bigint_print_hex(&a);
        cli_putstr_P(PSTR(" * "));
        bigint_print_hex(&b);
        cli_putstr_P(PSTR(" = "));

        if (b.length_W > 1) {
            free(a.wordv);
            free(b.wordv);
            cli_putstr_P(PSTR("\r\n end mul test"));
        }

        t = realloc(a.wordv, (a.length_W + 3) * sizeof(bigint_word_t));
        if (t == NULL) {
            cli_putstr_P(PSTR("\n\rERROR: Out of memory!"));
            free(a.wordv);
            free(b.wordv);
            continue;
        }
        a.wordv = t;
        bigint_mul_word(&a, &a, b.wordv[0]);
        bigint_print_hex(&a);
        cli_putstr_P(PSTR("\r\n"));
        free(a.wordv);
        free(b.wordv);
    }
}
예제 #12
0
void test_gcdext_bigint(void){
	bigint_t a, b, c, d, e;
	cli_putstr_P(PSTR("\r\ngcdext test\r\n"));
	for (;;) {
		cli_putstr_P(PSTR("\r\nenter a:"));
		if (bigint_read_hex_echo(&a, 0)) {
			cli_putstr_P(PSTR("\r\n end gcdext test"));
			return;
		}
		cli_putstr_P(PSTR("\r\nenter b:"));
		if (bigint_read_hex_echo(&b, 0)) {
			bigint_free(&a);
			cli_putstr_P(PSTR("\r\n end gcdext test"));
			return;
		}

		memset(&c, 0, sizeof(c));
        memset(&d, 0, sizeof(d));
        memset(&e, 0, sizeof(e));
		cli_putstr_P(PSTR("\r\n gcdext( "));
		bigint_print_hex(&a);
		cli_putstr_P(PSTR(", "));
		bigint_print_hex(&b);
		cli_putstr_P(PSTR(") => "));
		bigint_gcdext(&c, &d, &e, &a, &b);
		cli_putstr_P(PSTR("a = "));
		bigint_print_hex(&d);
		cli_putstr_P(PSTR("; b = "));
		bigint_print_hex(&e);
		cli_putstr_P(PSTR("; gcd = "));
		bigint_print_hex(&c);

		cli_putstr_P(PSTR("\r\n"));
		bigint_free(&a);
        bigint_free(&b);
        bigint_free(&c);
        bigint_free(&d);
        bigint_free(&e);
	}
}
예제 #13
0
void test_gcdext_bigint(void){
	bigint_t a, b, c, d, e;
	cli_putstr_P(PSTR("\r\ngcdext test\r\n"));
	for(;;){
		cli_putstr_P(PSTR("\r\nenter a:"));
		if(bigint_read_hex_echo(&a)){
			cli_putstr_P(PSTR("\r\n end gcdext test"));
			return;
		}
		cli_putstr_P(PSTR("\r\nenter b:"));
		if(bigint_read_hex_echo(&b)){
			free(a.wordv);
			cli_putstr_P(PSTR("\r\n end gcdext test"));
			return;
		}
		c.wordv = malloc((a.length_B<b.length_B)?a.length_B:b.length_B);
		d.wordv = malloc(1+(a.length_B>b.length_B)?a.length_B:b.length_B);
		e.wordv = malloc(1+(a.length_B>b.length_B)?a.length_B:b.length_B);

		cli_putstr_P(PSTR("\r\n gcdext( "));
		bigint_print_hex(&a);
		cli_putstr_P(PSTR(", "));
		bigint_print_hex(&b);
		cli_putstr_P(PSTR(") => "));
		bigint_gcdext(&c, &d, &e, &a, &b);
		cli_putstr_P(PSTR("a = "));
		bigint_print_hex(&d);
		cli_putstr_P(PSTR("; b = "));
		bigint_print_hex(&e);
		cli_putstr_P(PSTR("; gcd = "));
		bigint_print_hex(&c);

		cli_putstr_P(PSTR("\r\n"));
		free(a.wordv);
		free(b.wordv);
		free(c.wordv);
		free(d.wordv);
		free(e.wordv);
	}
}
예제 #14
0
void test_mul_bigint(void){
	bigint_t a, b, c;
	cli_putstr_P(PSTR("\r\nmul test\r\n"));
	for (;;) {
		cli_putstr_P(PSTR("\r\nenter a:"));
		if (bigint_read_hex_echo(&a, 0)) {
			cli_putstr_P(PSTR("\r\n end mul test"));
			return;
		}
		cli_putstr_P(PSTR("\r\nenter b:"));
		if (bigint_read_hex_echo(&b, 0)) {
			free(a.wordv);
			cli_putstr_P(PSTR("\r\n end mul test"));
			return;
		}
		cli_putstr_P(PSTR("\r\n "));
		bigint_print_hex(&a);
		cli_putstr_P(PSTR(" * "));
		bigint_print_hex(&b);
		cli_putstr_P(PSTR(" = "));
		bigint_word_t *c_b;
		c_b = malloc((MAX(a.length_W, b.length_W) + 1) * 2 * sizeof(bigint_word_t));
		if (c_b==NULL) {
			cli_putstr_P(PSTR("\n\rERROR: Out of memory!"));
			free(a.wordv);
			free(b.wordv);
			continue;
		}
		c.wordv = c_b;
		bigint_mul_schoolbook(&c, &a, &b);
		bigint_print_hex(&c);
		cli_putstr_P(PSTR("\r\n"));
		free(a.wordv);
		free(b.wordv);
		free(c_b);
	}
}
예제 #15
0
void test_add_bigint(void){
	bigint_t a, b, c;
	cli_putstr_P(PSTR("\r\nadd test\r\n"));
	for(;;){
		cli_putstr_P(PSTR("\r\nenter a:"));
		if(bigint_read_hex_echo(&a)){
			cli_putstr_P(PSTR("\r\n end add test"));
			return;
		}
		cli_putstr_P(PSTR("\r\nenter b:"));
		if(bigint_read_hex_echo(&b)){
			free(a.wordv);
			cli_putstr_P(PSTR("\r\n end add test"));
			return;
		}
		cli_putstr_P(PSTR("\r\n "));
		bigint_print_hex(&a);
		cli_putstr_P(PSTR(" + "));
		bigint_print_hex(&b);
		cli_putstr_P(PSTR(" = "));
		uint8_t *c_b;
		c_b = malloc(((a.length_B>b.length_B)?a.length_B:b.length_B)+2);
		if(c_b==NULL){
			cli_putstr_P(PSTR("\n\rERROR: Out of memory!"));
			free(a.wordv);
			free(b.wordv);
			continue;
		}
		c.wordv = c_b;
		bigint_add_s(&c, &a, &b);
		bigint_print_hex(&c);
		cli_putstr_P(PSTR("\r\n"));
		free(a.wordv);
		free(b.wordv);
		free(c_b);
	}
}
예제 #16
0
/*****************************************************************************
 *  additional validation-functions											 *
 *****************************************************************************/
void test_echo_bigint(void){
	bigint_t a;
	cli_putstr_P(PSTR("\r\necho test\r\n"));
	for(;;){
		cli_putstr_P(PSTR("\r\nenter hex number:"));
		if(bigint_read_hex_echo(&a)){
			cli_putstr_P(PSTR("\r\n end echo test"));
			return;
		}
		cli_putstr_P(PSTR("\r\necho: "));
		bigint_print_hex(&a);
		cli_putstr_P(PSTR("\r\n"));
		free(a.wordv);
	}
}
예제 #17
0
void testrun_genkey1(void){
    ecc_chudnovsky_point_t q;
    ecc_affine_point_t qa;

    uint8_t k_w[] = {
    //  e5ce89a34adddf25ff3bf1ffe6803f57d0220de3118798ea
        0xea, 0x98, 0x87, 0x11, 0xe3, 0x0d, 0x22, 0xd0,
        0x57, 0x3f, 0x80, 0xe6, 0xff, 0xf1, 0x3b, 0xff,
        0x25, 0xdf, 0xdd, 0x4a, 0xa3, 0x89, 0xce, 0xe5
    };

    bigint_t k = {
            .length_W = sizeof(k_w),
            .wordv = k_w,
            .info = 7
    };

    printf_P(PSTR("\n== testing key generation ==\n"));

    if(ecc_chudnovsky_point_alloc(&q, 192)){
        printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
        return;
    }
    if(ecc_affine_point_alloc(&qa, 192)){
        printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
        return;
    }

    printf_P(PSTR("  k:  "));
    bigint_print_hex(&k);
    ecc_chudnovsky_multiplication(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
    ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);

    printf_P(PSTR("\n  Qx: "));
    bigint_print_hex(&qa.x);
    printf_P(PSTR("\n  Qy: "));
    bigint_print_hex(&qa.y);
    puts("\n");

    ecc_affine_point_free(&qa);
    ecc_chudnovsky_point_free(&q);
}

void testrun_genkey3(void){
    ecc_chudnovsky_point_t q;
    ecc_affine_point_t qa;

    uint8_t k_w[] = {
        0xb2, 0x51, 0x97, 0xc3, 0x7c, 0x61, 0xf8, 0x8f,
        0x19, 0x91, 0xcc, 0x67, 0xb5, 0x1c, 0x34, 0x23,
        0xff, 0x13, 0xad, 0x14, 0x57, 0x43, 0x14, 0x7d
    };

    bigint_t k = {
            .length_W = sizeof(k_w),
            .wordv = k_w,
            .info = 6
    };

    printf_P(PSTR("\n== testing key generation ==\n"));

    if(ecc_chudnovsky_point_alloc(&q, 192)){
        printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
        return;
    }
    if(ecc_affine_point_alloc(&qa, 192)){
        printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
        return;
    }

    printf_P(PSTR("  k:  "));
    bigint_print_hex(&k);
    ecc_chudnovsky_double_and_add(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
    ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);

    printf_P(PSTR("\n  Qx: "));
    bigint_print_hex(&qa.x);
    printf_P(PSTR("\n  Qy: "));
    bigint_print_hex(&qa.y);
    puts("\n");

    ecc_affine_point_free(&qa);
    ecc_chudnovsky_point_free(&q);

}

void testrun_genkey(void){
    ecc_chudnovsky_point_t q;
    ecc_affine_point_t qa;
    uint32_t time;
    bigint_t k;
    uint8_t r;

    printf_P(PSTR("\n== testing key generation ==\n"));

    printf_P(PSTR("enter secret key d: "));
    bigint_read_hex_echo(&k);
    putchar('\n');

    if(ecc_chudnovsky_point_alloc(&q, 192)){
        printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
        return;
    }
    if(ecc_affine_point_alloc(&qa, 192)){
        ecc_chudnovsky_point_free(&q);
        printf_P(PSTR("ERROR: OOM! <%s %s %d>\n"), __FILE__, __func__, __LINE__);
        return;
    }

    printf_P(PSTR("(naf)  k:  "));
    bigint_print_hex(&k);
    startTimer(1);
    START_TIMER;
    r = ecc_chudnovsky_naf_multiplication(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
    STOP_TIMER;
    time = stopTimer();
    ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);

    printf_P(PSTR("\n  Qx: "));
    bigint_print_hex(&qa.x);
    printf_P(PSTR("\n  Qy: "));
    bigint_print_hex(&qa.y);
    printf_P(PSTR("\n time: %"PRIu32" cycles (r code: %"PRIu8")\n"), time, r);

    printf_P(PSTR("(d&a)  k:  "));
    bigint_print_hex(&k);
    startTimer(1);
    START_TIMER;
    r = ecc_chudnovsky_double_and_add(&q, &k, &nist_curve_p192_basepoint.chudnovsky, &nist_curve_p192);
    STOP_TIMER;
    time = stopTimer();
    ecc_chudnovsky_to_affine_point(&qa, &q, &nist_curve_p192);

    printf_P(PSTR("\n  Qx: "));
    bigint_print_hex(&qa.x);
    printf_P(PSTR("\n  Qy: "));
    bigint_print_hex(&qa.y);
    printf_P(PSTR("\n time: %"PRIu32" cycles (r code: %"PRIu8")\n"), time, r);
    free(k.wordv);
    ecc_chudnovsky_point_free(&q);
    ecc_affine_point_free(&qa);
}