#include #include #include #include "numalgo.h" #include "primes.h" using namespace std; vector smallprimes; bool smallprimes_inited=false; void fillsmallprimes(){ smallprimes_inited=true; //TODO: reserve expected amount of space in smallprimes smallprimes.push_back(2); const int highbound=65000; bool composite[highbound/2]; //entries for 3, 5, 7, 9, etc. memset(composite,0,highbound/2*sizeof(bool)); int roothighbound=sqrt(highbound); for(int i=3;i<=highbound;i+=2){ if(composite[i/2-1])continue; smallprimes.push_back(i); if(i>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; } else { high=low=cryptrandom_big(diff-maxrangesize); high+=maxrangesize; } if(low.even())low+=1; if(high.even())high-=1; Bigint sizeb(high-low+1); assert(sizeb>=0&&sizeb<=maxrangesize); int nnums=(sizeb.lowdigits()+1)/2; bool composite[nnums]; //low, low+2, low+4, ..., high (all odd numbers) memset(composite,0,nnums*sizeof(bool)); int nsmallprimes=smallprimes.size(); for(int i=1;i