int main() { mpz_t n, mod; mpz_init(n); mpz_init(mod); mpz_set_ui(n, 1237 + 566); mpz_set_str(n, "105476117015", 10); while (1) { mpz_add_ui(n, n, 1237); mpz_mod_ui(mod, n, 123); if (mpz_cmp_ui(mod, 12) != 0) continue; mpz_mod_ui(mod, n, 239); if (mpz_cmp_ui(mod, 57) != 0) continue; mpz_mod_ui(mod, n, 361); if (mpz_cmp_ui(mod, 239) != 0) continue; mpz_mod_ui(mod, n, 566); if (mpz_cmp_ui(mod, 361) != 0) continue; mpz_mod_ui(mod, n, 1237); if (mpz_cmp_ui(mod, 566) != 0) continue; gmp_printf("answer is %Zi\n", n); break; } mpz_clear(n); mpz_clear(mod); return 0; }
static unsigned long knuthSchroeppel(mpz_t n, unsigned long numPrimes) { unsigned int i, j, best_mult, knmod8; unsigned int maxprimes = (2*numPrimes <= 1000) ? 2*numPrimes : 1000; float best_score, contrib; float scores[NUMMULTS]; mpz_t temp; mpz_init(temp); for (i = 0; i < NUMMULTS; i++) { scores[i] = 0.5 * logf((float)multipliers[i]); mpz_mul_ui(temp, n, multipliers[i]); knmod8 = mpz_mod_ui(temp, temp, 8); switch (knmod8) { case 1: scores[i] -= 2 * M_LN2; break; case 5: scores[i] -= M_LN2; break; case 3: case 7: scores[i] -= 0.5 * M_LN2; break; default: break; } } { unsigned long prime, modp, knmodp; PRIME_ITERATOR(iter); for (i = 1; i < maxprimes; i++) { prime = prime_iterator_next(&iter); modp = mpz_mod_ui(temp, n, prime); contrib = logf((float)prime) / (float)(prime-1); for (j = 0; j < NUMMULTS; j++) { knmodp = (modp * multipliers[j]) % prime; if (knmodp == 0) { scores[j] -= contrib; } else { mpz_set_ui(temp, knmodp); if (mpz_kronecker_ui(temp, prime) == 1) scores[j] -= 2*contrib; } } } prime_iterator_destroy(&iter); } mpz_clear(temp); best_score = 1000.0; best_mult = 1; for (i = 0; i < NUMMULTS; i++) { float score = scores[i]; if (score < best_score) { best_score = score; best_mult = multipliers[i]; } } /* gmp_printf("%Zd mult %lu\n", n, best_mult); */ return best_mult; }
int main(void) { mpz_t p, r; unsigned maxlen = 0, imax = 0; unsigned i; mpz_init(p); mpz_init(r); for (i = 2; i < M; i++) { unsigned len = 1; if (i % 2 == 0 || i % 5 == 0) { continue; } mpz_set_ui(p, 10); while (mpz_mod_ui(r, p, i), mpz_cmp_ui(r, 1) != 0) { len++; mpz_mul_ui(p, p, 10); } if (len > maxlen) { maxlen = len; imax = i; } } printf("%u\n", imax); mpz_clear(p); mpz_clear(r); return 0; }
int main () { mpz_t max; mpz_t a; mpz_t b; mpz_t c; mpz_init(c); mpz_init_set_ui(a, 1); mpz_init_set_ui(b, 2); mpz_init_set_ui(max, 4000000); mpz_t count; mpz_t mod; mpz_init(mod); mpz_init_set_ui(count, 2); while (mpz_cmp(b, max) < 0) { //mpz_cmp returns a negative value if b < max mpz_mod_ui(mod, b, 2); if (mpz_cmp_ui(mod, 0) == 1) { mpz_add(count, count, b); } gmp_printf("%Zd\n", a); mpz_add(c, a, b); mpz_set(a, b); mpz_set(b, c); } gmp_printf("%Zd\n%Zd\n", a, b); gmp_printf("The count is %Zd\n", count); }
GmpInt& GmpInt::operator%=(long value) { copyIfShared(); if(value < 0) value = -value; if(operator<(0)) { negate(); mpz_mod_ui(mData->mInteger, mData->mInteger, value); negate(); } else { mpz_mod_ui(mData->mInteger, mData->mInteger, value); } return *this; }
int main( void ) { mpz_t num, digit; unsigned long long sum; mpz_init( num ); mpz_init( digit ); sum = 0; /****************************************************** * void mpz_fac_ui (mpz_t rop, unsigned long int op) * * -> Sets 'rop' to 'op!' * ******************************************************/ mpz_fac_ui( num, 100 ); while( mpz_sgn( num ) ) // while num > 0 { sum += mpz_mod_ui( digit, num, 10 ); mpz_fdiv_q_ui( num, num, 10 ); } printf( "Answer: %llu\n", sum ); mpz_clear( num ); return 0; }
ecc_point* mult(ecc_point p, mpz_t value){ ecc_point* result ; result =malloc(sizeof(ecc_point)); if (mpz_cmp_ui(value,0)==0) return NULL; if (mpz_cmp_ui(value,1)==0) return (&p); if (mpz_cmp_ui(value,2)==0) return double_p(p); mpz_t aux,aux1; mpz_init_set(aux,value); mpz_init_set(aux1,value); if (mpz_cmp_ui(aux,0)!=0){ mpz_mod_ui(aux,aux,2); if (mpz_cmp_ui(aux,0) != 0 ){ mpz_sub_ui(aux1,aux1,1); result = sum(p, (*mult(p,aux1))); }else{ mpz_set(aux,value); mpz_div_ui(aux1,aux1,2); result = double_p((*mult(p,aux1))); } } return result; }
int main (int argc,const char *argv[]){ mpz_t base; mpz_t result; mpz_t sum; mpz_t aux; mpz_init(base); mpz_init(result); mpz_init(sum); mpz_init(aux); mpz_set_str(base, "2", 10); mpz_pow_ui(result,base,1000); while(mpz_sgn (result)>0){ mpz_mod_ui(aux, result, 10); mpz_add(sum,sum,aux); mpz_div_ui (result, result, (unsigned long int) 10); } gmp_printf("%Zd\n", sum); /* free used memory */ mpz_clear(base); mpz_clear(sum); mpz_clear(aux); mpz_clear(result); return EXIT_SUCCESS; }
// get next prime where p mod 4 = 3 static void bbs_pseudo_next_prime ( mpz_t arg ) { mpz_t r; mpz_t mod; mpz_init(r); mpz_init(mod); mpz_set(r,arg); loop:; mpz_nextprime(r,r); mpz_mod_ui(mod,r,4); if ( 0 != mpz_cmp_ui(mod,3) ) { #if 0 && defined(CP_TEST) printf("%s: redo\n",__FUNCTION__); #endif goto loop; } mpz_set(arg,r); mpz_clear(r); mpz_clear(mod); }
/* Funktion, die die zu pruefende Zahl ("number") auf moegliche Teiler prueft - Diese Funktion wird von jedem Thread ausgefuehrt - In *index wird die Ordnungsnummer des Threads uebergeben - Mithilfe des *index greift der jeweilige Thread auf seinen Bereich der zu pruefenden Zahlen zu -> Globale Variablen *anf und *ende */ void *pruefeTeiler(void *index) { // Index des Threads uebernehmen int *i = (int*) index; // temporaerer Zwischenspeicher mpz_t temp; mpz_init(temp); // Zu pruefender Teiler fuer Schleife mpz_t teiler; mpz_init(teiler); // Teiler mit der ersten ungeraden Zahl belegen mpz_set(teiler, anf[*i]); if (mpz_mod_ui(temp, teiler, 2) == 0) mpz_add_ui(teiler, teiler, 1); do { // Teiler sequentiell pruefen mpz_mod(temp, number, teiler); if (mpz_sgn(temp) == 0) { // Teiler erfolgreich gefunden found = true; // Abbruch der Schleife! } else { mpz_add_ui(teiler, teiler, 2); mpz_sub(temp, ende[*i], teiler); } } while (mpz_sgn(temp) >= 0 && !found); mpz_clear(temp); mpz_clear(teiler); return NULL; }
/* Costo O(p) */ int legendre_sol(mpz_t n, unsigned int p, pair *sol ){ // questa variabile contiene il risultato // 1 se n è residuo quadratico mod p, 0 altrimenti int leg = 0; /* Parte del prof per la ricerca delle soluzioni di x^2=a mod p */ mpz_t m; // m = n % p; mpz_init(m); mpz_mod_ui(m,n,p); unsigned int mm = mpz_get_ui(m); // s = sup(sqrt(n)) unsigned int n1 = mpz_get_ui(n); float s1 = sqrt(n1); s1 = ceil(s1); unsigned int s = (unsigned int)(s1); // dichiaro j fuori per poter riiniziare il secondo ciclo // dall'ultimo valore valutato dal primo unsigned j; /* Uso due cicli for per calcolare le due soluzioni dell'equazione x^2=n mod p Al primo ciclo mi fermo subito dopo aver trovato la prima soluzione. Nel secondo riparto dal valore sul quale mi ero precedentemente fermato. NB if (j!=0) serve solo per non entrare nel secondo ciclo se non si è passati dal primo */ for (unsigned j = 0; 2 * j < p ; ++j){ if ((j*j) % p == mm) { leg = 1; } } for (j = 0; j < p ; ++j){ if ((j*j) % p == mm) { sol->sol1 = j; break; } } if(j!=0){ j++; for (j; j < p ; ++j){ if ((j*j) % p == mm) { sol->sol2 = j; break; } } } return leg; }
unsigned int RingZZ::mod_ui(mpz_t n, unsigned int p) { mpz_t ans; mpz_init(ans); unsigned int exp = static_cast<unsigned int>(mpz_mod_ui(ans, n, p)); mpz_clear(ans); return exp; }
ring_elem GF::from_int(mpz_ptr n) const { mpz_t result; mpz_init(result); mpz_mod_ui(result, n, P); int m = static_cast<int>(mpz_get_si(result)); if (m < 0) m += P; m = _from_int_table[m]; return ring_elem(m); }
int mpi_divisible_ui(MPI dividend, ulong divisor ) { ulong rem; mpz_t remtoo; mpz_init(remtoo); rem = mpz_mod_ui(remtoo, dividend, divisor); mpz_clear(remtoo); return rem == 0; }
ring_elem GF::from_int(mpz_ptr n) const { mpz_t result; mpz_init(result); mpz_mod_ui(result, n, characteristic()); long m1 = mpz_get_si(result); mpz_clear(result); if (m1 < 0) m1 += characteristic(); int m = static_cast<int>(m1); m = _from_int_table[m]; return ring_elem(m); }
ring_elem Z_mod::from_int(mpz_ptr n) const { // cout << "from_int("; // bignum_text_out(cout, n); // cout << ") = " << endl; mpz_t result; mpz_init(result); mpz_mod_ui(result, n, P); int m = static_cast<int>(mpz_get_si(result)); // cout << m << endl; if (m < 0) m += P; m = _log_table[m]; return ring_elem(m); }
void int_to_chargg(mpz_t we, int poz){ int l,ll; mpz_set(wep,we); mpz_ui_pow_ui(we_p,ch,m-1); mpz_tdiv_q(we_p2,wep,we_p); tab[(poz*m+0)]=mpz_get_ui(we_p2); l=0; for (ll=m-1;ll>1;ll--) {l++; mpz_ui_pow_ui(we_p,ch,ll); mpz_mod(we_p,wep,we_p); mpz_ui_pow_ui(we_p2,ch,ll-1); mpz_tdiv_q(we_p,we_p,we_p2); tab[(poz*m+l)]=mpz_get_ui(we_p); } mpz_mod_ui(we_p,wep,ch); tab[(poz*m+l+1)]=mpz_get_ui(we_p); }
UV mpz_order_ui(UV r, mpz_t n, UV limit) { UV j; mpz_t t; /* If n < limit, set limit to n */ if (mpz_cmp_ui(n, limit) < 0) limit = mpz_get_ui(n); mpz_init_set_ui(t, 1); for (j = 1; j <= limit; j++) { mpz_mul(t, t, n); mpz_mod_ui(t, t, r); if (!mpz_cmp_ui(t, 1)) break; } mpz_clear(t); return j; }
/* Costo O(p/2) */ int legendre(mpz_t n, unsigned int p ){ int sol; mpz_t m; mpz_init(m); mpz_mod_ui(m,n,p); // m = n % p; unsigned int mm = mpz_get_ui(m); for (unsigned j = 0; 2 * j < p ; ++j){ if ((j*j) % p == mm) { return 1; } } return 0; }
void Algorithms::GeneratePrime(mpz_t number, unsigned int numBits, unsigned int randomaiser) { unsigned int i; bool isComposite; char *prime_str = new char[numBits + 1]; mpz_t buf; mpz_init(buf); srand(randomaiser); prime_str[0] = '1'; while(true) { for(i = 1; i < numBits - 1; i++) prime_str[i] = (int)(2.0 * rand() / (RAND_MAX + 1.0)) + '0'; prime_str[numBits - 1] = '1'; prime_str[numBits] = '\0'; mpz_set_str(number,prime_str,2); for(isComposite = false, i = 0; i <= maxPrimeIndex; i++) { if(mpz_cmp_ui(number,shortPrimes[i]) <= 0)////////////////// break; mpz_mod_ui(buf, number, shortPrimes[i]);///////////////////// if(mpz_cmp_ui(buf,(unsigned long int)0) == 0)//////////////////// { isComposite = true; break; } } if(isComposite) continue; if(MillerRabin(number, numBits, 10)) break; } mpz_clear(buf); free(prime_str); }
long euler_problem_78() { long pcsize = 200000; mpz_t* pcache = (mpz_t*)malloc(sizeof(mpz_t)*pcsize); for(long i = 0; i < pcsize; ++i) { mpz_init(pcache[i]); } mpz_set_si(pcache[0], 1); mpz_set_si(pcache[1], 1); mpz_t pr; mpz_init(pr); mpz_t md; mpz_init(md); for(long i = 0; i < 100000; ++i) { p(i, pcache, pr); mpz_mod_ui(md, pr, 1000000); if(mpz_cmp_ui(md, 0) == 0) { return i; } } return 0; }
/* * \brief Encrypts/decrypts a message using the RSA algorithm. * * \param result a field to populate with the result of your RSA calculation. * \param message the message to perform RSA on. (probably a cert in this case) * \param e the encryption key from the key_file passed in through the * command-line arguments * \param n the modulus for RSA from the modulus_file passed in through * the command-line arguments * * Fill in this function with your proj0 solution or see staff solutions. */ static void perform_rsa(mpz_t result, mpz_t message, mpz_t e, mpz_t n) { mpz_t odd; mpz_init(odd); mpz_add_ui(result, result, 1); while (mpz_cmp_ui(e, 0)){ mpz_mod_ui(odd, e, 2); if (mpz_cmp_ui(odd, 0)) { mpz_mul(result, result, message); mpz_mod(result, result, n); mpz_sub_ui(e, e, 1); } else { mpz_mul(message, message, message); mpz_mod(message, message, n); mpz_div_ui(e, e, 2); } } mpz_clear(odd); }
int main( void ) { unsigned int a, b; unsigned long long sum, max; max = 0; mpz_t num, curr, digit; mpz_init(num); mpz_init(curr); mpz_init(digit); for( a = 1; a < 100; a++ ) { for( b = 2; b < 100; b++ ) { mpz_ui_pow_ui(num, a, b); mpz_set( curr, num ); sum = 0; while( mpz_sgn(curr) ) { sum += mpz_mod_ui(digit, curr, 10); mpz_fdiv_q_ui(curr, curr, 10); } max = ( sum > max ) ? sum : max; } } printf("Answer: %llu\n", max); mpz_clear(digit); mpz_clear(num); mpz_clear(curr); return 0; }
string bbs(int N) { mpz_t A, B, r, n, tmp; mpz_init(tmp); mpz_init(n); mpz_init(r); mpz_init(A); mpz_init(B); mpz_set_str(A, "32372334488362947019304797379371153325410700999", 10); mpz_set_str(B, "541528607341564832259551", 10); mpz_mul(n, A, B); mpz_set_ui(r, rand() % 100000 + 1); string res; while (N) { mpz_powm_ui(r, r, 2, n); mpz_mod_ui(tmp, r, 2); res += to_string(mpz_get_ui(tmp)); N--; } return res; }
uint32_t find_length_of_seq(uint16_t i) { mpz_t multiples_of_tens; mpz_t remainder; mpz_init(multiples_of_tens); mpz_init(remainder); mpz_set_ui(multiples_of_tens,10); mpz_set_ui(remainder,0); uint32_t length_of_sequence = 0; // loop mods multiples of 10 with i until the sequence ends (when 10^n%i == 1) while (1){ mpz_mod_ui(remainder,multiples_of_tens,i); length_of_sequence++; if (mpz_cmp_ui(remainder,1) == 0){ break; } mpz_mul_ui(multiples_of_tens, multiples_of_tens,10); } mpz_clear(multiples_of_tens); mpz_clear(remainder); return length_of_sequence; }
int executeSumCalculation(mpz_t num) { mpz_t sum, squareRoot, sqrtRem, st; mpz_t range, rem; int i; pthread_mutex_t mutex; pthread_cond_t cond; unsigned long long termCount; int err; SUM_THREAD_CONTEXT contexts[SUM_THREADS_PER_CALC]; mpz_init(squareRoot); mpz_init(sqrtRem); mpz_init(range); mpz_init(rem); pthread_mutex_init(&mutex, NULL); pthread_cond_init(&cond, NULL); termCount = 0; //The sum starts at 1 because 1 is a factor of any number mpz_init_set_ui(sum, 1); //We know that exactly 1 factor of every pair of factors will //appear before the square root. mpz_sqrtrem(squareRoot, sqrtRem, num); //Check if the the number is a square if (mpz_cmp_ui(sqrtRem, 0) != 0) { //Emulate ceil mpz_add_ui(squareRoot, squareRoot, 1); } //Factor starts at 2 mpz_init_set_ui(st, 2); //Compute range mpz_mod_ui(rem, squareRoot, SUM_THREADS_PER_CALC); mpz_sub(squareRoot, squareRoot, rem); mpz_divexact_ui(range, squareRoot, SUM_THREADS_PER_CALC); for (i = 0; i < SUM_THREADS_PER_CALC; i++) { mpz_init_set(contexts[i].st, st); mpz_init_set(contexts[i].factor, st); mpz_init(contexts[i].otherfactor); mpz_add(st, st, range); if (i == 0) { mpz_sub_ui(st, st, 2); } mpz_init_set(contexts[i].end, st); if (i == 0) { mpz_add(contexts[i].end, contexts[i].end, rem); mpz_add(st, st, rem); } mpz_init_set(contexts[i].num, num); contexts[i].sum = ∑ contexts[i].termCount = &termCount; contexts[i].termMutex = &mutex; contexts[i].termVar = &cond; printf("Assigning work to sum thread %d\n", i); err = pthread_create(&contexts[i].id, NULL, SumThread, &contexts[i]); if (err != 0) return -1; } fflush(stdout); for (;;) { pthread_mutex_lock(&mutex); printf("%llu sum threads complete\n", termCount); fflush(stdout); if (termCount == SUM_THREADS_PER_CALC) { pthread_mutex_unlock(&mutex); break; } if (mpz_cmp(sum, num) > 0) { printf("sum is too large; terminating children\n"); fflush(stdout); pthread_mutex_unlock(&mutex); break; } pthread_cond_wait(&cond, &mutex); pthread_mutex_unlock(&mutex); } for (i = 0; i < SUM_THREADS_PER_CALC; i++) { void *ret; pthread_cancel(contexts[i].id); pthread_join(contexts[i].id, &ret); mpz_clear(contexts[i].st); mpz_clear(contexts[i].num); mpz_clear(contexts[i].factor); mpz_clear(contexts[i].end); mpz_clear(contexts[i].otherfactor); } mpz_clear(squareRoot); mpz_clear(sqrtRem); mpz_clear(range); mpz_clear(rem); mpz_clear(st); if (mpz_cmp(sum, num) == 0) { mpz_clear(sum); return 1; } else { mpz_clear(sum); return 0; } }
bool Algorithms::MillerRabin(mpz_t number, unsigned int numBits, unsigned int numTest) { unsigned int i, j, k; char *a_str; mpz_t buf, t, gcd, a, c; mpz_init(buf); mpz_init(t); mpz_init(gcd); mpz_init(a); mpz_init(c); if(mpz_cmp_ui(number,(unsigned long)2) == 0) return true; mpz_mod_ui(buf, number, (unsigned long)2); if(mpz_cmp_ui(buf,(unsigned long)0) == 0) return false; unsigned long s = 0; mpz_sub_ui(t,number,(unsigned long)1); mpz_mod_ui(buf, t, (unsigned long)2); while(mpz_cmp_ui(buf,(unsigned long)0) == 0) { mpz_tdiv_qr_ui(t, buf, t, (unsigned long)2); mpz_mod_ui(buf, t, (unsigned long)2); s++; } a_str = new char[numBits]; for(i = 0; i < numTest; i++) { for(k = 0; k < numBits - 1; k++) a_str[k] = (int)(2.0 * rand() / (RAND_MAX + 1.0)) + '0'; a_str[k] = '\0'; mpz_set_str(a,a_str,2); mpz_gcd(gcd,a,number); if(mpz_cmp_ui(gcd,(unsigned long)1) != 0) return false; mpz_powm(c, a, t, number); if(mpz_cmp_ui(c,(unsigned long)1) == 0) continue; mpz_sub_ui(buf,number,(unsigned long)1); if(mpz_cmp(c,buf) == 0) continue; bool f = true; for(j = 0; j < s - 1; j++) { mpz_powm_ui(c, c,(unsigned long)2, number); if(mpz_cmp(c,buf) == 0) f = false; } if(f) return false; } mpz_clear(buf); mpz_clear(t); mpz_clear(gcd); mpz_clear(a); mpz_clear(c); free(a_str); return true; }
void rsa_random_prime(MP_INT *ret, RandomState *state, unsigned int bits) { MP_INT start, aux; unsigned int num_primes; int *moduli; long difference; mpz_init(&start); mpz_init(&aux); retry: /* Pick a random integer of the appropriate size. */ rsa_random_integer(&start, state, bits); /* Set the two highest bits. */ mpz_set_ui(&aux, 3); mpz_mul_2exp(&aux, &aux, bits - 2); mpz_ior(&start, &start, &aux); /* Set the lowest bit to make it odd. */ mpz_set_ui(&aux, 1); mpz_ior(&start, &start, &aux); /* Initialize moduli of the small primes with respect to the given random number. */ moduli = xmalloc(MAX_PRIMES_IN_TABLE * sizeof(moduli[0])); if (bits < 16) num_primes = 0; /* Don\'t use the table for very small numbers. */ else { for (num_primes = 0; small_primes[num_primes] != 0; num_primes++) { mpz_mod_ui(&aux, &start, small_primes[num_primes]); moduli[num_primes] = mpz_get_ui(&aux); } } /* Look for numbers that are not evenly divisible by any of the small primes. */ for (difference = 0; ; difference += 2) { unsigned int i; if (difference > 0x70000000) { /* Should never happen, I think... */ if (rsa_verbose) fprintf(stderr, "rsa_random_prime: failed to find a prime, retrying.\n"); xfree(moduli); goto retry; } /* Check if it is a multiple of any small prime. Note that this updates the moduli into negative values as difference grows. */ for (i = 0; i < num_primes; i++) { while (moduli[i] + difference >= small_primes[i]) moduli[i] -= small_primes[i]; if (moduli[i] + difference == 0) break; } if (i < num_primes) continue; /* Multiple of a known prime. */ /* It passed the small prime test (not divisible by any of them). */ if (rsa_verbose) { fprintf(stderr, "."); } /* Compute the number in question. */ mpz_add_ui(ret, &start, difference); /* Perform the fermat test for witness 2. This means: it is not prime if 2^n mod n != 2. */ mpz_set_ui(&aux, 2); mpz_powm(&aux, &aux, ret, ret); if (mpz_cmp_ui(&aux, 2) == 0) { /* Passed the fermat test for witness 2. */ if (rsa_verbose) { fprintf(stderr, "+"); } /* Perform a more tests. These are probably unnecessary. */ if (mpz_probab_prime_p(ret, 20)) break; /* It is a prime with probability 1 - 2^-40. */ } } /* Found a (probable) prime. It is in ret. */ if (rsa_verbose) { fprintf(stderr, "+ (distance %ld)\n", difference); } /* Free the small prime moduli; they are no longer needed. */ xfree(moduli); /* Sanity check: does it still have the high bit set (we might have wrapped around)? */ mpz_div_2exp(&aux, ret, bits - 1); if (mpz_get_ui(&aux) != 1) { if (rsa_verbose) fprintf(stderr, "rsa_random_prime: high bit not set, retrying.\n"); goto retry; } mpz_clear(&start); mpz_clear(&aux); /* Return value already set in ret. */ }
void fast_fermat_alg( mpz_t n ) { mpz_t rem, k, y, fl_y, lhs, rhs; int d; mpz_init( rem ); mpz_init( k ); mpz_init( y ); mpz_init( fl_y ); mpz_init( lhs ); mpz_init( rhs ); /* even number check*/ mpz_mod_ui( rem, n, 2 ); if (mpz_cmp_ui( rem, 0) == 0) gmp_printf( "%Zd is even\n", n ); /* initialise bits */ mpz_sqrt( k, n ); mpz_add_ui( k, k, 1 ); mpz_pow_ui( y, k, 2 ); mpz_sub( y, y, n ); d = 1; while ( 1 ) { mpz_sqrt( fl_y, y ); mpz_pow_ui(lhs, fl_y, 2 ); mpz_pow_ui(lhs, lhs, 2 ); mpz_pow_ui(rhs, y, 2 ); if ( mpz_cmp( lhs, rhs ) == 0 ) { printf( "Have found factors:\n" ); break; } mpz_mul_si( lhs, k, 2 ); mpz_add_ui( lhs, lhs, d ); mpz_add( y, y, lhs ); d = d + 2; mpz_cdiv_q_ui( rhs, n, 2 ); if (mpz_cmp(fl_y, rhs) > 1) { printf( "No factor found\n" ); return; } } mpz_add( k, n, y ); mpz_sqrt( lhs, k ); mpz_sqrt( rhs, y ); gmp_printf( " the non-trivial factors of %Zd are\n", n ); mpz_sub( k, lhs, rhs ); gmp_printf( "%Zd and\n", k ); mpz_add( k, lhs, rhs ); gmp_printf( "%Zd\n", k ); }
int main (int argc, char **argv) { mpz_t base, exp, mod; mpz_t r1, r2, t1, exp2, base2; mp_size_t base_size, exp_size, mod_size; int i; int reps = 100; gmp_randstate_ptr rands; mpz_t bs; unsigned long bsi, size_range; tests_start (); rands = 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 (t1); mpz_init (exp2); 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, 7L); exp_size = mpz_get_ui (bs); mpz_rrandomb (exp, rands, exp_size); } while (mpz_cmp_ui (base, 0) == 0 && mpz_cmp_ui (exp, 0) == 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 %ld\n", SIZ (base), SIZ (exp), SIZ (mod)); */ mpz_powm (r1, base, exp, mod); mpz_set_ui (r2, 1); mpz_set (base2, base); mpz_set (exp2, exp); mpz_mod (r2, r2, mod); /* needed when exp==0 and mod==1 */ while (mpz_cmp_ui (exp2, 0) != 0) { mpz_mod_ui (t1, exp2, 2); if (mpz_cmp_ui (t1, 0) != 0) { mpz_mul (r2, r2, base2); mpz_mod (r2, r2, mod); } mpz_mul (base2, base2, base2); mpz_mod (base2, base2, mod); mpz_div_ui (exp2, exp2, 2); } if (mpz_cmp (r1, r2) != 0) { fprintf (stderr, "\nIncorrect results for operands:\n"); debug_mp (base, -16); debug_mp (exp, -16); debug_mp (mod, -16); fprintf (stderr, "mpz_powm 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 (t1); mpz_clear (exp2); mpz_clear (base2); tests_end (); exit (0); }