void bn_lcm(bn_t c, const bn_t a, const bn_t b) { bn_t u, v; bn_null(u); bn_null(v); TRY { bn_new(u); bn_new(v); bn_gcd(u, a, b); if (bn_cmp_abs(a, b) == CMP_LT) { bn_div(v, a, u); bn_mul(c, b, v); } else { bn_div(v, b, u); bn_mul(c, a, v); } c->sign = BN_POS; } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(u); bn_free(v); } }
void ep2_rand(ep2_t p) { bn_t n, k; ep2_t gen; bn_null(k); bn_null(n); ep2_null(gen); TRY { bn_new(k); bn_new(n); ep2_new(gen); ep2_curve_get_ord(n); bn_rand_mod(k, n); ep2_curve_get_gen(gen); ep2_mul(p, gen, k); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(k); bn_free(n); ep2_free(gen); } }
int cp_pss_sig(g1_t a, g1_t b, uint8_t *msg, int len, bn_t r, bn_t s) { bn_t m, n; int result = RLC_OK; bn_null(m); bn_null(n); TRY { bn_new(m); bn_new(n); g1_get_ord(n); bn_read_bin(m, msg, len); bn_mul(m, m, s); bn_mod(m, m, n); bn_add(m, m, r); bn_mod(m, m, n); g1_rand(a); g1_mul(b, a, m); } CATCH_ANY { result = RLC_ERR; } FINALLY { bn_free(m); bn_free(n); } return result; }
int cp_phpe_gen(bn_t n, bn_t l, int bits) { bn_t p, q; int result = STS_OK; bn_null(p); bn_null(q); TRY { bn_new(p); bn_new(q); /* Generate primes p and q of equivalent length. */ do { bn_gen_prime(p, bits / 2); bn_gen_prime(q, bits / 2); } while (bn_cmp(p, q) == CMP_EQ); /* Compute n = pq and l = \phi(n). */ bn_mul(n, p, q); bn_sub_dig(p, p, 1); bn_sub_dig(q, q, 1); bn_mul(l, p, q); } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(p); bn_free(q); } return result; }
void pp_exp_k2(fp2_t c, fp2_t a) { bn_t e, n; bn_null(n); bn_null(e); TRY { bn_new(n); bn_new(e); ep_curve_get_ord(n); fp2_conv_uni(c, a); dv_copy(e->dp, fp_prime_get(), FP_DIGS); e->used = FP_DIGS; e->sign = BN_POS; bn_add_dig(e, e, 1); bn_div(e, e, n); fp2_exp_uni(c, c, e); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); bn_free(e); } }
int cp_ecss_sig(bn_t e, bn_t s, uint8_t *msg, int len, bn_t d) { bn_t n, k, x, r; ec_t p; uint8_t hash[MD_LEN]; uint8_t m[len + FC_BYTES]; int result = STS_OK; bn_null(n); bn_null(k); bn_null(x); bn_null(r); ec_null(p); TRY { bn_new(n); bn_new(k); bn_new(x); bn_new(r); ec_new(p); ec_curve_get_ord(n); do { bn_rand_mod(k, n); ec_mul_gen(p, k); ec_get_x(x, p); bn_mod(r, x, n); } while (bn_is_zero(r)); memcpy(m, msg, len); bn_write_bin(m + len, FC_BYTES, r); md_map(hash, m, len + FC_BYTES); if (8 * MD_LEN > bn_bits(n)) { len = CEIL(bn_bits(n), 8); bn_read_bin(e, hash, len); bn_rsh(e, e, 8 * MD_LEN - bn_bits(n)); } else { bn_read_bin(e, hash, MD_LEN); } bn_mod(e, e, n); bn_mul(s, d, e); bn_mod(s, s, n); bn_sub(s, n, s); bn_add(s, s, k); bn_mod(s, s, n); } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(n); bn_free(k); bn_free(x); bn_free(r); ec_free(p); } return result; }
void bn_mxp_monty(bn_t c, const bn_t a, const bn_t b, const bn_t m) { bn_t tab[2], u; dig_t mask; int t; bn_null(tab[0]); bn_null(tab[1]); bn_null(u); TRY { bn_new(u); bn_mod_pre(u, m); bn_new(tab[0]); bn_new(tab[1]); #if BN_MOD == MONTY bn_set_dig(tab[0], 1); bn_mod_monty_conv(tab[0], tab[0], m); bn_mod_monty_conv(tab[1], a, m); #else bn_set_dig(tab[0], 1); bn_copy(tab[1], a); #endif for (int i = bn_bits(b) - 1; i >= 0; i--) { int j = bn_get_bit(b, i); dv_swap_cond(tab[0]->dp, tab[1]->dp, BN_DIGS, j ^ 1); mask = -(j ^ 1); t = (tab[0]->used ^ tab[1]->used) & mask; tab[0]->used ^= t; tab[1]->used ^= t; bn_mul(tab[0], tab[0], tab[1]); bn_mod(tab[0], tab[0], m, u); bn_sqr(tab[1], tab[1]); bn_mod(tab[1], tab[1], m, u); dv_swap_cond(tab[0]->dp, tab[1]->dp, BN_DIGS, j ^ 1); mask = -(j ^ 1); t = (tab[0]->used ^ tab[1]->used) & mask; tab[0]->used ^= t; tab[1]->used ^= t; } #if BN_MOD == MONTY bn_mod_monty_back(c, tab[0], m); #else bn_copy(c, tab[0]); #endif } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(tab[1]); bn_free(tab[0]); bn_free(u); } }
int cp_pss_ver(g1_t a, g1_t b, uint8_t *msg, int len, g2_t g, g2_t x, g2_t y) { g1_t p[2]; g2_t r[2]; gt_t e; bn_t m, n; int result = 1; g1_null(p[0]); g1_null(p[1]); g2_null(r[0]); g2_null(r[1]); gt_null(e); bn_null(m); bn_null(n); TRY { g1_new(p[0]); g1_new(p[1]); g2_new(r[0]); g2_new(r[1]); gt_new(e); bn_new(m); bn_new(n); if (g1_is_infty(a)) { result = 0; } g1_copy(p[0], a); g1_copy(p[1], b); g2_copy(r[1], g); g2_neg(r[1], r[1]); g1_get_ord(n); bn_read_bin(m, msg, len); bn_mod(m, m, n); g2_mul(r[0], y, m); g2_add(r[0], r[0], x); g2_norm(r[0], r[0]); pc_map_sim(e, p, r, 2); if (!gt_is_unity(e)) { result = 0; } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { g1_free(p[0]); g1_free(p[1]); g2_free(r[0]); g2_free(r[1]); gt_free(e); bn_free(m); bn_free(n); } return result; }
int cp_rsa_gen_basic(rsa_t pub, rsa_t prv, int bits) { bn_t t, r; int result = STS_OK; if (pub == NULL || prv == NULL || bits == 0) { return STS_ERR; } bn_null(t); bn_null(r); TRY { bn_new(t); bn_new(r); /* Generate different primes p and q. */ do { bn_gen_prime(prv->p, bits / 2); bn_gen_prime(prv->q, bits / 2); } while (bn_cmp(prv->p, prv->q) == CMP_EQ); /* Swap p and q so that p is smaller. */ if (bn_cmp(prv->p, prv->q) == CMP_LT) { bn_copy(t, prv->p); bn_copy(prv->p, prv->q); bn_copy(prv->q, t); } bn_mul(pub->n, prv->p, prv->q); bn_copy(prv->n, pub->n); bn_sub_dig(prv->p, prv->p, 1); bn_sub_dig(prv->q, prv->q, 1); bn_mul(t, prv->p, prv->q); bn_set_2b(pub->e, 16); bn_add_dig(pub->e, pub->e, 1); bn_gcd_ext(r, prv->d, NULL, pub->e, t); if (bn_sign(prv->d) == BN_NEG) { bn_add(prv->d, prv->d, t); } if (bn_cmp_dig(r, 1) == CMP_EQ) { bn_add_dig(prv->p, prv->p, 1); bn_add_dig(prv->q, prv->q, 1); } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(t); bn_free(r); } return result; }
int cp_bgn_dec2(dig_t *out, g2_t in[2], bgn_t prv) { bn_t r, n; g2_t s, t, u; int i, result = STS_ERR; bn_null(n); bn_null(r); g2_null(s); g2_null(t); g2_null(u); TRY { bn_new(n); bn_new(r); g2_new(s); g2_new(t); g2_new(u); g2_get_ord(n); /* Compute T = x(ym + r)G - (zm + xr)G = m(xy - z)G. */ g2_mul(t, in[0], prv->x); g2_sub(t, t, in[1]); g2_norm(t, t); /* Compute U = (xy - z)G and find m. */ bn_mul(r, prv->x, prv->y); bn_sub(r, r, prv->z); bn_mod(r, r, n); g2_mul_gen(s, r); g2_copy(u, s); if (g2_is_infty(t) == 1) { *out = 0; result = STS_OK; } else { for (i = 0; i < INT_MAX; i++) { if (g2_cmp(t, u) == CMP_EQ) { *out = i + 1; result = STS_OK; break; } g2_add(u, u, s); g2_norm(u, u); } } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(n); bn_free(r); g2_free(s); g2_free(t); g2_free(u); } return result; }
void bn_mxp_basic(bn_t c, const bn_t a, const bn_t b, const bn_t m) { int i, l; bn_t t, u, r; if (bn_is_zero(b)) { bn_set_dig(c, 1); return; } bn_null(t); bn_null(u); bn_null(r); TRY { bn_new(t); bn_new(u); bn_new(r); bn_mod_pre(u, m); l = bn_bits(b); #if BN_MOD == MONTY bn_mod_monty_conv(t, a, m); #else bn_copy(t, a); #endif bn_copy(r, t); for (i = l - 2; i >= 0; i--) { bn_sqr(r, r); bn_mod(r, r, m, u); if (bn_get_bit(b, i)) { bn_mul(r, r, t); bn_mod(r, r, m, u); } } #if BN_MOD == MONTY bn_mod_monty_back(c, r, m); #else bn_copy(c, r); #endif } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(t); bn_free(u); bn_free(r); } }
int cp_phpe_enc(uint8_t *out, int *out_len, uint8_t *in, int in_len, bn_t n) { bn_t g, m, r, s; int size, result = STS_OK; bn_null(g); bn_null(m); bn_null(r); bn_null(s); size = bn_size_bin(n); if (n == NULL || in_len <= 0 || in_len > size) { return STS_ERR; } TRY { bn_new(g); bn_new(m); bn_new(r); bn_new(s); /* Represent m as a padded element of Z_n. */ bn_read_bin(m, in, in_len); /* Generate r in Z_n^*. */ bn_rand_mod(r, n); /* Compute c = (g^m)(r^n) mod n^2. */ bn_add_dig(g, n, 1); bn_sqr(s, n); bn_mxp(m, g, m, s); bn_mxp(r, r, n, s); bn_mul(m, m, r); bn_mod(m, m, s); if (2 * size <= *out_len) { *out_len = 2 * size; memset(out, 0, *out_len); bn_write_bin(out, *out_len, m); } else { result = STS_ERR; } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(g); bn_free(m); bn_free(r); bn_free(s); } return result; }
int cp_bdpe_dec(dig_t *out, uint8_t *in, int in_len, bdpe_t prv) { bn_t m, t, z; unsigned i; int size, result = STS_OK; size = bn_size_bin(prv->n); if (in_len < 0 || in_len != size) { return STS_ERR; } bn_null(m); bn_null(t); bn_null(z); TRY { bn_new(m); bn_new(t); bn_new(z); /* Compute t = (p-1)(q-1)/block. */ bn_mul(t, prv->p, prv->q); bn_sub(t, t, prv->p); bn_sub(t, t, prv->q); bn_add_dig(t, t, 1); bn_div_dig(t, t, prv->t); bn_read_bin(m, in, in_len); bn_mxp(m, m, t, prv->n); bn_mxp(t, prv->y, t, prv->n); for (i = 0; i < prv->t; i++) { bn_mxp_dig(z, t, i, prv->n); if (bn_cmp(z, m) == CMP_EQ) { *out = i; break; } } if (i == prv->t) { result = STS_ERR; } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(m); bn_free(t); bn_free(z); } return result; }
int cp_phpe_dec(uint8_t *out, int out_len, uint8_t *in, int in_len, bn_t n, bn_t l) { bn_t c, u, s; int size, result = STS_OK; size = bn_size_bin(n); if (in_len < 0 || in_len != 2 * size) { return STS_ERR; } bn_null(c); bn_null(u); bn_null(s); TRY { bn_new(c); bn_new(u); bn_new(s); /* Compute (c^l mod n^2) * u mod n. */ bn_sqr(s, n); bn_read_bin(c, in, in_len); bn_mxp(c, c, l, s); bn_sub_dig(c, c, 1); bn_div(c, c, n); bn_gcd_ext(s, u, NULL, l, n); if (bn_sign(u) == BN_NEG) { bn_add(u, u, n); } bn_mul(c, c, u); bn_mod(c, c, n); size = bn_size_bin(c); if (size <= out_len) { memset(out, 0, out_len); bn_write_bin(out + (out_len - size), size, c); } else { result = STS_ERR; } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(c); bn_free(u); bn_free(s); } return result; }
int cp_bbs_ver(g1_t s, uint8_t *msg, int len, int hash, g2_t q, gt_t z) { bn_t m, n; g2_t g; gt_t e; uint8_t h[MD_LEN]; int result = 0; bn_null(m); bn_null(n); g2_null(g); gt_null(e); TRY { bn_new(m); bn_new(n); g2_new(g); gt_new(e); g2_get_ord(n); /* m = H(msg). */ if (hash) { bn_read_bin(m, msg, len); } else { md_map(h, msg, len); bn_read_bin(m, h, MD_LEN); } bn_mod(m, m, n); g2_mul_gen(g, m); g2_add(g, g, q); g2_norm(g, g); pc_map(e, s, g); if (gt_cmp(e, z) == CMP_EQ) { result = 1; } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(m); bn_free(n); g2_free(g); gt_free(e); } return result; }
void fp_prime_set_pmers(const int *f, int len) { bn_t p, t; bn_null(p); bn_null(t); TRY { bn_new(p); bn_new(t); if (len >= MAX_TERMS) { THROW(ERR_NO_VALID); } bn_set_2b(p, f[len - 1]); for (int i = len - 2; i > 0; i--) { if (f[i] > 0) { bn_set_2b(t, f[i]); bn_add(p, p, t); } else { bn_set_2b(t, -f[i]); bn_sub(p, p, t); } } if (f[0] > 0) { bn_add_dig(p, p, f[0]); } else { bn_sub_dig(p, p, -f[0]); } #if FP_RDC == QUICK || !defined(STRIP) ctx_t *ctx = core_get(); for (int i = 0; i < len; i++) { ctx->sps[i] = f[i]; } ctx->sps[len] = 0; ctx->sps_len = len; #endif /* FP_RDC == QUICK */ fp_prime_set(p); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(p); bn_free(t); } }
/** * Computes c = a ^ b mod m. * * @param c - the result. * @param a - the basis. * @param b - the exponent. * @param m - the modulus. */ static void bn_exp(bn_t c, const bn_t a, const bn_t b, const bn_t m) { int i, l; bn_t t; bn_null(t); TRY { bn_new(t); l = bn_bits(b); bn_copy(t, a); for (i = l - 2; i >= 0; i--) { bn_sqr(t, t); bn_mod(t, t, m); if (bn_get_bit(b, i)) { bn_mul(t, t, a); bn_mod(t, t, m); } } bn_copy(c, t); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(t); } }
void pp_map_tatep_k2(fp2_t r, ep_t p, ep_t q) { ep_t _p[1], _q[1], t[1]; bn_t n; ep_null(_p[0]); ep_null(_q[0]); ep_null(t[0]); bn_null(n); TRY { ep_new(t[0]); bn_new(n); ep_norm(_p[0], p); ep_norm(_q[0], q); ep_curve_get_ord(n); /* Since p has order n, we do not have to perform last iteration. */ bn_sub_dig(n, n, 1); fp2_set_dig(r, 1); if (!ep_is_infty(p) && !ep_is_infty(q)) { pp_mil_k2(r, t, _p, _q, 1, n); pp_exp_k2(r, r); } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ep_free(_p[0]); ep_free(_q[0]); ep_free(t[0]); bn_free(n); } }
int cp_ecss_gen(bn_t d, ec_t q) { bn_t n; int result = STS_OK; bn_null(n); TRY { bn_new(n); ec_curve_get_ord(n); do { bn_rand(d, BN_POS, bn_bits(n)); bn_mod(d, d, n); } while (bn_is_zero(d)); ec_mul_gen(q, d); } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(n); } return result; }
int cp_psb_gen(bn_t r, bn_t s[], g2_t g, g2_t x, g2_t y[], int l) { bn_t n; int i, result = RLC_OK; bn_null(n); TRY { bn_new(n); g2_get_ord(n); bn_rand_mod(r, n); g2_rand(g); g2_mul(x, g, r); for (i = 0; i < l; i++) { bn_rand_mod(s[i], n); g2_mul(y[i], g, s[i]); } } CATCH_ANY { result = RLC_ERR; } FINALLY { bn_free(n); } return result; }
void ep2_mul_pre_nafwi(ep2_t *t, ep2_t p) { int l; bn_t n; bn_null(n); TRY { bn_new(n); ep2_curve_get_ord(n); l = bn_bits(n) + 1; l = ((l % EP_DEPTH) == 0 ? (l / EP_DEPTH) : (l / EP_DEPTH) + 1); ep2_copy(t[0], p); for (int i = 1; i < l; i++) { ep2_dbl(t[i], t[i - 1]); for (int j = 1; j < EP_DEPTH; j++) { ep2_dbl(t[i], t[i]); } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); } }
int fp3_srt(fp3_t c, fp3_t a) { int r = 0; fp3_t t0, t1, t2, t3; bn_t e; fp3_null(t0); fp3_null(t1); fp3_null(t2); fp3_null(t3); bn_null(e); TRY { fp3_new(t0); fp3_new(t1); fp3_new(t2); fp3_new(t3); bn_new(e); fp3_dbl(t3, a); fp3_frb(t0, t3, 1); fp3_sqr(t1, t0); fp3_mul(t2, t1, t0); fp3_mul(t1, t1, t2); fp3_frb(t0, t0, 1); fp3_mul(t3, t3, t1); fp3_mul(t0, t0, t3); e->used = FP_DIGS; dv_copy(e->dp, fp_prime_get(), FP_DIGS); bn_sub_dig(e, e, 5); bn_div_dig(e, e, 8); fp3_exp(t0, t0, e); fp3_mul(t0, t0, t2); fp3_sqr(t1, t0); fp3_mul(t1, t1, a); fp3_dbl(t1, t1); fp3_mul(t0, t0, a); fp_sub_dig(t1[0], t1[0], 1); fp3_mul(c, t0, t1); fp3_sqr(t0, c); if (fp3_cmp(t0, a) == CMP_EQ) { r = 1; } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp3_free(t0); fp3_free(t1); fp3_free(t2); fp3_free(t3); bn_free(e); } return r; }
void fp_read_bin(fp_t a, const uint8_t *bin, int len) { bn_t t; bn_null(t); if (len != RLC_FP_BYTES) { THROW(ERR_NO_BUFFER); } TRY { bn_new(t); bn_read_bin(t, bin, len); if (bn_is_zero(t)) { fp_zero(a); } else { if (t->used == 1) { fp_prime_conv_dig(a, t->dp[0]); } else { fp_prime_conv(a, t); } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(t); } }
void fp_read_bin(fp_t a, const unsigned char *str, int len) { bn_t t; bn_null(t); TRY { bn_new(t); bn_read_bin(t, (unsigned char *) str, len); if (bn_is_zero(t)) { fp_zero(a); } else { if (t->used == 1) { fp_prime_conv_dig(a, t->dp[0]); } else { fp_prime_conv(a, t); } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(t); } }
int cp_bgn_gen(bgn_t pub, bgn_t prv) { bn_t n; int result = STS_OK; bn_null(n); TRY { bn_new(n); g1_get_ord(n); bn_rand_mod(prv->x, n); bn_rand_mod(prv->y, n); bn_rand_mod(prv->z, n); g1_mul_gen(pub->gx, prv->x); g1_mul_gen(pub->gy, prv->y); g1_mul_gen(pub->gz, prv->z); g2_mul_gen(pub->hx, prv->x); g2_mul_gen(pub->hy, prv->y); g2_mul_gen(pub->hz, prv->z); } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(n); } return result; }
void ed_mul_pre_nafwi(ed_t *t, const ed_t p) { int l; bn_t n; bn_null(n); TRY { bn_new(n); ed_curve_get_ord(n); l = bn_bits(n) + 1; l = ((l % ED_DEPTH) == 0 ? (l / ED_DEPTH) : (l / ED_DEPTH) + 1); ed_copy(t[0], p); for (int i = 1; i < l; i++) { ed_dbl(t[i], t[i - 1]); for (int j = 1; j < ED_DEPTH; j++) { ed_dbl(t[i], t[i]); } } ed_norm_sim(t + 1, (const ed_t *)t + 1, l - 1); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(n); } }
void fp2_norm_low(fp2_t c, fp2_t a) { fp2_t t; bn_t b; fp2_null(t); bn_null(b); TRY { fp2_new(t); bn_new(b); #if FP_PRIME == 158 fp_dbl(t[0], a[0]); fp_dbl(t[0], t[0]); fp_sub(t[0], t[0], a[1]); fp_dbl(t[1], a[1]); fp_dbl(t[1], t[1]); fp_add(c[1], a[0], t[1]); fp_copy(c[0], t[0]); #elif defined(FP_QNRES) /* If p = 3 mod 8, (1 + i) is a QNR/CNR. */ fp_neg(t[0], a[1]); fp_add(c[1], a[0], a[1]); fp_add(c[0], t[0], a[0]); #else switch (fp_prime_get_mod8()) { case 3: /* If p = 3 mod 8, (1 + u) is a QNR/CNR. */ fp_neg(t[0], a[1]); fp_add(c[1], a[0], a[1]); fp_add(c[0], t[0], a[0]); break; case 5: /* If p = 5 mod 8, (u) is a QNR/CNR. */ fp2_mul_art(c, a); break; case 7: /* If p = 7 mod 8, we choose (2^(lg_4(b-1)) + u) as QNR/CNR. */ fp2_mul_art(t, a); fp2_dbl(c, a); fp_prime_back(b, ep_curve_get_b()); for (int i = 1; i < bn_bits(b) / 2; i++) { fp2_dbl(c, c); } fp2_add(c, c, t); break; default: THROW(ERR_NO_VALID); break; } #endif } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { fp2_free(t); bn_free(b); } }
void eb_mul_pre_combs(eb_t *t, eb_t p) { int i, j, l; bn_t ord; bn_null(ord); TRY { bn_new(ord); eb_curve_get_ord(ord); l = bn_bits(ord); l = ((l % EB_DEPTH) == 0 ? (l / EB_DEPTH) : (l / EB_DEPTH) + 1); eb_set_infty(t[0]); eb_copy(t[1], p); for (j = 1; j < EB_DEPTH; j++) { eb_dbl(t[1 << j], t[1 << (j - 1)]); for (i = 1; i < l; i++) { eb_dbl(t[1 << j], t[1 << j]); } for (i = 1; i < (1 << j); i++) { eb_add(t[(1 << j) + i], t[1 << j], t[i]); } } eb_norm_sim(t + 2, t + 2, EB_TABLE_COMBS - 2); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(ord); } }
void ep2_map(ep2_t p, uint8_t *msg, int len) { bn_t x; fp2_t t0; uint8_t digest[MD_LEN]; bn_null(x); fp2_null(t0); TRY { bn_new(x); fp2_new(t0); md_map(digest, msg, len); bn_read_bin(x, digest, MIN(FP_BYTES, MD_LEN)); fp_prime_conv(p->x[0], x); fp_zero(p->x[1]); fp_set_dig(p->z[0], 1); fp_zero(p->z[1]); while (1) { ep2_rhs(t0, p); if (fp2_srt(p->y, t0)) { p->norm = 1; break; } fp_add_dig(p->x[0], p->x[0], 1); } switch (ep_param_get()) { case BN_P158: case BN_P254: case BN_P256: case BN_P638: ep2_mul_cof_bn(p, p); break; case B12_P638: ep2_mul_cof_b12(p, p); break; default: /* Now, multiply by cofactor to get the correct group. */ ep2_curve_get_cof(x); if (bn_bits(x) < BN_DIGIT) { ep2_mul_dig(p, p, x->dp[0]); } else { ep2_mul(p, p, x); } break; } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(x); fp2_free(t0); } }
void fp_read_str(fp_t a, const char *str, int len, int radix) { bn_t t; bn_null(t); TRY { bn_new(t); bn_read_str(t, str, len, radix); if (bn_is_zero(t)) { fp_zero(a); } else { if (t->used == 1) { fp_prime_conv_dig(a, t->dp[0]); } else { fp_prime_conv(a, t); } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(t); } }