// only for prime N -- stupid but lazy, see if I care void bn_inv(u8 *d, u8 *a, u8 *N, u32 n) { u8 t[512], s[512]; bn_copy(t, N, n); bn_zero(s, n); s[n-1] = 2; bn_sub_modulus(t, s, n); bn_exp(d, a, N, n, t, n); }
int bn_is_prime_solov(const bn_t a) { bn_t t0, t1, t2; int i, result; bn_null(t0); bn_null(t1); bn_null(t2); result = 1; TRY { bn_new(t0); bn_new(t1); bn_new(t2); for (i = 0; i < 100; i++) { /* Generate t0, 2 <= t0, <= a - 2. */ do { bn_rand(t0, BN_POS, bn_bits(a)); bn_mod(t0, t0, a); } while (bn_cmp_dig(t0, 2) == CMP_LT); /* t2 = a - 1. */ bn_copy(t2, a); bn_sub_dig(t2, t2, 1); /* t1 = (a - 1)/2. */ bn_rsh(t1, t2, 1); /* t1 = t0^(a - 1)/2 mod a. */ #if BN_MOD != PMERS bn_mxp(t1, t0, t1, a); #else bn_exp(t1, t0, t1, a); #endif /* If t1 != 1 and t1 != n - 1 return 0 */ if (bn_cmp_dig(t1, 1) != CMP_EQ && bn_cmp(t1, t2) != CMP_EQ) { result = 0; break; } /* t2 = (t0|a). */ bn_smb_jac(t2, t0, a); if (bn_sign(t2) == BN_NEG) { bn_add(t2, t2, a); } /* If t1 != t2 (mod a) return 0. */ bn_mod(t1, t1, a); bn_mod(t2, t2, a); if (bn_cmp(t1, t2) != CMP_EQ) { result = 0; break; } } } CATCH_ANY { result = 0; THROW(ERR_CAUGHT); } FINALLY { bn_free(t0); bn_free(t1); bn_free(t2); } 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); } }
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; }