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; }
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_mxp_slide(bn_t c, const bn_t a, const bn_t b, const bn_t m) { bn_t tab[TABLE_SIZE], t, u, r; int i, j, l, w = 1; uint8_t win[BN_BITS]; bn_null(t); bn_null(u); bn_null(r); /* Initialize table. */ for (i = 0; i < TABLE_SIZE; i++) { bn_null(tab[i]); } TRY { /* Find window size. */ i = bn_bits(b); if (i <= 21) { w = 2; } else if (i <= 32) { w = 3; } else if (i <= 128) { w = 4; } else if (i <= 256) { w = 5; } else { w = 6; } for (i = 1; i < (1 << w); i += 2) { bn_new(tab[i]); } bn_new(t); bn_new(u); bn_new(r); bn_mod_pre(u, m); #if BN_MOD == MONTY bn_set_dig(r, 1); bn_mod_monty_conv(r, r, m); bn_mod_monty_conv(t, a, m); #else /* BN_MOD == BARRT || BN_MOD == RADIX */ bn_set_dig(r, 1); bn_copy(t, a); #endif bn_copy(tab[1], t); bn_sqr(t, tab[1]); bn_mod(t, t, m, u); /* Create table. */ for (i = 1; i < 1 << (w - 1); i++) { bn_mul(tab[2 * i + 1], tab[2 * i - 1], t); bn_mod(tab[2 * i + 1], tab[2 * i + 1], m, u); } l = BN_BITS + 1; bn_rec_slw(win, &l, b, w); for (i = 0; i < l; i++) { if (win[i] == 0) { bn_sqr(r, r); bn_mod(r, r, m, u); } else { for (j = 0; j < util_bits_dig(win[i]); j++) { bn_sqr(r, r); bn_mod(r, r, m, u); } bn_mul(r, r, tab[win[i]]); bn_mod(r, r, m, u); } } bn_trim(r); #if BN_MOD == MONTY bn_mod_monty_back(c, r, m); #else bn_copy(c, r); #endif } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { for (i = 1; i < (1 << w); i++) { bn_free(tab[i]); } bn_free(u); bn_free(t); bn_free(r); } }
int bn_is_prime_rabin(const bn_t a) { bn_t t, n1, y, r; int i, s, j, result, b, tests = 0; tests = 0; result = 1; bn_null(t); bn_null(n1); bn_null(y); bn_null(r); if (bn_cmp_dig(a, 1) == CMP_EQ) { return 0; } TRY { /* * These values are taken from Table 4.4 inside Handbook of Applied * Cryptography. */ b = bn_bits(a); if (b >= 1300) { tests = 2; } else if (b >= 850) { tests = 3; } else if (b >= 650) { tests = 4; } else if (b >= 550) { tests = 5; } else if (b >= 450) { tests = 6; } else if (b >= 400) { tests = 7; } else if (b >= 350) { tests = 8; } else if (b >= 300) { tests = 9; } else if (b >= 250) { tests = 12; } else if (b >= 200) { tests = 15; } else if (b >= 150) { tests = 18; } else { tests = 27; } bn_new(t); bn_new(n1); bn_new(y); bn_new(r); /* r = (n - 1)/2^s. */ bn_sub_dig(n1, a, 1); s = 0; while (bn_is_even(n1)) { s++; bn_rsh(n1, n1, 1); } bn_lsh(r, n1, s); for (i = 0; i < tests; i++) { /* Fix the basis as the first few primes. */ bn_set_dig(t, primes[i]); /* y = b^r mod a. */ #if BN_MOD != PMERS bn_mxp(y, t, r, a); #else bn_exp(y, t, r, a); #endif if (bn_cmp_dig(y, 1) != CMP_EQ && bn_cmp(y, n1) != CMP_EQ) { j = 1; while ((j <= (s - 1)) && bn_cmp(y, n1) != CMP_EQ) { bn_sqr(y, y); bn_mod(y, y, a); /* If y == 1 then composite. */ if (bn_cmp_dig(y, 1) == CMP_EQ) { result = 0; break; } ++j; } /* If y != n1 then composite. */ if (bn_cmp(y, n1) != CMP_EQ) { result = 0; break; } } } } CATCH_ANY { result = 0; THROW(ERR_CAUGHT); } FINALLY { bn_free(r); bn_free(y); bn_free(n1); bn_free(t); } return result; }
int cp_bgn_dec(dig_t *out, gt_t in[4], bgn_t prv) { int i, result = STS_ERR; g1_t g; g2_t h; gt_t t[4]; bn_t n, r, s; bn_null(n); bn_null(r); bn_null(s); g1_null(g); g2_null(h); TRY { bn_new(n); bn_new(r); bn_new(s); g1_new(g); g2_new(h); for (i = 0; i < 4; i++) { gt_null(t[i]); gt_new(t[i]); } gt_exp(t[0], in[0], prv->x); gt_exp(t[0], t[0], prv->x); gt_mul(t[1], in[1], in[2]); gt_exp(t[1], t[1], prv->x); gt_inv(t[1], t[1]); gt_mul(t[3], in[3], t[1]); gt_mul(t[3], t[3], t[0]); gt_get_ord(n); g1_get_gen(g); g2_get_gen(h); bn_mul(r, prv->x, prv->y); bn_sqr(r, r); bn_mul(s, prv->x, prv->y); bn_mul(s, s, prv->z); bn_sub(r, r, s); bn_sub(r, r, s); bn_sqr(s, prv->z); bn_add(r, r, s); bn_mod(r, r, n); pc_map(t[1], g, h); gt_exp(t[1], t[1], r); gt_copy(t[2], t[1]); if (gt_is_unity(t[3]) == 1) { *out = 0; result = STS_OK; } else { for (i = 0; i < INT_MAX; i++) { if (gt_cmp(t[2], t[3]) == CMP_EQ) { *out = i + 1; result = STS_OK; break; } gt_mul(t[2], t[2], t[1]); } } } CATCH_ANY { result = STS_ERR; } FINALLY { bn_free(n); bn_free(r); bn_free(s); g1_free(g); g2_free(h); for (i = 0; i < 4; i++) { gt_free(t[i]); } } return result; }
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); } }