void ep2_curve_get_vs(bn_t *v) { bn_t x, t; bn_null(x); bn_null(t); TRY { bn_new(x); bn_new(t); fp_param_get_var(x); bn_mul_dig(v[0], x, 3); bn_add_dig(v[0], v[0], 1); bn_copy(v[1], x); bn_copy(v[2], x); bn_copy(v[3], x); bn_sqr(x, x); bn_lsh(t, x, 1); bn_add(v[0], v[0], t); bn_add(v[3], v[3], t); bn_lsh(t, t, 1); bn_add(v[2], v[2], t); bn_lsh(t, t, 1); bn_add(v[1], v[1], t); fp_param_get_var(t); bn_mul(x, x, t); bn_mul_dig(t, x, 6); bn_add(v[2], v[2], t); bn_lsh(t, t, 1); bn_add(v[1], v[1], t); bn_neg(v[3], v[3]); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(x); bn_free(t); } }
void bn_read_str(bn_t a, const char *str, int len, int radix) { int sign, i, j; char c; bn_zero(a); if (radix < 2 || radix > 64) { THROW(ERR_NO_VALID) } j = 0; if (str[0] == '-') { j++; sign = BN_NEG; } else { sign = BN_POS; } while (str[j] && j < len) { c = (char)((radix < 36) ? TOUPPER(str[j]) : str[j]); for (i = 0; i < 64; i++) { if (c == util_conv_char(i)) { break; } } if (i < radix) { bn_mul_dig(a, a, (dig_t)radix); bn_add_dig(a, a, (dig_t)i); } else { break; } j++; } a->sign = sign; }
int cp_bdpe_gen(bdpe_t pub, bdpe_t prv, dig_t block, int bits) { bn_t t, r; int result = STS_OK; bn_null(t); bn_null(r); TRY { bn_new(t); bn_new(r); prv->t = pub->t = block; /* Make sure that block size is prime. */ bn_set_dig(t, block); if (bn_is_prime_basic(t) == 0) { THROW(ERR_NO_VALID); } /* Generate prime q such that gcd(block, (q - 1)) = 1. */ do { bn_gen_prime(prv->q, bits / 2); bn_sub_dig(prv->q, prv->q, 1); bn_gcd_dig(t, prv->q, block); bn_add_dig(prv->q, prv->q, 1); } while (bn_cmp_dig(t, 1) != CMP_EQ); /* Generate different primes p and q. */ do { /* Compute p = block * (x * block + b) + 1, 0 < b < block random. */ bn_rand(prv->p, BN_POS, bits / 2 - 2 * util_bits_dig(block)); bn_mul_dig(prv->p, prv->p, block); bn_rand(t, BN_POS, util_bits_dig(block)); bn_add_dig(prv->p, prv->p, t->dp[0]); /* We know that block divides (p-1). */ bn_gcd_dig(t, prv->p, block); bn_mul_dig(prv->p, prv->p, block); bn_add_dig(prv->p, prv->p, 1); } while (bn_cmp_dig(t, 1) != CMP_EQ || bn_is_prime(prv->p) == 0); /* Compute t = (p-1)*(q-1). */ bn_sub_dig(prv->q, prv->q, 1); bn_sub_dig(prv->p, prv->p, 1); bn_mul(t, prv->p, prv->q); bn_div_dig(t, t, block); /* Restore factors p and q and compute n = p * q. */ bn_add_dig(prv->p, prv->p, 1); bn_add_dig(prv->q, prv->q, 1); bn_mul(pub->n, prv->p, prv->q); bn_copy(prv->n, pub->n); /* Select random y such that y^{(p-1)(q-1)}/block \neq 1 mod N. */ do { bn_rand(pub->y, BN_POS, bits); bn_mxp(r, pub->y, t, pub->n); } while (bn_cmp_dig(r, 1) == CMP_EQ); bn_copy(prv->y, pub->y); } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(t); bn_free(r); } return result; }
void bn_gen_prime_stron(bn_t a, int bits) { dig_t i, j; int found, k; bn_t r, s, t; bn_null(r); bn_null(s); bn_null(t); TRY { bn_new(r); bn_new(s); bn_new(t); do { do { /* Generate two large primes r and s. */ bn_rand(s, BN_POS, bits / 2 - BN_DIGIT / 2); bn_rand(t, BN_POS, bits / 2 - BN_DIGIT / 2); } while (!bn_is_prime(s) || !bn_is_prime(t)); found = 1; bn_rand(a, BN_POS, bits / 2 - bn_bits(t) - 1); i = a->dp[0]; bn_dbl(t, t); do { /* Find first prime r = 2 * i * t + 1. */ bn_mul_dig(r, t, i); bn_add_dig(r, r, 1); i++; if (bn_bits(r) > bits / 2 - 1) { found = 0; break; } } while (!bn_is_prime(r)); if (found == 0) { continue; } /* Compute t = 2 * (s^(r-2) mod r) * s - 1. */ bn_sub_dig(t, r, 2); #if BN_MOD != PMERS bn_mxp(t, s, t, r); #else bn_exp(t, s, t, r); #endif bn_mul(t, t, s); bn_dbl(t, t); bn_sub_dig(t, t, 1); k = bits - bn_bits(r); k -= bn_bits(s); bn_rand(a, BN_POS, k); j = a->dp[0]; do { /* Find first prime a = t + 2 * j * r * s. */ bn_mul(a, r, s); bn_mul_dig(a, a, j); bn_dbl(a, a); bn_add(a, a, t); j++; if (bn_bits(a) > bits) { found = 0; break; } } while (!bn_is_prime(a)); } while (found == 0 && bn_bits(a) != bits); } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(r); bn_free(s); bn_free(t); } }
void pp_map_sim_oatep_k12(fp12_t r, ep_t *p, ep2_t *q, int m) { ep_t _p[m]; ep2_t t[m], _q[m]; bn_t a; int i, j, len = FP_BITS, s[FP_BITS]; TRY { bn_null(a); bn_new(a); for (i = 0; i < m; i++) { ep_null(_p[i]); ep2_null(_q[i]); ep2_null(t[i]); ep_new(_p[i]); ep2_new(_q[i]); ep2_new(t[i]); } j = 0; for (i = 0; i < m; i++) { if (!ep_is_infty(p[i]) && !ep2_is_infty(q[i])) { ep_norm(_p[j], p[i]); ep2_norm(_q[j++], q[i]); } } fp12_set_dig(r, 1); fp_param_get_var(a); bn_mul_dig(a, a, 6); bn_add_dig(a, a, 2); fp_param_get_map(s, &len); if (j > 0) { switch (ep_param_get()) { case BN_P158: case BN_P254: case BN_P256: case BN_P638: /* r = f_{|a|,Q}(P). */ pp_mil_sps_k12(r, t, _q, _p, j, s, len); if (bn_sign(a) == BN_NEG) { /* f_{-a,Q}(P) = 1/f_{a,Q}(P). */ fp12_inv_uni(r, r); } for (i = 0; i < j; i++) { if (bn_sign(a) == BN_NEG) { ep2_neg(t[i], t[i]); } pp_fin_k12_oatep(r, t[i], _q[i], _p[i]); } pp_exp_k12(r, r); break; case B12_P638: /* r = f_{|a|,Q}(P). */ pp_mil_sps_k12(r, t, _q, _p, j, s, len); if (bn_sign(a) == BN_NEG) { fp12_inv_uni(r, r); } pp_exp_k12(r, r); break; } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(a); for (i = 0; i < m; i++) { ep_free(_p[i]); ep2_free(_q[i]); ep2_free(t[i]); } } }
void pp_map_oatep_k12(fp12_t r, ep_t p, ep2_t q) { ep_t _p[1]; ep2_t t[1], _q[1]; bn_t a; int len = FP_BITS, s[FP_BITS]; ep_null(_p[0]); ep2_null(_q[0]); ep2_null(t[0]); bn_null(a); TRY { ep_new(_p[0]); ep2_new(_q[0]); ep2_new(t[0]); bn_new(a); fp_param_get_var(a); bn_mul_dig(a, a, 6); bn_add_dig(a, a, 2); fp_param_get_map(s, &len); fp12_set_dig(r, 1); ep_norm(_p[0], p); ep2_norm(_q[0], q); if (!ep_is_infty(_p[0]) && !ep2_is_infty(_q[0])) { switch (ep_param_get()) { case BN_P158: case BN_P254: case BN_P256: case BN_P638: /* r = f_{|a|,Q}(P). */ pp_mil_sps_k12(r, t, _q, _p, 1, s, len); if (bn_sign(a) == BN_NEG) { /* f_{-a,Q}(P) = 1/f_{a,Q}(P). */ fp12_inv_uni(r, r); ep2_neg(t[0], t[0]); } pp_fin_k12_oatep(r, t[0], _q[0], _p[0]); pp_exp_k12(r, r); break; case B12_P638: /* r = f_{|a|,Q}(P). */ pp_mil_sps_k12(r, t, _q, _p, 1, s, len); if (bn_sign(a) == BN_NEG) { fp12_inv_uni(r, r); ep2_neg(t[0], t[0]); } pp_exp_k12(r, r); break; } } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { ep_free(_p[0]); ep2_free(_q[0]); ep2_free(t[0]); bn_free(a); } }
void fp_param_set(int param) { bn_t t0, t1, t2, p; int f[10] = { 0 }; bn_null(t0); bn_null(t1); bn_null(t2); bn_null(p); /* Suppress possible unused parameter warning. */ (void) f; TRY { bn_new(t0); bn_new(t1); bn_new(t2); bn_new(p); core_get()->fp_id = param; switch (param) { #if FP_PRIME == 158 case BN_158: /* x = 4000000031. */ fp_param_get_var(t0); /* p = 36 * x^4 + 36 * x^3 + 24 * x^2 + 6 * x + 1. */ bn_set_dig(p, 1); bn_mul_dig(t1, t0, 6); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 24); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul(t1, t1, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); bn_mul(t0, t0, t0); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); fp_prime_set_dense(p); break; #elif FP_PRIME == 160 case SECG_160: /* p = 2^160 - 2^31 + 1. */ f[0] = -1; f[1] = -31; f[2] = 160; fp_prime_set_pmers(f, 3); break; case SECG_160D: /* p = 2^160 - 2^32 - 2^14 - 2^12 - 2^9 - 2^8 - 2^7 - 2^3 - 2^2 - 1.*/ f[0] = -1; f[1] = -2; f[2] = -3; f[3] = -7; f[4] = -8; f[5] = -9; f[6] = -12; f[7] = -14; f[8] = -32; f[9] = 160; fp_prime_set_pmers(f, 10); break; #elif FP_PRIME == 192 case NIST_192: /* p = 2^192 - 2^64 - 1. */ f[0] = -1; f[1] = -64; f[2] = 192; fp_prime_set_pmers(f, 3); break; case SECG_192: /* p = 2^192 - 2^32 - 2^12 - 2^8 - 2^7 - 2^6 - 2^3 - 1.*/ f[0] = -1; f[1] = -3; f[2] = -6; f[3] = -7; f[4] = -8; f[5] = -12; f[6] = -32; f[7] = 192; fp_prime_set_pmers(f, 8); break; #elif FP_PRIME == 224 case NIST_224: /* p = 2^224 - 2^96 + 1. */ f[0] = 1; f[1] = -96; f[2] = 224; fp_prime_set_pmers(f, 3); break; case SECG_224: /* p = 2^224 - 2^32 - 2^12 - 2^11 - 2^9 - 2^7 - 2^4 - 2 - 1.*/ f[0] = -1; f[1] = -1; f[2] = -4; f[3] = -7; f[4] = -9; f[5] = -11; f[6] = -12; f[7] = -32; f[8] = 224; fp_prime_set_pmers(f, 9); break; #elif FP_PRIME == 254 case BN_254: /* x = -4080000000000001. */ fp_param_get_var(t0); /* p = 36 * x^4 + 36 * x^3 + 24 * x^2 + 6 * x + 1. */ bn_set_dig(p, 1); bn_mul_dig(t1, t0, 6); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 24); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul(t1, t1, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); bn_mul(t0, t0, t0); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); fp_prime_set_dense(p); break; #elif FP_PRIME == 256 case NIST_256: /* p = 2^256 - 2^224 + 2^192 + 2^96 - 1. */ f[0] = -1; f[1] = 96; f[2] = 192; f[3] = -224; f[4] = 256; fp_prime_set_pmers(f, 5); break; case SECG_256: /* p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1. */ f[0] = -1; f[1] = -4; f[2] = -6; f[3] = -7; f[4] = -8; f[5] = -9; f[6] = -32; f[7] = 256; fp_prime_set_pmers(f, 8); break; case BN_256: /* x = 6000000000001F2D. */ fp_param_get_var(t0); /* p = 36 * x^4 + 36 * x^3 + 24 * x^2 + 6 * x + 1. */ bn_set_dig(p, 1); bn_mul_dig(t1, t0, 6); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 24); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul(t1, t1, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); bn_mul(t0, t0, t0); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); fp_prime_set_dense(p); break; #elif FP_PRIME == 384 case NIST_384: /* p = 2^384 - 2^128 - 2^96 + 2^32 - 1. */ f[0] = -1; f[1] = 32; f[2] = -96; f[3] = -128; f[4] = 384; fp_prime_set_pmers(f, 5); break; #elif FP_PRIME == 477 case B24_477: fp_param_get_var(t0); /* p = (u - 1)^2 * (u^8 - u^4 + 1) div 3 + u. */ bn_sub_dig(p, t0, 1); bn_sqr(p, p); bn_sqr(t1, t0); bn_sqr(t1, t1); bn_sqr(t2, t1); bn_sub(t2, t2, t1); bn_add_dig(t2, t2, 1); bn_mul(p, p, t2); bn_div_dig(p, p, 3); bn_add(p, p, t0); fp_prime_set_dense(p); break; #elif FP_PRIME == 508 case KSS_508: fp_param_get_var(t0); /* h = (49*u^2 + 245 * u + 343)/3 */ bn_mul_dig(p, t0, 245); bn_add_dig(p, p, 200); bn_add_dig(p, p, 143); bn_sqr(t1, t0); bn_mul_dig(t2, t1, 49); bn_add(p, p, t2); bn_div_dig(p, p, 3); /* n = (u^6 + 37 * u^3 + 343)/343. */ bn_mul(t1, t1, t0); bn_mul_dig(t2, t1, 37); bn_sqr(t1, t1); bn_add(t2, t2, t1); bn_add_dig(t2, t2, 200); bn_add_dig(t2, t2, 143); bn_div_dig(t2, t2, 49); bn_div_dig(t2, t2, 7); bn_mul(p, p, t2); /* t = (u^4 + 16 * u + 7)/7. */ bn_mul_dig(t1, t0, 16); bn_add_dig(t1, t1, 7); bn_sqr(t2, t0); bn_sqr(t2, t2); bn_add(t2, t2, t1); bn_div_dig(t2, t2, 7); bn_add(p, p, t2); bn_sub_dig(p, p, 1); fp_prime_set_dense(p); break; #elif FP_PRIME == 521 case NIST_521: /* p = 2^521 - 1. */ f[0] = -1; f[1] = 521; fp_prime_set_pmers(f, 2); break; #elif FP_PRIME == 638 case BN_638: fp_param_get_var(t0); /* p = 36 * x^4 + 36 * x^3 + 24 * x^2 + 6 * x + 1. */ bn_set_dig(p, 1); bn_mul_dig(t1, t0, 6); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 24); bn_add(p, p, t1); bn_mul(t1, t0, t0); bn_mul(t1, t1, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); bn_mul(t0, t0, t0); bn_mul(t1, t0, t0); bn_mul_dig(t1, t1, 36); bn_add(p, p, t1); fp_prime_set_dense(p); break; case B12_638: fp_param_get_var(t0); /* p = (x^2 - 2x + 1) * (x^4 - x^2 + 1)/3 + x. */ bn_sqr(t1, t0); bn_sqr(p, t1); bn_sub(p, p, t1); bn_add_dig(p, p, 1); bn_sub(t1, t1, t0); bn_sub(t1, t1, t0); bn_add_dig(t1, t1, 1); bn_mul(p, p, t1); bn_div_dig(p, p, 3); bn_add(p, p, t0); fp_prime_set_dense(p); break; #elif FP_PRIME == 1536 case SS_1536: fp_param_get_var(t0); bn_read_str(p, SS_P1536, strlen(SS_P1536), 16); bn_mul(p, p, t0); bn_dbl(p, p); bn_sub_dig(p, p, 1); fp_prime_set_dense(p); break; #else default: bn_gen_prime(p, FP_BITS); fp_prime_set_dense(p); core_get()->fp_id = 0; break; #endif } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(t0); bn_free(t1); bn_free(t2); bn_free(p); } }