/* find square root of a modulo p (p prime) */ int sqrtmod(int a,int p) { int p8,alpha,i; int x,c,s,n,b,J,r2a,r,ret; mpz_t za,zp; if(p==2) return a&1; mpz_init_set_si(za,a); mpz_init_set_si(zp,p); if(mpz_jacobi(za,zp)!=1) { /* no square root */ ret=0; goto end; } p8=p&7; if(p8==3 || p8==5 || p8==7) { if((p8&3)==3) { ret=powmod(a,(p+1)/4,p); goto end; } x=powmod(a,(p+3)/8,p); c=(ll)x*x%p; ret=c==a?x:(ll)x*powmod(2,(p-1)/4,p)%p; goto end; } alpha=0; s=p-1; while(!(s&1)) s>>=1,alpha++; r=powmod(a,(s+1)/2,p); r2a=(ll)r*powmod(a,(s+1)/2-1,p)%p; do { n=rand31()%(p-2)+2; mpz_set_si(za,n); } while(mpz_jacobi(za,zp)!=-1); b=powmod(n,s,p); J=0; for(i=0;i<alpha-1;i++) { c=powmod(b,2*J,p); c=(ll)r2a*c%p; c=powmod(c,1<<(alpha-i-2),p); if(c==p-1) J+=1<<i; } ret=(ll)r*powmod(b,J,p)%p; end: mpz_clear(zp); mpz_clear(za); return ret; }
/** * Minimal pseudo-random number generation, combining a simple PRNG with * past-collected entropy. * * @return a 31-bit random number. */ static int entropy_rand31(void) { int result; static size_t offset; result = rand31(); /* * Combine with previously generated entropy to create even better * randomness. That previous entropy is refreshed each time a new * entropy collection cycle is initiated. We simply loop over the * five 32-bit words, interpreted in a big-endian way. */ result += peek_be32(ptr_add_offset(&entropy_previous, offset)); offset = (offset + 4) % sizeof entropy_previous; return result & RAND31_MASK; }
double rand01() { return (double)rand31()/(1LL<<31); }