| 378 | } |
| 379 | |
| 380 | Integer ProvablePrime(RandomNumberGenerator &rng, unsigned int bits) |
| 381 | { |
| 382 | const unsigned smallPrimeBound = 29, c_opt=10; |
| 383 | Integer p; |
| 384 | |
| 385 | BuildPrimeTable(); |
| 386 | if (bits < smallPrimeBound) |
| 387 | { |
| 388 | do |
| 389 | p.Randomize(rng, Integer::Power2(bits-1), Integer::Power2(bits)-1, Integer::ODD); |
| 390 | while (TrialDivision(p, 1 << ((bits+1)/2))); |
| 391 | } |
| 392 | else |
| 393 | { |
| 394 | const unsigned margin = bits > 50 ? 20 : (bits-10)/2; |
| 395 | double relativeSize; |
| 396 | do |
| 397 | relativeSize = pow(2.0, double(rng.GetLong())/0xffffffff - 1); |
| 398 | while (bits * relativeSize >= bits - margin); |
| 399 | |
| 400 | Integer a,b; |
| 401 | Integer q = ProvablePrime(rng, unsigned(bits*relativeSize)); |
| 402 | Integer I = Integer::Power2(bits-2)/q; |
| 403 | Integer I2 = I << 1; |
| 404 | unsigned int trialDivisorBound = (unsigned int)STDMIN((unsigned long)primeTable[primeTableSize-1], (unsigned long)bits*bits/c_opt); |
| 405 | bool success = false; |
| 406 | do |
| 407 | { |
| 408 | p.Randomize(rng, I, I2, Integer::ANY); |
| 409 | p *= q; p <<= 1; ++p; |
| 410 | if (!TrialDivision(p, trialDivisorBound)) |
| 411 | { |
| 412 | a.Randomize(rng, 2, p-1, Integer::ANY); |
| 413 | b = a_exp_b_mod_c(a, (p-1)/q, p); |
| 414 | success = (GCD(b-1, p) == 1) && (a_exp_b_mod_c(b, q, p) == 1); |
| 415 | } |
| 416 | } |
| 417 | while (!success); |
| 418 | } |
| 419 | return p; |
| 420 | } |
| 421 | |
| 422 | Integer CRT(const Integer &xp, const Integer &p, const Integer &xq, const Integer &q, const Integer &u) |
| 423 | { |
nothing calls this directly
no test coverage detected