/* y <- exp(p/2^r) within 1 ulp, using 2^m terms from the series Assume |p/2^r| < 1. We use the following binary splitting formula: P(a,b) = p if a+1=b, P(a,c)*P(c,b) otherwise Q(a,b) = a*2^r if a+1=b [except Q(0,1)=1], Q(a,c)*Q(c,b) otherwise T(a,b) = P(a,b) if a+1=b, Q(c,b)*T(a,c)+P(a,c)*T(c,b) otherwise Then exp(p/2^r) ~ T(0,i)/Q(0,i) for i so that (p/2^r)^i/i! is small enough. Since P(a,b) = p^(b-a), and we consider only values of b-a of the form 2^j, we don't need to compute P(), we only precompute p^(2^j) in the ptoj[] array below. Since Q(a,b) is divisible by 2^(r*(b-a-1)), we don't compute the power of two part. */ static void mpfr_exp_rational (mpfr_ptr y, mpz_ptr p, long r, int m, mpz_t *Q, mpfr_prec_t *mult) { mp_bitcnt_t n, i, j; /* unsigned type, which is >= unsigned long */ mpz_t *S, *ptoj; mpfr_prec_t *log2_nb_terms; mpfr_exp_t diff, expo; mpfr_prec_t precy = MPFR_PREC(y), prec_i_have, prec_ptoj; int k, l; MPFR_ASSERTN ((size_t) m < sizeof (long) * CHAR_BIT - 1); S = Q + (m+1); ptoj = Q + 2*(m+1); /* ptoj[i] = mantissa^(2^i) */ log2_nb_terms = mult + (m+1); /* Normalize p */ MPFR_ASSERTD (mpz_cmp_ui (p, 0) != 0); n = mpz_scan1 (p, 0); /* number of trailing zeros in p */ MPFR_ASSERTN (n <= LONG_MAX); /* This is a limitation. */ mpz_tdiv_q_2exp (p, p, n); r -= (long) n; /* since |p/2^r| < 1 and p >= 1, r >= 1 */ /* Set initial var */ mpz_set (ptoj[0], p); for (k = 1; k < m; k++) mpz_mul (ptoj[k], ptoj[k-1], ptoj[k-1]); /* ptoj[k] = p^(2^k) */ mpz_set_ui (Q[0], 1); mpz_set_ui (S[0], 1); k = 0; mult[0] = 0; /* the multiplier P[k]/Q[k] for the remaining terms satisfies P[k]/Q[k] <= 2^(-mult[k]) */ log2_nb_terms[0] = 0; /* log2(#terms) [exact in 1st loop where 2^k] */ prec_i_have = 0; /* Main Loop */ n = 1UL << m; MPFR_ASSERTN (n != 0); /* no overflow */ for (i = 1; (prec_i_have < precy) && (i < n); i++) { /* invariant: Q[0]*Q[1]*...*Q[k] equals i! */ k++; log2_nb_terms[k] = 0; /* 1 term */ mpz_set_ui (Q[k], i + 1); mpz_set_ui (S[k], i + 1); j = i + 1; /* we have computed j = i+1 terms so far */ l = 0; while ((j & 1) == 0) /* combine and reduce */ { /* invariant: S[k] corresponds to 2^l consecutive terms */ mpz_mul (S[k], S[k], ptoj[l]); mpz_mul (S[k-1], S[k-1], Q[k]); /* Q[k] corresponds to 2^l consecutive terms too. Since it does not contains the factor 2^(r*2^l), when going from l to l+1 we need to multiply by 2^(r*2^(l+1))/2^(r*2^l) = 2^(r*2^l) */ 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] ++; /* number of terms in S[k-1] is a power of 2 by construction */ MPFR_MPZ_SIZEINBASE2 (prec_i_have, Q[k]); MPFR_MPZ_SIZEINBASE2 (prec_ptoj, ptoj[l]); mult[k-1] += prec_i_have + (r << l) - prec_ptoj - 1; prec_i_have = mult[k] = mult[k-1]; /* since mult[k] >= mult[k-1] + nbits(Q[k]), we have Q[0]*...*Q[k] <= 2^mult[k] = 2^prec_i_have */ l ++; j >>= 1; k --; } } /* accumulate all products in S[0] and Q[0]. Warning: contrary to above, here we do not have log2_nb_terms[k-1] = log2_nb_terms[k]+1. */ l = 0; /* number of accumulated terms in the right part S[k]/Q[k] */ while (k > 0) { j = log2_nb_terms[k-1]; mpz_mul (S[k], S[k], ptoj[j]); mpz_mul (S[k-1], S[k-1], Q[k]); l += 1 << log2_nb_terms[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]); k--; } /* Q[0] now equals i! */ MPFR_MPZ_SIZEINBASE2 (prec_i_have, S[0]); diff = (mpfr_exp_t) prec_i_have - 2 * (mpfr_exp_t) precy; expo = diff; if (diff >= 0) mpz_fdiv_q_2exp (S[0], S[0], diff); else mpz_mul_2exp (S[0], S[0], -diff); MPFR_MPZ_SIZEINBASE2 (prec_i_have, Q[0]); diff = (mpfr_exp_t) prec_i_have - (mpfr_prec_t) precy; expo -= diff; if (diff > 0) mpz_fdiv_q_2exp (Q[0], Q[0], diff); else mpz_mul_2exp (Q[0], Q[0], -diff); mpz_tdiv_q (S[0], S[0], Q[0]); mpfr_set_z (y, S[0], MPFR_RNDD); /* TODO: Check/prove that the following expression doesn't overflow. */ expo = MPFR_GET_EXP (y) + expo - r * (i - 1); MPFR_SET_EXP (y, expo); }
void riecoin_process(minerRiecoinBlock_t* block) { uint32 searchBits = block->targetCompact; if( riecoin_sieve ) memset(riecoin_sieve, 0x00, riecoin_sieveSize/8); else { riecoin_sieve = (uint8*)malloc(riecoin_sieveSize/8); memset(riecoin_sieve, 0x00, riecoin_sieveSize/8); } uint8* sieve = riecoin_sieve; // test data // getblock 16ee31c116b75d0299dc03cab2b6cbcb885aa29adf292b2697625bc9d28b2b64 //debug_parseHexStringLE("c59ba5357285de73b878fed43039a37f85887c8960e66bcb6e86bdad565924bd", 64, block->merkleRoot); //block->version = 2; //debug_parseHexStringLE("c64673c670fb327c2e009b3b626d2def01d51ad4131a7a1040e9cef7bfa34838", 64, block->prevBlockHash); //block->nTime = 1392151955; //block->nBits = 0x02013000; //debug_parseHexStringLE("0000000000000000000000000000000000000000000000000000000070b67515", 64, block->nOffset); // generate PoW hash (version to nBits) uint8 powHash[32]; sha256_ctx ctx; sha256_init(&ctx); sha256_update(&ctx, (uint8*)block, 80); sha256_final(&ctx, powHash); sha256_init(&ctx); sha256_update(&ctx, powHash, 32); sha256_final(&ctx, powHash); // generatePrimeBase uint32* powHashU32 = (uint32*)powHash; mpz_t z_target; mpz_t z_temp; mpz_init(z_temp); mpz_init_set_ui(z_target, 1); mpz_mul_2exp(z_target, z_target, zeroesBeforeHashInPrime); for(uint32 i=0; i<256; i++) { mpz_mul_2exp(z_target, z_target, 1); if( (powHashU32[i/32]>>(i))&1 ) z_target->_mp_d[0]++; } unsigned int trailingZeros = searchBits - 1 - zeroesBeforeHashInPrime - 256; mpz_mul_2exp(z_target, z_target, trailingZeros); // find first offset where x%2310 = 97 uint64 remainder2310 = mpz_tdiv_ui(z_target, 2310); remainder2310 = (2310-remainder2310)%2310; remainder2310 += 97; mpz_add_ui(z_temp, z_target, remainder2310); mpz_t z_temp2; mpz_init(z_temp2); mpz_t z_ft_r; mpz_init(z_ft_r); mpz_t z_ft_b; mpz_init_set_ui(z_ft_b, 2); mpz_t z_ft_n; mpz_init(z_ft_n); static uint32 primeTupleBias[6] = {0,4,6,10,12,16}; for(uint32 i=5; i<riecoin_primeTestSize; i++) { for(uint32 f=0; f<6; f++) { uint32 p = riecoin_primeTestTable[i]; uint32 remainder = mpz_tdiv_ui(z_temp, p);//; remainder += primeTupleBias[f]; remainder %= p; uint32 index; // a+b*x=0 (mod p) => b*x=p-a => x = (p-a)*modinv(b) sint32 pa = (p<remainder)?(p-remainder+p):(p-remainder); sint32 b = 2310; index = (pa%p)*int_invert(b, p); index %= p; while(index < riecoin_sieveSize) { sieve[(index)>>3] |= (1<<((index)&7)); index += p; } } } uint32 countCandidates = 0; uint32 countPrimes = 0; uint32 countPrimes2 = 0; // scan for candidates for(uint32 i=1; i<riecoin_sieveSize; i++) { if( sieve[(i)>>3] & (1<<((i)&7)) ) continue; countCandidates++; // test the first 4 numbers for being prime (5th and 6th is checked server side) // we use fermat test as it is slightly faster for virtually the same accuracy // p1 mpz_add_ui(z_temp, z_target, (uint64)remainder2310 + 2310ULL*(uint64)i); mpz_sub_ui(z_ft_n, z_temp, 1); mpz_powm(z_ft_r, z_ft_b, z_ft_n, z_temp); if (mpz_cmp_ui(z_ft_r, 1) != 0) continue; else countPrimes++; // p2 mpz_add_ui(z_temp, z_temp, 4); mpz_sub_ui(z_ft_n, z_temp, 1); mpz_powm(z_ft_r, z_ft_b, z_ft_n, z_temp); if (mpz_cmp_ui(z_ft_r, 1) != 0) continue; else countPrimes2++; total2ChainCount++; // p3 mpz_add_ui(z_temp, z_temp, 2); if( mpz_probab_prime_p(z_temp, 1) == 0 ) continue; total3ChainCount++; // p4 mpz_add_ui(z_temp, z_temp, 4); if( mpz_probab_prime_p(z_temp, 1) == 0 ) continue; total4ChainCount++; // calculate offset mpz_add_ui(z_temp, z_target, (uint64)remainder2310 + 2310ULL*(uint64)i); mpz_sub(z_temp2, z_temp, z_target); // submit share uint8 nOffset[32]; memset(nOffset, 0x00, 32); #ifdef _WIN64 for(uint32 d=0; d<min(32/8, z_temp2->_mp_size); d++) { *(uint64*)(nOffset+d*8) = z_temp2->_mp_d[d]; } #else for(uint32 d=0; d<min(32/4, z_temp2->_mp_size); d++) { *(uint32*)(nOffset+d*4) = z_temp2->_mp_d[d]; } #endif totalShareCount++; xptMiner_submitShare(block, nOffset); } }
/* 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; }
int main (int argc, char* argv[]) { if(argc !=4) { printf("usage : ./craquage p r m\n"); return EXIT_FAILURE; } //Initialisation des variables int nb_esclaves = atoi(argv[1]); int* tids = (int*) calloc(nb_esclaves, sizeof(int)); int longueur_mdp = atoi(argv[2]); char* mdp = (char*) calloc(strlen(argv[3])+1, sizeof(char)); strcpy(mdp, argv[3]); //declaration de type de tres long entiers (avec bibliotheque GMP) mpz_t debut_sequence, pas_reel, pas, fin_exec; mpz_init(debut_sequence); mpz_init(pas_reel); mpz_init(pas); mpz_init(fin_exec); //recuperation du chemin de l executable char* chemin = getcwd(NULL, 1000); strcat(chemin, "/craquage_esclave"); //creation des arguments pour l esclave char *argv_esclave[3]; argv_esclave[2]=NULL; argv_esclave[0] = (char*) calloc(strlen(argv[2])+1, sizeof(char)); strcpy(argv_esclave[0],argv[2]); argv_esclave[1] = (char*) calloc(strlen(argv[3])+1, sizeof(char)); strcpy(argv_esclave[1],argv[3]); //printf("strlen %lu, %lu\n", (long unsigned)strlen(argv[2]),(long unsigned) strlen(argv[3])); //printf("nb_esclaves %d\n", nb_esclaves); int i; int trouve = 0; int fini = 0; int size; int nb_envoi = 0; int nb_pas = nb_esclaves*longueur_mdp; int nb_changement = 0; char* envoi_char; int bufid, info, bytes, type, source; char * solution; pvm_catchout(stderr); struct timeval tv1, tv2; gettimeofday(&tv1, NULL); pvm_spawn(chemin, argv_esclave, PvmTaskDefault,"", nb_esclaves, tids); //calcul du pas, fin_exec (= fin execution) mpz_set_ui(debut_sequence, 0); mpz_ui_pow_ui(fin_exec, 15, longueur_mdp+1); mpz_sub_ui(fin_exec, fin_exec, 15); mpz_cdiv_q_ui(fin_exec, fin_exec, 14); mpz_set(pas, fin_exec); mpz_cdiv_q_ui(pas, pas, nb_pas); if(mpz_cmp_ui(pas, 0)==0) { mpz_set_ui(pas,1); } //gmp_printf("fin_exec: %Zd\npas:%Zd\ndebut_sequence:%Zd\n",fin_exec, pas, debut_sequence); //boucle principale while(!trouve && fini!=nb_esclaves) { //Attente de reception de donnees d un esclave bufid = pvm_recv( -1, -1 ); info = pvm_bufinfo( bufid, &bytes, &type, &source ); if (info < 0) { printf("Erreur de reception : %d\n", info); exit(1); } //selon le tag du message, demande de donnees ou solution trouvee switch(type) { case(0)://mot de passe trouve solution = calloc(bytes, sizeof(char)); pvm_upkstr(solution); printf("\nLa solution est : %s\n\n", solution); trouve = 1; break; case(1)://esclave veut plus de donnees //prendre en compte la fin des donnees dans le calcul du pas if(nb_changement <= 2 && nb_envoi>=(3*nb_pas/4)) { mpz_cdiv_q_ui(pas, pas, 2); nb_envoi = 0; nb_pas/=2; nb_changement++; } //gmp_printf("fin_exec: %Zd pas:%Zd debut_sequence:%Zd\n",fin_exec, pas, debut_sequence); if(mpz_cmp(debut_sequence, fin_exec)< 0){ mpz_sub(pas_reel, fin_exec, debut_sequence); if(mpz_cmp(pas, pas_reel)<0) { mpz_set(pas_reel, pas); } //envoi des donnes a l esclave pvm_initsend(PvmDataDefault); size = gmp_asprintf(&envoi_char, "%Zd", debut_sequence); pvm_pkint(&size, 1, 1); pvm_pkbyte(envoi_char,size+1, 1); free(envoi_char); size = gmp_asprintf(&envoi_char, "%Zd", pas_reel); pvm_pkint(&size, 1, 1); pvm_pkbyte(envoi_char,size+1 , 1); free(envoi_char); pvm_send(source,0); if(mpz_cmp(pas_reel,pas)!=0) { mpz_set(debut_sequence,fin_exec); } else { mpz_add(debut_sequence, debut_sequence,pas); } nb_envoi++; } else{ fini++ ; printf("Pas de solution pour %d esclave(s)\n", fini); } break; default: break; } } // suppression des esclave for(i=0; i<nb_esclaves;i++) { info = pvm_kill(tids[i]); //printf("Suppression de l esclave %d: retour de pvm_kill: %d\n",i ,info); } pvm_exit(); gettimeofday(&tv2, NULL); printf("%d %ld\n",longueur_mdp,(tv2.tv_sec-tv1.tv_sec)*1000 + (tv2.tv_usec-tv1.tv_usec)/1000); mpz_clear(debut_sequence); mpz_clear(pas_reel); mpz_clear(pas); mpz_clear(fin_exec); free(tids); free(mdp); free(argv_esclave[0]); free(argv_esclave[1]); return EXIT_SUCCESS; }
static PyObject * Pympz_mpmath_normalize(PyObject *self, PyObject *args) { long sign = 0; long bc = 0, prec = 0, shift, zbits, carry = 0; PyObject *exp = 0, *newexp = 0, *newexp2 = 0, *tmp = 0, *rndstr = 0; MPZ_Object *man = 0, *upper = 0, *lower = 0; char rnd = 0; int err1, err2, err3; if (PyTuple_GET_SIZE(args) == 6) { /* Need better error-checking here. Under Python 3.0, overflow into C-long is possible. */ sign = GMPy_Integer_AsLongAndError(PyTuple_GET_ITEM(args, 0), &err1); man = (MPZ_Object *)PyTuple_GET_ITEM(args, 1); exp = PyTuple_GET_ITEM(args, 2); bc = GMPy_Integer_AsLongAndError(PyTuple_GET_ITEM(args, 3), &err2); prec = GMPy_Integer_AsLongAndError(PyTuple_GET_ITEM(args, 4), &err3); rndstr = PyTuple_GET_ITEM(args, 5); if (err1 || err2 || err3) { TYPE_ERROR("arguments long, MPZ_Object*, PyObject*, long, long, char needed"); return NULL; } } else { TYPE_ERROR("6 arguments required"); return NULL; } if (!MPZ_Check(man)) { TYPE_ERROR("argument is not an mpz"); return NULL; } /* If rndstr really is a string, extract the first character. */ if (Py2or3String_Check(rndstr)) { rnd = Py2or3String_AsString(rndstr)[0]; } else { VALUE_ERROR("invalid rounding mode specified"); return NULL; } /* If the mantissa is 0, return the normalized representation. */ if (!mpz_sgn(man->z)) { Py_INCREF((PyObject*)man); return mpmath_build_mpf(0, man, 0, 0); } /* if bc <= prec and the number is odd return it */ if ((bc <= prec) && mpz_odd_p(man->z)) { Py_INCREF((PyObject*)man); Py_INCREF((PyObject*)exp); return mpmath_build_mpf(sign, man, exp, bc); } if (!(upper = GMPy_MPZ_New(NULL)) || !(lower = GMPy_MPZ_New(NULL))) { Py_XDECREF((PyObject*)upper); Py_XDECREF((PyObject*)lower); } shift = bc - prec; if (shift>0) { switch (rnd) { case 'f': if(sign) { mpz_cdiv_q_2exp(upper->z, man->z, shift); } else { mpz_fdiv_q_2exp(upper->z, man->z, shift); } break; case 'c': if(sign) { mpz_fdiv_q_2exp(upper->z, man->z, shift); } else { mpz_cdiv_q_2exp(upper->z, man->z, shift); } break; case 'd': mpz_fdiv_q_2exp(upper->z, man->z, shift); break; case 'u': mpz_cdiv_q_2exp(upper->z, man->z, shift); break; case 'n': default: mpz_tdiv_r_2exp(lower->z, man->z, shift); mpz_tdiv_q_2exp(upper->z, man->z, shift); if (mpz_sgn(lower->z)) { /* lower is not 0 so it must have at least 1 bit set */ if (mpz_sizeinbase(lower->z, 2) == shift) { /* lower is >= 1/2 */ if (mpz_scan1(lower->z, 0) == shift-1) { /* lower is exactly 1/2 */ if (mpz_odd_p(upper->z)) carry = 1; } else { carry = 1; } } } if (carry) mpz_add_ui(upper->z, upper->z, 1); } if (!(tmp = PyIntOrLong_FromLong(shift))) { Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); return NULL; } if (!(newexp = PyNumber_Add(exp, tmp))) { Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(tmp); return NULL; } Py_DECREF(tmp); bc = prec; } else { mpz_set(upper->z, man->z); newexp = exp; Py_INCREF(newexp); } /* Strip trailing 0 bits. */ if ((zbits = mpz_scan1(upper->z, 0))) mpz_tdiv_q_2exp(upper->z, upper->z, zbits); if (!(tmp = PyIntOrLong_FromLong(zbits))) { Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(newexp); return NULL; } if (!(newexp2 = PyNumber_Add(newexp, tmp))) { Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(tmp); Py_DECREF(newexp); return NULL; } Py_DECREF(newexp); Py_DECREF(tmp); bc -= zbits; /* Check if one less than a power of 2 was rounded up. */ if (!mpz_cmp_ui(upper->z, 1)) bc = 1; Py_DECREF((PyObject*)lower); return mpmath_build_mpf(sign, upper, newexp2, bc); }
/*========================================================================== evaluateSieve: Function: searches sieve for relations and sticks them into a matrix, then sticks their X and Y values into two arrays XArr and YArr ===========================================================================*/ static void evaluateSieve( unsigned long numPrimes, unsigned long Mdiv2, unsigned long * relations, unsigned long ctimesreps, unsigned long M, unsigned char * sieve, mpz_t A, mpz_t B, mpz_t C, unsigned long * soln1, unsigned long * soln2, unsigned char * flags, matrix_t m, mpz_t * XArr, unsigned long * aind, int min, int s, int * exponents, unsigned long * npartials, unsigned long * nrelsfound, unsigned long * nrelssought, mpz_t temp, mpz_t temp2, mpz_t temp3, mpz_t res) { long i,j,ii; unsigned int k; unsigned int exponent, vv; unsigned char extra; unsigned int modp; unsigned long * sieve2; unsigned char bits; int numfactors; unsigned long relsFound = *nrelsfound; unsigned long relSought = *nrelssought; mpz_set_ui(temp, 0); mpz_set_ui(temp2, 0); mpz_set_ui(temp3, 0); mpz_set_ui(res, 0); i = 0; j = 0; sieve2 = (unsigned long *) sieve; #ifdef POLS gmp_printf("%Zdx^2%+Zdx\n%+Zd\n",A,B,C); #endif while ( (unsigned long)j < M/sizeof(unsigned long)) { do { while (!(sieve2[j] & SIEVEMASK)) j++; i = j * sizeof(unsigned long); j++; while (((unsigned long)i < j*sizeof(unsigned long)) && (sieve[i] < threshold)) i++; } while (sieve[i] < threshold); if (((unsigned long)i<M) && (relsFound < relSought)) { mpz_set_ui(temp,i+ctimesreps); mpz_sub_ui(temp, temp, Mdiv2); /* X */ mpz_set(temp3, B); /* B */ mpz_addmul(temp3, A, temp); /* AX+B */ mpz_add(temp2, temp3, B); /* AX+2B */ mpz_mul(temp2, temp2, temp); /* AX^2+2BX */ mpz_add(res, temp2, C); /* AX^2+2BX+C */ bits = mpz_sizeinbase(res,2) - errorbits; numfactors=0; extra = 0; memset(exponents, 0, firstprime * sizeof(int)); if (factorBase[0] != 1 && mpz_divisible_ui_p(res, factorBase[0])) { extra += primeSizes[0]; if (factorBase[0] == 2) { exponent = mpz_scan1(res, 0); mpz_tdiv_q_2exp(res, res, exponent); } else { mpz_set_ui(temp,factorBase[0]); exponent = mpz_remove(res,res,temp); } exponents[0] = exponent; } exponents[1] = 0; if (mpz_divisible_ui_p(res, factorBase[1])) { extra += primeSizes[1]; if (factorBase[1] == 2) { exponent = mpz_scan1(res, 0); mpz_tdiv_q_2exp(res, res, exponent); } else { mpz_set_ui(temp,factorBase[1]); exponent = mpz_remove(res,res,temp); } exponents[1] = exponent; } for (k = 2; k < firstprime; k++) { modp=(i+ctimesreps)%factorBase[k]; exponents[k] = 0; if (soln2[k] != (unsigned long)-1) { if ((modp==soln1[k]) || (modp==soln2[k])) { extra+=primeSizes[k]; mpz_set_ui(temp,factorBase[k]); exponent = mpz_remove(res,res,temp); CHECK_EXPONENT(exponent, k); PRINT_FB(exponent, k); exponents[k] = exponent; } } else if (mpz_divisible_ui_p(res, factorBase[k])) { extra += primeSizes[k]; mpz_set_ui(temp,factorBase[k]); exponent = mpz_remove(res,res,temp); PRINT_FB(exponent, k); exponents[k] = exponent; } } sieve[i]+=extra; if (sieve[i] >= bits) { vv=((unsigned char)1<<(i&7)); for (k = firstprime; (k<secondprime)&&(extra<sieve[i]); k++) { modp=(i+ctimesreps)%factorBase[k]; if (soln2[k] != (unsigned long)-1) { if ((modp==soln1[k]) || (modp==soln2[k])) { extra+=primeSizes[k]; mpz_set_ui(temp,factorBase[k]); exponent = mpz_remove(res,res,temp); CHECK_EXPONENT(exponent, k); PRINT_FB(exponent, k); if (exponent) for (ii = 0; ii < (long)exponent; ii++) set_relation(relations, relsFound, ++numfactors, k); if (exponent & 1) insertEntry(m,relsFound,k); } } else if (mpz_divisible_ui_p(res, factorBase[k])) { extra += primeSizes[k]; mpz_set_ui(temp,factorBase[k]); exponent = mpz_remove(res,res,temp); PRINT_FB(exponent, k); for (ii = 0; ii < (long)exponent; ii++) set_relation(relations, relsFound, ++numfactors, k); if (exponent & 1) insertEntry(m,relsFound,k); } } for (k = secondprime; (k<numPrimes)&&(extra<sieve[i]); k++) { if (flags[k]&vv) { modp=(i+ctimesreps)%factorBase[k]; if ((modp==soln1[k]) || (modp==soln2[k])) { extra+=primeSizes[k]; mpz_set_ui(temp,factorBase[k]); exponent = mpz_remove(res,res,temp); CHECK_EXPONENT(exponent, k); PRINT_FB(exponent, k); if (exponent) for (ii = 0; ii < (long)exponent; ii++) set_relation(relations, relsFound, ++numfactors, k); if (exponent & 1) insertEntry(m,relsFound,k); } } } for (ii =0; ii<s; ii++) { xorEntry(m,relsFound,aind[ii]+min); set_relation(relations, relsFound, ++numfactors, aind[ii]+min); } if (mpz_cmp_ui(res,1000)>0) { if (mpz_cmp_ui(res,largeprime)<0) { (*npartials)++; } clearRow(m,numPrimes,relsFound); #ifdef RELPRINT gmp_printf(" %Zd\n",res); #endif } else { mpz_neg(res,res); if (mpz_cmp_ui(res,1000)>0) { if (mpz_cmp_ui(res,largeprime)<0) { (*npartials)++; } clearRow(m,numPrimes,relsFound); #ifdef RELPRINT gmp_printf(" %Zd\n",res); #endif } else { #ifdef RELPRINT printf("....R\n"); #endif for (ii = 0; ii < (long)firstprime; ii++) { int jj; for (jj = 0; jj < exponents[ii]; jj++) set_relation(relations, relsFound, ++numfactors, ii); if (exponents[ii] & 1) insertEntry(m,relsFound,ii); } set_relation(relations, relsFound, 0, numfactors); mpz_init_set(XArr[relsFound], temp3); /* (AX+B) */ relsFound++; #ifdef COUNT if (relsFound%20==0) fprintf(stderr,"%lu relations, %lu partials.\n", relsFound, *npartials); #endif } } } else { clearRow(m,numPrimes,relsFound); #ifdef RELPRINT printf("\r \r"); #endif } i++; } else if (relsFound >= relSought) i++; } /* Update caller */ *nrelsfound = relsFound; *nrelssought = relSought; }
int mpfr_zeta_ui (mpfr_ptr z, unsigned long m, mpfr_rnd_t r) { MPFR_ZIV_DECL (loop); if (m == 0) { mpfr_set_ui (z, 1, r); mpfr_div_2ui (z, z, 1, r); MPFR_CHANGE_SIGN (z); MPFR_RET (0); } else if (m == 1) { MPFR_SET_INF (z); MPFR_SET_POS (z); mpfr_set_divby0 (); return 0; } else /* m >= 2 */ { mpfr_prec_t p = MPFR_PREC(z); unsigned long n, k, err, kbits; mpz_t d, t, s, q; mpfr_t y; int inex; if (r == MPFR_RNDA) r = MPFR_RNDU; /* since the result is always positive */ if (m >= p) /* 2^(-m) < ulp(1) = 2^(1-p). This means that 2^(-m) <= 1/2*ulp(1). We have 3^(-m)+4^(-m)+... < 2^(-m) i.e. zeta(m) < 1+2*2^(-m) for m >= 3 */ { if (m == 2) /* necessarily p=2 */ return mpfr_set_ui_2exp (z, 13, -3, r); else if (r == MPFR_RNDZ || r == MPFR_RNDD || (r == MPFR_RNDN && m > p)) { mpfr_set_ui (z, 1, r); return -1; } else { mpfr_set_ui (z, 1, r); mpfr_nextabove (z); return 1; } } /* now treat also the case where zeta(m) - (1+1/2^m) < 1/2*ulp(1), and the result is either 1+2^(-m) or 1+2^(-m)+2^(1-p). */ mpfr_init2 (y, 31); if (m >= p / 2) /* otherwise 4^(-m) > 2^(-p) */ { /* the following is a lower bound for log(3)/log(2) */ mpfr_set_str_binary (y, "1.100101011100000000011010001110"); mpfr_mul_ui (y, y, m, MPFR_RNDZ); /* lower bound for log2(3^m) */ if (mpfr_cmp_ui (y, p + 2) >= 0) { mpfr_clear (y); mpfr_set_ui (z, 1, MPFR_RNDZ); mpfr_div_2ui (z, z, m, MPFR_RNDZ); mpfr_add_ui (z, z, 1, MPFR_RNDZ); if (r != MPFR_RNDU) return -1; mpfr_nextabove (z); return 1; } } mpz_init (s); mpz_init (d); mpz_init (t); mpz_init (q); p += MPFR_INT_CEIL_LOG2(p); /* account of the n term in the error */ p += MPFR_INT_CEIL_LOG2(p) + 15; /* initial value */ MPFR_ZIV_INIT (loop, p); for(;;) { /* 0.39321985067869744 = log(2)/log(3+sqrt(8)) */ n = 1 + (unsigned long) (0.39321985067869744 * (double) p); err = n + 4; mpfr_set_prec (y, p); /* computation of the d[k] */ mpz_set_ui (s, 0); mpz_set_ui (t, 1); mpz_mul_2exp (t, t, 2 * n - 1); /* t[n] */ mpz_set (d, t); for (k = n; k > 0; k--) { count_leading_zeros (kbits, k); kbits = GMP_NUMB_BITS - kbits; /* if k^m is too large, use mpz_tdiv_q */ if (m * kbits > 2 * GMP_NUMB_BITS) { /* if we know in advance that k^m > d, then floor(d/k^m) will be zero below, so there is no need to compute k^m */ kbits = (kbits - 1) * m + 1; /* k^m has at least kbits bits */ if (kbits > mpz_sizeinbase (d, 2)) mpz_set_ui (q, 0); else { mpz_ui_pow_ui (q, k, m); mpz_tdiv_q (q, d, q); } } else /* use several mpz_tdiv_q_ui calls */ { unsigned long km = k, mm = m - 1; while (mm > 0 && km < ULONG_MAX / k) { km *= k; mm --; } mpz_tdiv_q_ui (q, d, km); while (mm > 0) { km = k; mm --; while (mm > 0 && km < ULONG_MAX / k) { km *= k; mm --; } mpz_tdiv_q_ui (q, q, km); } } if (k % 2) mpz_add (s, s, q); else mpz_sub (s, s, q); /* we have d[k] = sum(t[i], i=k+1..n) with t[i] = n*(n+i-1)!*4^i/(n-i)!/(2i)! t[k-1]/t[k] = k*(2k-1)/(n-k+1)/(n+k-1)/2 */ #if (GMP_NUMB_BITS == 32) #define KMAX 46341 /* max k such that k*(2k-1) < 2^32 */ #elif (GMP_NUMB_BITS == 64) #define KMAX 3037000500 #endif #ifdef KMAX if (k <= KMAX) mpz_mul_ui (t, t, k * (2 * k - 1)); else #endif { mpz_mul_ui (t, t, k); mpz_mul_ui (t, t, 2 * k - 1); } mpz_fdiv_q_2exp (t, t, 1); /* Warning: the test below assumes that an unsigned long has no padding bits. */ if (n < 1UL << ((sizeof(unsigned long) * CHAR_BIT) / 2)) /* (n - k + 1) * (n + k - 1) < n^2 */ mpz_divexact_ui (t, t, (n - k + 1) * (n + k - 1)); else { mpz_divexact_ui (t, t, n - k + 1); mpz_divexact_ui (t, t, n + k - 1); } mpz_add (d, d, t); } /* multiply by 1/(1-2^(1-m)) = 1 + 2^(1-m) + 2^(2-m) + ... */ mpz_fdiv_q_2exp (t, s, m - 1); do { err ++; mpz_add (s, s, t); mpz_fdiv_q_2exp (t, t, m - 1); } while (mpz_cmp_ui (t, 0) > 0); /* divide by d[n] */ mpz_mul_2exp (s, s, p); mpz_tdiv_q (s, s, d); mpfr_set_z (y, s, MPFR_RNDN); mpfr_div_2ui (y, y, p, MPFR_RNDN); err = MPFR_INT_CEIL_LOG2 (err); if (MPFR_LIKELY(MPFR_CAN_ROUND (y, p - err, MPFR_PREC(z), r))) break; MPFR_ZIV_NEXT (loop, p); } MPFR_ZIV_FREE (loop); mpz_clear (d); mpz_clear (t); mpz_clear (q); mpz_clear (s); inex = mpfr_set (z, y, r); mpfr_clear (y); return inex; } }
static int check_for_factor(mpz_t f, mpz_t inputn, mpz_t fmin, mpz_t n, int stage, mpz_t* sfacs, int* nsfacs, int degree) { int success, sfaci; UV B1; /* Use this so we don't modify their input value */ mpz_set(n, inputn); if (mpz_cmp(n, fmin) <= 0) return 0; #if 0 /* Use this to really encourage n-1 / n+1 proof types */ if (degree <= 0) { if (stage == 1) return -1; if (stage == 0) stage = 1; } #endif /* Utilize GMP's fast gcd algorithms. Trial to 224737+ with two gcds. */ mpz_tdiv_q_2exp(n, n, mpz_scan1(n, 0)); while (mpz_divisible_ui_p(n, 3)) mpz_divexact_ui(n, n, 3); while (mpz_divisible_ui_p(n, 5)) mpz_divexact_ui(n, n, 5); if (mpz_cmp(n, fmin) <= 0) return 0; mpz_gcd(f, n, _gcd_small); while (mpz_cmp_ui(f, 1) > 0) { mpz_divexact(n, n, f); mpz_gcd(f, f, n); } if (mpz_cmp(n, fmin) <= 0) return 0; mpz_gcd(f, n, _gcd_large); while (mpz_cmp_ui(f, 1) > 0) { mpz_divexact(n, n, f); mpz_gcd(f, f, n); } sfaci = 0; success = 1; while (success) { UV nsize = mpz_sizeinbase(n, 2); const int do_pm1 = 1; const int do_pp1 = 1; const int do_pbr = 0; const int do_ecm = 0; if (mpz_cmp(n, fmin) <= 0) return 0; if (is_bpsw_prime(n)) { mpz_set(f, n); return (mpz_cmp(f, fmin) > 0); } success = 0; B1 = 300 + 3 * nsize; if (degree <= 2) B1 += nsize; /* D1 & D2 are cheap to prove. */ if (degree <= 0) B1 += 2*nsize; /* N-1 and N+1 are really cheap. */ if (degree > 20 && stage <= 1) B1 -= nsize; /* Less time on big polys. */ if (degree > 40) B1 -= nsize/2; /* Less time on big polys. */ if (stage == 0) { /* A relatively small performance hit, makes slightly smaller proofs. */ if (nsize < 900 && degree <= 2) B1 *= 1.8; /* We need to try a bit harder for the large sizes :( */ if (nsize > 1400) B1 *= 2; if (nsize > 2000) B1 *= 2; if (!success) success = _GMP_pminus1_factor(n, f, 100+B1/8, 100+B1); } else if (stage >= 1) { /* P-1 */ if ((!success && do_pm1)) success = _GMP_pminus1_factor(n, f, B1, 6*B1); /* Pollard's Rho */ if ((!success && do_pbr && nsize < 500)) success = _GMP_pbrent_factor(n, f, nsize % 53, 1000-nsize); /* P+1 */ if ((!success && do_pp1)) { UV ppB = (nsize < 2000) ? B1/4 : B1/16; success = _GMP_pplus1_factor(n, f, 0, ppB, ppB); } if ((!success && do_ecm)) success = _GMP_ecm_factor_projective(n, f, 400, 2000, 1); #ifdef USE_LIBECM /* TODO: LIBECM in other stages */ /* Note: this will be substantially slower than our code for small sizes * and the small B1/B2 values we're using. */ if (!success && degree <= 2 && nsize > 600) { ecm_params params; ecm_init(params); params->method = ECM_ECM; mpz_set_ui(params->B2, 10*B1); mpz_set_ui(params->sigma, 0); success = ecm_factor(f, n, B1/4, params); ecm_clear(params); if (mpz_cmp(f, n) == 0) success = 0; if (success) { printf("ECM FOUND FACTOR\n"); } } #endif } /* Try any factors found in previous stage 2+ calls */ while (!success && sfaci < *nsfacs) { if (mpz_divisible_p(n, sfacs[sfaci])) { mpz_set(f, sfacs[sfaci]); success = 1; } sfaci++; } if (stage > 1 && !success) { if (stage == 2) { /* if (!success) success = _GMP_pbrent_factor(n, f, nsize-1, 8192); */ if (!success) success = _GMP_pminus1_factor(n, f, 6*B1, 60*B1); /* p+1 with different initial point and searching farther */ if (!success) success = _GMP_pplus1_factor(n, f, 1, B1/2, B1/2); if (!success) success = _GMP_ecm_factor_projective(n, f, 250, 2500, 8); } else if (stage == 3) { if (!success) success = _GMP_pbrent_factor(n, f, nsize+1, 16384); if (!success) success = _GMP_pminus1_factor(n, f, 60*B1, 600*B1); /* p+1 with a third initial point and searching farther */ if (!success) success = _GMP_pplus1_factor(n, f, 2, 1*B1, 1*B1); if (!success) success = _GMP_ecm_factor_projective(n, f, B1/4, B1*4, 5); } else if (stage == 4) { if (!success) success = _GMP_pminus1_factor(n, f, 300*B1, 300*20*B1); if (!success) success = _GMP_ecm_factor_projective(n, f, B1/2, B1*8, 4); } else if (stage >= 5) { UV B = B1 * (stage-4) * (stage-4) * (stage-4); if (!success) success = _GMP_ecm_factor_projective(n, f, B, 10*B, 8+stage); } } if (success) { if (mpz_cmp_ui(f, 1) == 0 || mpz_cmp(f, n) == 0) { gmp_printf("factoring %Zd resulted in factor %Zd\n", n, f); croak("internal error in ECPP factoring"); } /* Add the factor to the saved factors list */ if (stage > 1 && *nsfacs < MAX_SFACS) { /* gmp_printf(" ***** adding factor %Zd ****\n", f); */ mpz_init_set(sfacs[*nsfacs], f); nsfacs[0]++; } /* Is the factor f what we want? */ if ( mpz_cmp(f, fmin) > 0 && is_bpsw_prime(f) ) return 1; /* Divide out f */ mpz_divexact(n, n, f); } } /* n is larger than fmin and not prime */ mpz_set(f, n); return -1; }
void check_n (void) { { int n = -1; check_one ("blah", "%nblah", &n); ASSERT_ALWAYS (n == 0); } { int n = -1; check_one ("hello ", "hello %n", &n); ASSERT_ALWAYS (n == 6); } { int n = -1; check_one ("hello world", "hello %n world", &n); ASSERT_ALWAYS (n == 6); } #define CHECK_N(type, string) \ do { \ type x[2]; \ char fmt[128]; \ \ x[0] = ~ (type) 0; \ x[1] = ~ (type) 0; \ sprintf (fmt, "%%d%%%sn%%d", string); \ check_one ("123456", fmt, 123, &x[0], 456); \ \ /* should write whole of x[0] and none of x[1] */ \ ASSERT_ALWAYS (x[0] == 3); \ ASSERT_ALWAYS (x[1] == (type) ~ (type) 0); \ \ } while (0) CHECK_N (mp_limb_t, "M"); CHECK_N (char, "hh"); CHECK_N (long, "l"); #if HAVE_LONG_LONG CHECK_N (long long, "L"); #endif #if HAVE_INTMAX_T CHECK_N (intmax_t, "j"); #endif #if HAVE_PTRDIFF_T CHECK_N (ptrdiff_t, "t"); #endif CHECK_N (short, "h"); CHECK_N (size_t, "z"); { mpz_t x[2]; mpz_init_set_si (x[0], -987L); mpz_init_set_si (x[1], 654L); check_one ("123456", "%d%Zn%d", 123, x[0], 456); MPZ_CHECK_FORMAT (x[0]); MPZ_CHECK_FORMAT (x[1]); ASSERT_ALWAYS (mpz_cmp_ui (x[0], 3L) == 0); ASSERT_ALWAYS (mpz_cmp_ui (x[1], 654L) == 0); mpz_clear (x[0]); mpz_clear (x[1]); } { mpq_t x[2]; mpq_init (x[0]); mpq_init (x[1]); mpq_set_ui (x[0], 987L, 654L); mpq_set_ui (x[1], 4115L, 226L); check_one ("123456", "%d%Qn%d", 123, x[0], 456); MPQ_CHECK_FORMAT (x[0]); MPQ_CHECK_FORMAT (x[1]); ASSERT_ALWAYS (mpq_cmp_ui (x[0], 3L, 1L) == 0); ASSERT_ALWAYS (mpq_cmp_ui (x[1], 4115L, 226L) == 0); mpq_clear (x[0]); mpq_clear (x[1]); } { mpf_t x[2]; mpf_init (x[0]); mpf_init (x[1]); mpf_set_ui (x[0], 987L); mpf_set_ui (x[1], 654L); check_one ("123456", "%d%Fn%d", 123, x[0], 456); MPF_CHECK_FORMAT (x[0]); MPF_CHECK_FORMAT (x[1]); ASSERT_ALWAYS (mpf_cmp_ui (x[0], 3L) == 0); ASSERT_ALWAYS (mpf_cmp_ui (x[1], 654L) == 0); mpf_clear (x[0]); mpf_clear (x[1]); } { mp_limb_t a[5]; mp_limb_t a_want[numberof(a)]; mp_size_t i; a[0] = 123; check_one ("blah", "bl%Nnah", a, (mp_size_t) 0); ASSERT_ALWAYS (a[0] == 123); MPN_ZERO (a_want, numberof (a_want)); for (i = 1; i < numberof (a); i++) { check_one ("blah", "bl%Nnah", a, i); a_want[0] = 2; ASSERT_ALWAYS (mpn_cmp (a, a_want, i) == 0); } } }
bool C_BigInt::isZero (void) const { return mpz_cmp_ui (mGMPint, 0) == 0 ; }
bool C_BigInt::isOne (void) const { return mpz_cmp_ui (mGMPint, 1) == 0 ; }
int aks (mpz_t n) { mpz_t r; mpz_t a; mpz_t max_a; mpz_t gcd_rslt; mpz_t totient_r; mpf_t ftotient_r; mpf_t sqrt_rslt; mpf_t sqrt_rslt2; mpf_t temp; mpf_t temp2; sli_t logn; /* For the sake of maple kernel */ int argc = 0; char **argv; char err[2048]; mpz_init (r); mpz_init (a); mpz_init (max_a); mpz_init (gcd_rslt); mpz_init (totient_r); mpf_init (ftotient_r); mpf_init (sqrt_rslt); mpf_init (sqrt_rslt2); mpf_init (temp); mpf_init (temp2); /* 1. If (n = a^k for a in N and b > 1) output COMPOSITE */ if (mpz_perfect_power_p (n) != 0) { printf ("Step 1 detected composite\n"); return FALSE; } /* 2. Find the smallest r such that or(n) > 4(log n)^2 */ find_smallest_r (r, n); gmp_printf ("good r seems to be %Zd\n", r); /* 3. If 1 < gcd(a, n) < n for some a <= r, output COMPOSITE */ /* for (a = 1; a <= r; a++) { * gcd_rslt = gcd(a, n); * if (gcd_rslt > 1 && gcd_rslt < n) { * return FALSE; * } * } */ for (mpz_set_ui (a, 1); mpz_cmp (a, r) < 0 || mpz_cmp (a, r) == 0; mpz_add_ui (a, a, 1)) { mpz_gcd (gcd_rslt, a, n); if (mpz_cmp_ui (gcd_rslt, 1) > 0 && mpz_cmp (gcd_rslt, n) < 0) { printf ("Step 3 detected composite\n"); return FALSE; } } /* 4. If n <= r, output PRIME */ if (mpz_cmp (n, r) < 0 || mpz_cmp (n, r) == 0) { printf ("Step 4 detected prime\n"); return TRUE; } /* 5. For a = 1 to floor(2*sqrt(totient(r))*(log n) * if ( (X+a)^n != X^n + a (mod X^r-1, n) ), output COMPOSITE * * Choices of implementation to evaluate the polynomial equality: * (1) Implement powermodreduce on polynomial ourselves (tough manly way) * (2) Use MAPLE (not so manly, but less painful) */ /* Compute totient(r), since r is prime, this is simply r-1 */ mpz_sub_ui (totient_r, r, 1); /* Compute log n (ceilinged) */ mpz_logbase2cl (&logn, n); /* Compute sqrt(totient(r)) */ mpf_set_z (ftotient_r, totient_r); mpf_sqrt (sqrt_rslt, ftotient_r); /* Compute 2*sqrt(totient(r)) */ mpf_mul_ui (sqrt_rslt2, sqrt_rslt, 2); /* Compute 2*sqrt(totient(r))*(log n) */ mpf_set (temp, sqrt_rslt2); mpf_set_si (temp2, logn); mpf_mul (temp, temp, temp2); /* Finally, compute max_a, after lots of singing and dancing */ mpf_floor (temp, temp); mpz_set_f (max_a, temp); gmp_printf ("max_a = %Zd\n", max_a); /* Now evaluate the polynomial equality with the help of maple kernel */ /* Set up maple kernel incantations */ MKernelVector kv; MCallBackVectorDesc cb = { textCallBack, 0, /* errorCallBack not used */ 0, /* statusCallBack not used */ 0, /* readLineCallBack not used */ 0, /* redirectCallBack not used */ 0, /* streamCallBack not used */ 0, /* queryInterrupt not used */ 0 /* callBackCallBack not used */ }; /* Initialize Maple */ if ((kv = StartMaple (argc, argv, &cb, NULL, NULL, err)) == NULL) { printf ("Could not start Maple, %s\n", err); exit (666); } /* Here comes the complexity and bottleneck */ /* for (a = 1; a <= max_a; a++) { * if (!poly_eq_holds(kv, a, n, r)) { * return FALSE; * } * } */ /* Make max_a only up to 5 */ mpz_set_ui (max_a, 5); for (mpz_set_ui (a, 1); mpz_cmp (a, max_a) < 0 || mpz_cmp (a, max_a) == 0; mpz_add_ui (a, a, 1)) { if (!poly_eq_holds (kv, a, n, r)) { printf ("Step 5 detected composite\n"); return FALSE; } } /* 6. Output PRIME */ printf ("Step 6 detected prime\n"); return TRUE; }
/* Generate Private Public Keys */ void keysGeneration(){ //char* initNbChar = malloc(sizeof(char) * (initNbLength+1)); char* initNbChar; //mpz_init(gcdResult); //mpz_init(nn); //mpz_init(lambda); do{ initNbChar = malloc(sizeof(char) * (initNbLength+1)); generateInitNb(initNbChar, initNbLength); mpz_set_str(initNbMpz, initNbChar, 10/*decimal*/); mpz_nextprime (p, initNbMpz); initNbChar = malloc(sizeof(char) * (initNbLength+1)); generateInitNb(initNbChar, initNbLength); mpz_set_str(initNbMpz, initNbChar, 10/*decimal*/); mpz_nextprime (q, initNbMpz); //6666666666666666666666666666666666666 //mpz_init_set_str(p,"7",10); //mpz_init_set_str(q,"11",10); //6666666666666666666666666666 mpz_sub_ui(p_1, p, 1); mpz_sub_ui(q_1, q, 1); mpz_mul(n, p, q); mpz_mul(tmpI, p_1, q_1); mpz_gcd(gcdResult, tmpI, n); }while(mpz_cmp_ui(gcdResult, 1) != 0); // check if (gcd(pq, (p-1)(q-1)) = 1 // mpz_mul(n, p, q); mpz_mul(nn, n, n); mpz_lcm(lambda, p_1, q_1); // generate a number g within the range 0 to n*n-1 inclusive ! // this way i can get rid of using mod n^2 on this step gmp_randstate_t state; gmp_randinit_mt (state); // initiallize state with Mersenne Twister which is basically fast one ! mpz_urandomm(g, state, nn); //66666666666666666666666666666666 //mpz_init_set_str(g,"5652",10); //666666666666666666666666666666666666666 // Now we check if g is good enough for us mpz_powm(tmpI, g/*base*/, lambda/*exp*/, nn/*mod*/); // tmp = base^exp modulo mod // now L(u) = (u-1)/n mpz_sub_ui(tmpI, tmpI, 1); mpz_tdiv_q(tmpI, tmpI, n); mpz_gcd(gcdResult, n, tmpI); if (mpz_cmp_ui(gcdResult, 1) != 0){ printf("G is not proper !!!\n"); exit(EXIT_FAILURE); } printf("Keys Generation Result : \n"); printf("Start -- \n"); printf("Public Key : \n"); gmp_printf ("\nn = %Zd\n", n); gmp_printf ("\ng= %Zd\n", g); printf("\nPrivate Key : \n"); gmp_printf ("\nlambda = %Zd\n", lambda); printf("Micro :3 \n"); printf("End -- \n"); }
int main(){ mpz_t p , q , N ,phi_N,e,d,M,C,res; mpz_inits(p,q,N,phi_N,e,d,M,C,res,NULL); gmp_randstate_t state ; gmp_randinit_mt(state); //Manual input of p and q //int repeats=5,primecheck=0; // printf("Enter p \n"); // gmp_scanf("%Zd",&p); // //mpz_inp_str(p,stdin,10); // primecheck = mpz_probab_prime_p(p,repeats); // if(primecheck != 2) // {printf(" p is not prime . Error code : %d \n",primecheck);exit(1); // } // printf("Enter q \n"); // gmp_scanf("%Zd",&q); // //mpz_inp_str(q,stdin,10); // primecheck = mpz_probab_prime_p(q,repeats); // if(primecheck!= 2) // {printf(" q is not prime . Error code : %d \n",primecheck);exit(1); // } // Randomly generating p and q //b - bits uradomb ( 0- 2^n -1 ) urandom (0 - n-1) mpz_urandomb(p,state,512); mpz_nextprime(p,p); gmp_printf("p : %Zd \n",p ); mpz_urandomb(q,state,512); mpz_nextprime(q,q); gmp_printf("q : %Zd \n",q ); printf("Enter M \n"); gmp_scanf("%Zd",&M); mpz_mul(N,p,q); gmp_printf("N : %Zd \n",N ); mpz_sub_ui(p,p,1); mpz_sub_ui(q,q,1); mpz_mul(phi_N,p,q); gmp_printf("phi_N : %Zd \n",phi_N ); // mpz_urandomm(e,state,phi_N); // mpz_nextprime(e,e); mpz_set_ui(e,2); mpz_gcd(res,e,phi_N); while( mpz_cmp_ui(res,1) != 0 ){ mpz_add_ui(e,e,1); mpz_gcd(res,e,phi_N); } gmp_printf("e : %Zd \n",e); gmp_printf("\n\nPublic key : { %Zd , %Zd \n }",e,N); mpz_invert(d,e,phi_N); gmp_printf("\n\nd : %Zd \n",d); gmp_printf("\n\nPrivate key : { %Zd , %Zd \n }",d,N); mpz_powm (C , M , e , N ); gmp_printf("\n\nC : %Zd \n",C ); mpz_powm (M , C , d, N ); gmp_printf("\n\nM : %Zd \n",M ); }
int _dsa_validate_dss_pq(struct dsa_params *pub, struct dss_params_validation_seeds *cert) { int ret; unsigned p_bits, q_bits; struct dsa_params pub2; struct dss_params_validation_seeds cert2; mpz_t r, s; p_bits = mpz_sizeinbase(pub->p, 2); q_bits = mpz_sizeinbase(pub->q, 2); ret = _dsa_check_qp_sizes(q_bits, p_bits, 0); if (ret == 0) { return 0; } mpz_init(r); mpz_init(s); dsa_params_init(&pub2); nettle_mpz_set_str_256_u(s, cert->seed_length, cert->seed); /* firstseed < 2^(N-1) */ mpz_set_ui(r, 1); mpz_mul_2exp(r, r, q_bits - 1); if (mpz_cmp(s, r) < 0) { goto fail; } /* 2^N <= q */ mpz_set_ui(r, 1); mpz_mul_2exp(r, r, q_bits); if (mpz_cmp(r, pub->q) <= 0) { goto fail; } /* 2^L <= p */ mpz_set_ui(r, 1); mpz_mul_2exp(r, r, p_bits); if (mpz_cmp(r, pub->p) <= 0) { goto fail; } /* p-1 mod q != 0 */ mpz_set(r, pub->p); mpz_sub_ui(r, r, 1); mpz_mod(r, r, pub->q); if (mpz_cmp_ui(r, 0) != 0) { goto fail; } /* replay the construction */ ret = _dsa_generate_dss_pq(&pub2, &cert2, cert->seed_length, cert->seed, NULL, NULL, p_bits, q_bits); if (ret == 0) { goto fail; } if ((cert->pseed_length > 0 && cert->pseed_length != cert2.pseed_length) || (cert->qseed_length > 0 && cert->qseed_length != cert2.qseed_length) || (cert->pgen_counter > 0 && cert->pgen_counter != cert2.pgen_counter) || (cert->qgen_counter > 0 && cert->qgen_counter != cert2.qgen_counter) || (cert->qseed_length > 0 && memcmp(cert->qseed, cert2.qseed, cert2.qseed_length) != 0) || (cert->pseed_length > 0 && memcmp(cert->pseed, cert2.pseed, cert2.pseed_length) != 0)) { goto fail; } if (mpz_cmp(pub->q, pub2.q) != 0) { goto fail; } if (mpz_cmp(pub->p, pub2.p) != 0) { goto fail; } if (mpz_sizeinbase(s, 2) < q_bits - 1) { goto fail; } ret = 1; goto finish; fail: ret = 0; finish: dsa_params_clear(&pub2); mpz_clear(r); mpz_clear(s); return ret; }
int main(int argc, char *argv[]) { int poly_idx; gls_config_t cfg; fb_t fb; u_int32_t i, n_roots; u_int64_t fb_idx, fb_alloc; mpz_t P, roots[MAX_POLY_DEGREE]; u_int32_t roots_ui[MAX_POLY_DEGREE]; char fname[4096]; off_t align; int fd; if(argc < 2) { fprintf(stderr, "usage: %s <polyconfig>\n", argv[0]); return 1; } gls_config_init(cfg); if(polyfile_read(cfg, argv[1]) < 0) return 1; mpz_init(P); for(i = 0; i < sizeof(roots) / sizeof(roots[0]); i++) mpz_init(roots[i]); for(poly_idx = 0; poly_idx < POLY_CNT; poly_idx++) { fb_init(fb); fb_idx = 0; fb_alloc = 0; for(mpz_set_ui(P, 2); mpz_cmp_ui(P, MAX_SMALL_PRIME) < 0 && mpz_cmp_ui(P, cfg->lim[poly_idx]) < 0; mpz_nextprime(P, P)) { n_roots = poly_get_zeros(roots_ui, cfg->poly[poly_idx], mpz_get_ui(P), 0); if(!n_roots) continue; qsort(roots_ui, n_roots, sizeof(roots_ui[0]), ui_cmp); //#define TEST_ROOTFINDER 1 #ifdef TEST_ROOTFINDER for(i = 0; i < n_roots; i++) { mpz_t tmp1, tmp2; mpz_init_set_ui(tmp1, roots_ui[i]); mpz_init(tmp2); mpzpoly_eval_mod(tmp2, cfg->poly[poly_idx], tmp1, P); if(mpz_cmp_ui(tmp2, 0) != 0) { printf("BAD ROOT (%u,%u)\n", roots_ui[i], mpz_get_ui(P)); exit(-1); } mpz_clear(tmp1); mpz_clear(tmp2); } #endif fb->n_small += n_roots; if(fb->n_small > fb_alloc) { fb_alloc += 4096; fb->r_small = (u_int32_t *) realloc(fb->r_small, sizeof(u_int32_t) * fb_alloc); fb->p_small = (u_int32_t *) realloc(fb->p_small, sizeof(u_int32_t) * fb_alloc); if(!fb->r_small || !fb->p_small) { perror("realloc"); exit(1); } } for(i = 0; i < n_roots; i++) { fb->r_small[fb_idx] = roots_ui[i]; fb->p_small[fb_idx] = mpz_get_ui(P); fb_idx++; } } fb_idx = 0; fb_alloc = 0; for(; mpz_cmp_ui(P, cfg->lim[poly_idx]) < 0; mpz_nextprime(P, P)) { n_roots = mpzpoly_get_roots(roots, cfg->poly[poly_idx], P); if(!n_roots) continue; fb->n_large += n_roots; if(fb->n_large > fb_alloc) { fb_alloc += 4096; fb->r_large = (u_int64_t *) realloc(fb->r_large, sizeof(u_int64_t) * fb_alloc); fb->p_large = (u_int64_t *) realloc(fb->p_large, sizeof(u_int64_t) * fb_alloc); if(!fb->r_large || !fb->p_large) { perror("realloc"); exit(1); } } for(i = 0; i < n_roots; i++) { fb->r_large[fb_idx] = mpz_get_ui(roots[i]); fb->p_large[fb_idx] = mpz_get_ui(P); fb_idx++; } } memset(fname, 0, sizeof(fname)); snprintf(fname, sizeof(fname) - 1, "%s.fb.%u", argv[1], poly_idx); if(fb_filesave(fb, fname) < 0) return 1; //#define TEST_SAVELOAD 1 #ifdef TEST_SAVELOAD { fb_t fb2; fb_init(fb2); if(fb_fileread(fb2, fname) < 0) return 1; if(fb->n_small != fb2->n_small || fb->n_large != fb2->n_large) { printf("COUNT MISMATCH\n"); return 1; } if(memcmp(fb->p_small, fb2->p_small, sizeof(u_int32_t) * fb->n_small) != 0) { printf("SMALL MISMATCH\n"); return 1; } if(memcmp(fb->p_large, fb2->p_large, sizeof(u_int64_t) * fb->n_large) != 0) { printf("LARGE MISMATCH\n"); return 1; } fb_clear(fb2); } #endif fb_clear(fb); } return 0; }
int _dsa_validate_dss_g(struct dsa_params *pub, unsigned domain_seed_size, const uint8_t *domain_seed, unsigned index) { int ret; unsigned p_bits, q_bits; struct dsa_params pub2; mpz_t r; p_bits = mpz_sizeinbase(pub->p, 2); q_bits = mpz_sizeinbase(pub->q, 2); ret = _dsa_check_qp_sizes(q_bits, p_bits, 0); if (ret == 0) { return 0; } mpz_init(r); dsa_params_init(&pub2); mpz_set(pub2.p, pub->p); mpz_set(pub2.q, pub->q); /* verify g */ if (index > 255) { goto fail; } /* 2<= g <= p-1 */ mpz_set(r, pub->p); mpz_sub_ui(r, r, 1); if (mpz_cmp_ui(pub->g, 2) < 0 || mpz_cmp(pub->g, r) >= 0) { goto fail; } /* g^q == 1 mod p */ mpz_powm(r, pub->g, pub->q, pub->p); if (mpz_cmp_ui(r, 1) != 0) { goto fail; } /* repeat g generation */ ret = _dsa_generate_dss_g(&pub2, domain_seed_size, domain_seed, NULL, NULL, index); if (ret == 0) { goto fail; } if (mpz_cmp(pub->g, pub2.g) != 0) { goto fail; } /* everything looks ok */ ret = 1; goto finish; fail: ret = 0; finish: dsa_params_clear(&pub2); mpz_clear(r); return ret; }
void mpz_next_prime_candidate (mpz_ptr p, mpz_srcptr n, gmp_randstate_t rnd) { unsigned short *moduli; unsigned long difference; int i, prime_limit; int composite; TMP_DECL; /* First handle tiny numbers */ if (mpz_cmp_ui (n, 2) < 0) { mpz_set_ui (p, 2); return; } mpz_add_ui (p, n, 1); mpz_setbit (p, 0); if (mpz_cmp_ui (p, 7) <= 0) return; prime_limit = NUMBER_OF_PRIMES - 1; if (mpz_cmp_ui (p, primes[prime_limit]) <= 0) { int lo = 0, hi = NUMBER_OF_PRIMES - 1, mid; i = mpz_get_ui(p); while(lo <= hi) { mid = lo + (hi - lo) / 2; if(i > primes[mid]) lo = mid + 1; else if(i < primes[mid]) hi = mid - 1; else { lo = mid; break; } } mpz_set_ui(p, primes[lo]); return; } TMP_MARK; /* Compute residues modulo small odd primes */ moduli = (unsigned short *) TMP_ALLOC (prime_limit * sizeof moduli[0]); for (i = 0; i < prime_limit; i++) moduli[i] = mpz_fdiv_ui (p, primes[i]); for (difference = 0; ; difference += 2) { composite = 0; /* First check residues */ for (i = 0; i < prime_limit; i++) { int acc, pr; composite |= (moduli[i] == 0); acc = moduli[i] + 2; pr = primes[i]; moduli[i] = acc >= pr ? acc - pr : acc; } if (composite) continue; mpz_add_ui (p, p, difference); difference = 0; /* Miller-Rabin test */ if (mpz_miller_rabin (p, 2, rnd)) break; } TMP_FREE; }
int mpz_congruent_ui_p (mpz_srcptr a, unsigned long cu, unsigned long du) { mp_srcptr ap; mp_size_t asize; mp_limb_t c, d, r; if (UNLIKELY (du == 0)) return (mpz_cmp_ui (a, cu) == 0); asize = SIZ(a); if (asize == 0) { if (cu < du) return cu == 0; else return (cu % du) == 0; } /* For nails don't try to be clever if c or d is bigger than a limb, just fake up some mpz_t's and go to the main mpz_congruent_p. */ if (du > GMP_NUMB_MAX || cu > GMP_NUMB_MAX) { mp_limb_t climbs[2], dlimbs[2]; mpz_t cz, dz; ALLOC(cz) = 2; PTR(cz) = climbs; ALLOC(dz) = 2; PTR(dz) = dlimbs; mpz_set_ui (cz, cu); mpz_set_ui (dz, du); return mpz_congruent_p (a, cz, dz); } /* NEG_MOD works on limbs, so convert ulong to limb */ c = cu; d = du; if (asize < 0) { asize = -asize; NEG_MOD (c, c, d); } ap = PTR (a); if (BELOW_THRESHOLD (asize, MODEXACT_1_ODD_THRESHOLD)) { r = mpn_mod_1 (ap, asize, d); if (c < d) return r == c; else return r == (c % d); } if ((d & 1) == 0) { /* Strip low zero bits to get odd d required by modexact. If d==e*2^n then a==c mod d if and only if both a==c mod 2^n and a==c mod e. */ unsigned twos; if ((ap[0]-c) & LOW_ZEROS_MASK (d)) return 0; count_trailing_zeros (twos, d); d >>= twos; }
int quadratic_residue(mpz_t x,mpz_t q,mpz_t n) { int leg; mpz_t tmp,ofac,nr,t,r,c,b; unsigned int mod4; mp_bitcnt_t twofac=0,m,i,ix; mod4=mpz_tstbit(n,0); if(!mod4) // must be odd return 0; mod4+=2*mpz_tstbit(n,1); leg=mpz_legendre(q,n); if(leg!=1) return leg; mpz_init_set(tmp,n); if(mod4==3) // directly, x = q^(n+1)/4 mod n { printf("diretamente\n\n"); mpz_add_ui(tmp,tmp,1UL); mpz_tdiv_q_2exp(tmp,tmp,2); mpz_powm(x,q,tmp,n); gmp_printf("NUMERO X %Zd \n\n",x); mpz_clear(tmp); } else // Tonelli-Shanks { printf("Tonelli shanks!!!\n"); mpz_inits(ofac,t,r,c,b,NULL); // split n - 1 into odd number times power of 2 ofac*2^twofac mpz_sub_ui(tmp,tmp,1UL); twofac=mpz_scan1(tmp,twofac); // largest power of 2 divisor if(twofac) mpz_tdiv_q_2exp(ofac,tmp,twofac); // shift right // look for non-residue mpz_init_set_ui(nr,2UL); while(mpz_legendre(nr,n)!=-1) mpz_add_ui(nr,nr,1UL); mpz_powm(c,nr,ofac,n); // c = nr^ofac mod n mpz_add_ui(tmp,ofac,1UL); mpz_tdiv_q_2exp(tmp,tmp,1); mpz_powm(r,q,tmp,n); // r = q^(ofac+1)/2 mod n mpz_powm(t,q,ofac,n); mpz_mod(t,t,n); // t = q^ofac mod n if(mpz_cmp_ui(t,1UL)!=0) // if t = 1 mod n we're done { m=twofac; do { i=2; ix=1; while(ix<m) { // find lowest 0 < ix < m | t^2^ix = 1 mod n mpz_powm_ui(tmp,t,i,n); // repeatedly square t if(mpz_cmp_ui(tmp,1UL)==0) break; i<<=1; // i = 2, 4, 8, ... ix++; // ix is log2 i } mpz_powm_ui(b,c,1<<(m-ix-1),n); // b = c^2^(m-ix-1) mod n mpz_mul(r,r,b); mpz_mod(r,r,n); // r = r*b mod n mpz_mul(c,b,b); mpz_mod(c,c,n); // c = b^2 mod n mpz_mul(t,t,c); mpz_mod(t,t,n); // t = t b^2 mod n m=ix; }while(mpz_cmp_ui(t,1UL)!=0); // while t mod n != 1 } mpz_set(x,r); mpz_clears(tmp,ofac,nr,t,r,c,b,NULL); } return 1; }
/** * Start at a random md5 hash and search through all possible hashes to find * a string that hashes to itself. */ int main(void) { /* there are 2^128 possible md5 hashes */ mpz_t max; mpz_init(max); mpz_ui_pow_ui(max, 2, MD5_BITS); /* initialize PRNG with MT algorithm and seed with time */ gmp_randstate_t rand_state; gmp_randinit_mt(rand_state); gmp_randseed_ui(rand_state, time(NULL)); /* pick a random one to start with and free PRNG memory */ mpz_t start; mpz_init(start); mpz_urandomb(start, rand_state, MD5_BITS); gmp_randclear(rand_state); printf("Starting with random string: \""); mpz_out_str(stdout, HEX_BASE, start); printf("\"\n"); /* current hash */ mpz_t current; mpz_init_set(current, start); /* get ready to calculate hashes */ MD5_CTX md5_ctx; unsigned char input[MD5_BYTES]; unsigned char digest[MD5_BYTES]; char input_str[MD5_STR_LEN + 1]; char digest_str[MD5_STR_LEN + 1]; /* search from start until max */ while(mpz_cmp(current, max) < 0) { /* initialize MD5 and get current as an unsigned char[] */ MD5_Init(&md5_ctx); mpz_export(input, NULL, 1, 1, 0, 0, current); /* hash the input string */ hex_str(input_str, input, MD5_BYTES); MD5_Update(&md5_ctx, input_str, MD5_STR_LEN); MD5_Final(digest, &md5_ctx); /* check for a match */ if(strncmp(input, digest, MD5_BYTES) == 0) { /* we have a winner! */ hex_str(digest_str, digest, MD5_BYTES); printf("md5(\"%s\") = \"%s\"\n", input_str, digest_str); } /* keep looking */ mpz_add_ui(current, current, 1); } /* now search backwards from start */ mpz_set(current, start); mpz_sub_ui(current, current, 1); while(mpz_cmp_ui(current, 0) >= 0) { /* initialize MD5 and get current as an unsigned char[] */ MD5_Init(&md5_ctx); mpz_export(input, NULL, 1, 1, 0, 0, current); /* hash the input string */ hex_str(input_str, input, MD5_BYTES); MD5_Update(&md5_ctx, input_str, MD5_STR_LEN); MD5_Final(digest, &md5_ctx); /* check for a match */ if(strncmp(input, digest, MD5_BYTES) == 0) { /* we have a winner! */ hex_str(digest_str, digest, MD5_BYTES); printf("md5(\"%s\") = \"%s\"\n", input_str, digest_str); } /* keep looking */ mpz_sub_ui(current, current, 1); } /* clean up */ mpz_clear(max); mpz_clear(start); mpz_clear(current); }
int chinese(mpz_t ret, mpz_t lcm, mpz_t *a, mpz_t *m, int items) { mpz_t sum, gcd, u, v, s, t, temp1, temp2; int i, rval = 1; #if 0 if (items >= 128) { int first = items/2; mpz_t ca[2], cm[2]; for (i = 0; i < 2; i++) { mpz_init(ca[i]); mpz_init(cm[i]); } rval = chinese(ca[0], cm[0], a, m, first); if (rval == 1) rval = chinese(ca[1], cm[1], a+first, m+first, items-first); if (rval == 1) rval = chinese(ret, lcm, ca, cm, 2); for (i = 0; i < 2; i++) { mpz_clear(ca[i]); mpz_clear(cm[i]); } return rval; } #else #define CRTN 8 if (items >= 64) { int start = 0, step = items/CRTN; mpz_t ca[CRTN], cm[CRTN]; for (i = 0; i < CRTN; i++) { mpz_init(ca[i]); mpz_init(cm[i]); } for (i = 0; rval && i < CRTN; i++) { int citems = (i==CRTN-1) ? items-(CRTN-1)*step : step; rval = chinese(ca[i], cm[i], a+i*step, m+i*step, citems); } if (rval) rval = chinese(ret, lcm, ca, cm, CRTN); for (i = 0; i < CRTN; i++) { mpz_clear(ca[i]); mpz_clear(cm[i]); } return rval; } #endif mpz_init(temp1); mpz_init(temp2); mpz_init(sum); mpz_init(gcd); mpz_init(s); mpz_init(t); mpz_init(u); mpz_init(v); mpz_set(lcm, m[0]); mpz_mod(sum, a[0], m[0]); for (i = 1; i < items; i++) { mpz_gcdext(gcd, u, v, lcm, m[i]); mpz_divexact(s, m[i], gcd); mpz_divexact(t, lcm, gcd); if (mpz_cmp_ui(gcd,1) != 0) { mpz_mod(temp1, sum, gcd); mpz_mod(temp2, a[i], gcd); if (mpz_cmp(temp1, temp2) != 0) { rval = 0; break; } } if (mpz_sgn(s) < 0) mpz_neg(s,s); if (mpz_sgn(t) < 0) mpz_neg(t,t); mpz_mul(lcm, lcm, s); if (mpz_sgn(u) < 0) mpz_add(u, u, lcm); if (mpz_sgn(v) < 0) mpz_add(v, v, lcm); mpz_mul(temp1, v, s); mpz_mul(v, temp1, sum); mpz_mul(temp1, u, t); mpz_mul(u, temp1, a[i]); mpz_add(temp1, v, u); mpz_mod(sum, temp1, lcm); } mpz_set(ret, sum); mpz_clear(sum); mpz_clear(gcd); mpz_clear(s); mpz_clear(t); mpz_clear(u); mpz_clear(v); mpz_clear(temp1); mpz_clear(temp2); return rval; }
static PyObject * Pympz_mpmath_create(PyObject *self, PyObject *args) { long sign; long bc, shift, zbits, carry = 0, prec = 0; PyObject *exp = 0, *newexp = 0, *newexp2 = 0, *tmp = 0; MPZ_Object *man = 0, *upper = 0, *lower = 0; int error; const char *rnd = "f"; if (PyTuple_GET_SIZE(args) < 2) { TYPE_ERROR("mpmath_create() expects 'mpz','int'[,'int','str'] arguments"); return NULL; } switch (PyTuple_GET_SIZE(args)) { case 4: rnd = Py2or3String_AsString(PyTuple_GET_ITEM(args, 3)); case 3: prec = GMPy_Integer_AsLongAndError(PyTuple_GET_ITEM(args, 2), &error); if (error) return NULL; prec = ABS(prec); case 2: exp = PyTuple_GET_ITEM(args, 1); case 1: man = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL); if (!man) { TYPE_ERROR("mpmath_create() expects 'mpz','int'[,'int','str'] arguments"); return NULL; } } /* If the mantissa is 0, return the normalized representation. */ if (!mpz_sgn(man->z)) { return mpmath_build_mpf(0, man, 0, 0); } upper = GMPy_MPZ_New(NULL); lower = GMPy_MPZ_New(NULL); if (!upper || !lower) { Py_DECREF((PyObject*)man); Py_XDECREF((PyObject*)upper); Py_XDECREF((PyObject*)lower); return NULL; } /* Extract sign, make man positive, and set bit count */ sign = (mpz_sgn(man->z) == -1); mpz_abs(upper->z, man->z); bc = mpz_sizeinbase(upper->z, 2); if (!prec) prec = bc; shift = bc - prec; if (shift > 0) { switch (rnd[0]) { case 'f': if(sign) { mpz_cdiv_q_2exp(upper->z, upper->z, shift); } else { mpz_fdiv_q_2exp(upper->z, upper->z, shift); } break; case 'c': if(sign) { mpz_fdiv_q_2exp(upper->z, upper->z, shift); } else { mpz_cdiv_q_2exp(upper->z, upper->z, shift); } break; case 'd': mpz_fdiv_q_2exp(upper->z, upper->z, shift); break; case 'u': mpz_cdiv_q_2exp(upper->z, upper->z, shift); break; case 'n': default: mpz_tdiv_r_2exp(lower->z, upper->z, shift); mpz_tdiv_q_2exp(upper->z, upper->z, shift); if (mpz_sgn(lower->z)) { /* lower is not 0 so it must have at least 1 bit set */ if (mpz_sizeinbase(lower->z, 2)==shift) { /* lower is >= 1/2 */ if (mpz_scan1(lower->z, 0)==shift-1) { /* lower is exactly 1/2 */ if (mpz_odd_p(upper->z)) carry = 1; } else { carry = 1; } } } if (carry) mpz_add_ui(upper->z, upper->z, 1); } if (!(tmp = PyIntOrLong_FromLong(shift))) { Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); return NULL; } if (!(newexp = PyNumber_Add(exp, tmp))) { Py_DECREF((PyObject*)man); Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(tmp); return NULL; } Py_DECREF(tmp); bc = prec; } else { newexp = exp; Py_INCREF(newexp); } /* Strip trailing 0 bits. */ if ((zbits = mpz_scan1(upper->z, 0))) mpz_tdiv_q_2exp(upper->z, upper->z, zbits); if (!(tmp = PyIntOrLong_FromLong(zbits))) { Py_DECREF((PyObject*)man); Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(newexp); return NULL; } if (!(newexp2 = PyNumber_Add(newexp, tmp))) { Py_DECREF((PyObject*)man); Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(tmp); Py_DECREF(newexp); return NULL; } Py_DECREF(newexp); Py_DECREF(tmp); bc -= zbits; /* Check if one less than a power of 2 was rounded up. */ if (!mpz_cmp_ui(upper->z, 1)) bc = 1; Py_DECREF((PyObject*)lower); Py_DECREF((PyObject*)man); return mpmath_build_mpf(sign, upper, newexp2, bc); }
/* See Cohen section 1.5. * See http://www.math.vt.edu/people/brown/doc/sqrts.pdf */ int sqrtmod(mpz_t x, mpz_t a, mpz_t p, mpz_t t, mpz_t q, mpz_t b, mpz_t z) /* 4 temp variables */ { int r, e, m; /* Easy cases from page 31 (or Menezes 3.36, 3.37) */ if (mpz_congruent_ui_p(p, 3, 4)) { mpz_add_ui(t, p, 1); mpz_tdiv_q_2exp(t, t, 2); mpz_powm(x, a, t, p); return verify_sqrt(x, a, p, t, q); } if (mpz_congruent_ui_p(p, 5, 8)) { mpz_sub_ui(t, p, 1); mpz_tdiv_q_2exp(t, t, 2); mpz_powm(q, a, t, p); if (mpz_cmp_si(q, 1) == 0) { /* s = a^((p+3)/8) mod p */ mpz_add_ui(t, p, 3); mpz_tdiv_q_2exp(t, t, 3); mpz_powm(x, a, t, p); } else { /* s = 2a * (4a)^((p-5)/8) mod p */ mpz_sub_ui(t, p, 5); mpz_tdiv_q_2exp(t, t, 3); mpz_mul_ui(q, a, 4); mpz_powm(x, q, t, p); mpz_mul_ui(x, x, 2); mpz_mulmod(x, x, a, p, x); } return verify_sqrt(x, a, p, t, q); } if (mpz_kronecker(a, p) != 1) { /* Possible no solution exists. Check Euler criterion. */ mpz_sub_ui(t, p, 1); mpz_tdiv_q_2exp(t, t, 1); mpz_powm(x, a, t, p); if (mpz_cmp_si(x, 1) != 0) { mpz_set_ui(x, 0); return 0; } } mpz_sub_ui(q, p, 1); e = mpz_scan1(q, 0); /* Remove 2^e from q */ mpz_tdiv_q_2exp(q, q, e); mpz_set_ui(t, 2); while (mpz_legendre(t, p) != -1) /* choose t "at random" */ mpz_add_ui(t, t, 1); mpz_powm(z, t, q, p); /* Step 1 complete */ r = e; mpz_powm(b, a, q, p); mpz_add_ui(q, q, 1); mpz_divexact_ui(q, q, 2); mpz_powm(x, a, q, p); /* Done with q, will use it for y now */ while (mpz_cmp_ui(b, 1)) { /* calculate how many times b^2 mod p == 1 */ mpz_set(t, b); m = 0; do { mpz_powm_ui(t, t, 2, p); m++; } while (m < r && mpz_cmp_ui(t, 1)); if (m >= r) break; mpz_ui_pow_ui(t, 2, r-m-1); mpz_powm(t, z, t, p); mpz_mulmod(x, x, t, p, x); mpz_powm_ui(z, t, 2, p); mpz_mulmod(b, b, z, p, b); r = m; } return verify_sqrt(x, a, p, t, q); }
int main (int argc, char *argv[]) { gmp_randstate_t rs; mpz_t p, q, pq, pm1, qm1, phi, e, d, p_i_q, dp, dq, msg[1024], smsg; unsigned long int n, i, niter, t0, ti; double t, f, ops_per_sec; int decimals; if (argc != 2) { fprintf (stderr, "usage: %s n\n", argv[0]); fprintf (stderr, " where n is number of bits in numbers tested\n"); return -1; } if (argc == 2) n = atoi (argv[1]); gmp_randinit_default (rs); mpz_init (p); mpz_init (q); mpz_init (pq); printf ("Generating p, q, d..."); fflush (stdout); #if 0 mpz_urandomb (p, rs, n/2); mpz_setbit (p, n / 2 - 1); mpz_setbit (p, n / 2 - 2); mpz_nextprime (p, p); mpz_urandomb (q, rs, n/2); mpz_setbit (q, n / 2 - 1); mpz_setbit (q, n / 2 - 2); mpz_nextprime (q, q); #else do { mpz_urandomb (p, rs, n/2); mpz_setbit (p, n / 2 - 1); mpz_setbit (p, n / 2 - 2); mpz_setbit (p, 0); mpz_urandomb (q, rs, n/2); mpz_setbit (q, n / 2 - 1); mpz_setbit (q, n / 2 - 2); mpz_setbit (q, 0); mpz_gcd (pq, p, q); } while (mpz_cmp_ui (pq, 1) != 0); #endif mpz_mul (pq, p, q); mpz_init_set_ui (e, RSA_EXP); mpz_init (d); mpz_init (pm1); mpz_init (qm1); mpz_init (phi); mpz_sub_ui (pm1, p, 1); mpz_sub_ui (qm1, q, 1); mpz_mul (phi, pm1, qm1); if (mpz_invert (d, e, phi) == 0) abort (); printf ("done; pq is %d bits\n", (int) mpz_sizeinbase (pq, 2)); printf ("Precomputing CRT constants\n"); mpz_init (p_i_q); if (mpz_invert (p_i_q, p, q) == 0) abort (); mpz_init (dp); mpz_init (dq); mpz_mod (dp, d, pm1); mpz_mod (dq, d, qm1); printf ("Generating random messages\n"); for (i = 0; i < 1024; i++) { mpz_init (msg[i]); mpz_urandomb (msg[i], rs, n); } mpz_init (smsg); printf ("Calibrating CPU speed..."); fflush (stdout); TIME (t, rsa_sign (smsg, msg[0], p, q, pq, p_i_q, dp, dq)); printf ("done\n"); niter = (unsigned long) (1e4 / t); if (niter == 0) niter = 1; printf ("Signing random messages %lu times...", niter); fflush (stdout); t0 = cputime (); for (i = niter; i > 0; i--) { rsa_sign (smsg, msg[i % 1024], p, q, pq, p_i_q, dp, dq); } ti = cputime () - t0; printf ("done!\n"); ops_per_sec = 1000.0 * niter / ti; f = 100.0; for (decimals = 0;; decimals++) { if (ops_per_sec > f) break; f = f * 0.1; } printf ("RESULT: %.*f operations per second\n", decimals, ops_per_sec); return 0; }
static void check_mixed (void) { int ch = 'a'; #ifndef NPRINTF_HH signed char sch = -1; unsigned char uch = 1; #endif short sh = -1; unsigned short ush = 1; int i = -1; int j = 1; unsigned int ui = 1; long lo = -1; unsigned long ulo = 1; float f = -1.25; double d = -1.25; #if !defined(NPRINTF_T) || !defined(NPRINTF_L) long double ld = -1.25; #endif #ifndef NPRINTF_T ptrdiff_t p = 1, saved_p; #endif size_t sz = 1; mpz_t mpz; mpq_t mpq; mpf_t mpf; mpfr_rnd_t rnd = MPFR_RNDN; mpfr_t mpfr; mpfr_prec_t prec; mpz_init (mpz); mpz_set_ui (mpz, ulo); mpq_init (mpq); mpq_set_si (mpq, lo, ulo); mpf_init (mpf); mpf_set_q (mpf, mpq); mpfr_init (mpfr); mpfr_set_f (mpfr, mpf, MPFR_RNDN); prec = mpfr_get_prec (mpfr); check_vprintf ("a. %Ra, b. %u, c. %lx%n", mpfr, ui, ulo, &j); check_length (1, j, 22, d); check_vprintf ("a. %c, b. %Rb, c. %u, d. %li%ln", i, mpfr, i, lo, &ulo); check_length (2, ulo, 36, lu); check_vprintf ("a. %hi, b. %*f, c. %Re%hn", ush, 3, f, mpfr, &ush); check_length (3, ush, 29, hu); check_vprintf ("a. %hi, b. %f, c. %#.2Rf%n", sh, d, mpfr, &i); check_length (4, i, 29, d); check_vprintf ("a. %R*A, b. %Fe, c. %i%zn", rnd, mpfr, mpf, sz, &sz); check_length (5, (unsigned long) sz, 34, lu); /* no format specifier '%zu' in C89 */ check_vprintf ("a. %Pu, b. %c, c. %RUG, d. %Zi%Zn", prec, ch, mpfr, mpz, &mpz); check_length_with_cmp (6, mpz, 24, mpz_cmp_ui (mpz, 24), Zi); check_vprintf ("%% a. %#.0RNg, b. %Qx%Rn c. %p", mpfr, mpq, &mpfr, (void *) &i); check_length_with_cmp (7, mpfr, 15, mpfr_cmp_ui (mpfr, 15), Rg); #ifndef NPRINTF_T saved_p = p; check_vprintf ("%% a. %RNg, b. %Qx, c. %td%tn", mpfr, mpq, p, &p); if (p != 20) mpfr_fprintf (stderr, "Error in test 8, got '%% a. %RNg, b. %Qx, c. %td'\n", mpfr, mpq, saved_p); check_length (8, (long) p, 20, ld); /* no format specifier '%td' in C89 */ #endif #ifndef NPRINTF_L check_vprintf ("a. %RA, b. %Lf, c. %QX%zn", mpfr, ld, mpq, &sz); check_length (9, (unsigned long) sz, 30, lu); /* no format specifier '%zu' in C89 */ #endif #ifndef NPRINTF_HH check_vprintf ("a. %hhi, b. %Ra, c. %hhu%hhn", sch, mpfr, uch, &uch); check_length (10, (unsigned int) uch, 22, u); /* no format specifier '%hhu' in C89 */ #endif #if defined(HAVE_LONG_LONG) && !defined(NPRINTF_LL) { long long llo = -1; unsigned long long ullo = 1; check_vprintf ("a. %Re, b. %llx%Qn", mpfr, ullo, &mpq); check_length_with_cmp (11, mpq, 16, mpq_cmp_ui (mpq, 16, 1), Qu); check_vprintf ("a. %lli, b. %Rf%lln", llo, mpfr, &ullo); check_length (12, ullo, 19, llu); } #endif #if defined(_MPFR_H_HAVE_INTMAX_T) && !defined(NPRINTF_J) { intmax_t im = -1; uintmax_t uim = 1; check_vprintf ("a. %*RA, b. %ji%Fn", 10, mpfr, im, &mpf); check_length_with_cmp (31, mpf, 20, mpf_cmp_ui (mpf, 20), Fg); check_vprintf ("a. %.*Re, b. %jx%jn", 10, mpfr, uim, &im); check_length (32, (long) im, 25, li); /* no format specifier "%ji" in C89 */ } #endif mpfr_clear (mpfr); mpf_clear (mpf); mpq_clear (mpq); mpz_clear (mpz); }
/* Allocates the rel_t object, and adds it to the list in the polygroup if it factored or was a partial. * It determines the factors by trial division, and it also adds the factors to the linked list in the * rel_t. If it didn't factor and wasn't a partial, the relation is freed. */ void construct_relation (mpz_t qx, int32_t x, poly_t *p, nsieve_t *ns){ ns->tdiv_ct ++; rel_t *rel = (rel_t *)(malloc(sizeof(rel_t))); if (rel == NULL){ printf ("Malloc failed\n"); exit(1); } rel->poly = p; rel->x = x; rel->cofactor = 1; rel->factors = NULL; if (mpz_cmp_ui (qx, 0) < 0){ fl_add (rel, 0); } mpz_abs(qx, qx); uint64_t q = 0; int i; while (mpz_divisible_ui_p(qx, 2)){ // handle 2 separately mpz_divexact_ui(qx, qx, 2); fl_add (rel, 1); } for (i=1; i < ns->fb_len; i++){ // instead of doing a multi-precision divisiblilty test, we can use the get_offset method to // detect if 'x' is in the arithmetic progression of sieve values divisible by ns->fb[i]. if (get_offset (ns->fb[i], i, x, 0, p, p->group, ns) == 0 || get_offset (ns->fb[i], i, x, 1, p, p->group, ns) == 0){ mpz_divexact_ui(qx, qx, ns->fb[i]); fl_add (rel, i+1); // add to the factor list // If the result of the division fits in 64 bits, ditch the arbitrary precision. if (mpz_fits_64 (qx)) goto fixedprec_tdiv; while (mpz_divisible_ui_p (qx, ns->fb[i])){ // the sieve doesn't tell us mpz_divexact_ui(qx, qx, ns->fb[i]); // how many times the factor divided fl_add (rel, i+1); if (mpz_fits_64 (qx)){ goto fixedprec_tdiv; } } } } fixedprec_tdiv: q = mpz_get_64 (qx); if (q < ns->fb[i] * ns->fb[i]){ // q must be prime if (q < ns->fb_bound){ // if it's less than the factor base bound, it had better be in the FB. fl_add (rel, fb_lookup (q, ns)); // look it up and add it to the list. goto add_rel; } if (q < ns->lp_bound) { // in this case we have a partial relation. rel->cofactor = q; goto add_rel; } } while (i < ns->fb_len){ // continue the trial division while (q % ns->fb[i] == 0){ // it is no longer efficient to compute offsets here (that q /= ns->fb[i]; // calculation involved mods!) fl_add (rel, i+1); if (q < ns->fb[i] * ns->fb[i]){ if (q < ns->fb_bound){ fl_add (rel, fb_lookup (q, ns)); goto add_rel; } if (q < ns->lp_bound) { rel->cofactor = q; goto add_rel; } } } i++; } // if we're here, we weren't able to do anything with this relation. // rel_free (rel); return; add_rel: // add the relation to the list in the poly_group_t we're working with. if (p->group->nrels < PG_REL_STORAGE){ p->group->relns[ p->group->nrels ] = rel; p->group->nrels ++; return; } else { // if we ran out of space, just let it go. // rel_free(rel); return; } }
static int mpfr_rem1 (mpfr_ptr rem, long *quo, mpfr_rnd_t rnd_q, mpfr_srcptr x, mpfr_srcptr y, mpfr_rnd_t rnd) { mpfr_exp_t ex, ey; int compare, inex, q_is_odd, sign, signx = MPFR_SIGN (x); mpz_t mx, my, r; MPFR_ASSERTD (rnd_q == MPFR_RNDN || rnd_q == MPFR_RNDZ); if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (x) || MPFR_IS_SINGULAR (y))) { if (MPFR_IS_NAN (x) || MPFR_IS_NAN (y) || MPFR_IS_INF (x) || MPFR_IS_ZERO (y)) { /* for remquo, quo is undefined */ MPFR_SET_NAN (rem); MPFR_RET_NAN; } else /* either y is Inf and x is 0 or non-special, or x is 0 and y is non-special, in both cases the quotient is zero. */ { if (quo) *quo = 0; return mpfr_set (rem, x, rnd); } } /* now neither x nor y is NaN, Inf or zero */ mpz_init (mx); mpz_init (my); mpz_init (r); ex = mpfr_get_z_2exp (mx, x); /* x = mx*2^ex */ ey = mpfr_get_z_2exp (my, y); /* y = my*2^ey */ /* to get rid of sign problems, we compute it separately: quo(-x,-y) = quo(x,y), rem(-x,-y) = -rem(x,y) quo(-x,y) = -quo(x,y), rem(-x,y) = -rem(x,y) thus quo = sign(x/y)*quo(|x|,|y|), rem = sign(x)*rem(|x|,|y|) */ sign = (signx == MPFR_SIGN (y)) ? 1 : -1; mpz_abs (mx, mx); mpz_abs (my, my); q_is_odd = 0; /* divide my by 2^k if possible to make operations mod my easier */ { unsigned long k = mpz_scan1 (my, 0); ey += k; mpz_fdiv_q_2exp (my, my, k); } if (ex <= ey) { /* q = x/y = mx/(my*2^(ey-ex)) */ mpz_mul_2exp (my, my, ey - ex); /* divide mx by my*2^(ey-ex) */ if (rnd_q == MPFR_RNDZ) /* 0 <= |r| <= |my|, r has the same sign as mx */ mpz_tdiv_qr (mx, r, mx, my); else /* 0 <= |r| <= |my|, r has the same sign as my */ mpz_fdiv_qr (mx, r, mx, my); if (rnd_q == MPFR_RNDN) q_is_odd = mpz_tstbit (mx, 0); if (quo) /* mx is the quotient */ { mpz_tdiv_r_2exp (mx, mx, WANTED_BITS); *quo = mpz_get_si (mx); } } else /* ex > ey */ { if (quo) /* remquo case */ /* for remquo, to get the low WANTED_BITS more bits of the quotient, we first compute R = X mod Y*2^WANTED_BITS, where X and Y are defined below. Then the low WANTED_BITS of the quotient are floor(R/Y). */ mpz_mul_2exp (my, my, WANTED_BITS); /* 2^WANTED_BITS*Y */ else if (rnd_q == MPFR_RNDN) /* remainder case */ /* Let X = mx*2^(ex-ey) and Y = my. Then both X and Y are integers. Assume X = R mod Y, then x = X*2^ey = R*2^ey mod (Y*2^ey=y). To be able to perform the rounding, we need the least significant bit of the quotient, i.e., one more bit in the remainder, which is obtained by dividing by 2Y. */ mpz_mul_2exp (my, my, 1); /* 2Y */ mpz_set_ui (r, 2); mpz_powm_ui (r, r, ex - ey, my); /* 2^(ex-ey) mod my */ mpz_mul (r, r, mx); mpz_mod (r, r, my); if (quo) /* now 0 <= r < 2^WANTED_BITS*Y */ { mpz_fdiv_q_2exp (my, my, WANTED_BITS); /* back to Y */ mpz_tdiv_qr (mx, r, r, my); /* oldr = mx*my + newr */ *quo = mpz_get_si (mx); q_is_odd = *quo & 1; } else if (rnd_q == MPFR_RNDN) /* now 0 <= r < 2Y in the remainder case */ { mpz_fdiv_q_2exp (my, my, 1); /* back to Y */ /* least significant bit of q */ q_is_odd = mpz_cmpabs (r, my) >= 0; if (q_is_odd) mpz_sub (r, r, my); } /* now 0 <= |r| < |my|, and if needed, q_is_odd is the least significant bit of q */ } if (mpz_cmp_ui (r, 0) == 0) { inex = mpfr_set_ui (rem, 0, MPFR_RNDN); /* take into account sign of x */ if (signx < 0) mpfr_neg (rem, rem, MPFR_RNDN); } else { if (rnd_q == MPFR_RNDN) { /* FIXME: the comparison 2*r < my could be done more efficiently at the mpn level */ mpz_mul_2exp (r, r, 1); compare = mpz_cmpabs (r, my); mpz_fdiv_q_2exp (r, r, 1); compare = ((compare > 0) || ((rnd_q == MPFR_RNDN) && (compare == 0) && q_is_odd)); /* if compare != 0, we need to subtract my to r, and add 1 to quo */ if (compare) { mpz_sub (r, r, my); if (quo && (rnd_q == MPFR_RNDN)) *quo += 1; } } /* take into account sign of x */ if (signx < 0) mpz_neg (r, r); inex = mpfr_set_z_2exp (rem, r, ex > ey ? ey : ex, rnd); } if (quo) *quo *= sign; mpz_clear (mx); mpz_clear (my); mpz_clear (r); return inex; }
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; }
int mpfr_exp_3 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode) { mpfr_t t, x_copy, tmp; mpz_t uk; mpfr_exp_t ttt, shift_x; unsigned long twopoweri; mpz_t *P; mpfr_prec_t *mult; int i, k, loop; int prec_x; mpfr_prec_t realprec, Prec; int iter; int inexact = 0; MPFR_SAVE_EXPO_DECL (expo); MPFR_ZIV_DECL (ziv_loop); MPFR_LOG_FUNC (("x[%Pu]=%.*Rg rnd=%d", mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode), ("y[%Pu]=%.*Rg inexact=%d", mpfr_get_prec(y), mpfr_log_prec, y, inexact)); MPFR_SAVE_EXPO_MARK (expo); /* decompose x */ /* we first write x = 1.xxxxxxxxxxxxx ----- k bits -- */ prec_x = MPFR_INT_CEIL_LOG2 (MPFR_PREC (x)) - MPFR_LOG2_GMP_NUMB_BITS; if (prec_x < 0) prec_x = 0; ttt = MPFR_GET_EXP (x); mpfr_init2 (x_copy, MPFR_PREC(x)); mpfr_set (x_copy, x, MPFR_RNDD); /* we shift to get a number less than 1 */ if (ttt > 0) { shift_x = ttt; mpfr_div_2ui (x_copy, x, ttt, MPFR_RNDN); ttt = MPFR_GET_EXP (x_copy); } else shift_x = 0; MPFR_ASSERTD (ttt <= 0); /* Init prec and vars */ realprec = MPFR_PREC (y) + MPFR_INT_CEIL_LOG2 (prec_x + MPFR_PREC (y)); Prec = realprec + shift + 2 + shift_x; mpfr_init2 (t, Prec); mpfr_init2 (tmp, Prec); mpz_init (uk); /* Main loop */ MPFR_ZIV_INIT (ziv_loop, realprec); for (;;) { int scaled = 0; MPFR_BLOCK_DECL (flags); k = MPFR_INT_CEIL_LOG2 (Prec) - MPFR_LOG2_GMP_NUMB_BITS; /* now we have to extract */ twopoweri = GMP_NUMB_BITS; /* Allocate tables */ P = (mpz_t*) (*__gmp_allocate_func) (3*(k+2)*sizeof(mpz_t)); for (i = 0; i < 3*(k+2); i++) mpz_init (P[i]); mult = (mpfr_prec_t*) (*__gmp_allocate_func) (2*(k+2)*sizeof(mpfr_prec_t)); /* Particular case for i==0 */ mpfr_extract (uk, x_copy, 0); MPFR_ASSERTD (mpz_cmp_ui (uk, 0) != 0); mpfr_exp_rational (tmp, uk, shift + twopoweri - ttt, k + 1, P, mult); for (loop = 0; loop < shift; loop++) mpfr_sqr (tmp, tmp, MPFR_RNDD); twopoweri *= 2; /* General case */ iter = (k <= prec_x) ? k : prec_x; for (i = 1; i <= iter; i++) { mpfr_extract (uk, x_copy, i); if (MPFR_LIKELY (mpz_cmp_ui (uk, 0) != 0)) { mpfr_exp_rational (t, uk, twopoweri - ttt, k - i + 1, P, mult); mpfr_mul (tmp, tmp, t, MPFR_RNDD); } MPFR_ASSERTN (twopoweri <= LONG_MAX/2); twopoweri *=2; } /* Clear tables */ for (i = 0; i < 3*(k+2); i++) mpz_clear (P[i]); (*__gmp_free_func) (P, 3*(k+2)*sizeof(mpz_t)); (*__gmp_free_func) (mult, 2*(k+2)*sizeof(mpfr_prec_t)); if (shift_x > 0) { MPFR_BLOCK (flags, { for (loop = 0; loop < shift_x - 1; loop++) mpfr_sqr (tmp, tmp, MPFR_RNDD); mpfr_sqr (t, tmp, MPFR_RNDD); } ); if (MPFR_UNLIKELY (MPFR_OVERFLOW (flags))) { /* tmp <= exact result, so that it is a real overflow. */ inexact = mpfr_overflow (y, rnd_mode, 1); MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_OVERFLOW); break; } if (MPFR_UNLIKELY (MPFR_UNDERFLOW (flags))) { /* This may be a spurious underflow. So, let's scale the result. */ mpfr_mul_2ui (tmp, tmp, 1, MPFR_RNDD); /* no overflow, exact */ mpfr_sqr (t, tmp, MPFR_RNDD); if (MPFR_IS_ZERO (t)) { /* approximate result < 2^(emin - 3), thus exact result < 2^(emin - 2). */ inexact = mpfr_underflow (y, (rnd_mode == MPFR_RNDN) ? MPFR_RNDZ : rnd_mode, 1); MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, MPFR_FLAGS_UNDERFLOW); break; } scaled = 1; } }