int BN_rand_range_ex(BIGNUM *r, BN_ULONG min_inclusive, const BIGNUM *max_exclusive, RAND *rng) { unsigned n; unsigned count = 100; if (BN_cmp_word(max_exclusive, min_inclusive) <= 0) { OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE); return 0; } n = BN_num_bits(max_exclusive); /* n > 0 */ /* BN_is_bit_set(range, n - 1) always holds */ if (n == 1) { BN_zero(r); return 1; } do { if (!--count) { OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS); return 0; } if (!BN_is_bit_set(max_exclusive, n - 2) && !BN_is_bit_set(max_exclusive, n - 3)) { /* range = 100..._2, so 3*range (= 11..._2) is exactly one bit longer * than range. This is a common scenario when generating a random value * modulo an RSA public modulus, e.g. for RSA base blinding. */ if (!BN_rand(r, n + 1, -1 /* don't set most significant bits */, 0 /* don't set least significant bits */, rng)) { return 0; } /* If r < 3*range, use r := r MOD range (which is either r, r - range, or * r - 2*range). Otherwise, iterate again. Since 3*range = 11..._2, each * iteration succeeds with probability >= .75. */ if (BN_cmp(r, max_exclusive) >= 0) { if (!BN_sub(r, r, max_exclusive)) { return 0; } if (BN_cmp(r, max_exclusive) >= 0) { if (!BN_sub(r, r, max_exclusive)) { return 0; } } } } else { /* range = 11..._2 or range = 101..._2 */ if (!BN_rand(r, n, -1, 0, rng)) { return 0; } } } while (BN_cmp_word(r, min_inclusive) < 0 || BN_cmp(r, max_exclusive) >= 0); return 1; }
static int bn_rand_range_with_additional_data( BIGNUM *r, BN_ULONG min_inclusive, const BIGNUM *max_exclusive, const uint8_t additional_data[32]) { if (BN_cmp_word(max_exclusive, min_inclusive) <= 0) { OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE); return 0; } /* This function is used to implement steps 4 through 7 of FIPS 186-4 * appendices B.4.2 and B.5.2. When called in those contexts, |max_exclusive| * is n and |min_inclusive| is one. */ unsigned count = 100; unsigned n = BN_num_bits(max_exclusive); /* n > 0 */ do { if (!--count) { OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS); return 0; } if (/* steps 4 and 5 */ !bn_rand_with_additional_data(r, n, BN_RAND_TOP_ANY, BN_RAND_BOTTOM_ANY, additional_data) || /* step 7 */ !BN_add_word(r, min_inclusive)) { return 0; } /* Step 6. This loops if |r| >= |max_exclusive|. This is identical to * checking |r| > |max_exclusive| - 1 or |r| - 1 > |max_exclusive| - 2, the * formulation stated in FIPS 186-4. */ } while (BN_cmp(r, max_exclusive) >= 0); return 1; }
int BN_enhanced_miller_rabin_primality_test( enum bn_primality_result_t *out_result, const BIGNUM *w, int iterations, BN_CTX *ctx, BN_GENCB *cb) { /* Enhanced Miller-Rabin is only valid on odd integers greater than 3. */ if (!BN_is_odd(w) || BN_cmp_word(w, 3) <= 0) { OPENSSL_PUT_ERROR(BN, BN_R_INVALID_INPUT); return 0; } if (iterations == BN_prime_checks) { iterations = BN_prime_checks_for_size(BN_num_bits(w)); } int ret = 0; BN_MONT_CTX *mont = NULL; BN_CTX_start(ctx); BIGNUM *w1 = BN_CTX_get(ctx); if (w1 == NULL || !BN_copy(w1, w) || !BN_sub_word(w1, 1)) { goto err; } /* Write w1 as m*2^a (Steps 1 and 2). */ int a = 0; while (!BN_is_bit_set(w1, a)) { a++; } BIGNUM *m = BN_CTX_get(ctx); if (m == NULL || !BN_rshift(m, w1, a)) { goto err; } BIGNUM *b = BN_CTX_get(ctx); BIGNUM *g = BN_CTX_get(ctx); BIGNUM *z = BN_CTX_get(ctx); BIGNUM *x = BN_CTX_get(ctx); BIGNUM *x1 = BN_CTX_get(ctx); if (b == NULL || g == NULL || z == NULL || x == NULL || x1 == NULL) { goto err; } /* Montgomery setup for computations mod A */ mont = BN_MONT_CTX_new(); if (mont == NULL || !BN_MONT_CTX_set(mont, w, ctx)) { goto err; } /* The following loop performs in inner iteration of the Enhanced Miller-Rabin * Primality test (Step 4). */ for (int i = 1; i <= iterations; i++) { /* Step 4.1-4.2 */ if (!BN_rand_range_ex(b, 2, w1)) { goto err; } /* Step 4.3-4.4 */ if (!BN_gcd(g, b, w, ctx)) { goto err; } if (BN_cmp_word(g, 1) > 0) { *out_result = bn_composite; ret = 1; goto err; } /* Step 4.5 */ if (!BN_mod_exp_mont(z, b, m, w, ctx, mont)) { goto err; } /* Step 4.6 */ if (BN_is_one(z) || BN_cmp(z, w1) == 0) { goto loop; } /* Step 4.7 */ for (int j = 1; j < a; j++) { if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) { goto err; } if (BN_cmp(z, w1) == 0) { goto loop; } if (BN_is_one(z)) { goto composite; } } /* Step 4.8-4.9 */ if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) { goto err; } /* Step 4.10-4.11 */ if (!BN_is_one(z) && !BN_copy(x, z)) { goto err; } composite: /* Step 4.12-4.14 */ if (!BN_copy(x1, x) || !BN_sub_word(x1, 1) || !BN_gcd(g, x1, w, ctx)) { goto err; } if (BN_cmp_word(g, 1) > 0) { *out_result = bn_composite; } else { *out_result = bn_non_prime_power_composite; } ret = 1; goto err; loop: /* Step 4.15 */ if (!BN_GENCB_call(cb, 1, i)) { goto err; } } *out_result = bn_probably_prime; ret = 1; err: BN_MONT_CTX_free(mont); BN_CTX_end(ctx); return ret; }