#include #include #include #include #include "numalgo.h" #include "primes.h" using namespace std; vector smallprimes; bool smallprimes_inited=false; void fillsmallprimes(){ // cerr<<"Filling small primes..."<roothighbound)continue; for(int j=i*i;j<=highbound;j+=2*i){ composite[j/2-1]=true; } } //for(int p : smallprimes)cerr< genprimepair(int nbits){ // for x = nbits/2: // (2^x)^2 = 2^(2x) // (2^x + 2^(x-2))^2 = 2^(2x) + 2^(2x-1) + 2^(2x-4) // ergo: (2^x + lambda*2^(x-2))^2 \in [2^(2x), 2^(2x+1)), for lambda \in [0,1] // To make sure the primes "differ in length by a few digits" [RSA78], we use x1=x-2 in the first // prime and x2-x+2 in the second int x1=nbits/2-2,x2=(nbits+1)/2+2; assert(x1+x2==nbits); return make_pair( randprime(Bigint::one<biglow); static const int maxrangesize=100001; Bigint diff(bighigh-biglow); Bigint low,high; //inclusive if(diff<=maxrangesize){ low=biglow; high=bighigh; // cerr<<"low=biglow="< maybeprimes; maybeprimes.reserve(nleft); // cerr<<"Left ("<>=1; if(expmod(Bigint::two,d,n)==nm1)return true; } if(expmod(Bigint::two,d,n)==1)return true; return false; } bool bailliePSW(const Bigint &n){ //https://en.wikipedia.org/wiki/Baillie%E2%80%93PSW_primality_test#The_test if(!strongPseudoPrime2(n))return false; int D; if ((D= 5),jacobiSymbol(Bigint(D),n)==-1); else if((D= -7),jacobiSymbol(Bigint(D),n)==-1); else if((D= 9),jacobiSymbol(Bigint(D),n)==-1); else if((D=-11),jacobiSymbol(Bigint(D),n)==-1); else { Bigint root(isqrt(n)); if(root*root==n)return false; //perfect square for(int i=6;;i++){ D=2*i+1; if(i%2==1)D=-D; if(jacobiSymbol(Bigint(D),n)==-1)break; } } //now we have a D int P=1,Q=(1-D)/4; return strongLucasPrime(n,D,P,Q); }