int main(int argc, char *argv[]) { mpz_t total; mpz_init_set_str(total, "0", 10); mpz_t i; mpz_init_set_str(i, "1", 10); mpz_t upper_bound; mpz_init_set_str(upper_bound, "9999999996", 10); printf("upper_bound: "); mpz_out_str(stdout, 10, upper_bound); printf("\n"); mpz_t prev_pow; mpz_init_set_str(prev_pow, "1", 10); for (; mpz_cmp(i, upper_bound) < 0; mpz_add_ui(i, i, 1)) { // (i+1)^2 mpz_t tmp; mpz_init(tmp); mpz_add_ui(tmp, i, 1); mpz_pow_ui(tmp, tmp, 2); // prev_pow + tmp mpz_t tmp_sum; mpz_init(tmp_sum); mpz_add(tmp_sum, prev_pow, tmp); // sqrt(prev_pow + tmp) mpf_t result; mpf_init(result); mpf_set_z(result, tmp_sum); mpf_sqrt(result, result); mpz_clear(tmp_sum); mpz_set(prev_pow, tmp); mpz_clear(tmp); // (int) result mpz_t result_int; mpz_init(result_int); mpz_set_f(result_int, result); // (float) (int) result mpf_t result_int_float; mpf_init(result_int_float); mpf_set_z(result_int_float, result_int); // result = (float) (int) result ? if (mpf_cmp(result, result_int_float) == 0) { mpz_out_str(stdout, 10, i); printf("\n"); mpz_add(total, total, i); } mpz_clear(result_int); mpf_clear(result_int_float); mpf_clear(result); } printf("Total: "); mpz_out_str(stdout, 10, total); printf("\n"); mpz_clear(total); mpz_clear(i); mpz_clear(upper_bound); mpz_clear(prev_pow); return 0; }
void main (void) { int i, j, k, kmax, r; int F,C; mpz_t t; mpz_t prod; mpz_t u; mpz_t auxi1; mpz_t auxi2; mpz_init (prod); mpz_init (u); mpz_init (auxi1); mpz_init (auxi2); mpz_init (t); k = 2; kmax = 1; llln_b=llln_proc_entrada(&F,&C); llln_H=new (mpz_t *)[F+1]; for (i=1; i<=F; i++) { llln_H[i]=new mpz_t[F+1]; for (j=1; j<F+1; j++) { mpz_init (llln_H[i][j]); if (i==j) mpz_set_ui (llln_H[i][j],1); else mpz_set_ui (llln_H[i][j],0); } } llln_f=new int[F+1]; llln_d=new mpz_t[F+1]; llln_lambda=new (mpz_t *)[F+1]; mpz_init (llln_d[0]); for (i=1; i<=F; i++) { mpz_init (llln_d[i]); llln_lambda[i]=new mpz_t[F+1]; for (j=1; j<=F; j++) mpz_init(llln_lambda[i][j]); } mpz_set_ui (llln_d[0],1); llln_producto (llln_b[1],llln_b[1], C, &prod); mpz_set (t, prod); if (mpz_cmp_ui (t,0) != 0 ) { mpz_set (llln_d[1], t); llln_f[1]=1; } else { mpz_set_ui (llln_d[1],1); llln_f[1]=0; } while (k <= F) { if (k > kmax) { kmax = k; for (j=1;j<=k;j++) { if (llln_f[j]==0 & j<k) mpz_set_ui (llln_lambda[k][j], 0); else { llln_producto (llln_b[k],llln_b[j], C, &prod); mpz_set (u, prod); for (i=1; i<=j-1; i++) { if (llln_f[i] != 0) { mpz_mul (auxi1, llln_d[i], u); mpz_mul (auxi2, llln_lambda[k][i], llln_lambda[j][i]); mpz_sub (u, auxi1, auxi2); mpz_tdiv_q ( u, u, llln_d[i-1]); } } if (j<k) { mpz_set (llln_lambda[k][j], u); } else { if (mpz_sgn (u) == 0) { mpz_set (llln_d[k], llln_d[k-1]); llln_f[k]=0; } else { mpz_set (llln_d[k], u); llln_f[k]=1; } } } } } llln_test (&k, kmax, C, F); for (i=k-2; i>0; i--) { if (llln_f[i] != 0) llln_redi (k,i,C,F); } k = k+1; } r=0; i=1; while (llln_f[i] == 0 & i<=F) r = i++; for (i=1; i<=r; i++) { printf("\n"); for (j=1; j<=F; j++) { fprintf(stdout, " "); mpz_out_str (stdout, 0, llln_H[i][j]); fprintf(stdout, " "); } printf ("\n"); } mpz_clear (auxi1); mpz_clear (auxi2); mpz_clear (u); mpz_clear (prod); mpz_clear (t); for (i = 1; i <= F; i++) { mpz_clear (llln_d[i]); for (j = 1; j <= F; j++) mpz_clear (llln_lambda[i][j]); mpz_clear (llln_H[i][j]); delete[]llln_lambda[i]; delete[]llln_H[i]; } delete[]llln_lambda; delete[]llln_H; delete[]llln_d; delete[]llln_f; for (i = 1; i < F + 1; i++) { for (j = 1; j < C + 1; j++) mpz_clear (llln_b[i][j]); delete[]llln_b[i]; } delete[]llln_b; }
//============================================ // 四則演算のテストプログラム //============================================ void test_arithmetic_operation(Field f) { int i; unsigned long long int t1, t2; Element a, b, c, d; char loop[] = "100"; mpz_t e, exp; //-------------------- // init //-------------------- element_init(a, f); element_init(b, f); element_init(c, f); element_init(d, f); //-------------------- // add //-------------------- element_set_str(a, "1C12C39A2AD14054EDC9EE504301127AFFEEAADC59A78B50FCFFED87AC6EB8BF 20E1A922384561EA82602CD664D85D442DAC5D391E142ABB3CFEC2A095C22DF9"); element_set_str(b, "F1B91250A124F268B8239185B23B31EB25179A11A9A0398E61B701F7D4F7265 20D206C5F7D007EDBA34A4B041622289D64F04CA28CEAC490619585AA14F7B2F"); element_set_str(d, "7BD59BA97A27FBD2AD60CD0173FC358353DE53D5C418EE8649AFDA729BE2B23 1E42B4E392D45A19EE1EB6EE1F557D8C86F922C32EE2D702C497BAFB3711A927"); element_add(c, a, b); assert(element_cmp(c, d) == 0); t1 = rdtsc(); for (i = 0; i < N; i++) { element_add(c, a, b); } t2 = rdtsc(); printf("element add: %.2lf [clock]\n", (double)(t2 - t1) / N); //-------------------- // sub //-------------------- element_set(d, c); element_sub(c, c, d); assert(element_is_zero(c)); //-------------------- // mul //-------------------- element_mul(c, a, b); element_set_str(d, "1D0562FF0AB317FFDE555320A7072D2B29C07077E08996CE5F093BB8E4200B2C 9B04361A24DC7F37C8BD09A7C51A9D8577168AD021BF2B4AC3D67552F481B1A"); assert(element_cmp(c, d) == 0); t1 = rdtsc(); for (i = 0; i < N; i++) { element_mul(c, a, b); } t2 = rdtsc(); printf("element mul: %.2lf [clock]\n", (double)(t2 - t1) / N); mpz_init_set_str(e, "1B45F16C848B9C476C1D2FF1FD60A0D0C19BBA6F3ECE3CF6C5FCE4FAB7CAD4FF", 16); element_pow(c, a, e); element_set_str(d, "B40190CE812CB4F668A839952128D19B1748F3BB19E902480D089AF9053A6D2 19DA59F09C3C20472C3BD19A4FC95BCAF266B9D1539AAD23E3C67C4F3A7CA51D"); assert(element_cmp(c, d) == 0); mpz_clear(e); //-------------------- // sqr //-------------------- element_sqr(c, a); element_mul(d, a, a); assert(element_cmp(c, d) == 0); t1 = rdtsc(); for (i = 0; i < N; i++) { element_sqr(c, a); } t2 = rdtsc(); printf("element sqr: %.2lf [clock]\n", (double)(t2 - t1) / N); //-------------------- // random //-------------------- element_random(a); element_random(b); //-------------------- // inv //-------------------- element_mul(c, a, b); element_inv(b, b); element_mul(c, c, b); element_inv(d, a); element_mul(d, a, d); assert(element_cmp(c, a) == 0); assert(element_is_one(d)); t1 = rdtsc(); for (i = 0; i < N; i++) { element_inv(b, a); } t2 = rdtsc(); printf("element inv: %.2lf [clock]\n", (double)(t2 - t1) / N); //-------------------- // pow //-------------------- mpz_init_set_str(exp, loop, 10); element_set_one(b); for (i = 0; i < atoi(loop); i++) { element_mul(b, b, a); } element_pow(c, a, exp); assert(element_cmp(b, c) == 0); mpz_set(exp, f->order); for (i = 0; i < 100; i++) { element_random(a); element_pow(b, a, exp); assert(element_cmp(b, a) == 0); } t1 = rdtsc(); for (i = 0; i < N; i++) { element_pow(b, a, exp); } t2 = rdtsc(); printf("element pow with order: %.2lf [clock]\n", (double)(t2 - t1) / N); mpz_clear(exp); //-------------------- // clear //-------------------- element_clear(a); element_clear(b); element_clear(c); element_clear(d); }
struct F { static void eval(RawArray<mp_limb_t> result, RawArray<const Vector<Exact<1>,d>> X) { mpz_set(result,X[1][axis]-X[0][axis]); }};
struct GMPmat *projection(struct GMPmat *inp, int d) { lrs_dic *Pv, *Ph; /* structure for holding current dictionary and indices */ lrs_dat *Qv, *Qh; /* structure for holding static problem data */ lrs_mp_vector output; /* one line of output:ray,vertex,facet,linearity */ lrs_mp_matrix Lin; /* holds input linearities if any are found */ size_t i, j, cols, rows; long col; /* output column index for dictionary */ /* Global initialization - done once */ assert( my_lrs_init () == 0 ); Qv = lrs_alloc_dat ("LRS globals"); assert( Qv!= NULL ); Qv->m = GMPmat_Rows(inp); Qv->n = GMPmat_Cols(inp); output = lrs_alloc_mp_vector (Qv->n); lrs_mp_vector num, den; num = lrs_alloc_mp_vector(GMPmat_Cols(inp)); den = lrs_alloc_mp_vector(GMPmat_Cols(inp)); Pv = lrs_alloc_dic (Qv); /* allocate and initialize lrs_dic */ assert( Pv != NULL ); struct GMPmat *Helper; Helper = GMPmat_create(0, GMPmat_Cols(inp), 1); mpq_t *curRow; curRow = calloc(GMPmat_Cols(inp), sizeof(mpq_t)); assert( curRow != NULL ); mpq_row_init(curRow, GMPmat_Cols(inp)); for (i = 1; i <= GMPmat_Rows(inp); ++i) { GMPmat_getRow(num, den, inp, i-1); lrs_set_row_mp(Pv,Qv,i,num,den,GE); } assert( lrs_getfirstbasis (&Pv, Qv, &Lin, TRUE) ); for (col = 0L; col < Qv->nredundcol; col++) /* print linearity space */ lrs_printoutput (Qv, Lin[col]); do { for (col = 0L; col <= Pv->d; col++) if (lrs_getsolution (Pv, Qv, output, col)) { mpz_to_mpq(curRow, output, GMPmat_Cols(Helper)); Helper = GMPmat_appendRow(Helper, curRow); GMPmal_everyNrows(Helper, pN, "vertices/rays"); } } while (lrs_getnextbasis (&Pv, Qv, FALSE)); mpq_row_clean(curRow, GMPmat_Cols(Helper)); lrs_clear_mp_vector (output, Qv->n); lrs_clear_mp_vector (num, Qv->n); lrs_clear_mp_vector (den, Qv->n); lrs_free_dic (Pv,Qv); /* deallocate lrs_dic */ lrs_free_dat (Qv); /* deallocate lrs_dat */ Helper = reducevertices(Helper); Qh = lrs_alloc_dat ("LRS globals"); assert( Qh != NULL ); Qh->m = GMPmat_Rows(Helper); Qh->n = GMPmat_Cols(Helper) - d; Qh->hull = TRUE; /* convex hull problem: facet enumeration */ Qh->polytope = TRUE; /* input is a polytope */ output = lrs_alloc_mp_vector (Qh->n); num = lrs_alloc_mp_vector (Qh->n); den = lrs_alloc_mp_vector (Qh->n); Ph = lrs_alloc_dic (Qh); assert( Ph != NULL ); struct GMPmat *retVal; retVal = GMPmat_create(0, Qh->n, 0); rows = GMPmat_Rows (Helper); cols = GMPmat_Cols (retVal); curRow = calloc(cols, sizeof(mpq_t)); assert( curRow != NULL ); mpq_row_init(curRow, cols); mpq_t curVal; mpq_init(curVal); for (i = 0; i < rows; ++i) { for (j = 0; j < cols; ++j) { GMPmat_getValue (curVal, Helper, i, j); mpz_set (num[j], mpq_numref(curVal)); mpz_set (den[j], mpq_denref(curVal)); } lrs_set_row_mp (Ph, Qh, i+1 ,num, den, GE); } mpq_clear(curVal); assert( lrs_getfirstbasis (&Ph, Qh, &Lin, TRUE) ); for (col = 0L; col < Qh->nredundcol; col++) /* print linearity space */ lrs_printoutput (Qh, Lin[col]); do { for (col = 0L; col <= Ph->d; col++) if (lrs_getsolution (Ph, Qh, output, col)){ mpz_to_mpq(curRow, output, GMPmat_Cols(retVal)); retVal = GMPmat_appendRow(retVal, curRow); GMPmal_everyNrows(retVal, pN, "inequalities"); } } while (lrs_getnextbasis (&Ph, Qh, FALSE)); GMPmat_destroy(Helper); mpq_row_clean(curRow, GMPmat_Cols(retVal)); lrs_clear_mp_vector (output, Qh->n); lrs_clear_mp_vector (num, Qh->n); lrs_clear_mp_vector (den, Qh->n); lrs_free_dic (Ph,Qh); lrs_free_dat (Qh); // lrs_close ("lrsTrial:"); printf ("\n"); GMPmat_destroy(inp); return retVal; }
/* To generate a DH key either q must be set in the params or * level should be set to the number of required bits. */ static int wrap_nettle_pk_generate_keys(gnutls_pk_algorithm_t algo, unsigned int level /*bits */ , gnutls_pk_params_st * params) { int ret; unsigned int i; switch (algo) { case GNUTLS_PK_DSA: #ifdef ENABLE_FIPS140 { struct dsa_public_key pub; struct dsa_private_key priv; if (params->params[DSA_Q] == NULL) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); _dsa_params_to_pubkey(params, &pub); dsa_private_key_init(&priv); mpz_init(pub.y); ret = dsa_generate_dss_keypair(&pub, &priv, NULL, rnd_func, NULL, NULL); if (ret != 1) { gnutls_assert(); ret = GNUTLS_E_PK_GENERATION_ERROR; goto dsa_fail; } ret = _gnutls_mpi_init_multi(¶ms->params[DSA_Y], ¶ms->params[DSA_X], NULL); if (ret < 0) { gnutls_assert(); goto dsa_fail; } mpz_set(TOMPZ(params->params[DSA_Y]), pub.y); mpz_set(TOMPZ(params->params[DSA_X]), priv.x); params->params_nr += 2; dsa_fail: dsa_private_key_clear(&priv); mpz_clear(pub.y); if (ret < 0) goto fail; break; } #endif case GNUTLS_PK_DH: { struct dsa_public_key pub; mpz_t r; mpz_t x, y; int max_tries; unsigned have_q = 0; if (algo != params->algo) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); _dsa_params_to_pubkey(params, &pub); if (params->params[DSA_Q] != NULL) have_q = 1; /* This check is for the case !ENABLE_FIPS140 */ if (algo == GNUTLS_PK_DSA && have_q == 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); mpz_init(r); mpz_init(x); mpz_init(y); max_tries = 3; do { if (have_q) { mpz_set(r, pub.q); mpz_sub_ui(r, r, 2); nettle_mpz_random(x, NULL, rnd_func, r); mpz_add_ui(x, x, 1); } else { unsigned size = mpz_sizeinbase(pub.p, 2); if (level == 0) level = MIN(size, DH_EXPONENT_SIZE(size)); nettle_mpz_random_size(x, NULL, rnd_func, level); if (level >= size) mpz_mod(x, x, pub.p); } mpz_powm(y, pub.g, x, pub.p); max_tries--; if (max_tries <= 0) { gnutls_assert(); ret = GNUTLS_E_RANDOM_FAILED; goto dh_fail; } } while(mpz_cmp_ui(y, 1) == 0); ret = _gnutls_mpi_init_multi(¶ms->params[DSA_Y], ¶ms->params[DSA_X], NULL); if (ret < 0) { gnutls_assert(); goto dh_fail; } mpz_set(TOMPZ(params->params[DSA_Y]), y); mpz_set(TOMPZ(params->params[DSA_X]), x); params->params_nr += 2; ret = 0; dh_fail: mpz_clear(r); mpz_clear(x); mpz_clear(y); if (ret < 0) goto fail; break; } case GNUTLS_PK_RSA: { struct rsa_public_key pub; struct rsa_private_key priv; rsa_public_key_init(&pub); rsa_private_key_init(&priv); mpz_set_ui(pub.e, 65537); #ifdef ENABLE_FIPS140 ret = rsa_generate_fips186_4_keypair(&pub, &priv, NULL, rnd_func, NULL, NULL, level); #else ret = rsa_generate_keypair(&pub, &priv, NULL, rnd_func, NULL, NULL, level, 0); #endif if (ret != 1) { gnutls_assert(); ret = GNUTLS_E_PK_GENERATION_ERROR; goto rsa_fail; } params->params_nr = 0; for (i = 0; i < RSA_PRIVATE_PARAMS; i++) { ret = _gnutls_mpi_init(¶ms->params[i]); if (ret < 0) { gnutls_assert(); goto rsa_fail; } params->params_nr++; } mpz_set(TOMPZ(params->params[0]), pub.n); mpz_set(TOMPZ(params->params[1]), pub.e); mpz_set(TOMPZ(params->params[2]), priv.d); mpz_set(TOMPZ(params->params[3]), priv.p); mpz_set(TOMPZ(params->params[4]), priv.q); mpz_set(TOMPZ(params->params[5]), priv.c); mpz_set(TOMPZ(params->params[6]), priv.a); mpz_set(TOMPZ(params->params[7]), priv.b); ret = 0; rsa_fail: rsa_private_key_clear(&priv); rsa_public_key_clear(&pub); if (ret < 0) goto fail; break; } case GNUTLS_PK_EC: { struct ecc_scalar key; struct ecc_point pub; const struct ecc_curve *curve; curve = get_supported_curve(level); if (curve == NULL) return gnutls_assert_val (GNUTLS_E_ECC_UNSUPPORTED_CURVE); ecc_scalar_init(&key, curve); ecc_point_init(&pub, curve); ecdsa_generate_keypair(&pub, &key, NULL, rnd_func); ret = _gnutls_mpi_init_multi(¶ms->params[ECC_X], ¶ms->params[ECC_Y], ¶ms->params[ECC_K], NULL); if (ret < 0) { gnutls_assert(); goto ecc_fail; } params->flags = level; params->params_nr = ECC_PRIVATE_PARAMS; ecc_point_get(&pub, TOMPZ(params->params[ECC_X]), TOMPZ(params->params[ECC_Y])); ecc_scalar_get(&key, TOMPZ(params->params[ECC_K])); ret = 0; ecc_fail: ecc_point_clear(&pub); ecc_scalar_clear(&key); if (ret < 0) goto fail; break; } default: gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } FAIL_IF_LIB_ERROR; return 0; fail: for (i = 0; i < params->params_nr; i++) { _gnutls_mpi_release(¶ms->params[i]); } params->params_nr = 0; FAIL_IF_LIB_ERROR; return ret; }
int main(void) { long sd = 0; int t = 20; int s,j_rab;//miller int result = 0; //miller //metavlites gia metatropi keimenou se int k tubalin char mystring[MAXCHARS];//my text to encrypt - decrypt hope so long int str_len; char c; mpz_t max_int, c_int, str_int, encrypted,decrypted; mpz_init(max_int); mpz_init(c_int); mpz_init(str_int);mpz_init(encrypted); mpz_init(decrypted); mpz_t psi, d, n_minus_one;//miller mpz_t n_prime,n,three,two,a,one,p,q,phi,p_minus_one,q_minus_one,e,gcd,d_priv,t2; mpz_t seed; mpz_t ro;//for encry-decry gmp_randinit(stat,GMP_RAND_ALG_LC,120); mpz_init(n_prime); mpz_init(n);//iniatialize mpz_init(three); mpz_init(a); mpz_init(two); mpz_init(one); mpz_init(seed); mpz_init(psi);//for miller-rabin mpz_init(p); mpz_init(q); mpz_init(phi); mpz_init(p_minus_one); mpz_init(q_minus_one); mpz_init(e); mpz_init(gcd); mpz_init(d_priv); mpz_init(ro); mpz_init(t2); mpz_set_str(three, "3", 10); mpz_set_str(two, "2", 10); mpz_set_str(one, "1", 10); srand((unsigned)getpid()); //initialize stat sd = rand(); mpz_set_ui(seed,sd); gmp_randseed(stat,seed); int countpq=0;//0 primes pros to paron, kantous 2 (p kai q) int i = 0; //printf("Give a message (till %d chars):\n",MAXCHARS-1); //fgets(mystring,MAXCHARS,stdin); // FILE *fp; /* declare the file pointer */ fp = fopen ("file.txt", "r"); while(fgets(mystring, MAXCHARS, fp) != NULL) { sscanf (mystring, "%d"); } fclose(fp); // do{ // mehri na vreis 2 prime do{//RANDOM NUMBER mpz_urandomb(n_prime,stat,512);//create a random number }while((mpz_even_p(n_prime))&& (n_prime<=three));//checking n to be >=3 && n be odd mpz_init(n_minus_one); //initialize mpz_sub_ui(n_minus_one, n_prime, 1);//n_minus_one = n-1 s = 0; mpz_init_set(d, n_minus_one); while (mpz_even_p(d)) {// gia oso ine artios mpz_fdiv_q_2exp(d, d, 1); //shift right s++;//inc s } for (i = 0; i < t; ++i) { do{ mpz_urandomb(a,stat,20);//create random number }while(!((a<=(n_prime-two)) && (a>=two)));//checking a must be (2<=a<=n-2) mpz_powm(psi,a,d,n_prime); if(mpz_cmp(psi,one)!=0 && mpz_cmp(psi,n_minus_one)){ j_rab=1; while(j_rab<s && mpz_cmp(psi,n_minus_one)){ mpz_mul(psi,psi,psi); // y^2 mpz_mod(psi,psi,n_prime); //psi= psi^2 mod n if(mpz_cmp(psi,one)==0){//if y=1 result = 1; goto exit_miller; } j_rab++; } if(mpz_cmp(psi,n_minus_one)!=0){//if y=n-1 result = 1; goto exit_miller; } }//end external if }//end for if(result!=1){ countpq++; //an ine prime tote save if(countpq==1){mpz_set(p,n_prime);}//save p else{ mpz_set(q,n_prime);}//save q } exit_miller: result = 0; if(mpz_cmp(p,q)==0){countpq=0;}//an p kai q idioi pame pali }while(countpq<2); gmp_printf ("p = %Zd\n", p); gmp_printf ("q = %Zd\n", q); mpz_mul(n,p,q); //calculate p*q gmp_printf ("n = p*q = %Zd\n", n); mpz_sub(p_minus_one,p,one); mpz_sub(q_minus_one,q,one); gmp_printf ("p-1 = %Zd\n", p_minus_one); gmp_printf ("q-1 = %Zd\n", q_minus_one); mpz_mul(phi,p_minus_one,q_minus_one); gmp_printf ("phi = %Zd\n", phi); do{ mpz_urandomm(e,stat,phi);//create random number e opou < tou phi mpz_add(e,e,two);//add two to be bigger the e from ena mpz_gcd(gcd,e,phi); }while((!(mpz_cmp(gcd,one)==0)));//checking..gcd=1 gmp_printf ("e = %Zd\n", e); gmp_printf ("gcd = %Zd\n", gcd); mpz_invert(d_priv,e,phi);//ypologismos antistrofou e mod phi gmp_printf ("private key (d) = %Zd\n", d_priv); gmp_printf ("public key (n,e) = (%Zd , %Zd)\n", n,e); ////// convert myText to myIntegerText str_len = strlen(mystring); if(mystring[str_len - 1] == '\n') mystring[str_len - 1] = '\0'; str_len = strlen(mystring); printf("%s -> %ld \n", mystring, str_len); for(i = str_len - 1; i >= 0; i--){ c = mystring[i]; mpz_mul_ui(ro,ro,BASE); // r=r*BASE mpz_add_ui(ro, ro, c); // r=r+c }//now ro is mystring as Integers gmp_printf("My text is: %s and has %ld chars.\nAs Integer is:%Zd",mystring, strlen(mystring), ro); ////// encrypt text mpz_powm(encrypted,ro,e,n);// gmp_printf("\nEncrypted message is: %Zd",encrypted); //// //// create encrypted file fp= fopen("encrypted_file.txt","w"); fprintf(fp, encrypted); fclose(fp); //// ////// decrypt text mpz_powm(decrypted,encrypted,d_priv,n);// gmp_printf("\nDecrypted message is: %Zd",decrypted); ////// convert myIntegerText to myText mpz_set(str_int, ro);//integerText to mytext mpz_set_ui(max_int, 1UL);//larger int set for(i = 0; i < 10; i++){// maxlength =100 if(mpz_cmp(str_int, max_int) <= 0){ str_len = i; break;} mpz_mul_ui(max_int, max_int, BASE);} for(i = 0; i < str_len; i++){ mpz_mod_ui(c_int, str_int,BASE); // ekxoreitai sthn metablhth c_int=str_int mod BASE mpz_sub(str_int, str_int, c_int); mpz_tdiv_q_ui(str_int, str_int,BASE); mystring[i] = mpz_get_ui(c_int);} mystring[str_len] = '\0'; //printf("Num of Chars--> %ld\n", str_len); ///////plaintext gmp_printf("\nPlaintext message is: %s",mystring); mpz_clear(n_prime); mpz_clear(n);//clear mpz_clear(three); mpz_clear(a); mpz_clear(two); mpz_clear(seed); mpz_clear(one); mpz_clear(d); mpz_clear(n_minus_one); mpz_clear(psi); mpz_clear(p); mpz_clear(q); mpz_clear(phi); mpz_clear(p_minus_one); mpz_clear(q_minus_one); mpz_clear(e); mpz_clear(gcd); mpz_clear(d_priv); mpz_clear(ro); mpz_clear(max_int); mpz_clear(c_int); mpz_clear(str_int); mpz_clear(t2); mpz_clear(encrypted); mpz_clear(decrypted); return 0; }
static void mpz_b_1_op(cl_object out, cl_object i, cl_object j) { if (i != out) mpz_set(out->big.big_num, i->big.big_num); }
static void mpz_b_2_op(cl_object out, cl_object i, cl_object j) { mpz_set(out->big.big_num, j->big.big_num); }
/* Valid sizes, according to FIPS 186-3 are (1024, 160), (2048. 224), (2048, 256), (3072, 256). Currenty, we use only q_bits of 160 or 256. */ int dsa_generate_keypair(struct dsa_public_key *pub, struct dsa_private_key *key, void *random_ctx, nettle_random_func *random, void *progress_ctx, nettle_progress_func *progress, unsigned p_bits, unsigned q_bits) { mpz_t p0, p0q, r; unsigned p0_bits; unsigned a; switch (q_bits) { case 160: if (p_bits < DSA_SHA1_MIN_P_BITS) return 0; break; case 256: if (p_bits < DSA_SHA256_MIN_P_BITS) return 0; break; default: return 0; } mpz_init (p0); mpz_init (p0q); mpz_init (r); nettle_random_prime (pub->q, q_bits, 0, random_ctx, random, progress_ctx, progress); p0_bits = (p_bits + 3)/2; nettle_random_prime (p0, p0_bits, 0, random_ctx, random, progress_ctx, progress); if (progress) progress (progress_ctx, 'q'); /* Generate p = 2 r q p0 + 1, such that 2^{n-1} < p < 2^n. * * We select r in the range i + 1 < r <= 2i, with i = floor (2^{n-2} / (p0 q). */ mpz_mul (p0q, p0, pub->q); _nettle_generate_pocklington_prime (pub->p, r, p_bits, 0, random_ctx, random, p0, pub->q, p0q); if (progress) progress (progress_ctx, 'p'); mpz_mul (r, r, p0); for (a = 2; ; a++) { mpz_set_ui (pub->g, a); mpz_powm (pub->g, pub->g, r, pub->p); if (mpz_cmp_ui (pub->g, 1) != 0) break; } if (progress) progress (progress_ctx, 'g'); mpz_set(r, pub->q); mpz_sub_ui(r, r, 2); nettle_mpz_random(key->x, random_ctx, random, r); mpz_add_ui(key->x, key->x, 1); mpz_powm(pub->y, pub->g, key->x, pub->p); if (progress) progress (progress_ctx, '\n'); mpz_clear (p0); mpz_clear (p0q); mpz_clear (r); return 1; }
mp_bitcnt_t mpz_remove (mpz_ptr dest, mpz_srcptr src, mpz_srcptr f) { mpz_t fpow[GMP_LIMB_BITS]; /* Really MP_SIZE_T_BITS */ mpz_t x, rem; mp_bitcnt_t pwr; int p; if (mpz_cmp_ui (f, 1) <= 0) DIVIDE_BY_ZERO; if (SIZ (src) == 0) { if (src != dest) mpz_set (dest, src); return 0; } if (mpz_cmp_ui (f, 2) == 0) { mp_bitcnt_t s0; s0 = mpz_scan1 (src, 0); mpz_div_2exp (dest, src, s0); return s0; } /* We could perhaps compute mpz_scan1(src,0)/mpz_scan1(f,0). It is an upper bound of the result we're seeking. We could also shift down the operands so that they become odd, to make intermediate values smaller. */ mpz_init (rem); mpz_init (x); pwr = 0; mpz_init (fpow[0]); mpz_set (fpow[0], f); mpz_set (dest, src); /* Divide by f, f^2, ..., f^(2^k) until we get a remainder for f^(2^k). */ for (p = 0;; p++) { mpz_tdiv_qr (x, rem, dest, fpow[p]); if (SIZ (rem) != 0) break; mpz_init (fpow[p + 1]); mpz_mul (fpow[p + 1], fpow[p], fpow[p]); mpz_set (dest, x); } pwr = (1L << p) - 1; mpz_clear (fpow[p]); /* Divide by f^(2^(k-1)), f^(2^(k-2)), ..., f for all divisors that give a zero remainder. */ while (--p >= 0) { mpz_tdiv_qr (x, rem, dest, fpow[p]); if (SIZ (rem) == 0) { pwr += 1L << p; mpz_set (dest, x); } mpz_clear (fpow[p]); } mpz_clear (x); mpz_clear (rem); return pwr; }
void gfc_advance_section (mpz_t *section_index, gfc_array_ref *ar, mpz_t *offset_ret) { int i; mpz_t delta; mpz_t tmp; bool forwards; int cmp; for (i = 0; i < ar->dimen; i++) { if (ar->dimen_type[i] != DIMEN_RANGE) continue; if (ar->stride[i]) { mpz_add (section_index[i], section_index[i], ar->stride[i]->value.integer); if (mpz_cmp_si (ar->stride[i]->value.integer, 0) >= 0) forwards = true; else forwards = false; } else { mpz_add_ui (section_index[i], section_index[i], 1); forwards = true; } if (ar->end[i]) cmp = mpz_cmp (section_index[i], ar->end[i]->value.integer); else cmp = mpz_cmp (section_index[i], ar->as->upper[i]->value.integer); if ((cmp > 0 && forwards) || (cmp < 0 && !forwards)) { /* Reset index to start, then loop to advance the next index. */ if (ar->start[i]) mpz_set (section_index[i], ar->start[i]->value.integer); else mpz_set (section_index[i], ar->as->lower[i]->value.integer); } else break; } mpz_set_si (*offset_ret, 0); mpz_init_set_si (delta, 1); mpz_init (tmp); for (i = 0; i < ar->dimen; i++) { mpz_sub (tmp, section_index[i], ar->as->lower[i]->value.integer); mpz_mul (tmp, tmp, delta); mpz_add (*offset_ret, tmp, *offset_ret); mpz_sub (tmp, ar->as->upper[i]->value.integer, ar->as->lower[i]->value.integer); mpz_add_ui (tmp, tmp, 1); mpz_mul (delta, tmp, delta); } mpz_clear (tmp); mpz_clear (delta); }
gfc_try gfc_assign_data_value (gfc_expr *lvalue, gfc_expr *rvalue, mpz_t index, mpz_t *repeat) { gfc_ref *ref; gfc_expr *init; gfc_expr *expr = NULL; gfc_constructor *con; gfc_constructor *last_con; gfc_symbol *symbol; gfc_typespec *last_ts; mpz_t offset; symbol = lvalue->symtree->n.sym; init = symbol->value; last_ts = &symbol->ts; last_con = NULL; mpz_init_set_si (offset, 0); /* Find/create the parent expressions for subobject references. */ for (ref = lvalue->ref; ref; ref = ref->next) { /* Break out of the loop if we find a substring. */ if (ref->type == REF_SUBSTRING) { /* A substring should always be the last subobject reference. */ gcc_assert (ref->next == NULL); break; } /* Use the existing initializer expression if it exists. Otherwise create a new one. */ if (init == NULL) expr = gfc_get_expr (); else expr = init; /* Find or create this element. */ switch (ref->type) { case REF_ARRAY: if (ref->u.ar.as->rank == 0) { gcc_assert (ref->u.ar.as->corank > 0); if (init == NULL) free (expr); continue; } if (init && expr->expr_type != EXPR_ARRAY) { gfc_error ("'%s' at %L already is initialized at %L", lvalue->symtree->n.sym->name, &lvalue->where, &init->where); goto abort; } if (init == NULL) { /* The element typespec will be the same as the array typespec. */ expr->ts = *last_ts; /* Setup the expression to hold the constructor. */ expr->expr_type = EXPR_ARRAY; expr->rank = ref->u.ar.as->rank; } if (ref->u.ar.type == AR_ELEMENT) get_array_index (&ref->u.ar, &offset); else mpz_set (offset, index); /* Check the bounds. */ if (mpz_cmp_si (offset, 0) < 0) { gfc_error ("Data element below array lower bound at %L", &lvalue->where); goto abort; } else if (repeat != NULL && ref->u.ar.type != AR_ELEMENT) { mpz_t size, end; gcc_assert (ref->u.ar.type == AR_FULL && ref->next == NULL); mpz_init_set (end, offset); mpz_add (end, end, *repeat); if (spec_size (ref->u.ar.as, &size) == SUCCESS) { if (mpz_cmp (end, size) > 0) { mpz_clear (size); gfc_error ("Data element above array upper bound at %L", &lvalue->where); goto abort; } mpz_clear (size); } con = gfc_constructor_lookup (expr->value.constructor, mpz_get_si (offset)); if (!con) { con = gfc_constructor_lookup_next (expr->value.constructor, mpz_get_si (offset)); if (con != NULL && mpz_cmp (con->offset, end) >= 0) con = NULL; } /* Overwriting an existing initializer is non-standard but usually only provokes a warning from other compilers. */ if (con != NULL && con->expr != NULL) { /* Order in which the expressions arrive here depends on whether they are from data statements or F95 style declarations. Therefore, check which is the most recent. */ gfc_expr *exprd; exprd = (LOCATION_LINE (con->expr->where.lb->location) > LOCATION_LINE (rvalue->where.lb->location)) ? con->expr : rvalue; if (gfc_notify_std (GFC_STD_GNU, "re-initialization of '%s' at %L", symbol->name, &exprd->where) == FAILURE) return FAILURE; } while (con != NULL) { gfc_constructor *next_con = gfc_constructor_next (con); if (mpz_cmp (con->offset, end) >= 0) break; if (mpz_cmp (con->offset, offset) < 0) { gcc_assert (mpz_cmp_si (con->repeat, 1) > 0); mpz_sub (con->repeat, offset, con->offset); } else if (mpz_cmp_si (con->repeat, 1) > 0 && mpz_get_si (con->offset) + mpz_get_si (con->repeat) > mpz_get_si (end)) { int endi; splay_tree_node node = splay_tree_lookup (con->base, mpz_get_si (con->offset)); gcc_assert (node && con == (gfc_constructor *) node->value && node->key == (splay_tree_key) mpz_get_si (con->offset)); endi = mpz_get_si (con->offset) + mpz_get_si (con->repeat); if (endi > mpz_get_si (end) + 1) mpz_set_si (con->repeat, endi - mpz_get_si (end)); else mpz_set_si (con->repeat, 1); mpz_set (con->offset, end); node->key = (splay_tree_key) mpz_get_si (end); break; } else gfc_constructor_remove (con); con = next_con; } con = gfc_constructor_insert_expr (&expr->value.constructor, NULL, &rvalue->where, mpz_get_si (offset)); mpz_set (con->repeat, *repeat); repeat = NULL; mpz_clear (end); break; } else { mpz_t size; if (spec_size (ref->u.ar.as, &size) == SUCCESS) { if (mpz_cmp (offset, size) >= 0) { mpz_clear (size); gfc_error ("Data element above array upper bound at %L", &lvalue->where); goto abort; } mpz_clear (size); } } con = gfc_constructor_lookup (expr->value.constructor, mpz_get_si (offset)); if (!con) { con = gfc_constructor_insert_expr (&expr->value.constructor, NULL, &rvalue->where, mpz_get_si (offset)); } else if (mpz_cmp_si (con->repeat, 1) > 0) { /* Need to split a range. */ if (mpz_cmp (con->offset, offset) < 0) { gfc_constructor *pred_con = con; con = gfc_constructor_insert_expr (&expr->value.constructor, NULL, &con->where, mpz_get_si (offset)); con->expr = gfc_copy_expr (pred_con->expr); mpz_add (con->repeat, pred_con->offset, pred_con->repeat); mpz_sub (con->repeat, con->repeat, offset); mpz_sub (pred_con->repeat, offset, pred_con->offset); } if (mpz_cmp_si (con->repeat, 1) > 0) { gfc_constructor *succ_con; succ_con = gfc_constructor_insert_expr (&expr->value.constructor, NULL, &con->where, mpz_get_si (offset) + 1); succ_con->expr = gfc_copy_expr (con->expr); mpz_sub_ui (succ_con->repeat, con->repeat, 1); mpz_set_si (con->repeat, 1); } } break; case REF_COMPONENT: if (init == NULL) { /* Setup the expression to hold the constructor. */ expr->expr_type = EXPR_STRUCTURE; expr->ts.type = BT_DERIVED; expr->ts.u.derived = ref->u.c.sym; } else gcc_assert (expr->expr_type == EXPR_STRUCTURE); last_ts = &ref->u.c.component->ts; /* Find the same element in the existing constructor. */ con = find_con_by_component (ref->u.c.component, expr->value.constructor); if (con == NULL) { /* Create a new constructor. */ con = gfc_constructor_append_expr (&expr->value.constructor, NULL, NULL); con->n.component = ref->u.c.component; } break; default: gcc_unreachable (); } if (init == NULL) { /* Point the container at the new expression. */ if (last_con == NULL) symbol->value = expr; else last_con->expr = expr; } init = con->expr; last_con = con; } mpz_clear (offset); gcc_assert (repeat == NULL); if (ref || last_ts->type == BT_CHARACTER) { if (lvalue->ts.u.cl->length == NULL && !(ref && ref->u.ss.length != NULL)) return FAILURE; expr = create_character_initializer (init, last_ts, ref, rvalue); } else { /* Overwriting an existing initializer is non-standard but usually only provokes a warning from other compilers. */ if (init != NULL) { /* Order in which the expressions arrive here depends on whether they are from data statements or F95 style declarations. Therefore, check which is the most recent. */ expr = (LOCATION_LINE (init->where.lb->location) > LOCATION_LINE (rvalue->where.lb->location)) ? init : rvalue; if (gfc_notify_std (GFC_STD_GNU, "re-initialization of '%s' at %L", symbol->name, &expr->where) == FAILURE) return FAILURE; } expr = gfc_copy_expr (rvalue); if (!gfc_compare_types (&lvalue->ts, &expr->ts)) gfc_convert_type (expr, &lvalue->ts, 0); } if (last_con == NULL) symbol->value = expr; else last_con->expr = expr; return SUCCESS; abort: if (!init) gfc_free_expr (expr); mpz_clear (offset); return FAILURE; }
void check_random (int argc, char *argv[]) { mpz_t x, s0, s1, s2, s3, m; mp_size_t xsize; int i; int reps = 100000; int bit0, bit1, bit2, bit3; unsigned long int bitindex; const char *s = ""; if (argc == 2) reps = atoi (argv[1]); mpz_init (x); mpz_init (s0); mpz_init (s1); mpz_init (s2); mpz_init (s3); mpz_init (m); for (i = 0; i < reps; i++) { xsize = urandom () % (2 * SIZE) - SIZE; mpz_random2 (x, xsize); bitindex = urandom () % SIZE; mpz_set (s0, x); bit0 = mpz_tstbit (x, bitindex); mpz_setbit (x, bitindex); MPZ_CHECK_FORMAT (x); mpz_set (s1, x); bit1 = mpz_tstbit (x, bitindex); mpz_clrbit (x, bitindex); MPZ_CHECK_FORMAT (x); mpz_set (s2, x); bit2 = mpz_tstbit (x, bitindex); mpz_setbit (x, bitindex); MPZ_CHECK_FORMAT (x); mpz_set (s3, x); bit3 = mpz_tstbit (x, bitindex); #define FAIL(str) do { s = str; goto fail; } while (0) if (bit1 != 1) FAIL ("bit1 != 1"); if (bit2 != 0) FAIL ("bit2 != 0"); if (bit3 != 1) FAIL ("bit3 != 1"); if (bit0 == 0) { if (mpz_cmp (s0, s1) == 0 || mpz_cmp (s0, s2) != 0 || mpz_cmp (s0, s3) == 0) abort (); } else { if (mpz_cmp (s0, s1) != 0 || mpz_cmp (s0, s2) == 0 || mpz_cmp (s0, s3) != 0) abort (); } if (mpz_cmp (s1, s2) == 0 || mpz_cmp (s1, s3) != 0) abort (); if (mpz_cmp (s2, s3) == 0) abort (); mpz_ui_pow_ui (m, 2L, bitindex); MPZ_CHECK_FORMAT (m); mpz_ior (x, s2, m); MPZ_CHECK_FORMAT (x); if (mpz_cmp (x, s3) != 0) abort (); mpz_com (m, m); MPZ_CHECK_FORMAT (m); mpz_and (x, s1, m); MPZ_CHECK_FORMAT (x); if (mpz_cmp (x, s2) != 0) abort (); } mpz_clear (x); mpz_clear (s0); mpz_clear (s1); mpz_clear (s2); mpz_clear (s3); mpz_clear (m); return; fail: printf ("%s\n", s); printf ("bitindex = %lu\n", bitindex); printf ("x = "); mpz_out_str (stdout, -16, x); printf (" hex\n"); exit (1); }
BigInteger &operator=(const BigInteger &i) { mpz_set(integer, i.integer); return *this; }
void check_all (mpz_ptr want, mpz_srcptr x_orig, mpz_srcptr y_orig) { mpz_t got, x, y; int negx, negy, swap, inplace; mpz_init (got); mpz_init_set (x, x_orig); mpz_init_set (y, y_orig); for (swap = 0; swap < 2; swap++) { mpz_swap (x, y); for (negx = 0; negx < 2; negx++) { mpz_neg (x, x); for (negy = 0; negy < 2; negy++) { mpz_neg (y, y); for (inplace = 0; inplace <= 1; inplace++) { if (inplace) { mpz_set (got, x); mpz_lcm (got, got, y); } else mpz_lcm (got, x, y); MPZ_CHECK_FORMAT (got); if (mpz_cmp (got, want) != 0) { printf ("mpz_lcm wrong, inplace=%d\n", inplace); fail: mpz_trace ("x", x); mpz_trace ("y", y); mpz_trace ("got", got); mpz_trace ("want", want); abort (); } if (mpz_fits_ulong_p (y)) { unsigned long yu = mpz_get_ui (y); if (inplace) { mpz_set (got, x); mpz_lcm_ui (got, got, yu); } else mpz_lcm_ui (got, x, yu); if (mpz_cmp (got, want) != 0) { printf ("mpz_lcm_ui wrong, inplace=%d\n", inplace); printf ("yu=%lu\n", yu); goto fail; } } } } } } mpz_clear (got); mpz_clear (x); mpz_clear (y); }
int main (int argc, char **argv) { int i; int pass, reps = 400; mpz_t in1, in2, in3; unsigned long int in2i; mp_size_t size; mpz_t res1, res2, res3; mpz_t ref1, ref2, ref3; mpz_t t; unsigned long int r1, r2; gmp_randstate_ptr rands; mpz_t bs; unsigned long bsi, size_range; tests_start (); TESTS_REPS (reps, argv, argc); rands = RANDS; mpz_init (bs); mpz_init (in1); mpz_init (in2); mpz_init (in3); mpz_init (ref1); mpz_init (ref2); mpz_init (ref3); mpz_init (res1); mpz_init (res2); mpz_init (res3); mpz_init (t); for (pass = 1; pass <= reps; pass++) { if (isatty (fileno (stdout))) { printf ("\r%d/%d passes", pass, reps); fflush (stdout); } mpz_urandomb (bs, rands, 32); size_range = mpz_get_ui (bs) % 21 + 2; if ((pass & 1) == 0) { /* Make all input operands have quite different sizes */ mpz_urandomb (bs, rands, 32); size = mpz_get_ui (bs) % size_range; mpz_rrandomb (in1, rands, size); mpz_urandomb (bs, rands, 32); size = mpz_get_ui (bs) % size_range; mpz_rrandomb (in2, rands, size); mpz_urandomb (bs, rands, 32); size = mpz_get_ui (bs) % size_range; mpz_rrandomb (in3, rands, size); } else { /* Make all input operands have about the same size */ mpz_urandomb (bs, rands, size_range); size = mpz_get_ui (bs); mpz_rrandomb (in1, rands, size); mpz_urandomb (bs, rands, size_range); size = mpz_get_ui (bs); mpz_rrandomb (in2, rands, size); mpz_urandomb (bs, rands, size_range); size = mpz_get_ui (bs); mpz_rrandomb (in3, rands, size); } mpz_urandomb (bs, rands, 3); bsi = mpz_get_ui (bs); if ((bsi & 1) != 0) mpz_neg (in1, in1); if ((bsi & 2) != 0) mpz_neg (in2, in2); if ((bsi & 4) != 0) mpz_neg (in3, in3); for (i = 0; i < numberof (dss); i++) { if (dss[i].isdivision && mpz_sgn (in2) == 0) continue; if (dss[i].isslow && size_range > 19) continue; (dss[i].fptr) (ref1, in1, in2); MPZ_CHECK_FORMAT (ref1); mpz_set (res1, in1); INVOKE_RSS (dss[i], res1, res1, in2); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0) FAIL (dss, i, in1, in2, NULL); mpz_set (res1, in2); INVOKE_RSS (dss[i], res1, in1, res1); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0) FAIL (dss, i, in1, in2, NULL); } for (i = 0; i < numberof (ddss_div); i++) { if (mpz_sgn (in2) == 0) continue; (ddss_div[i].fptr) (ref1, ref2, in1, in2); MPZ_CHECK_FORMAT (ref1); MPZ_CHECK_FORMAT (ref2); mpz_set (res1, in1); INVOKE_RRSS (ddss_div[i], res1, res2, res1, in2); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) FAIL (ddss_div, i, in1, in2, NULL); mpz_set (res2, in1); INVOKE_RRSS (ddss_div[i], res1, res2, res2, in2); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) FAIL (ddss_div, i, in1, in2, NULL); mpz_set (res1, in2); INVOKE_RRSS (ddss_div[i], res1, res2, in1, res1); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) FAIL (ddss_div, i, in1, in2, NULL); mpz_set (res2, in2); INVOKE_RRSS (ddss_div[i], res1, res2, in1, res2); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) FAIL (ddss_div, i, in1, in2, NULL); } for (i = 0; i < numberof (ds); i++) { if (ds[i].nonneg && mpz_sgn (in1) < 0) continue; (ds[i].fptr) (ref1, in1); MPZ_CHECK_FORMAT (ref1); mpz_set (res1, in1); INVOKE_RS (ds[i], res1, res1); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0) FAIL (ds, i, in1, in2, NULL); } in2i = mpz_get_ui (in2); for (i = 0; i < numberof (dsi); i++) { if (dsi[i].mod != 0) in2i = mpz_get_ui (in2) % dsi[i].mod; (dsi[i].fptr) (ref1, in1, in2i); MPZ_CHECK_FORMAT (ref1); mpz_set (res1, in1); INVOKE_RRS (dsi[i], res1, res1, in2i); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0) FAIL (dsi, i, in1, in2, NULL); } if (in2i != 0) /* Don't divide by 0. */ { for (i = 0; i < numberof (dsi_div); i++) { r1 = (dsi_div[i].fptr) (ref1, in1, in2i); MPZ_CHECK_FORMAT (ref1); mpz_set (res1, in1); r2 = (dsi_div[i].fptr) (res1, res1, in2i); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0 || r1 != r2) FAIL (dsi_div, i, in1, in2, NULL); } for (i = 0; i < numberof (ddsi_div); i++) { r1 = (ddsi_div[i].fptr) (ref1, ref2, in1, in2i); MPZ_CHECK_FORMAT (ref1); mpz_set (res1, in1); r2 = (ddsi_div[i].fptr) (res1, res2, res1, in2i); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2) FAIL (ddsi_div, i, in1, in2, NULL); mpz_set (res2, in1); (ddsi_div[i].fptr) (res1, res2, res2, in2i); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || r1 != r2) FAIL (ddsi_div, i, in1, in2, NULL); } } if (mpz_sgn (in1) >= 0) { mpz_sqrtrem (ref1, ref2, in1); MPZ_CHECK_FORMAT (ref1); MPZ_CHECK_FORMAT (ref2); mpz_set (res1, in1); mpz_sqrtrem (res1, res2, res1); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) FAIL2 (mpz_sqrtrem, in1, NULL, NULL); mpz_set (res2, in1); mpz_sqrtrem (res1, res2, res2); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) FAIL2 (mpz_sqrtrem, in1, NULL, NULL); mpz_set (res1, in1); mpz_sqrtrem (res1, res1, res1); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref2, res1) != 0) FAIL2 (mpz_sqrtrem, in1, NULL, NULL); } if (mpz_sgn (in1) >= 0) { mpz_root (ref1, in1, in2i % 0x100 + 1); MPZ_CHECK_FORMAT (ref1); mpz_set (res1, in1); mpz_root (res1, res1, in2i % 0x100 + 1); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0) FAIL2 (mpz_root, in1, in2, NULL); } if (mpz_sgn (in1) >= 0) { mpz_rootrem (ref1, ref2, in1, in2i % 0x100 + 1); MPZ_CHECK_FORMAT (ref1); MPZ_CHECK_FORMAT (ref2); mpz_set (res1, in1); mpz_rootrem (res1, res2, res1, in2i % 0x100 + 1); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) FAIL2 (mpz_rootrem, in1, in2, NULL); mpz_set (res2, in1); mpz_rootrem (res1, res2, res2, in2i % 0x100 + 1); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0) FAIL2 (mpz_rootrem, in1, in2, NULL); } if (size_range < 18) /* run fewer tests since gcdext lots of time */ { mpz_gcdext (ref1, ref2, ref3, in1, in2); MPZ_CHECK_FORMAT (ref1); MPZ_CHECK_FORMAT (ref2); MPZ_CHECK_FORMAT (ref3); mpz_set (res1, in1); mpz_gcdext (res1, res2, res3, res1, in2); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); MPZ_CHECK_FORMAT (res3); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || mpz_cmp (ref3, res3) != 0) FAIL2 (mpz_gcdext, in1, in2, NULL); mpz_set (res2, in1); mpz_gcdext (res1, res2, res3, res2, in2); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); MPZ_CHECK_FORMAT (res3); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || mpz_cmp (ref3, res3) != 0) FAIL2 (mpz_gcdext, in1, in2, NULL); mpz_set (res3, in1); mpz_gcdext (res1, res2, res3, res3, in2); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); MPZ_CHECK_FORMAT (res3); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || mpz_cmp (ref3, res3) != 0) FAIL2 (mpz_gcdext, in1, in2, NULL); mpz_set (res1, in2); mpz_gcdext (res1, res2, res3, in1, res1); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); MPZ_CHECK_FORMAT (res3); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || mpz_cmp (ref3, res3) != 0) FAIL2 (mpz_gcdext, in1, in2, NULL); mpz_set (res2, in2); mpz_gcdext (res1, res2, res3, in1, res2); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); MPZ_CHECK_FORMAT (res3); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || mpz_cmp (ref3, res3) != 0) FAIL2 (mpz_gcdext, in1, in2, NULL); mpz_set (res3, in2); mpz_gcdext (res1, res2, res3, in1, res3); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); MPZ_CHECK_FORMAT (res3); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || mpz_cmp (ref3, res3) != 0) FAIL2 (mpz_gcdext, in1, in2, NULL); mpz_set (res1, in1); mpz_gcdext (res1, res2, NULL, res1, in2); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || mpz_cmp (ref3, res3) != 0) FAIL2 (mpz_gcdext, in1, in2, NULL); mpz_set (res2, in1); mpz_gcdext (res1, res2, NULL, res2, in2); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || mpz_cmp (ref3, res3) != 0) FAIL2 (mpz_gcdext, in1, in2, NULL); mpz_set (res1, in2); mpz_gcdext (res1, res2, NULL, in1, res1); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || mpz_cmp (ref3, res3) != 0) FAIL2 (mpz_gcdext, in1, in2, NULL); mpz_set (res2, in2); mpz_gcdext (res1, res2, NULL, in1, res2); MPZ_CHECK_FORMAT (res1); MPZ_CHECK_FORMAT (res2); if (mpz_cmp (ref1, res1) != 0 || mpz_cmp (ref2, res2) != 0 || mpz_cmp (ref3, res3) != 0) FAIL2 (mpz_gcdext, in1, in2, NULL); } /* Don't run mpz_powm for huge exponents or when undefined. */ if (size_range < 17 && mpz_sizeinbase (in2, 2) < 250 && mpz_sgn (in3) != 0 && (mpz_sgn (in2) >= 0 || mpz_invert (t, in1, in3))) { mpz_powm (ref1, in1, in2, in3); MPZ_CHECK_FORMAT (ref1); mpz_set (res1, in1); mpz_powm (res1, res1, in2, in3); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0) FAIL2 (mpz_powm, in1, in2, in3); mpz_set (res1, in2); mpz_powm (res1, in1, res1, in3); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0) FAIL2 (mpz_powm, in1, in2, in3); mpz_set (res1, in3); mpz_powm (res1, in1, in2, res1); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0) FAIL2 (mpz_powm, in1, in2, in3); } /* Don't run mpz_powm_ui when undefined. */ if (size_range < 17 && mpz_sgn (in3) != 0) { mpz_powm_ui (ref1, in1, in2i, in3); MPZ_CHECK_FORMAT (ref1); mpz_set (res1, in1); mpz_powm_ui (res1, res1, in2i, in3); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0) FAIL2 (mpz_powm_ui, in1, in2, in3); mpz_set (res1, in3); mpz_powm_ui (res1, in1, in2i, res1); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0) FAIL2 (mpz_powm_ui, in1, in2, in3); } { r1 = mpz_gcd_ui (ref1, in1, in2i); MPZ_CHECK_FORMAT (ref1); mpz_set (res1, in1); r2 = mpz_gcd_ui (res1, res1, in2i); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0) FAIL2 (mpz_gcd_ui, in1, in2, NULL); } if (mpz_sgn (in2) != 0) { /* Test mpz_remove */ mp_bitcnt_t refretval, retval; refretval = mpz_remove (ref1, in1, in2); MPZ_CHECK_FORMAT (ref1); mpz_set (res1, in1); retval = mpz_remove (res1, res1, in2); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0 || refretval != retval) FAIL2 (mpz_remove, in1, in2, NULL); mpz_set (res1, in2); retval = mpz_remove (res1, in1, res1); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0 || refretval != retval) FAIL2 (mpz_remove, in1, in2, NULL); } if (mpz_sgn (in2) != 0) { /* Test mpz_divexact */ mpz_mul (t, in1, in2); mpz_divexact (ref1, t, in2); MPZ_CHECK_FORMAT (ref1); mpz_set (res1, t); mpz_divexact (res1, res1, in2); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0) FAIL2 (mpz_divexact, t, in2, NULL); mpz_set (res1, in2); mpz_divexact (res1, t, res1); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0) FAIL2 (mpz_divexact, t, in2, NULL); } if (mpz_sgn (in2) > 0) { /* Test mpz_divexact_gcd, same as mpz_divexact */ mpz_mul (t, in1, in2); mpz_divexact_gcd (ref1, t, in2); MPZ_CHECK_FORMAT (ref1); mpz_set (res1, t); mpz_divexact_gcd (res1, res1, in2); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0) FAIL2 (mpz_divexact_gcd, t, in2, NULL); mpz_set (res1, in2); mpz_divexact_gcd (res1, t, res1); MPZ_CHECK_FORMAT (res1); if (mpz_cmp (ref1, res1) != 0) FAIL2 (mpz_divexact_gcd, t, in2, NULL); } } if (isatty (fileno (stdout))) printf ("\r%20s", ""); mpz_clear (bs); mpz_clear (in1); mpz_clear (in2); mpz_clear (in3); mpz_clear (ref1); mpz_clear (ref2); mpz_clear (ref3); mpz_clear (res1); mpz_clear (res2); mpz_clear (res3); mpz_clear (t); if (isatty (fileno (stdout))) printf ("\r"); tests_end (); exit (0); }
void check_primes (void) { static unsigned long prime[] = { 2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97, 101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181, 191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277, 281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383, 389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487, }; mpz_t want, x, y; int i; mpz_init (want); mpz_init (x); mpz_init (y); /* New prime each time. */ mpz_set_ui (want, 1L); for (i = 0; i < numberof (prime); i++) { mpz_set (x, want); mpz_set_ui (y, prime[i]); mpz_mul_ui (want, want, prime[i]); check_all (want, x, y); } /* Old prime each time. */ mpz_set (x, want); for (i = 0; i < numberof (prime); i++) { mpz_set_ui (y, prime[i]); check_all (want, x, y); } /* One old, one new each time. */ mpz_set_ui (want, prime[0]); for (i = 1; i < numberof (prime); i++) { mpz_set (x, want); mpz_set_ui (y, prime[i] * prime[i-1]); mpz_mul_ui (want, want, prime[i]); check_all (want, x, y); } /* Triplets with A,B in x and B,C in y. */ mpz_set_ui (want, 1L); mpz_set_ui (x, 1L); mpz_set_ui (y, 1L); for (i = 0; i+2 < numberof (prime); i += 3) { mpz_mul_ui (want, want, prime[i]); mpz_mul_ui (want, want, prime[i+1]); mpz_mul_ui (want, want, prime[i+2]); mpz_mul_ui (x, x, prime[i]); mpz_mul_ui (x, x, prime[i+1]); mpz_mul_ui (y, y, prime[i+1]); mpz_mul_ui (y, y, prime[i+2]); check_all (want, x, y); } mpz_clear (want); mpz_clear (x); mpz_clear (y); }
/* Generates algorithm's parameters. That is: * For DSA: p, q, and g are generated. * For RSA: nothing * For ECDSA: just checks the curve is ok */ static int wrap_nettle_pk_generate_params(gnutls_pk_algorithm_t algo, unsigned int level /*bits or curve*/ , gnutls_pk_params_st * params) { int ret; unsigned int i, q_bits; params->algo = algo; switch (algo) { case GNUTLS_PK_DSA: case GNUTLS_PK_DH: { struct dsa_public_key pub; struct dsa_private_key priv; #ifdef ENABLE_FIPS140 struct dss_params_validation_seeds cert; unsigned index; #endif dsa_public_key_init(&pub); dsa_private_key_init(&priv); if (GNUTLS_BITS_HAVE_SUBGROUP(level)) { q_bits = GNUTLS_BITS_TO_SUBGROUP(level); level = GNUTLS_BITS_TO_GROUP(level); } else { q_bits = _gnutls_pk_bits_to_subgroup_bits(level); } if (q_bits == 0) return gnutls_assert_val(GNUTLS_E_ILLEGAL_PARAMETER); #ifdef ENABLE_FIPS140 if (algo==GNUTLS_PK_DSA) index = 1; else index = 2; ret = dsa_generate_dss_pqg(&pub, &cert, index, NULL, rnd_func, NULL, NULL, level, q_bits); if (ret != 1) { gnutls_assert(); ret = GNUTLS_E_PK_GENERATION_ERROR; goto dsa_fail; } /* verify the generated parameters */ ret = dsa_validate_dss_pqg(&pub, &cert, index); if (ret != 1) { gnutls_assert(); ret = GNUTLS_E_PK_GENERATION_ERROR; goto dsa_fail; } #else /* unfortunately nettle only accepts 160 or 256 * q_bits size. The check below makes sure we handle * cases in between by rounding up, but fail when * larger numbers are requested. */ if (q_bits < 160) q_bits = 160; else if (q_bits > 160 && q_bits <= 256) q_bits = 256; ret = dsa_generate_keypair(&pub, &priv, NULL, rnd_func, NULL, NULL, level, q_bits); if (ret != 1) { gnutls_assert(); ret = GNUTLS_E_PK_GENERATION_ERROR; goto dsa_fail; } #endif params->params_nr = 0; ret = _gnutls_mpi_init_multi(¶ms->params[DSA_P], ¶ms->params[DSA_Q], ¶ms->params[DSA_G], NULL); if (ret < 0) { gnutls_assert(); goto dsa_fail; } params->params_nr = 3; mpz_set(TOMPZ(params->params[DSA_P]), pub.p); mpz_set(TOMPZ(params->params[DSA_Q]), pub.q); mpz_set(TOMPZ(params->params[DSA_G]), pub.g); ret = 0; dsa_fail: dsa_private_key_clear(&priv); dsa_public_key_clear(&pub); if (ret < 0) goto fail; break; } case GNUTLS_PK_RSA: case GNUTLS_PK_EC: ret = 0; break; default: gnutls_assert(); return GNUTLS_E_INVALID_REQUEST; } FAIL_IF_LIB_ERROR; return 0; fail: for (i = 0; i < params->params_nr; i++) { _gnutls_mpi_release(¶ms->params[i]); } params->params_nr = 0; FAIL_IF_LIB_ERROR; return ret; }
void find_candidates(mpz_t num, mpz_t gmp_root) { num_cands = 0; mpz_add_ui(gmp_root, gmp_root, 1); size_t sieve_size = primes[B-1]*100; double *table = malloc(sizeof(double)*sieve_size); uint64_t root = mpz_get_ui(gmp_root); double approx = mpz_get_d(num); mpz_t tmp, tmp2; mpz_init(tmp); mpz_init(tmp2); mpz_set_ui(tmp, root); mpz_pow_ui(tmp, tmp, 2); mpz_sub(tmp, tmp, num); mpz_set(first_cands[0], tmp); unsigned int used_primes[B]; double used_log[B]; used_primes[0] = 2; used_log[0] = log_primes[0]; size_t next_prime = 1; size_t offsets[B][2]; uint64_t cand_offsets[B+1]; size_t next_cand = 1; // Find prime numbers that appear in the candidate series for(size_t p = 1; p < B; ++p) { unsigned int prime = primes[p]; mpz_set_ui(tmp2, prime); mpz_powm_ui(tmp, num, (prime-1)/2, tmp2); if(mpz_cmp_ui(tmp, 1)) // Skip non-quadratic residues continue; used_primes[next_prime] = prime; used_log[next_prime] = log_primes[p]; // Generate more exact candidates for(int i = next_cand; i < prime; ++i) { mpz_set_ui(tmp, root + i); mpz_pow_ui(tmp, tmp, 2); mpz_sub(tmp, tmp, num); mpz_set(first_cands[i], tmp); } next_cand = prime; // find offsets for them // TODO Shanks-tonelli unsigned int foo = tonelli_shanks(num, prime); printf("root for %u is %u and %u\n", prime, foo, prime-foo); size_t idx = 0; for(int i = 0; i < prime; ++i) { if(mpz_divisible_ui_p(first_cands[i], prime)) { offsets[next_prime][idx++] = i; if(idx == 2) break; } } assert(idx == 2); ++next_prime; } // sieve until we find more than B candidates, guarantees linear dependence size_t sieve_offset = 0; while(num_cands <= B) { for(size_t i = 0; i < sieve_size; ++i) { double d = root + i; d += sieve_offset; table[i] = log(d*d-approx); } // cross out even ones for(size_t i = mpz_tstbit(tmp, 1)^(sieve_offset & 1); i < sieve_size; i+=2) table[i] -= log_primes[0]; for(int p = 1; p < next_prime && num_cands <= B; ++p) { unsigned int prime = used_primes[p]; double log_prime = used_log[p]; // fprintf(stderr, "offsets[%d] are %d and %d\n", used_primes[p], offsets[p][0], offsets[p][1]); for(int x = 0; x < 2; ++x) { size_t off = (offsets[p][x] + sieve_offset + prime-1) % prime; for(int a = off; a < sieve_size; a += prime) { table[a] -= log_prime; if(table[a] > LIMIT) continue; cand_offsets[num_cands++] = root + a + sieve_offset; if(num_cands > B) break; } } } sieve_offset += sieve_size; } for(size_t i = 0; i < num_cands; ++i) { //fprintf(stderr, "%llu\n", cand_offsets[i]); // TODO REMOVE VERY SLOW STUFF mpz_set_ui(tmp, root + i); mpz_pow_ui(tmp, tmp, 2); mpz_sub(tmp, tmp, num); // mpz_out_str(stderr, 10, tmp); // fputc('\n', stderr); } fprintf(stderr, "%d used candidates\n", num_cands); free(table); mpz_clear(tmp); mpz_clear(tmp2); }
/* Double an ECC point @param P The point to double @param R [out] The destination of the double @param a Curve's a value @param modulus The modulus of the field the ECC curve is in @return GNUTLS_E_SUCCESS on success */ int ecc_projective_dbl_point (ecc_point * P, ecc_point * R, mpz_t a, mpz_t modulus) { /* Using "dbl-2004-hmv" algorithm. * It costs 4M + 4S + half. */ mpz_t t1, t2; int err; if (P == NULL || R == NULL || modulus == NULL) return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; if ( (err = ecc_projective_isneutral(P, modulus)) == 1 ) { if ((err = mp_init_multi(&t1, &t2, NULL)) != 0) { return err; } if (P != R) { mpz_set(R->x, P->x); mpz_set(R->y, P->y); mpz_set(R->z, P->z); } if (mpz_cmp_ui (P->z, 1) != 0) { /* t1 = Z * Z */ mpz_mul(t1, R->z, R->z); mpz_mod(t1, t1, modulus); /* Z = Y * Z */ mpz_mul(R->z, R->y, R->z); mpz_mod(R->z, R->z, modulus); /* Z = 2Z */ mpz_add(R->z, R->z, R->z); if (mpz_cmp(R->z, modulus) >= 0) { mpz_sub(R->z, R->z, modulus); } } else { /* t1 = 1 */ mpz_set(t1, P->z); /* Z = 2Y */ mpz_add(R->z, R->y, R->y); if (mpz_cmp(R->z, modulus) >= 0) { mpz_sub(R->z, R->z, modulus); } } /* T2 = X - T1 */ mpz_sub(t2, R->x, t1); if (mpz_cmp_ui(t2, 0) < 0) { mpz_add(t2, t2, modulus); } /* T1 = X + T1 */ mpz_add(t1, t1, R->x); if (mpz_cmp(t1, modulus) >= 0) { mpz_sub(t1, t1, modulus); } /* T2 = T1 * T2 */ mpz_mul(t2, t1, t2); mpz_mod(t2, t2, modulus); /* T1 = 2T2 */ mpz_add(t1, t2, t2); if (mpz_cmp(t1, modulus) >= 0) { mpz_sub(t1, t1, modulus); } /* T1 = T1 + T2 */ mpz_add(t1, t1, t2); if (mpz_cmp(t1, modulus) >= 0) { mpz_sub(t1, t1, modulus); } /* Y = 2Y */ mpz_add(R->y, R->y, R->y); if (mpz_cmp(R->y, modulus) >= 0) { mpz_sub(R->y, R->y, modulus); } /* Y = Y * Y */ mpz_mul(R->y, R->y, R->y); mpz_mod(R->y, R->y, modulus); /* T2 = Y * Y */ mpz_mul(t2, R->y, R->y); mpz_mod(t2, t2, modulus); /* T2 = T2/2 */ if (mpz_odd_p(t2)) { mpz_add(t2, t2, modulus); } mpz_divexact_ui(t2, t2, 2); /* Y = Y * X */ mpz_mul(R->y, R->y, R->x); mpz_mod(R->y, R->y, modulus); /* X = T1 * T1 */ mpz_mul(R->x, t1, t1); mpz_mod(R->x, R->x, modulus); /* X = X - Y */ mpz_sub(R->x, R->x, R->y); if (mpz_cmp_ui(R->x, 0) < 0) { mpz_add(R->x, R->x, modulus); } /* X = X - Y */ mpz_sub(R->x, R->x, R->y); if (mpz_cmp_ui(R->x, 0) < 0) { mpz_add(R->x, R->x, modulus); } /* Y = Y - X */ mpz_sub(R->y, R->y, R->x); if (mpz_cmp_ui(R->y, 0) < 0) { mpz_add(R->y, R->y, modulus); } /* Y = Y * T1 */ mpz_mul(R->y, R->y, t1); mpz_mod(R->y, R->y, modulus); /* Y = Y - T2 */ mpz_sub(R->y, R->y, t2); if (mpz_cmp_ui(R->y, 0) < 0) { mpz_add( R->y, R->y, modulus); } err = GNUTLS_E_SUCCESS; mp_clear_multi(&t1, &t2, NULL); return err; } else if (err == 0) { /* 2*neutral = neutral */ mpz_set_ui(R->x, 1); mpz_set_ui(R->y, 1); mpz_set_ui(R->z, 0); return GNUTLS_E_SUCCESS; } else { return err; } }
unsigned int tonelli_shanks(mpz_t num, unsigned int prime) { fprintf(stderr, "shanks for %d\n", prime); mpz_t tmp, mpz_prime, r, c, t, b; mpz_init(tmp); mpz_init(mpz_prime); mpz_init(r); mpz_init(c); mpz_init(t); mpz_init(b); mpz_set_ui(mpz_prime, prime); unsigned int q = prime-1; unsigned int s = 0; while(!(q & 1)) { s += 1; q >>= 1; } unsigned int z; for(z = 2;; ++z) { mpz_set_ui(tmp, z); mpz_powm_ui(tmp, tmp, (prime-1)/2, mpz_prime); if(mpz_cmp_ui(tmp, 1)) break; // found non-quadratic residue } printf("c=%d^%d\n", z, q); // c = z^q mpz_set_ui(tmp, z); mpz_powm_ui(c, tmp, q, mpz_prime); // r = n^(q+1)/2 mpz_powm_ui(r, num, (q+1)/2, mpz_prime); // t = n^q mpz_powm_ui(t, num, q, mpz_prime); // m = s unsigned int m = s; //mpz_set_ui(m, s); // while t != 1 mod p while(mpz_cmp_ui(t, 1)) { mpz_out_str(stderr, 10, t); fputs(", durr\n", stderr); // find smallest i so that t^2^i = 1 mod p mpz_set(tmp, t); unsigned int i; for(i = 1; ;++i) { mpz_powm_ui(tmp, tmp, 2, mpz_prime); mpz_out_str(stderr, 10, tmp); fputs("!\n", stderr); if(!mpz_cmp_ui(tmp, 1)) break; } // TODO: For some reason i >= m here // set b to c^2^(m-i-1) as well, by repeated squaring mpz_set(b, c); printf("m = %d, i = %d\n", m, i); for(size_t foo = 0; foo < m-i-1; ++foo) { mpz_powm_ui(b, b, 2, mpz_prime); } // r = r*b mpz_mul(r, r, b); mpz_mod_ui(r, r, prime); // t = t*b² mpz_mul(t, t, b); mpz_mul(t, t, b); mpz_mod_ui(t, t, prime); // c = b² mpz_mul(c, b, b); mpz_mod_ui(c, c, prime); // m = i m = i; } unsigned int out = mpz_get_ui(r); mpz_clear(r); mpz_clear(c); mpz_clear(t); mpz_clear(b); mpz_clear(tmp); mpz_init(mpz_prime); return out; }
int main (int argc, char **argv) { mpz_t base, exp, mod; mpz_t r1, r2, base2; mp_size_t base_size, exp_size, mod_size; unsigned long int exp2; int i; int reps = 200; gmp_randstate_t rands; mpz_t bs; unsigned long bsi, size_range; tests_start (); gmp_randinit_default(rands); mpz_init (bs); if (argc == 2) reps = atoi (argv[1]); mpz_init (base); mpz_init (exp); mpz_init (mod); mpz_init (r1); mpz_init (r2); mpz_init (base2); for (i = 0; i < reps; i++) { mpz_urandomb (bs, rands, 32); size_range = mpz_get_ui (bs) % 13 + 2; do /* Loop until mathematically well-defined. */ { mpz_urandomb (bs, rands, size_range); base_size = mpz_get_ui (bs); mpz_rrandomb (base, rands, base_size); mpz_urandomb (bs, rands, 6L); exp_size = mpz_get_ui (bs); mpz_rrandomb (exp, rands, exp_size); exp2 = mpz_getlimbn (exp, (mp_size_t) 0); } while (mpz_cmp_ui (base, 0) == 0 && exp2 == 0); do { mpz_urandomb (bs, rands, size_range); mod_size = mpz_get_ui (bs); mpz_rrandomb (mod, rands, mod_size); } while (mpz_cmp_ui (mod, 0) == 0); mpz_urandomb (bs, rands, 2); bsi = mpz_get_ui (bs); if ((bsi & 1) != 0) mpz_neg (base, base); /* printf ("%ld %ld\n", SIZ (base), SIZ (mod)); */ #if 0 putc ('\n', stderr); debug_mp (base, -16); debug_mp (mod, -16); #endif mpz_powm_ui (r1, base, exp2, mod); mpz_set_ui (r2, 1); mpz_set (base2, base); mpz_mod (r2, r2, mod); /* needed when exp==0 and mod==1 */ while (exp2 != 0) { if (exp2 % 2 != 0) { mpz_mul (r2, r2, base2); mpz_mod (r2, r2, mod); } mpz_mul (base2, base2, base2); mpz_mod (base2, base2, mod); exp2 = exp2 / 2; } #if 0 debug_mp (r1, -16); debug_mp (r2, -16); #endif if (mpz_cmp (r1, r2) != 0) { fprintf (stderr, "\ntest %d: Incorrect results for operands:\n", i); debug_mp (base, -16); debug_mp (exp, -16); debug_mp (mod, -16); fprintf (stderr, "mpz_powm_ui result:\n"); debug_mp (r1, -16); fprintf (stderr, "reference result:\n"); debug_mp (r2, -16); abort (); } } mpz_clear (bs); mpz_clear (base); mpz_clear (exp); mpz_clear (mod); mpz_clear (r1); mpz_clear (r2); mpz_clear (base2); gmp_randclear(rands); tests_end (); exit (0); }
void IBE_setup(params_t params, byte_string_t master, int k, int qk, char *id) /* generate system parameters * k = number of bits in p (should be at least 512) * qk = number of bits in q (size of subgroup, 160 is typical) * id = system ID */ { mpz_t p, q, r; mpz_t x; point_ptr P; int solinasa, solinasb; int kqk = k - qk - 4; //lose 4 bits since 12 is a 4-bit no. unsigned int seed; mpz_init(p); mpz_init(q); mpz_init(r); mpz_init(x); //find random k-bit prime p such that //p = 2 mod 3 and q = (p+1)/12r is prime as well for some r //now also want q to be a Solinas prime //we use rand() to help us find one: should be ok crypto_rand_bytes((unsigned char *) &seed, sizeof(int)); srand(seed); for(;;) { //once q was just a random qk-bit prime //now it must be a Solinas one mpz_set_ui(q, 0); solinasa = qk - 1; mpz_setbit(q, solinasa); mpz_set_ui(r, 0); solinasb = rand() % qk; mpz_setbit(r, solinasb); if (rand() % 2) { mpz_add(q, q, r); } else { mpz_sub(q, q, r); solinasb = -solinasb; } mpz_set_ui(r, 1); if (rand() % 2) { mpz_add(q, q, r); } else { mpz_sub(q, q, r); solinasa = -solinasa; } if (!mpz_probab_prime_p(q, 10)) continue; mympz_randomb(r, kqk); //p = q * r mpz_mul(p, q, r); //r = (((p << 1) + p) << 2) (= 12p) mpz_mul_2exp(r, p, 1); mpz_add(r, r, p); mpz_mul_2exp(r, r, 2); //p = r - 1 mpz_set_ui(p, 1); mpz_sub(p, r, p); if (mpz_probab_prime_p(p, 10)) break; } //pick master key x from F_q mympz_randomm(x, q); byte_string_set_mpz(master, x); mpz_init(params->p); mpz_init(params->q); mpz_set(params->p, p); mpz_set(params->q, q); initpq(params); //pick random point P of order q from E/F_p point_init(params->P); P = params->P; do { point_random(P, params->curve); point_make_order_q(P, params); } while (P->infinity); point_init(params->Ppub); point_mul(params->Ppub, x, P, params->curve); point_mul_preprocess(P, params->curve); miller_cache_init(params->Ppub_mc, params->curve); tate_preprocess(params->Ppub_mc, params->Ppub, params->curve); point_init(params->PhiPpub); point_Phi(params->PhiPpub, params->Ppub, params); params->id = (char *) malloc(strlen(id) + 1); strcpy(params->id, id); params->sharet = params->sharen = 0; params->version = (char *) malloc(strlen(IBE_VERSION) + 1); strcpy(params->version, IBE_VERSION); mpz_clear(p); mpz_clear(q); mpz_clear(r); mpz_clear(x); }
void llln_swapk (int k, int kmax, int C, int F) { int i,j; mpz_t lamb; mpz_t auxi1; mpz_t t; mpz_t swap; mpz_init (lamb); mpz_init (auxi1); mpz_init (t); mpz_init (swap); for (j=1; j<F+1 ;j++) { mpz_set (swap, llln_H[k][j]); mpz_set (llln_H[k][j], llln_H[k-1][j]); mpz_set (llln_H[k-1][j], swap); } for (j=1; j<C+1 ;j++) { mpz_set (swap, llln_b[k][j]); mpz_set (llln_b[k][j], llln_b[k-1][j]); mpz_set (llln_b[k-1][j], swap); } if (k>2) { for (j=1;j<=k-2;j++) { mpz_set (swap, llln_lambda[k][j]); mpz_set (llln_lambda[k][j], llln_lambda[k-1][j]); mpz_set (llln_lambda[k-1][j], swap); } } mpz_set (lamb, llln_lambda[k][k-1]); if (mpz_sgn (lamb) == 0) { mpz_set (llln_d[k-1], llln_d[k-2]); llln_f[k-1]= 0; llln_f[k]= 1; mpz_set_ui (llln_lambda[k][k-1], 0); for (j=k+1; j <= kmax ; j++) { mpz_set (llln_lambda[j][k], llln_lambda[j][k-1]); mpz_set_ui (llln_lambda[j][k-1],0); } } else { for (j=k+1; j <= kmax ; j++)s { mpz_mul (auxi1, lamb, llln_lambda[j][k-1]); mpz_tdiv_q (llln_lambda[j][k-1], auxi1, llln_d[k-1]); } mpz_set (t, llln_d[k]); mpz_mul (auxi1, lamb, lamb); mpz_tdiv_q (llln_d[k-1], auxi1, llln_d[k-1]); mpz_set (llln_d[k], llln_d[k-1]); for (j=k+1; j <= kmax -1 ; j++) { for (i=j+1; i<= kmax; i++) { mpz_mul (auxi1, llln_lambda[i][j], llln_d[k-1]); mpz_tdiv_q (llln_lambda[i][j], auxi1, t); } } for (j=k+1; j<= kmax; j++) { mpz_mul (auxi1, llln_d[j], llln_d[k-1]); mpz_tdiv_q (llln_d[j], auxi1, t); } } mpz_clear (auxi1); mpz_clear (lamb); mpz_clear (t); mpz_clear (swap); }
void IBE_split_master(byte_string_t *mshare, byte_string_t master, int t, int n, params_t params) //split the master key into n pieces //t of them are required to generate a key { mpz_t * poly = malloc(sizeof(mpz_t)*t); mpz_t *x; mpz_t *y = malloc(sizeof(mpz_t)*n); mpz_t z; mpz_t r; int i, j; byte_string_t bs1, bs2; //start with random polynomial with degree <= t-2 //(in F_q) //whose constant term = master mpz_init(r); mpz_init(poly[0]); mympz_set_byte_string(poly[0], master); for (i=1; i<t; i++) { mpz_init(poly[i]); mympz_randomm(r, params->q); mpz_set(poly[i], r); } mpz_init(z); if (0) { printf("secret poly: "); for (i=0; i<t; i++) { printf(" "); mpz_out_str(NULL, 0, poly[i]); } printf("\n"); } params->robustx = (mpz_t *) malloc(n * sizeof(mpz_t)); params->robustP = (point_t *) malloc(n * sizeof(point_t)); params->sharet = t; params->sharen = n; x = params->robustx; for (i=0; i<n; i++) { mympz_randomm(r, params->q); mpz_init(x[i]); mpz_set(x[i], r); //Horner's rule mpz_set_ui(z, 0); for (j=t-1; j>=0; j--) { mpz_mul(z, z, x[i]); mpz_add(z, z, poly[j]); mpz_mod(z, z, params->q); } mpz_init_set(y[i], z); byte_string_set_int(bs1, i); byte_string_set_mpz(bs2, z); byte_string_join(mshare[i], bs1, bs2); byte_string_clear(bs1); byte_string_clear(bs2); } for (i=0; i<n; i++) { point_init(params->robustP[i]); point_mul(params->robustP[i], y[i], params->Ppub, params->curve); } for (i=0; i<t; i++) { mpz_clear(poly[i]); } for (i=0; i<n; i++) { mpz_clear(y[i]); } mpz_clear(z); mpz_clear(r); }
/* This is the code of 'generic.c' slighty optimized for mpfr_atan. If x = p/2^r, put in y an approximation of atan(x)/x using 2^m terms for the series expansion, with an error of at most 1 ulp. Assumes |x| < 1. If X=x^2, we want 1 - X/3 + X^2/5 - ... + (-1)^k*X^k/(2k+1) + ... */ static void mpfr_atan_aux (mpfr_ptr y, mpz_ptr p, long r, int m, mpz_t *tab) { mpz_t *S, *Q, *ptoj; unsigned long n, i, k, j, l; mp_exp_t diff, expo; int im, done; mp_prec_t mult, *accu, *log2_nb_terms; mp_prec_t precy = MPFR_PREC(y); if (mpz_cmp_ui (p, 0) == 0) { mpfr_set_ui (y, 1, GMP_RNDN); /* limit(atan(x)/x, x=0) */ return; } accu = (mp_prec_t*) (*__gmp_allocate_func) ((2 * m + 2) * sizeof (mp_prec_t)); log2_nb_terms = accu + m + 1; /* Set Tables */ S = tab; /* S */ ptoj = S + 1*(m+1); /* p^2^j Precomputed table */ Q = S + 2*(m+1); /* Product of Odd integer table */ /* From p to p^2, and r to 2r */ mpz_mul (p, p, p); MPFR_ASSERTD (2 * r > r); r = 2 * r; /* Normalize p */ n = mpz_scan1 (p, 0); mpz_tdiv_q_2exp (p, p, n); /* exact */ MPFR_ASSERTD (r > n); r -= n; /* since |p/2^r| < 1, and p is a non-zero integer, necessarily r > 0 */ MPFR_ASSERTD (mpz_sgn (p) > 0); MPFR_ASSERTD (m > 0); /* check if p=1 (special case) */ l = 0; /* We compute by binary splitting, with X = x^2 = p/2^r: P(a,b) = p if a+1=b, P(a,c)*P(c,b) otherwise Q(a,b) = (2a+1)*2^r if a+1=b [except Q(0,1)=1], Q(a,c)*Q(c,b) otherwise S(a,b) = p*(2a+1) if a+1=b, Q(c,b)*S(a,c)+Q(a,c)*P(a,c)*S(c,b) otherwise Then atan(x)/x ~ S(0,i)/Q(0,i) for i so that (p/2^r)^i/i is small enough. The factor 2^(r*(b-a)) in Q(a,b) is implicit, thus we have to take it into account when we compute with Q. */ accu[0] = 0; /* accu[k] = Mult[0] + ... + Mult[k], where Mult[j] is the number of bits of the corresponding term S[j]/Q[j] */ if (mpz_cmp_ui (p, 1) != 0) { /* p <> 1: precompute ptoj table */ mpz_set (ptoj[0], p); for (im = 1 ; im <= m ; im ++) mpz_mul (ptoj[im], ptoj[im - 1], ptoj[im - 1]); /* main loop */ n = 1UL << m; /* the ith term being X^i/(2i+1) with X=p/2^r, we can stop when p^i/2^(r*i) < 2^(-precy), i.e. r*i > precy + log2(p^i) */ for (i = k = done = 0; (i < n) && (done == 0); i += 2, k ++) { /* initialize both S[k],Q[k] and S[k+1],Q[k+1] */ mpz_set_ui (Q[k+1], 2 * i + 3); /* Q(i+1,i+2) */ mpz_mul_ui (S[k+1], p, 2 * i + 1); /* S(i+1,i+2) */ mpz_mul_2exp (S[k], Q[k+1], r); mpz_sub (S[k], S[k], S[k+1]); /* S(i,i+2) */ mpz_mul_ui (Q[k], Q[k+1], 2 * i + 1); /* Q(i,i+2) */ log2_nb_terms[k] = 1; /* S[k]/Q[k] corresponds to 2 terms */ for (j = (i + 2) >> 1, l = 1; (j & 1) == 0; l ++, j >>= 1, k --) { /* invariant: S[k-1]/Q[k-1] and S[k]/Q[k] correspond to 2^l terms each. We combine them into S[k-1]/Q[k-1] */ MPFR_ASSERTD (k > 0); mpz_mul (S[k], S[k], Q[k-1]); mpz_mul (S[k], S[k], ptoj[l]); mpz_mul (S[k-1], S[k-1], Q[k]); mpz_mul_2exp (S[k-1], S[k-1], r << l); mpz_add (S[k-1], S[k-1], S[k]); mpz_mul (Q[k-1], Q[k-1], Q[k]); log2_nb_terms[k-1] = l + 1; /* now S[k-1]/Q[k-1] corresponds to 2^(l+1) terms */ MPFR_MPZ_SIZEINBASE2(mult, ptoj[l+1]); /* FIXME: precompute bits(ptoj[l+1]) outside the loop? */ mult = (r << (l + 1)) - mult - 1; accu[k-1] = (k == 1) ? mult : accu[k-2] + mult; if (accu[k-1] > precy) done = 1; } } }
BigInteger(const BigInteger &i) { mpz_init(integer); mpz_set(integer, i.integer); }
/* Perform a point multiplication @param k The scalar to multiply by @param G The base point @param R [out] Destination for kG @param modulus The modulus of the field the ECC curve is in @param map Boolean whether to map back to affine or not (1==map, 0 == leave in projective) @return CRYPT_OK on success */ int ecc_mulmod (mpz_t k, ecc_point * G, ecc_point * R, mpz_t a, mpz_t modulus, int map) { ecc_point *tG, *M[8]; int i, j, err, bitidx; int first, bitbuf, bitcpy, mode; if (k == NULL || G == NULL || R == NULL || modulus == NULL) return -1; /* alloc ram for window temps */ for (i = 0; i < 8; i++) { M[i] = ecc_new_point(); if (M[i] == NULL) { for (j = 0; j < i; j++) { ecc_del_point(M[j]); } return -1; } } /* make a copy of G incase R==G */ tG = ecc_new_point(); if (tG == NULL) { err = -1; goto done; } /* tG = G and convert to montgomery */ mpz_set (tG->x, G->x); mpz_set (tG->y, G->y); mpz_set (tG->z, G->z); /* calc the M tab, which holds kG for k==8..15 */ /* M[0] == 8G */ if ((err = ecc_projective_dbl_point (tG, M[0], a, modulus)) != 0) goto done; if ((err = ecc_projective_dbl_point (M[0], M[0], a, modulus)) != 0) goto done; if ((err = ecc_projective_dbl_point (M[0], M[0], a, modulus)) != 0) goto done; /* now find (8+k)G for k=1..7 */ for (j = 9; j < 16; j++) { if (ecc_projective_add_point(M[j-9], tG, M[j-8], a, modulus) != 0) goto done; } /* setup sliding window */ mode = 0; bitidx = mpz_size (k) * GMP_NUMB_BITS - 1; bitcpy = bitbuf = 0; first = 1; /* perform ops */ for (;;) { /* grab next digit as required */ if (bitidx == -1) { break; } /* grab the next msb from the ltiplicand */ i = mpz_tstbit (k, bitidx--); /* skip leading zero bits */ if (mode == 0 && i == 0) { continue; } /* if the bit is zero and mode == 1 then we double */ if (mode == 1 && i == 0) { if ((err = ecc_projective_dbl_point(R, R, a, modulus)) != 0) goto done; continue; } /* else we add it to the window */ bitbuf |= (i << (WINSIZE - ++bitcpy)); mode = 2; if (bitcpy == WINSIZE) { /* if this is the first window we do a simple copy */ if (first == 1) { /* R = kG [k = first window] */ mpz_set(R->x, M[bitbuf-8]->x); mpz_set(R->y, M[bitbuf-8]->y); mpz_set(R->z, M[bitbuf-8]->z); first = 0; } else { /* normal window */ /* ok window is filled so double as required and add */ /* double first */ for (j = 0; j < WINSIZE; j++) { if ((err = ecc_projective_dbl_point(R, R, a, modulus)) != 0) goto done; } /* then add, bitbuf will be 8..15 [8..2^WINSIZE] guaranteed */ if ((err = ecc_projective_add_point(R, M[bitbuf-8], R, a, modulus)) != 0) goto done; } /* empty window and reset */ bitcpy = bitbuf = 0; mode = 1; } } /* if bits remain then double/add */ if (mode == 2 && bitcpy > 0) { /* double then add */ for (j = 0; j < bitcpy; j++) { /* only double if we have had at least one add first */ if (first == 0) { if ((err = ecc_projective_dbl_point(R, R, a, modulus)) != 0) goto done; } bitbuf <<= 1; if ((bitbuf & (1 << WINSIZE)) != 0) { if (first == 1){ /* first add, so copy */ mpz_set(R->x, tG->x); mpz_set(R->y, tG->y); mpz_set(R->z, tG->z); first = 0; } else { /* then add */ if ((err = ecc_projective_add_point(R, tG, R, a, modulus)) != 0) goto done; } } } } /* map R back from projective space */ if (map) { err = ecc_map(R, modulus); } else { err = 0; } done: ecc_del_point(tG); for (i = 0; i < 8; i++) { ecc_del_point(M[i]); } return err; }
uint64 *sieve_to_depth(uint32 *seed_p, uint32 num_sp, mpz_t lowlimit, mpz_t highlimit, int count, int num_witnesses, uint64 *num_p) { //public interface to a routine which will sieve a range of integers //with the supplied primes and either count or compute the values //that survive. Basically, it is just the sieve, but with no //guareentees that what survives the sieving is prime. The idea is to //remove cheap composites. uint64 retval, i, range, tmpl, tmph; uint64 *values = NULL; mpz_t tmpz; mpz_t *offset; if (mpz_cmp(highlimit, lowlimit) <= 0) { printf("error: lowlimit must be less than highlimit\n"); *num_p = 0; return values; } offset = (mpz_t *)malloc(sizeof(mpz_t)); mpz_init(tmpz); mpz_init(*offset); mpz_set(*offset, lowlimit); mpz_sub(tmpz, highlimit, lowlimit); range = mpz_get_64(tmpz); if (count) { //this needs to be a range of at least 1e6 if (range < 1000000) { //go and get a new range. tmpl = 0; tmph = 1000000; //since this is a small range, we need to //find a bigger range and count them. values = GetPRIMESRange(seed_p, num_sp, offset, tmpl, tmph, &retval); *num_p = 0; //count how many are in the original range of interest for (i = 0; i < retval; i++) { mpz_add_ui(tmpz, *offset, values[i]); if ((mpz_cmp(tmpz, lowlimit) >= 0) && (mpz_cmp(highlimit, tmpz) >= 0)) (*num_p)++; } free(values); values = NULL; } else { //check for really big ranges uint64 maxrange = 100000000000ULL; if (range > maxrange) { uint32 num_ranges = (uint32)(range / maxrange); uint64 remainder = range % maxrange; uint32 j; *num_p = 0; tmpl = 0; tmph = tmpl + maxrange; for (j = 0; j < num_ranges; j++) { *num_p += spSOE(seed_p, num_sp, offset, tmpl, &tmph, 1, NULL); if (VFLAG > 1) printf("so far, found %" PRIu64 " primes\n",*num_p); tmpl += maxrange; tmph = tmpl + maxrange; } if (remainder > 0) { tmph = tmpl + remainder; *num_p += spSOE(seed_p, num_sp, offset, tmpl, &tmph, 1, NULL); } if (VFLAG > 1) printf("so far, found %" PRIu64 " primes\n",*num_p); } else { //we're in a sweet spot already, just get the requested range *num_p = spSOE(seed_p, num_sp, offset, 0, &range, 1, NULL); } } } else { //this needs to be a range of at least 1e6 if (range < 1000000) { //there is slack built into the sieve limit, so go ahead and increase //the size of the interval to make it at least 1e6. tmpl = 0; tmph = tmpl + 1000000; //since this is a small range, we need to //find a bigger range and count them. values = GetPRIMESRange(seed_p, num_sp, offset, tmpl, tmph, &retval); *num_p = 0; for (i = 0; i < retval; i++) { mpz_add_ui(tmpz, *offset, values[i]); if ((mpz_cmp(tmpz, lowlimit) >= 0) && (mpz_cmp(highlimit, tmpz) >= 0)) (*num_p)++; } } else { //we don't need to mess with the requested range, //so GetPRIMESRange will return the requested range directly //and the count will be in NUM_P values = GetPRIMESRange(seed_p, num_sp, offset, 0, range, num_p); } if (num_witnesses > 0) { int pchar = 0; thread_soedata_t *thread_data; //an array of thread data objects uint32 lastid; int j; //allocate thread data structure thread_data = (thread_soedata_t *)malloc(THREADS * sizeof(thread_soedata_t)); // conduct PRP tests on all surviving values if (VFLAG > 0) printf("starting PRP tests with %d witnesses on %" PRIu64 " surviving candidates\n", num_witnesses, *num_p); // start the threads for (i = 0; i < THREADS - 1; i++) start_soe_worker_thread(thread_data + i, 0); start_soe_worker_thread(thread_data + i, 1); range = *num_p / THREADS; lastid = 0; // divvy up the range for (j = 0; j < THREADS; j++) { thread_soedata_t *t = thread_data + j; t->startid = lastid; t->stopid = t->startid + range; lastid = t->stopid; if (VFLAG > 2) printf("thread %d computing PRPs from %u to %u\n", (int)i, t->startid, t->stopid); } // the last one gets any leftover if (thread_data[THREADS-1].stopid != (uint32)*num_p) thread_data[THREADS-1].stopid = (uint32)*num_p; // allocate space for stuff in the threads if (THREADS == 1) { thread_data[0].ddata.primes = values; } else { for (j = 0; j < THREADS; j++) { thread_soedata_t *t = thread_data + j; mpz_init(t->tmpz); mpz_init(t->offset); mpz_init(t->lowlimit); mpz_init(t->highlimit); mpz_set(t->offset, *offset); mpz_set(t->lowlimit, lowlimit); mpz_set(t->highlimit, highlimit); t->current_line = (uint64)num_witnesses; t->ddata.primes = (uint64 *)malloc((t->stopid - t->startid) * sizeof(uint64)); for (i = t->startid; i < t->stopid; i++) t->ddata.primes[i - t->startid] = values[i]; } } // now run with the threads for (j = 0; j < THREADS; j++) { thread_soedata_t *t = thread_data + j; if (j == (THREADS - 1)) { t->linecount = 0; for (i = t->startid; i < t->stopid; i++) { if (((i & 128) == 0) && (VFLAG > 0)) { int k; for (k = 0; k<pchar; k++) printf("\b"); pchar = printf("progress: %d%%",(int)((double)i / (double)(*num_p) * 100.0)); fflush(stdout); } mpz_add_ui(tmpz, *offset, t->ddata.primes[i - t->startid]); if ((mpz_cmp(tmpz, lowlimit) >= 0) && (mpz_cmp(highlimit, tmpz) >= 0)) { if (mpz_probab_prime_p(tmpz, num_witnesses)) t->ddata.primes[t->linecount++] = t->ddata.primes[i - t->startid]; } } } else { t->command = SOE_COMPUTE_PRPS; #if defined(WIN32) || defined(_WIN64) SetEvent(t->run_event); #else pthread_cond_signal(&t->run_cond); pthread_mutex_unlock(&t->run_lock); #endif } } //wait for each thread to finish for (i = 0; i < THREADS; i++) { thread_soedata_t *t = thread_data + i; if (i < (THREADS - 1)) { #if defined(WIN32) || defined(_WIN64) WaitForSingleObject(t->finish_event, INFINITE); #else pthread_mutex_lock(&t->run_lock); while (t->command != SOE_COMMAND_WAIT) pthread_cond_wait(&t->run_cond, &t->run_lock); #endif } } //stop the worker threads for (i=0; i<THREADS - 1; i++) stop_soe_worker_thread(thread_data + i, 0); // combine results and free stuff if (THREADS == 1) { retval = thread_data[0].linecount; } else { retval = 0; for (i=0; i<THREADS; i++) { thread_soedata_t *t = thread_data + i; for (j=0; j < t->linecount; j++) values[retval++] = t->ddata.primes[j]; free(t->ddata.primes); mpz_clear(t->tmpz); mpz_clear(t->offset); mpz_clear(t->lowlimit); mpz_clear(t->highlimit); } } free(thread_data); if (VFLAG > 0) { int k; for (k = 0; k<pchar; k++) printf("\b"); } *num_p = retval; if (VFLAG > 0) printf("found %" PRIu64 " PRPs\n", *num_p); } // now dump the requested range of primes to a file, or the // screen, both, or neither, depending on the state of a couple // global configuration variables if (PRIMES_TO_FILE) { FILE *out; if (num_witnesses > 0) out = fopen("prp_values.dat", "w"); else out = fopen("sieved_values.dat","w"); if (out == NULL) { printf("fopen error: %s\n", strerror(errno)); printf("can't open file for writing\n"); } else { for (i = 0; i < *num_p; i++) { mpz_add_ui(tmpz, *offset, values[i]); if ((mpz_cmp(tmpz, lowlimit) >= 0) && (mpz_cmp(highlimit, tmpz) >= 0)) gmp_fprintf(out,"%Zd\n",tmpz); } fclose(out); } } if (PRIMES_TO_SCREEN) { for (i = 0; i < *num_p; i++) { mpz_add_ui(tmpz, *offset, values[i]); if ((mpz_cmp(tmpz, lowlimit) >= 0) && (mpz_cmp(highlimit, tmpz) >= 0)) gmp_printf("%Zd\n",tmpz); } printf("\n"); } } mpz_clear(tmpz); mpz_clear(*offset); free(offset); return values; }