// find a prime p of length n and a generator alpha of Z^*_p // Alg 4.86 Menezes et al () Handbook, p.164 void gensafeprime(mpint *p, mpint *alpha, int n, int accuracy) { mpint *q, *b; q = mpnew(n-1); while(1){ genprime(q, n-1, accuracy); mpleft(q, 1, p); mpadd(p, mpone, p); // p = 2*q+1 if(probably_prime(p, accuracy)) break; } // now find a generator alpha of the multiplicative // group Z*_p of order p-1=2q b = mpnew(0); while(1){ mprand(n, genrandom, alpha); mpmod(alpha, p, alpha); mpmul(alpha, alpha, b); mpmod(b, p, b); if(mpcmp(b, mpone) == 0) continue; mpexp(alpha, q, p, b); if(mpcmp(b, mpone) != 0) break; } mpfree(b); mpfree(q); }
struct reesa_privkey* genpriv () { /* Allocate a new private key ready-to-use */ struct reesa_privkey* priv = malloc(sizeof(struct reesa_privkey)); mpz_init(priv->q); mpz_init(priv->p); mpz_init(priv->modulus); mpz_init(priv->totient_modulus); mpz_init(priv->private_exponent); mpz_init_set_str(priv->public_exponent, "65537", 10); gmp_randstate_t random_state; gmp_randinit_default(random_state); gmp_randseed_ui(random_state, ++random_seed); void genprime(mpz_t, gmp_randstate_t); genprime(priv->q, random_state); genprime(priv->p, random_state); gmp_randclear(random_state); mpz_mul(priv->modulus, priv->p, priv->q); mpz_t p1; mpz_init(p1); mpz_sub_ui(p1, priv->p, 1); mpz_t q1; mpz_init(q1); mpz_sub_ui(q1, priv->q, 1); mpz_mul(priv->totient_modulus, p1, q1); mpz_clear(q1); mpz_clear(p1); int inverse(mpz_t, const mpz_t, const mpz_t); inverse(priv->private_exponent, priv->public_exponent, priv->totient_modulus); return priv; }
int main(int argc, char **argv) { prime_t start = argc > 1 ? atol(argv[1]) : 0, stop = argc > 2 ? atol(argv[2]) + 1 : 0, x, last; struct timeval begin, end; double duration; for (x = start; x < stop; x += start) { gettimeofday(&begin, NULL); last = genprime(x); gettimeofday(&end, NULL); duration = (double)(end.tv_sec - begin.tv_sec) + ((double)(end.tv_usec) - (double)(begin.tv_usec)) / 1000000.0; printf ("Found %8lu primes in %10.5f seconds (last was %10lu)\n", x, (float)duration, last); } return 0; }
RSApriv* rsagen(int nlen, int elen, int rounds) { mpint *p, *q, *e, *d, *phi, *n, *t1, *t2, *kp, *kq, *c2; RSApriv *rsa; p = mpnew(nlen/2); q = mpnew(nlen/2); n = mpnew(nlen); e = mpnew(elen); d = mpnew(0); phi = mpnew(nlen); // create the prime factors and euclid's function genprime(p, nlen/2, rounds); genprime(q, nlen - mpsignif(p) + 1, rounds); mpmul(p, q, n); mpsub(p, mpone, e); mpsub(q, mpone, d); mpmul(e, d, phi); // find an e relatively prime to phi t1 = mpnew(0); t2 = mpnew(0); mprand(elen, genrandom, e); if(mpcmp(e,mptwo) <= 0) itomp(3, e); // See Menezes et al. p.291 "8.8 Note (selecting primes)" for discussion // of the merits of various choices of primes and exponents. e=3 is a // common and recommended exponent, but doesn't necessarily work here // because we chose strong rather than safe primes. for(;;){ mpextendedgcd(e, phi, t1, d, t2); if(mpcmp(t1, mpone) == 0) break; mpadd(mpone, e, e); } mpfree(t1); mpfree(t2); // compute chinese remainder coefficient c2 = mpnew(0); mpinvert(p, q, c2); // for crt a**k mod p == (a**(k mod p-1)) mod p kq = mpnew(0); kp = mpnew(0); mpsub(p, mpone, phi); mpmod(d, phi, kp); mpsub(q, mpone, phi); mpmod(d, phi, kq); rsa = rsaprivalloc(); rsa->pub.ek = e; rsa->pub.n = n; rsa->dk = d; rsa->kp = kp; rsa->kq = kq; rsa->p = p; rsa->q = q; rsa->c2 = c2; mpfree(phi); return rsa; }
int main() { int t,n,i,j,k,p,s,e,x,y,c,ans,f,d; for(i=0;i<100;i++) check[i]=0; prime[0]=2; c=genprime(1000000); // printf("%d\n",prime[c-1]); // printf("%d\n",c); // for(i=0;i<c;i++) // printf("%d ",prime[i]); // printf("\n"); scanf("%d",&t); while(t--) { scanf("%d %lld %d",&n,&m,&p); for(i=1;i<=n;i++) { scanf("%d",&tazo[i]); a[i].root=i; a[i].wt=tazo[i]; a[i].count=1; } for(i=0;i<m;i++) { scanf("%d %d",&s,&e); x=find(s); y=find(e); // printf("%d %d\n",x,y); if(x!=y) { unionset(x,y); } } ans=0; for(i=1;i<=n;i++) { // printf("%d %d %d %d\n",i,a[i].root,a[i].wt,a[i].count); if(a[i].root==i) { f=0; d=(a[i].wt+p); for(j=0;j<c;j++) { if(d==prime[j]) { f=1; break; } } // printf("f : %d\n",f); if(f==1) { ans++; } } } printf("%d\n",ans); } return 0; }