void bn_gen_prime_basic(bn_t a, int bits) { while (1) { do { bn_rand(a, BN_POS, bits); } while (bn_bits(a) != bits); if (bn_is_prime(a)) { return; } } }
void bn_gen_prime_safep(bn_t a, int bits) { while (1) { do { bn_rand(a, BN_POS, bits); } while (bn_bits(a) != bits); /* Check if (a - 1)/2 is prime. */ bn_sub_dig(a, a, 1); bn_rsh(a, a, 1); if (bn_is_prime(a)) { /* Restore a. */ bn_lsh(a, a, 1); bn_add_dig(a, a, 1); if (bn_is_prime(a)) { /* Should be prime now. */ return; } } } }
int fp_param_set_any_dense() { bn_t modulus; int result = STS_OK; bn_null(modulus); TRY { bn_new(modulus); bn_gen_prime(modulus, FP_BITS); if (!bn_is_prime(modulus)) { result = STS_ERR; } else { fp_prime_set_dense(modulus); } } CATCH_ANY { THROW(ERR_CAUGHT); } FINALLY { bn_free(modulus); } return result; }
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); } }