void fb_poly_set_trino(int a) { fb_t f; fb_null(f); TRY { poly_a = a; poly_b = poly_c = 0; pos_a = poly_a >> FB_DIG_LOG; pos_b = pos_c = -1; fb_new(f); fb_zero(f); fb_set_bit(f, FB_BITS, 1); fb_set_bit(f, a, 1); fb_set_bit(f, 0, 1); fb_poly_set(f); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fb_free(f); } }
void fb_poly_set_penta(int a, int b, int c) { fb_t f; fb_null(f); TRY { fb_new(f); poly_a = a; poly_b = b; poly_c = c; pos_a = poly_a >> FB_DIG_LOG; pos_b = poly_b >> FB_DIG_LOG; pos_c = poly_c >> FB_DIG_LOG; fb_zero(f); fb_set_bit(f, FB_BITS, 1); fb_set_bit(f, a, 1); fb_set_bit(f, b, 1); fb_set_bit(f, c, 1); fb_set_bit(f, 0, 1); fb_poly_set(f); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fb_free(f); } }
void fb_poly_set_penta(int a, int b, int c) { fb_t f; ctx_t *ctx = core_get(); fb_null(f); TRY { fb_new(f); ctx->fb_pa = a; ctx->fb_pb = b; ctx->fb_pc = c; ctx->fb_na = ctx->fb_pa >> FB_DIG_LOG; ctx->fb_nb = ctx->fb_pb >> FB_DIG_LOG; ctx->fb_nc = ctx->fb_pc >> FB_DIG_LOG; fb_zero(f); fb_set_bit(f, FB_BITS, 1); fb_set_bit(f, a, 1); fb_set_bit(f, b, 1); fb_set_bit(f, c, 1); fb_set_bit(f, 0, 1); fb_poly_set(f); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fb_free(f); } }
void fb_poly_set_trino(int a) { fb_t f; ctx_t *ctx = core_get(); fb_null(f); TRY { ctx->fb_pa = a; ctx->fb_pb = ctx->fb_pc = 0; ctx->fb_na = ctx->fb_pa >> FB_DIG_LOG; ctx->fb_nb = ctx->fb_nc = -1; fb_new(f); fb_zero(f); fb_set_bit(f, FB_BITS, 1); fb_set_bit(f, a, 1); fb_set_bit(f, 0, 1); fb_poly_set(f); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fb_free(f); } }
/** * Precomputes half-traces for z^i with odd i. * * @throw ERR_NO_MEMORY if there is no available memory. */ static void find_solve() { int i, j, k, l; fb_t t0; fb_null(t0); TRY { fb_new(t0); l = 0; for (i = 0; i < FB_BITS; i += 8, l++) { for (j = 0; j < 16; j++) { fb_zero(t0); for (k = 0; k < 4; k++) { if (j & (1 << k)) { fb_set_bit(t0, i + 2 * k + 1, 1); } } fb_copy(fb_half[l][j], t0); for (k = 0; k < (FB_BITS - 1) / 2; k++) { fb_sqr(fb_half[l][j], fb_half[l][j]); fb_sqr(fb_half[l][j], fb_half[l][j]); fb_add(fb_half[l][j], fb_half[l][j], t0); } } fb_rsh(fb_half[l][j], fb_half[l][j], 1); } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fb_free(t0); } }
/** * Find non-zero bits for fast trace computation. * * @throw ERR_NO_MEMORY if there is no available memory. * @throw ERR_NO_VALID if the polynomial is invalid. */ static void find_trace() { fb_t t0, t1; int counter; ctx_t *ctx = core_get(); fb_null(t0); fb_null(t1); ctx->fb_ta = ctx->fb_tb = ctx->fb_tc = -1; TRY { fb_new(t0); fb_new(t1); counter = 0; for (int i = 0; i < FB_BITS; i++) { fb_zero(t0); fb_set_bit(t0, i, 1); fb_copy(t1, t0); for (int j = 1; j < FB_BITS; j++) { fb_sqr(t1, t1); fb_add(t0, t0, t1); } if (!fb_is_zero(t0)) { switch (counter) { case 0: ctx->fb_ta = i; ctx->fb_tb = ctx->fb_tc = -1; break; case 1: ctx->fb_tb = i; ctx->fb_tc = -1; break; case 2: ctx->fb_tc = i; break; default: THROW(ERR_NO_VALID); break; } counter++; } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fb_free(t0); fb_free(t1); } }
/** * Find non-zero bits for fast trace computation. * * @throw ERR_NO_MEMORY if there is no available memory. * @throw ERR_INVALID if the polynomial is invalid. */ static void find_trace() { fb_t t0, t1; int i, j, counter; fb_null(t0); fb_null(t1); trc_a = trc_b = trc_c = -1; TRY { fb_new(t0); fb_new(t1); counter = 0; for (i = 0; i < FB_BITS; i++) { fb_zero(t0); fb_set_bit(t0, i, 1); fb_copy(t1, t0); for (j = 1; j < FB_BITS; j++) { fb_sqr(t1, t1); fb_add(t0, t0, t1); } if (!fb_is_zero(t0)) { switch (counter) { case 0: trc_a = i; trc_b = trc_c = -1; break; case 1: trc_b = i; trc_c = -1; break; case 2: trc_c = i; break; default: THROW(ERR_INVALID); break; } counter++; } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fb_free(t0); fb_free(t1); } }
void eb_read_bin(eb_t a, const uint8_t *bin, int len) { if (len == 1) { if (bin[0] == 0) { eb_set_infty(a); return; } else { THROW(ERR_NO_BUFFER); return; } } if (len != (FB_BYTES + 1) && len != (2 * FB_BYTES + 1)) { THROW(ERR_NO_BUFFER); return; } a->norm = 1; fb_set_dig(a->z, 1); fb_read_bin(a->x, bin + 1, FB_BYTES); if (len == FB_BYTES + 1) { switch(bin[0]) { case 2: fb_zero(a->y); break; case 3: fb_zero(a->y); fb_set_bit(a->y, 0, 1); break; default: THROW(ERR_NO_VALID); break; } eb_upk(a, a); } if (len == 2 * FB_BYTES + 1) { if (bin[0] == 4) { fb_read_bin(a->y, bin + FB_BYTES + 1, FB_BYTES); } else { THROW(ERR_NO_VALID); } } }
/** * Multiplies and adds two binary elliptic curve points simultaneously, * optionally choosing the first point as the generator depending on an optional * table of precomputed points. * * @param[out] r - the result. * @param[in] p - the first point to multiply. * @param[in] k - the first integer. * @param[in] q - the second point to multiply. * @param[in] m - the second integer. * @param[in] t - the pointer to a precomputed table. */ static void eb_mul_sim_kbltz(eb_t r, const eb_t p, const bn_t k, const eb_t q, const bn_t m, const eb_t *t) { int l0, l1, l, i, n0, n1, w, g; int8_t u, tnaf0[FB_BITS + 8], tnaf1[FB_BITS + 8], *_k, *_m; eb_t t0[1 << (EB_WIDTH - 2)]; eb_t t1[1 << (EB_WIDTH - 2)]; bn_t vm, s0, s1; bn_null(vm); bn_null(s0); bn_null(s1); for (i = 0; i < (1 << (EB_WIDTH - 2)); i++) { eb_null(t0[i]); eb_null(t1[i]); } TRY { bn_new(vm); bn_new(s0); bn_new(s1); /* Compute the w-TNAF representation of k. */ if (eb_curve_opt_a() == OPT_ZERO) { u = -1; } else { u = 1; } g = (t == NULL ? 0 : 1); if (!g) { for (i = 0; i < (1 << (EB_WIDTH - 2)); i++) { eb_new(t0[i]); eb_set_infty(t0[i]); fb_set_bit(t0[i]->z, 0, 1); t0[i]->norm = 1; } eb_tab(t0, p, EB_WIDTH); t = (const eb_t *)t0; } /* Prepare the precomputation table. */ for (i = 0; i < (1 << (EB_WIDTH - 2)); i++) { eb_new(t1[i]); eb_set_infty(t1[i]); fb_set_bit(t1[i]->z, 0, 1); t1[i]->norm = 1; } /* Compute the precomputation table. */ eb_tab(t1, q, EB_WIDTH); /* Compute the w-TNAF representation of k. */ if (g) { w = EB_DEPTH; } else { w = EB_WIDTH; } eb_curve_get_vm(vm); eb_curve_get_s0(s0); eb_curve_get_s1(s1); l0 = l1 = FB_BITS + 8; bn_rec_tnaf(tnaf0, &l0, k, vm, s0, s1, u, FB_BITS, w); bn_rec_tnaf(tnaf1, &l1, m, vm, s0, s1, u, FB_BITS, EB_WIDTH); l = MAX(l0, l1); _k = tnaf0 + l - 1; _m = tnaf1 + l - 1; for (i = l0; i < l; i++) tnaf0[i] = 0; for (i = l1; i < l; i++) tnaf1[i] = 0; _k = tnaf0 + l - 1; _m = tnaf1 + l - 1; eb_set_infty(r); for (i = l - 1; i >= 0; i--, _k--, _m--) { eb_frb(r, r); n0 = *_k; n1 = *_m; if (n0 > 0) { eb_add(r, r, t[n0 / 2]); } if (n0 < 0) { eb_sub(r, r, t[-n0 / 2]); } if (n1 > 0) { eb_add(r, r, t1[n1 / 2]); } if (n1 < 0) { eb_sub(r, r, t1[-n1 / 2]); } } /* Convert r to affine coordinates. */ eb_norm(r, r); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { if (!g) { for (i = 0; i < (1 << (EB_WIDTH - 2)); i++) { eb_free(t0[i]); } } for (i = 0; i < (1 << (EB_WIDTH - 2)); i++) { eb_free(t1[i]); } bn_free(vm); bn_free(s0); bn_free(s1); } }
void eb_param_set(int param) { char str[2 * FB_BYTES + 1]; fb_t a, b; eb_t g; bn_t r; bn_t h; fb_null(a); fb_null(b); eb_null(g); bn_null(r); bn_null(h); TRY { fb_new(a); fb_new(b); eb_new(g); bn_new(r); bn_new(h); core_get()->eb_id = 0; switch (param) { #if defined(EB_PLAIN) && FB_POLYN == 163 case NIST_B163: ASSIGN(NIST_B163, NIST_163); break; #endif #if defined(EB_KBLTZ) && FB_POLYN == 163 case NIST_K163: ASSIGN(NIST_K163, NIST_163); break; #endif #if defined(EB_PLAIN) && FB_POLYN == 233 case NIST_B233: ASSIGN(NIST_B233, NIST_233); break; #endif #if defined(EB_KBLTZ) && FB_POLYN == 233 case NIST_K233: ASSIGN(NIST_K233, NIST_233); break; #endif #if defined(EB_KBLTZ) && FB_POLYN == 239 case SECG_K239: ASSIGN(SECG_K239, SECG_239); break; #endif #if defined(EB_PLAIN) && FB_POLYN == 251 case EBACS_B251: ASSIGN(EBACS_B251, PENTA_251); break; #endif #if defined(EB_PLAIN) && FB_POLYN == 257 case HALVE_B257: ASSIGN(HALVE_B257, TRINO_257); break; #endif #if defined(EB_PLAIN) && FB_POLYN == 283 case NIST_B283: ASSIGN(NIST_B283, NIST_283); break; #endif #if defined(EB_KBLTZ) && FB_POLYN == 283 case NIST_K283: ASSIGN(NIST_K283, NIST_283); break; #endif #if defined(EB_PLAIN) && FB_POLYN == 409 case NIST_B409: ASSIGN(NIST_B409, NIST_409); break; #endif #if defined(EB_KBLTZ) && FB_POLYN == 409 case NIST_K409: ASSIGN(NIST_K409, NIST_409); break; #endif #if defined(EB_PLAIN) && FB_POLYN == 571 case NIST_B571: ASSIGN(NIST_B571, NIST_571); break; #endif #if defined(EB_KBLTZ) && FB_POLYN == 571 case NIST_K571: ASSIGN(NIST_K571, NIST_571); break; #endif default: (void)str; THROW(ERR_NO_VALID); break; } fb_zero(g->z); fb_set_bit(g->z, 0, 1); g->norm = 1; eb_curve_set(a, b, g, r, h); core_get()->eb_id = param; } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fb_free(a); fb_free(b); eb_free(g); bn_free(r); bn_free(h); } }
void eb_param_set(int param) { int super = 0; int ordin = 0; int kbltz = 0; char str[2 * FB_BYTES + 1]; fb_t a, b, c; eb_t g; bn_t r; bn_t h; fb_null(a); fb_null(b); fb_null(c); eb_null(g); bn_null(r); bn_null(h); TRY { fb_new(a); fb_new(b); fb_new(c); eb_new(g); bn_new(r); bn_new(h); core_get()->eb_id = 0; switch (param) { #if defined(EB_ORDIN) && FB_POLYN == 163 case NIST_B163: ASSIGN(NIST_B163, NIST_163); ordin = 1; break; #endif #if defined(EB_KBLTZ) && FB_POLYN == 163 case NIST_K163: ASSIGN(NIST_K163, NIST_163); kbltz = 1; break; #endif #if defined(EB_ORDIN) && FB_POLYN == 233 case NIST_B233: ASSIGN(NIST_B233, NIST_233); ordin = 1; break; #endif #if defined(EB_KBLTZ) && FB_POLYN == 233 case NIST_K233: ASSIGN(NIST_K233, NIST_233); kbltz = 1; break; #endif #if defined(EB_ORDIN) && FB_POLYN == 251 case EBACS_B251: ASSIGN(EBACS_B251, PENTA_251); ordin = 1; break; #endif #if defined(EB_ORDIN) && FB_POLYN == 257 case HALVE_B257: ASSIGN(HALVE_B257, TRINO_257); ordin = 1; break; #endif #if defined(EB_ORDIN) && FB_POLYN == 283 case NIST_B283: ASSIGN(NIST_B283, NIST_283); ordin = 1; break; #endif #if defined(EB_KBLTZ) && FB_POLYN == 283 case NIST_K283: ASSIGN(NIST_K283, NIST_283); kbltz = 1; break; #endif #if defined(EB_KBLTZ) && FB_POLYN == 239 case SECG_K239: ASSIGN(SECG_K239, SECG_239); kbltz = 1; break; #endif #if defined(EB_ORDIN) && FB_POLYN == 409 case NIST_B409: ASSIGN(NIST_B409, NIST_409); ordin = 1; break; #endif #if defined(EB_KBLTZ) && FB_POLYN == 409 case NIST_K409: ASSIGN(NIST_K409, NIST_409); kbltz = 1; break; #endif #if defined(EB_ORDIN) && FB_POLYN == 571 case NIST_B571: ASSIGN(NIST_B571, NIST_571); ordin = 1; break; #endif #if defined(EB_KBLTZ) && FB_POLYN == 571 case NIST_K571: ASSIGN(NIST_K571, NIST_571); kbltz = 1; break; #endif #if defined(EB_SUPER) && FB_POLYN == 271 case ETAT_P271: ASSIGNS(ETAT_P271, PENTA_271); super = 1; break; case ETAT_T271: ASSIGNS(ETAT_T271, TRINO_271); super = 1; break; #endif #if defined(EB_SUPER) && FB_POLYN == 353 case ETAT_S353: ASSIGNS(ETAT_S353, TRINO_353); super = 1; break; #endif #if defined(EB_SUPER) && FB_POLYN == 1223 case ETAT_S1223: ASSIGNS(ETAT_S1223, TRINO_1223); super = 1; break; #endif default: (void)str; THROW(ERR_NO_VALID); break; } /* Do not generate warnings. */ (void)kbltz; (void)ordin; (void)super; (void)c; fb_zero(g->z); fb_set_bit(g->z, 0, 1); g->norm = 1; #if defined(EB_ORDIN) if (ordin) { eb_curve_set_ordin(a, b, g, r, h); core_get()->eb_id = param; } #endif #if defined(EB_KBLTZ) if (kbltz) { eb_curve_set_kbltz(a, g, r, h); core_get()->eb_id = param; } #elif defined(EB_ORDIN) if (kbltz) { eb_curve_set_ordin(a, b, g, r, h); core_get()->eb_id = param; } #endif #if defined(EB_SUPER) if (super) { eb_curve_set_super(a, b, c, g, r, h); core_get()->eb_id = param; } #endif } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fb_free(a); fb_free(b); fb_free(c); eb_free(g); bn_free(r); bn_free(h); } }