/* Division */ Rational bignum_div(Bignum _n, Bignum _m) { mpz_t n, m, tmp; *n = *theBIGNUM(_n); *m = *theBIGNUM(_m); mpz_init(tmp); mpz_mod(tmp, n, m); /* Divided evenly */ if (mpz_sgn(tmp) == 0) { mpz_cdiv_q(tmp, n, m); return make_bignum(tmp); } else { mpz_t q; ratio_t r; mpz_gcd(tmp, n, m); r = malloc(sizeof(struct ratio_t)); mpz_cdiv_q(q, n, tmp); r->numerator = make_bignum(q); mpz_cdiv_q(q, m, tmp); r->denominator = make_bignum(q); return make_ratio(r); } }
int main (int argc, char *argv[]) { mpz_t c, m1, m2, pc, q1, q2, e, d1, d2, phi1, phi2, tmp1, tmp2, key1, key2; FILE *fp, *fp1; char chars[3]; //initializations mpz_inits(c, m1, m2, pc, q1, q2, e, d1, d2, phi1, phi2, tmp1, tmp2, key1, key2, NULL); //Welcome! printf("Begin task 4 / 5...\n"); printf("*******************************\n"); printf("Welcome to fun with big numbers\n"); printf("Lets do some decryption\n"); printf("*******************************\n"); //Get needed input from file fp = fopen("p4in.txt", "r"); gmp_fscanf(fp, "%Zd\n%Zd\n%Zd\n%Zd", &key1, &key2, &pc, &c); gmp_printf("key1=%Zd\n\nkey2=%Zd\n\nCommon factor=%Zd\n\ncipher=%Zd\n\n", key1, key2, pc, c); fclose(fp); //setup calculating needed values mpz_cdiv_q(q1, key1, pc); mpz_cdiv_q(q2, key2, pc); mpz_set_ui(e, 65537); mpz_sub_ui(tmp1, pc, 1); mpz_sub_ui(tmp2, q1, 1); mpz_mul(phi1, tmp1, tmp2); mpz_sub_ui(tmp2, q2, 1); mpz_mul(phi2, tmp1, tmp2); mpz_invert(d1, e, phi1); mpz_invert(d2, e, phi2); //Lets try and decrypt decrypt(&m1, c, d1, key1); decrypt(&m2, c, d2, key2); fp = fopen("p4out.txt", "w"); gmp_fprintf(fp, "%Zx\n%Zx\n", m1, m2); fclose(fp); mpz_clears(c, m1, m2, pc, q1, q2, e, d1, d2, phi1, phi2, tmp1, tmp2, key1, key2, NULL); fp = fopen("p4out.txt", "r"); chars[2] = 0; while (fscanf(fp, "%c%c", chars, chars + 1) > 0){ printf("%c", (int)strtol(chars, NULL, 16)); } fclose(fp); return 0; }
/* q = a / b */ static int wrap_nettle_mpi_div(bigint_t q, const bigint_t a, const bigint_t b) { mpz_cdiv_q(TOMPZ(q), TOMPZ(a), TOMPZ(b)); return 0; }
void make_headers(void) { mpz_t newk, oldk, thing, div; mpz_init(newk); mpz_init(thing); mpz_ui_pow_ui(thing, 2, M); mpz_init_set(div, thing); mpz_init_set_ui(oldk, 3); int size = SIZE; for(int i = 0; i <= LEVELS; i++) { mpz_set_ui(newk, 0); int r = 1; int n; while(mpz_get_ui(newk) < 3) { r++; double bottom = mpz_get_d(oldk); n = floor(((M+1)*log(2.0) + log((double) r))/log(bottom)); mpz_pow_ui(thing, oldk, n); mpz_cdiv_q(newk, thing, div); } headers[i].chunksize = n; headers[i].K = mpz_get_ui(oldk); mpz_set(oldk,newk); headers[i].size = size; size = ceil((double)size/n); } fwrite(headers, sizeof(header), LEVELS + 1, output); mpz_clear(oldk); mpz_clear(div); mpz_clear(thing); mpz_clear(newk); }
/* * It is a function that performs Extended Euclid * input: mpz_t of a, b, s and t * output: variable a as the GCD and give s and t values */ void extendedEuclid(mpz_t a, mpz_t b, mpz_t s, mpz_t t){ mpz_t q, r, r1, r2,s1,s2,t1,t2, temp; mpz_init(q); mpz_init(r1); mpz_init(r2); mpz_init(temp); mpz_set(r1, a); mpz_set(r2, b); mpz_init_set_str(r, "1", 10); //to prevent r from inheriting other value mpz_init_set_str(s1, "1", 10); mpz_init_set_str(s2, "0", 10); mpz_init_set_str(t1, "0", 10); mpz_init_set_str(t2, "1", 10); while(mpz_cmp_ui(r2,0) != 0){ mpz_cdiv_q(q, r1, r2); mpz_cdiv_r(r, r1, r2); mpz_mul(temp, q, s2); mpz_sub(s, s1, temp); mpz_mul(temp, q, t2); mpz_sub(t, t1, temp); mpz_set(r1, r2); mpz_set(r2, r); mpz_set(s1, s2); mpz_set(s2, s); mpz_set(t1, t2); mpz_set(t2, t); } mpz_set(s, s1); mpz_set(t, t1); mpz_set(a, r1); }
/* * Step 3 of bleichenbacher's algorithm : search space reduction */ int b98_update_boundaries(struct bleichenbacher_98_t *b98) { mpz_t min_r, max_r; mpz_init(min_r); mpz_mul(min_r, b98->a, b98->s ); mpz_sub(min_r, min_r, b98->max_range); mpz_cdiv_q (min_r, min_r, b98->n); if (!mpz_sgn(min_r)) mpz_add_ui(min_r, min_r, 1); mpz_init(max_r); mpz_mul(max_r, b98->b, b98->s ); mpz_sub(max_r, max_r, b98->min_range); mpz_fdiv_q (max_r, max_r, b98->n); if (mpz_cmp(min_r, max_r) > 0) { mpz_set(min_r, b98->r); mpz_set(max_r, b98->r); } b98_update_a(b98->a, min_r, b98->s, b98->min_range, b98->max_range, b98->n ); b98_update_b(b98->b, max_r, b98->s, b98->min_range, b98->max_range, b98->n ); mpz_clear(min_r); mpz_clear(max_r); return 0x00; }
static PyObject * Pygmpy_c_div(PyObject *self, PyObject *args) { PyObject *x, *y; PympzObject *q, *tempx, *tempy; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("c_div() requires 'mpz','mpz' arguments"); return NULL; } x = PyTuple_GET_ITEM(args, 0); y = PyTuple_GET_ITEM(args, 1); if (!(q = Pympz_new())) return NULL; if (CHECK_MPZANY(x) && CHECK_MPZANY(y)) { if (mpz_sgn(Pympz_AS_MPZ(y)) == 0) { ZERO_ERROR("c_div() division by 0"); Py_DECREF((PyObject*)q); return NULL; } mpz_cdiv_q(q->z, Pympz_AS_MPZ(x), Pympz_AS_MPZ(y)); } else { tempx = Pympz_From_Integer(x); tempy = Pympz_From_Integer(y); if (!tempx || !tempy) { TYPE_ERROR("c_div() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)q); return NULL; } if (mpz_sgn(Pympz_AS_MPZ(tempy)) == 0) { ZERO_ERROR("c_div() division by 0"); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)q); return NULL; } mpz_cdiv_q(q->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); } return (PyObject*)q; }
void getPrivateKey(mpz_t p, mpz_t q, mpz_t modulii, mpz_t publicKey, mpz_t privateKey) { mpz_cdiv_q(q, modulii, p); //q is now other prime //get keys getKeysWithPrimes(p, q, publicKey, privateKey); }
void fmpz_cdiv_q(fmpz_t f, const fmpz_t g, const fmpz_t h) { fmpz c1 = *g; fmpz c2 = *h; if (fmpz_is_zero(h)) { printf("Exception: division by zero in fmpz_cdiv_q\n"); abort(); } if (!COEFF_IS_MPZ(c1)) /* g is small */ { if (!COEFF_IS_MPZ(c2)) /* h is also small */ { fmpz q = c1 / c2; /* compute C quotient */ fmpz r = c1 - c2 * q; /* compute remainder */ if (r && ((c2 ^ r) > 0L)) /* r != 0, c2 and r same sign */ ++q; fmpz_set_si(f, q); } else /* h is large and g is small */ { if ((c1 < 0L && fmpz_sgn(h) < 0) || (c1 > 0L && fmpz_sgn(h) > 0)) /* signs are the same */ fmpz_set_ui(f, 1); /* quotient is positive, round up to one */ else fmpz_zero(f); /* quotient is zero, or negative, round up to zero */ } } else /* g is large */ { __mpz_struct * mpz_ptr = _fmpz_promote(f); if (!COEFF_IS_MPZ(c2)) /* h is small */ { if (c2 > 0) /* h > 0 */ { mpz_cdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), c2); } else { mpz_fdiv_q_ui(mpz_ptr, COEFF_TO_PTR(c1), -c2); mpz_neg(mpz_ptr, mpz_ptr); } } else /* both are large */ { mpz_cdiv_q(mpz_ptr, COEFF_TO_PTR(c1), COEFF_TO_PTR(c2)); } _fmpz_demote_val(f); /* division by h may result in small value */ } }
/** * Applique euclide etendu a nb1 et nb2 * @param resultat tableau de 3 entiers : u, v et r tels que r=pgcd(nb1, nb2) et a*u+b*v=r */ void euclide_etendu(mpz_t nb1, mpz_t nb2, mpz_t *resultat){ mpz_t r, r1, u, u1, v, v1; mpz_inits(r, r1, NULL); mpz_set(r, nb1); mpz_set(r1, nb2); mpz_init_set_si(u, 1); mpz_init_set_si(u1, 0); mpz_init_set_si(v, 0); mpz_init_set_si(v1, 1); /* printf("u=%ld, v=%ld, pgcd=%ld\n",mpz_get_si(u),mpz_get_si(v), mpz_get_si(r)); */ mpz_t q, r_temp, u_temp, v_temp, tmp; mpz_inits(q, r_temp, u_temp, v_temp, tmp, NULL); while (mpz_get_si(r1) != 0){ mpz_cdiv_q(q,r,r1); /* Division entiere */ mpz_set(r_temp,r); mpz_set(u_temp,u); mpz_set(v_temp,v); mpz_set(r,r1); mpz_set(u,u1); mpz_set(v,v1); mpz_mul(tmp, q, r1); mpz_sub(r1, r_temp, tmp); /* r1=r_temp-q*r1; */ mpz_mul(tmp, q, u1); mpz_sub(u1, u_temp, tmp); mpz_mul(tmp, q, v1); mpz_sub(v1, v_temp, tmp); } if(mpz_get_si(r)<0){ mpz_neg(u,u); mpz_neg(v,v); mpz_neg(r,r); } mpz_set(resultat[0],u); mpz_set(resultat[1],v); mpz_set(resultat[2],r); /* Creer une fonction */ /* Clear */ mpz_clear(r); mpz_clear(r1); mpz_clear(u); mpz_clear(u1); mpz_clear(v); mpz_clear(v1); }
static Variant HHVM_FUNCTION(gmp_div_q, const Variant& dataA, const Variant& dataB, int64_t round = GMP_ROUND_ZERO) { mpz_t gmpDataA, gmpDataB, gmpReturn; if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIV_Q, gmpDataA, dataA)) { return false; } if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIV_Q, gmpDataB, dataB)) { mpz_clear(gmpDataA); return false; } if (mpz_sgn(gmpDataB) == 0) { mpz_clear(gmpDataA); mpz_clear(gmpDataB); raise_warning(cs_GMP_INVALID_VALUE_MUST_NOT_BE_ZERO, cs_GMP_FUNC_NAME_GMP_DIV_Q); return false; } mpz_init(gmpReturn); switch (round) { case GMP_ROUND_ZERO: mpz_tdiv_q(gmpReturn, gmpDataA, gmpDataB); break; case GMP_ROUND_PLUSINF: mpz_cdiv_q(gmpReturn, gmpDataA, gmpDataB); break; case GMP_ROUND_MINUSINF: mpz_fdiv_q(gmpReturn, gmpDataA, gmpDataB); break; default: mpz_clear(gmpDataA); mpz_clear(gmpDataB); mpz_clear(gmpReturn); return null_variant; } Variant ret = NEWOBJ(GMPResource)(gmpReturn); mpz_clear(gmpDataA); mpz_clear(gmpDataB); mpz_clear(gmpReturn); return ret; }
static PyObject * Pympq_ceil(PyObject *self, PyObject *other) { PympzObject *result; if ((result = (PympzObject*)Pympz_new())) { mpz_cdiv_q(result->z, mpq_numref(Pympq_AS_MPQ(self)), mpq_denref(Pympq_AS_MPQ(self))); } return (PyObject*)result; }
/* * Step 2.a of bleichenbacher's algorithm : initial search */ int b98_initial_search(struct bleichenbacher_98_t *b98) { int pad_check = 0x00; mpz_cdiv_q (b98->s, b98->n, b98->max_range); while(!pad_check) { mpz_add_ui(b98->s, b98->s, 1); pad_check = b98_check_padding(b98); } return 0x00; }
static int transform_sections (mpz_t X1, mpz_t X2, mpz_t no_of_elements, gfc_expr * l_start, gfc_expr * l_end, gfc_expr * l_stride, gfc_expr * r_start, gfc_expr * r_stride) { if (NULL == l_start || NULL == l_end || NULL == r_start) return 1; /* TODO : Currently we check the dependency only when start, end and stride are constant. We could also check for equal (variable) values, and common subexpressions, eg. x vs. x+1. */ if (l_end->expr_type != EXPR_CONSTANT || l_start->expr_type != EXPR_CONSTANT || r_start->expr_type != EXPR_CONSTANT || ((NULL != l_stride) && (l_stride->expr_type != EXPR_CONSTANT)) || ((NULL != r_stride) && (r_stride->expr_type != EXPR_CONSTANT))) { return 1; } get_no_of_elements (no_of_elements, l_end, l_start, l_stride); mpz_sub (X1, r_start->value.integer, l_start->value.integer); if (l_stride != NULL) mpz_cdiv_q (X1, X1, l_stride->value.integer); if (r_stride == NULL) mpz_set (X2, no_of_elements); else mpz_mul (X2, no_of_elements, r_stride->value.integer); if (l_stride != NULL) mpz_cdiv_q (X2, X2, r_stride->value.integer); mpz_add (X2, X2, X1); return 0; }
enum lp_result PL_polyhedron_opt(Polyhedron *P, Value *obj, Value denom, enum lp_dir dir, Value *opt) { int i; int first = 1; Value val, d; enum lp_result res = lp_empty; POL_ENSURE_VERTICES(P); if (emptyQ(P)) return res; value_init(val); value_init(d); for (i = 0; i < P->NbRays; ++ i) { Inner_Product(P->Ray[i]+1, obj, P->Dimension+1, &val); if (value_zero_p(P->Ray[i][0]) && value_notzero_p(val)) { res = lp_unbounded; break; } if (value_zero_p(P->Ray[i][1+P->Dimension])) { if ((dir == lp_min && value_neg_p(val)) || (dir == lp_max && value_pos_p(val))) { res = lp_unbounded; break; } } else { res = lp_ok; value_multiply(d, denom, P->Ray[i][1+P->Dimension]); if (dir == lp_min) mpz_cdiv_q(val, val, d); else mpz_fdiv_q(val, val, d); if (first || (dir == lp_min ? value_lt(val, *opt) : value_gt(val, *opt))) value_assign(*opt, val); first = 0; } } value_clear(d); value_clear(val); return res; }
static void find_factors(mpz_t base) { char *str; int res; mpz_t i; mpz_t half; mpz_t two; mpz_init_set_str(two, "2", 10); mpz_init_set_str(i, "2", 10); mpz_init(half); mpz_cdiv_q(half, base, two); str = mpz_to_str(base); if (!str) return; /* * We simply return the prime number itself if the base is prime. * (We use the GMP probabilistic function with 10 repetitions). */ res = mpz_probab_prime_p(base, 10); if (res) { printf("%s is a prime number\n", str); free(str); return; } printf("Trial: prime factors for %s are:", str); free(str); do { if (mpz_divisible_p(base, i) && verify_is_prime(i)) { str = mpz_to_str(i); if (!str) return; printf(" %s", str); free(str); } mpz_nextprime(i, i); } while (mpz_cmp(i, half) <= 0); printf("\n"); }
/* * It is a function that performs binomial theorem/expansion * (a+b)^n = {n "summation" k} [n k]*a^(n-k)b*^k * input: mpz_t n, mpz_t k and mpz_t *bin(pointer) to retrieve the output * output: mpz_t *bin as a pointer */ void binomial(mpz_t n, mpz_t k, mpz_t *bin){ mpz_t f1; mpz_t f2; mpz_t f3; mpz_t temp; mpz_t denominator; mpz_init(f1); mpz_init(f2); mpz_init(f3); mpz_init(temp); mpz_init(denominator); factorial(k, &f1); mpz_sub(temp, n, k); factorial(temp, &f2); mpz_mul(denominator, f1, f2); //gmp_printf("%Zd\n", denominator); factorial(n, &f3); //gmp_printf("%Zd\n", f3); mpz_cdiv_q(*bin, f3, denominator); }
static void copy_solution(struct isl_vec *vec, int maximize, isl_int *opt, isl_int *opt_denom, PipQuast *sol) { int i; PipList *list; isl_int tmp; if (opt) { if (opt_denom) { isl_seq_cpy_from_pip(opt, &sol->list->vector->the_vector[0], 1); isl_seq_cpy_from_pip(opt_denom, &sol->list->vector->the_deno[0], 1); } else if (maximize) mpz_fdiv_q(*opt, sol->list->vector->the_vector[0], sol->list->vector->the_deno[0]); else mpz_cdiv_q(*opt, sol->list->vector->the_vector[0], sol->list->vector->the_deno[0]); } if (!vec) return; isl_int_init(tmp); isl_int_set_si(vec->el[0], 1); for (i = 0, list = sol->list->next; list; ++i, list = list->next) { isl_seq_cpy_from_pip(&vec->el[1 + i], &list->vector->the_deno[0], 1); isl_int_lcm(vec->el[0], vec->el[0], vec->el[1 + i]); } for (i = 0, list = sol->list->next; list; ++i, list = list->next) { isl_seq_cpy_from_pip(&tmp, &list->vector->the_deno[0], 1); isl_int_divexact(tmp, vec->el[0], tmp); isl_seq_cpy_from_pip(&vec->el[1 + i], &list->vector->the_vector[0], 1); isl_int_mul(vec->el[1 + i], vec->el[1 + i], tmp); } isl_int_clear(tmp); }
int main(void) { int i, result; FLINT_TEST_INIT(state); flint_printf("cdiv_q...."); fflush(stdout); for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a, b, c; mpz_t d, e, f, g; fmpz_init(a); fmpz_init(b); fmpz_init(c); mpz_init(d); mpz_init(e); mpz_init(f); mpz_init(g); fmpz_randtest(a, state, 200); fmpz_randtest_not_zero(b, state, 200); fmpz_get_mpz(d, a); fmpz_get_mpz(e, b); fmpz_cdiv_q(c, a, b); mpz_cdiv_q(f, d, e); fmpz_get_mpz(g, c); result = (mpz_cmp(f, g) == 0); if (!result) { flint_printf("FAIL\n"); gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); abort(); } fmpz_clear(a); fmpz_clear(b); fmpz_clear(c); mpz_clear(d); mpz_clear(e); mpz_clear(f); mpz_clear(g); } /* Check aliasing of a and b */ for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a, c; mpz_t d, f, g; fmpz_init(a); fmpz_init(c); mpz_init(d); mpz_init(f); mpz_init(g); fmpz_randtest_not_zero(a, state, 200); fmpz_get_mpz(d, a); fmpz_cdiv_q(c, a, a); mpz_cdiv_q(f, d, d); fmpz_get_mpz(g, c); result = (mpz_cmp(f, g) == 0); if (!result) { flint_printf("FAIL\n"); gmp_printf("d = %Zd, f = %Zd, g = %Zd\n", d, f, g); abort(); } fmpz_clear(a); fmpz_clear(c); mpz_clear(d); mpz_clear(f); mpz_clear(g); } /* Test aliasing of a and c */ for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a, b; mpz_t d, e, f, g; fmpz_init(a); fmpz_init(b); mpz_init(d); mpz_init(e); mpz_init(f); mpz_init(g); fmpz_randtest(a, state, 200); fmpz_randtest_not_zero(b, state, 200); fmpz_get_mpz(d, a); fmpz_get_mpz(e, b); fmpz_cdiv_q(a, a, b); mpz_cdiv_q(f, d, e); fmpz_get_mpz(g, a); result = (mpz_cmp(f, g) == 0); if (!result) { flint_printf("FAIL\n"); gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); abort(); } fmpz_clear(a); fmpz_clear(b); mpz_clear(d); mpz_clear(e); mpz_clear(f); mpz_clear(g); } /* Test aliasing of b and c */ for (i = 0; i < 10000 * flint_test_multiplier(); i++) { fmpz_t a, b; mpz_t d, e, f, g; fmpz_init(a); fmpz_init(b); mpz_init(d); mpz_init(e); mpz_init(f); mpz_init(g); fmpz_randtest(a, state, 200); fmpz_randtest_not_zero(b, state, 200); fmpz_get_mpz(d, a); fmpz_get_mpz(e, b); fmpz_cdiv_q(b, a, b); mpz_cdiv_q(f, d, e); fmpz_get_mpz(g, b); result = (mpz_cmp(f, g) == 0); if (!result) { flint_printf("FAIL\n"); gmp_printf("d = %Zd, e = %Zd, f = %Zd, g = %Zd\n", d, e, f, g); abort(); } fmpz_clear(a); fmpz_clear(b); mpz_clear(d); mpz_clear(e); mpz_clear(f); mpz_clear(g); } FLINT_TEST_CLEANUP(state); flint_printf("PASS\n"); return 0; }
void response(int sockfd) { int ret; const char public_key[] = KEY_STRING; const char id[] = ID_STRING; const char http1[] = HTTP_RESPONSE_STRING1; const char http2[] = HTTP_RESPONSE_STRING2; char timestamp[36] = TIMESTAMP; char private_key[MAX_BUFFER]; char buf[MAX_BUFFER]; int len = MAX_BUFFER; char* pch = buf; char* pend = pch + MAX_BUFFER; char* pcheck = pch + Q1_STRING_LEN - 1; int found = 0; time_t tnow; struct tm* now; mpz_t x, xy, y; mpz_inits(x, y, xy, 0); //read while (!found) { #ifdef _DEBUG printf("reading...\n"); #endif ret = read(sockfd, pch, pend - pch); if (ret < 0) { perror("read failed..."); close(sockfd); return; } if (ret == 0) break; pch += ret; while (pch > pcheck) { if (*pcheck == ' ') { found = 1; break; } pcheck++; } if (ret == 0) { printf("read ret 0..."); //might be health check close(sockfd); return; } } if (strncmp(buf, Q1_STRING, Q1_STRING_LEN) != 0) { #ifdef _DEBUG printf("unknown message..."); #endif write(sockfd, HTTP_HEALTH_STRING, HTTP_HEALTH_STRING_LEN); close(sockfd); return; } //prepare response buffer *pcheck = '\0'; #ifdef _DEBUG printf("request: %s\n", buf); #endif mpz_set_str(xy, buf + Q1_STRING_LEN, 10); mpz_set_str(x, public_key, 10); mpz_cdiv_q(y, xy, x); mpz_get_str(private_key, 10, y); time(&tnow); now = localtime(&tnow); strftime(buf + DATE_OFFSET, sizeof(buf)-DATE_OFFSET, "%a, %d %b %Y %H:%M:%S %z", now); buf[DATEEND_OFFSET] = '\n'; strftime(timestamp, sizeof(timestamp), "%Y:%m:%d %H:%M:%S", now); len = strlen(private_key) + 1 + ID_STRING_LEN + 1 + strlen(timestamp) + 1; sprintf(buf, "%s%d%s%s\n%s\n%s\n", http1, len, http2, private_key, id, timestamp); #ifdef _DEBUG printf("response: %s\n", buf); #endif //write pend = buf + strlen(buf); pch = buf; while (pch < pend) { ret = write(sockfd, buf, pend - pch); if (ret < 0) { perror("write failed..."); close(sockfd); return; } pch += ret; } close(sockfd); }
int main(int argc, char **argv) { gettimeofday(&start_global, NULL); print_lib_version(); mpz_init(N); mpz_t B; mpz_init(B); unsigned long int uBase; int64_t nb_primes; modular_root_t *modular_roots; uint64_t i, j; if (mpz_init_set_str(N, argv[1], 10) == -1) { printf("Cannot load N %s\n", argv[1]); exit(2); } mpz_t sqrtN, rem; mpz_init(sqrtN); mpz_init(rem); mpz_sqrtrem(sqrtN, rem, N); if (mpz_cmp_ui(rem, 0) != 0) /* if not perfect square, calculate the ceiling */ mpz_add_ui(sqrtN, sqrtN, 1); else /* N is a perfect square, factored! */ { printf("\n<<<[FACTOR]>>> %s\n", mpz_get_str(NULL, 10, sqrtN)); return 0; } if (mpz_probab_prime_p(N, 10) > 0) /* don't bother factoring */ { printf("N:%s is prime\n", mpz_get_str(NULL, 10, N)); exit(0); } OPEN_LOG_FILE("freq"); //-------------------------------------------------------- // calculate the smoothness base for the given N //-------------------------------------------------------- get_smoothness_base(B, N); /* if N is too small, the program will surely fail, please consider a pen and paper instead */ uBase = mpz_get_ui(B); printf("n: %s\tBase: %s\n", mpz_get_str(NULL, 10, N), mpz_get_str(NULL, 10, B)); //-------------------------------------------------------- // sieve primes that are less than the smoothness base using Eratosthenes sieve //-------------------------------------------------------- START_TIMER(); nb_primes = sieve_primes_up_to((int64_t) (uBase)); printf("\nPrimes found %" PRId64 " [Smoothness Base %lu]\n", nb_primes, uBase); STOP_TIMER_PRINT_TIME("\tEratosthenes Sieving done"); //-------------------------------------------------------- // fill the primes array with primes to which n is a quadratic residue //-------------------------------------------------------- START_TIMER(); primes = calloc(nb_primes, sizeof(int64_t)); nb_qr_primes = fill_primes_with_quadratic_residue(primes, N); /*for(i=0; i<nb_qr_primes; i++) printf("%" PRId64 "\n", primes[i]);*/ printf("\nN-Quadratic primes found %" PRId64 "\n", nb_qr_primes); STOP_TIMER_PRINT_TIME("\tQuadratic prime filtering done"); //-------------------------------------------------------- // calculate modular roots //-------------------------------------------------------- START_TIMER(); modular_roots = calloc(nb_qr_primes, sizeof(modular_root_t)); mpz_t tmp, r1, r2; mpz_init(tmp); mpz_init(r1); mpz_init(r2); for (i = 0; i < nb_qr_primes; i++) { mpz_set_ui(tmp, (unsigned long) primes[i]); mpz_sqrtm(r1, N, tmp); /* calculate the modular root */ mpz_neg(r2, r1); /* -q mod n */ mpz_mod(r2, r2, tmp); modular_roots[i].root1 = mpz_get_ui(r1); modular_roots[i].root2 = mpz_get_ui(r2); } mpz_clear(tmp); mpz_clear(r1); mpz_clear(r2); STOP_TIMER_PRINT_TIME("\nModular roots calculation done"); /*for(i=0; i<nb_qr_primes; i++) { printf("[%10" PRId64 "-> roots: %10u - %10u]\n", primes[i], modular_roots[i].root1, modular_roots[i].root2); }*/ //-------------------------------------------------------- // ***** initialize the matrix ***** //-------------------------------------------------------- START_TIMER(); init_matrix(&matrix, nb_qr_primes + NB_VECTORS_OFFSET, nb_qr_primes); mpz_init2(tmp_matrix_row, nb_qr_primes); STOP_TIMER_PRINT_TIME("\nMatrix initialized"); //-------------------------------------------------------- // [Sieving] //-------------------------------------------------------- START_TIMER(); mpz_t x, sieving_index, next_sieving_index; unsigned long ui_index, SIEVING_STEP = 50000; /* we sieve for 50000 elements at each loop */ uint64_t p_pow; smooth_number_t *x_squared; x_squared = calloc(SIEVING_STEP, sizeof(smooth_number_t)); smooth_numbers = calloc(nb_qr_primes + NB_VECTORS_OFFSET, sizeof(smooth_number_t)); mpz_init_set(x, sqrtN); mpz_init_set(sieving_index, x); mpz_init_set(next_sieving_index, x); mpz_t p; mpz_init(p); mpz_t str; mpz_init_set(str, sieving_index); printf("\nSieving ...\n"); //-------------------------------------------------------- // Init before sieving //-------------------------------------------------------- for (i = 0; i < SIEVING_STEP; i++) { mpz_init(x_squared[i].value_x); mpz_init(x_squared[i].value_x_squared); /* the factors_exp array is used to keep track of exponents */ //x_squared[i].factors_exp = calloc(nb_qr_primes, sizeof(uint64_t)); /* we use directly the exponents vector modulo 2 to preserve space */mpz_init2( x_squared[i].factors_vect, nb_qr_primes); mpz_add_ui(x, x, 1); } int nb_smooth_per_round = 0; char s[512]; //-------------------------------------------------------- // WHILE smooth numbers found less than the primes in the smooth base + NB_VECTORS_OFFSET //-------------------------------------------------------- while (nb_smooth_numbers_found < nb_qr_primes + NB_VECTORS_OFFSET) { nb_smooth_per_round = 0; mpz_set(x, next_sieving_index); /* sieve numbers from sieving_index to sieving_index + sieving_step */ mpz_set(sieving_index, next_sieving_index); printf("\r"); printf( "\t\tSieving at: %s30 <--> Smooth numbers found: %" PRId64 "/%" PRId64 "", mpz_get_str(NULL, 10, sieving_index), nb_smooth_numbers_found, nb_qr_primes); fflush(stdout); for (i = 0; i < SIEVING_STEP; i++) { mpz_set(x_squared[i].value_x, x); mpz_pow_ui(x_squared[i].value_x_squared, x, 2); /* calculate value_x_squared <- x²-n */ mpz_sub(x_squared[i].value_x_squared, x_squared[i].value_x_squared, N); mpz_clear(x_squared[i].factors_vect); mpz_init2(x_squared[i].factors_vect, nb_qr_primes); /* reconstruct a new fresh 0ed vector of size nb_qr_primes bits */ mpz_add_ui(x, x, 1); } mpz_set(next_sieving_index, x); //-------------------------------------------------------- // eliminate factors in the x_squared array, those who are 'destructed' to 1 are smooth //-------------------------------------------------------- for (i = 0; i < nb_qr_primes; i++) { mpz_set_ui(p, (unsigned long) primes[i]); mpz_set(x, sieving_index); /* get the first multiple of p that is directly larger that sieving_index * Quadratic SIEVING: all elements from this number and in positions multiples of root1 and root2 * are also multiples of p */ get_sieving_start_index(x, x, p, modular_roots[i].root1); mpz_set(str, x); mpz_sub(x, x, sieving_index); /* x contains index of first number that is divisible by p */ for (j = mpz_get_ui(x); j < SIEVING_STEP; j += primes[i]) { p_pow = mpz_remove(x_squared[j].value_x_squared, x_squared[j].value_x_squared, p); /* eliminate all factors of p */ if (p_pow & 1) /* mark bit if odd power of p exists in this x_squared[j] */ { mpz_setbit(x_squared[j].factors_vect, i); } if (mpz_cmp_ui(x_squared[j].value_x_squared, 1) == 0) { save_smooth_number(x_squared[j]); nb_smooth_per_round++; } /* sieve next element located p steps from here */ } /* same goes for root2 */ if (modular_roots[i].root2 == modular_roots[i].root1) continue; mpz_set(x, sieving_index); get_sieving_start_index(x, x, p, modular_roots[i].root2); mpz_set(str, x); mpz_sub(x, x, sieving_index); for (j = mpz_get_ui(x); j < SIEVING_STEP; j += primes[i]) { p_pow = mpz_remove(x_squared[j].value_x_squared, x_squared[j].value_x_squared, p); if (p_pow & 1) { mpz_setbit(x_squared[j].factors_vect, i); } if (mpz_cmp_ui(x_squared[j].value_x_squared, 1) == 0) { save_smooth_number(x_squared[j]); nb_smooth_per_round++; } } } //printf("\tSmooth numbers found %" PRId64 "\n", nb_smooth_numbers_found); /*sprintf(s, "[start: %s - end: %s - step: %" PRId64 "] nb_smooth_per_round: %d", mpz_get_str(NULL, 10, sieving_index), mpz_get_str(NULL, 10, next_sieving_index), SIEVING_STEP, nb_smooth_per_round); APPEND_TO_LOG_FILE(s);*/ } STOP_TIMER_PRINT_TIME("\nSieving DONE"); uint64_t t = 0; //-------------------------------------------------------- //the matrix ready, start Gauss elimination. The Matrix is filled on the call of save_smooth_number() //-------------------------------------------------------- START_TIMER(); gauss_elimination(&matrix); STOP_TIMER_PRINT_TIME("\nGauss elimination done"); //print_matrix_matrix(&matrix); //print_matrix_identity(&matrix); uint64_t row_index = nb_qr_primes + NB_VECTORS_OFFSET - 1; /* last row in the matrix */ int nb_linear_relations = 0; mpz_t linear_relation_z, solution_z; mpz_init(linear_relation_z); mpz_init(solution_z); get_matrix_row(linear_relation_z, &matrix, row_index--); /* get the last few rows in the Gauss eliminated matrix*/ while (mpz_cmp_ui(linear_relation_z, 0) == 0) { nb_linear_relations++; get_matrix_row(linear_relation_z, &matrix, row_index--); } printf("\tLinear dependent relations found : %d\n", nb_linear_relations); //-------------------------------------------------------- // Factor //-------------------------------------------------------- //We use the last linear relation to reconstruct our solution START_TIMER(); printf("\nFactorizing..\n"); mpz_t solution_X, solution_Y; mpz_init(solution_X); mpz_init(solution_Y); /* we start testing from the first linear relation encountered in the matrix */ for (j = nb_linear_relations; j > 0; j--) { printf("Trying %d..\n", nb_linear_relations - j + 1); mpz_set_ui(solution_X, 1); mpz_set_ui(solution_Y, 1); get_identity_row(solution_z, &matrix, nb_qr_primes + NB_VECTORS_OFFSET - j + 1); for (i = 0; i < nb_qr_primes; i++) { if (mpz_tstbit(solution_z, i)) { mpz_mul(solution_X, solution_X, smooth_numbers[i].value_x); mpz_mod(solution_X, solution_X, N); /* reduce x to modulo N */ mpz_mul(solution_Y, solution_Y, smooth_numbers[i].value_x_squared); /*TODO: handling huge stuff here, there is no modulo N like in the solution_X case! * eliminate squares as long as you go*/ } } mpz_sqrt(solution_Y, solution_Y); mpz_mod(solution_Y, solution_Y, N); /* y = sqrt(MUL(xi²-n)) mod N */ mpz_sub(solution_X, solution_X, solution_Y); mpz_gcd(solution_X, solution_X, N); if (mpz_cmp(solution_X, N) != 0 && mpz_cmp_ui(solution_X, 1) != 0) /* factor can be 1 or N, try another relation */ break; } mpz_cdiv_q(solution_Y, N, solution_X); printf("\n>>>>>>>>>>> FACTORED %s =\n", mpz_get_str(NULL, 10, N)); printf("\tFactor 1: %s \n\tFactor 2: %s", mpz_get_str(NULL, 10, solution_X), mpz_get_str(NULL, 10, solution_Y)); /*sprintf(s, "\n>>>>>>>>>>> FACTORED %s =\n", mpz_get_str(NULL, 10, N)); APPEND_TO_LOG_FILE(s); sprintf(s, "\tFactor 1: %s \n\tFactor 2: %s", mpz_get_str(NULL, 10, solution_X), mpz_get_str(NULL, 10, solution_Y)); APPEND_TO_LOG_FILE(s); gettimeofday(&end_global, NULL); timersub(&end_global, &start_global, &elapsed); sprintf(s, "****** TOTAL TIME: %.3f ms\n", elapsed.tv_sec * 1000 + elapsed.tv_usec / (double) 1000); APPEND_TO_LOG_FILE(s);*/ STOP_TIMER_PRINT_TIME("\nFactorizing done"); printf("Cleaning memory..\n"); /********************** clear the x_squared array **********************/ for (i = 0; i < SIEVING_STEP; i++) { mpz_clear(x_squared[i].value_x); mpz_clear(x_squared[i].value_x_squared); //free(x_squared[i].factors_exp); mpz_clear(x_squared[i].factors_vect); } free(x_squared); /********************** clear the x_squared array **********************/ free(modular_roots); /********************** clear the smooth_numbers array **********************/ for (i = 0; i < nb_qr_primes + NB_VECTORS_OFFSET; i++) { mpz_clear(smooth_numbers[i].value_x); mpz_clear(smooth_numbers[i].value_x_squared); //free(smooth_numbers[i].factors_exp); } free(smooth_numbers); /********************** clear the smooth_numbers array **********************/ free(primes); /********************** clear mpz _t **********************/mpz_clear(B); mpz_clear(N); sqrtN, rem; mpz_clear(x); mpz_clear(sieving_index); mpz_clear(next_sieving_index); mpz_clear(p); mpz_clear(str); /********************** clear mpz _t **********************/ free_matrix(&matrix); gettimeofday(&end_global, NULL); timersub(&end_global, &start_global, &elapsed); printf("****** TOTAL TIME: %.3f ms\n", elapsed.tv_sec * 1000 + elapsed.tv_usec / (double) 1000); show_mem_usage(); return 0; }
/* * It is a function that performs Miller Rabin Primality test * input: number(mpz_t) to be tested and number of iterations(int) to run the test * output: int 1 and 0 which represents pass and fail the test respectively */ int Miller(mpz_t p, int iterations){ mpz_t a; mpz_init(a); mpz_t p4; mpz_init(p4); mpz_sub_ui(p4, p, 4); mpz_t p1; mpz_init(p1); mpz_sub_ui(p1, p, 1); mpz_t x; mpz_init(x); mpz_t m; mpz_init_set_str(m, "1", 10); mpz_t val; mpz_init(val); gmp_randstate_t state; srand(time(NULL)); int seed = rand(); gmp_randinit_default (state); gmp_randseed_ui(state, seed); //find t and m int check = 0; int t = 1; while(check != 1){ mpz_ui_pow_ui(val, 2, t); mpz_cdiv_r(m,p1,val); if(mpz_cmp_ui(m,0) == 0){ mpz_cdiv_q(m,p1,val); check = 1; } else{ t++; } } //step 1 mpz_urandomb(a,state,64); mpz_mod(a, a, p4); mpz_add_ui(a, a, 2); //base must not be bigger than p - 2 //gmp_printf("a = %Zd\n", a); //step 2 mpz_powm(x, a, m, p); //gmp_printf("x = %Zd\n", x); if(mpz_cmp_ui(x, 1) == 0 || mpz_cmp(x, p1) == 0) return 1; else if(t == 1) return 0; int j = 1; //step 3 & 4 int capture; do { printf("what is t, %d\n", t); capture = step3(j,m,x,a,p,p1); printf("capture = %d\n", capture); if(capture == 0) return 0; else if(capture == 1) return 1; else{ j = capture; printf("here when j = %d\n", j); } }while(j < (t-1)); //step 5 capture = step3(j+1, m, x, a, p, p1); if(capture == 1) return 1; else return 0; }
/*-----------------------------------------------------------------------------*/ void build_tree(tree_t tree) { mpz_t M_tmp; mpz_init(M_tmp); /* si on est appelé et que l'on a le droit à aucune addition, */ /* cela signifie que l'on a déjà trouvé une solution directe */ /* par ailleurs: on rend la main et disant qu'on n'a pas trouvé. */ if(mpz_cmp_ui(tree->max_add, 0) <= 0) { mpz_set_si(tree->max_add,-1); return; } if(!mpz_cmp_ui(tree->M_red, 1)) { mpz_set_ui(tree->max_add,0); } else { char *bin; int len; int k; tree_t node; /* M = M'+1 */ mpz_sub_ui(M_tmp, tree->M_red, 1); tree->node[0] = create_node(M_tmp); mpz_sub_ui(tree->node[0]->max_add, tree->max_add, 1); mpz_set_si(tree->max_add, -1); build_tree(tree->node[0]); if(mpz_cmp_si(tree->node[0]->max_add, -1) != 0) { mpz_set(tree->max_add, tree->node[0]->max_add); mpz_add_ui(tree->max_add, tree->max_add, 1); } /* M = M'-1 */ mpz_add_ui(M_tmp, tree->M_red, 1); tree->node[1] = create_node(M_tmp); mpz_sub_ui(tree->node[1]->max_add, tree->max_add, 1); build_tree(tree->node[1]); if(mpz_cmp_si(tree->node[1]->max_add, -1) != 0) { mpz_set(tree->max_add, tree->node[1]->max_add); mpz_add_ui(tree->max_add, tree->max_add, 1); } bin = mpz_get_str(NULL, 2, tree->M_red); len = strlen(bin); free(bin); /* M = (2^k+1)M' */ tree->node[2] = NULL; for(k=len-1;k>0;k--) { mpz_set_ui(M_tmp, 1); mpz_mul_2exp(M_tmp, M_tmp, k); mpz_add_ui(M_tmp, M_tmp, 1); if(mpz_divisible_p(tree->M_red, M_tmp)) { mpz_cdiv_q(M_tmp, tree->M_red, M_tmp); node = create_node(M_tmp); mpz_sub_ui(node->max_add, tree->max_add, 1); build_tree(node); if(mpz_cmp_si(node->max_add, -1) != 0) { destroy_node(tree->node[2]); tree->node[2] = node; tree->k = k; mpz_set(tree->max_add, tree->node[2]->max_add); mpz_add_ui(tree->max_add, tree->max_add, 1); } else destroy_node(node); } } /* M = (2^k-1)M' */ tree->node[3] = NULL; for(k=len-1;k>0;k--) { mpz_set_ui(M_tmp, 1); mpz_mul_2exp(M_tmp, M_tmp, k); mpz_sub_ui(M_tmp, M_tmp, 1); if(mpz_divisible_p(tree->M_red, M_tmp)) { mpz_cdiv_q(M_tmp, tree->M_red, M_tmp); node = create_node(M_tmp); mpz_sub_ui(node->max_add, tree->max_add, 1); build_tree(node); if(mpz_cmp_si(node->max_add, -1) != 0) { destroy_node(tree->node[3]); tree->node[3] = node; tree->k = k; mpz_set(tree->max_add, tree->node[3]->max_add); mpz_add_ui(tree->max_add, tree->max_add, 1); } else destroy_node(node); } } } mpz_clear(M_tmp); }
int scanhash_m7m_hash(int thr_id, uint32_t *pdata, const uint32_t *ptarget, uint64_t max_nonce, unsigned long *hashes_done) { uint32_t data[32] __attribute__((aligned(128))); uint32_t *data_p64 = data + (M7_MIDSTATE_LEN / sizeof(data[0])); uint32_t hash[8] __attribute__((aligned(32))); uint8_t bhash[7][64] __attribute__((aligned(32))); uint32_t n = pdata[19] - 1; const uint32_t first_nonce = pdata[19]; char data_str[161], hash_str[65], target_str[65]; uint8_t *bdata = 0; mpz_t bns[8]; int rc = 0; int bytes, nnNonce2; mpz_t product; mpz_init(product); for(int i=0; i < 8; i++){ mpz_init(bns[i]); } memcpy(data, pdata, 80); sph_sha256_context ctx_final_sha256; sph_sha256_context ctx_sha256; sph_sha512_context ctx_sha512; sph_keccak512_context ctx_keccak; sph_whirlpool_context ctx_whirlpool; sph_haval256_5_context ctx_haval; sph_tiger_context ctx_tiger; sph_ripemd160_context ctx_ripemd; sph_sha256_init(&ctx_sha256); sph_sha256 (&ctx_sha256, data, M7_MIDSTATE_LEN); sph_sha512_init(&ctx_sha512); sph_sha512 (&ctx_sha512, data, M7_MIDSTATE_LEN); sph_keccak512_init(&ctx_keccak); sph_keccak512 (&ctx_keccak, data, M7_MIDSTATE_LEN); sph_whirlpool_init(&ctx_whirlpool); sph_whirlpool (&ctx_whirlpool, data, M7_MIDSTATE_LEN); sph_haval256_5_init(&ctx_haval); sph_haval256_5 (&ctx_haval, data, M7_MIDSTATE_LEN); sph_tiger_init(&ctx_tiger); sph_tiger (&ctx_tiger, data, M7_MIDSTATE_LEN); sph_ripemd160_init(&ctx_ripemd); sph_ripemd160 (&ctx_ripemd, data, M7_MIDSTATE_LEN); sph_sha256_context ctx2_sha256; sph_sha512_context ctx2_sha512; sph_keccak512_context ctx2_keccak; sph_whirlpool_context ctx2_whirlpool; sph_haval256_5_context ctx2_haval; sph_tiger_context ctx2_tiger; sph_ripemd160_context ctx2_ripemd; do { data[19] = ++n; nnNonce2 = (int)(data[19]/2); memset(bhash, 0, 7 * 64); ctx2_sha256 = ctx_sha256; sph_sha256 (&ctx2_sha256, data_p64, 80 - M7_MIDSTATE_LEN); sph_sha256_close(&ctx2_sha256, (void*)(bhash[0])); ctx2_sha512 = ctx_sha512; sph_sha512 (&ctx2_sha512, data_p64, 80 - M7_MIDSTATE_LEN); sph_sha512_close(&ctx2_sha512, (void*)(bhash[1])); ctx2_keccak = ctx_keccak; sph_keccak512 (&ctx2_keccak, data_p64, 80 - M7_MIDSTATE_LEN); sph_keccak512_close(&ctx2_keccak, (void*)(bhash[2])); ctx2_whirlpool = ctx_whirlpool; sph_whirlpool (&ctx2_whirlpool, data_p64, 80 - M7_MIDSTATE_LEN); sph_whirlpool_close(&ctx2_whirlpool, (void*)(bhash[3])); ctx2_haval = ctx_haval; sph_haval256_5 (&ctx2_haval, data_p64, 80 - M7_MIDSTATE_LEN); sph_haval256_5_close(&ctx2_haval, (void*)(bhash[4])); ctx2_tiger = ctx_tiger; sph_tiger (&ctx2_tiger, data_p64, 80 - M7_MIDSTATE_LEN); sph_tiger_close(&ctx2_tiger, (void*)(bhash[5])); ctx2_ripemd = ctx_ripemd; sph_ripemd160 (&ctx2_ripemd, data_p64, 80 - M7_MIDSTATE_LEN); sph_ripemd160_close(&ctx2_ripemd, (void*)(bhash[6])); for(int i=0; i < 7; i++){ set_one_if_zero(bhash[i]); mpz_set_uint512(bns[i],bhash[i]); } mpz_set_ui(bns[7],0); for(int i=0; i < 7; i++){ mpz_add(bns[7], bns[7], bns[i]); } mpz_set_ui(product,1); for(int i=0; i < 8; i++){ mpz_mul(product,product,bns[i]); } mpz_pow_ui(product, product, 2); bytes = mpz_sizeinbase(product, 256); bdata = (uint8_t *)realloc(bdata, bytes); mpz_export((void *)bdata, NULL, -1, 1, 0, 0, product); sph_sha256_init(&ctx_final_sha256); sph_sha256 (&ctx_final_sha256, bdata, bytes); sph_sha256_close(&ctx_final_sha256, (void*)(hash)); int digits=(int)((sqrt((double)(nnNonce2))*(1.+EPS))/9000+75); int iterations=20; mpf_set_default_prec((long int)(digits*BITS_PER_DIGIT+16)); mpz_t magipi; mpz_t magisw; mpf_t magifpi; mpf_t mpa1, mpb1, mpt1, mpp1; mpf_t mpa2, mpb2, mpt2, mpp2; mpf_t mpsft; mpz_init(magipi); mpz_init(magisw); mpf_init(magifpi); mpf_init(mpsft); mpf_init(mpa1); mpf_init(mpb1); mpf_init(mpt1); mpf_init(mpp1); mpf_init(mpa2); mpf_init(mpb2); mpf_init(mpt2); mpf_init(mpp2); uint32_t usw_; usw_ = sw_(nnNonce2, SW_DIVS); if (usw_ < 1) usw_ = 1; mpz_set_ui(magisw, usw_); uint32_t mpzscale=mpz_size(magisw); for(int i=0; i < NM7M; i++){ if (mpzscale > 1000) { mpzscale = 1000; } else if (mpzscale < 1) { mpzscale = 1; } mpf_set_ui(mpa1, 1); mpf_set_ui(mpb1, 2); mpf_set_d(mpt1, 0.25*mpzscale); mpf_set_ui(mpp1, 1); mpf_sqrt(mpb1, mpb1); mpf_ui_div(mpb1, 1, mpb1); mpf_set_ui(mpsft, 10); for(int j=0; j <= iterations; j++){ mpf_add(mpa2, mpa1, mpb1); mpf_div_ui(mpa2, mpa2, 2); mpf_mul(mpb2, mpa1, mpb1); mpf_abs(mpb2, mpb2); mpf_sqrt(mpb2, mpb2); mpf_sub(mpt2, mpa1, mpa2); mpf_abs(mpt2, mpt2); mpf_sqrt(mpt2, mpt2); mpf_mul(mpt2, mpt2, mpp1); mpf_sub(mpt2, mpt1, mpt2); mpf_mul_ui(mpp2, mpp1, 2); mpf_swap(mpa1, mpa2); mpf_swap(mpb1, mpb2); mpf_swap(mpt1, mpt2); mpf_swap(mpp1, mpp2); } mpf_add(magifpi, mpa1, mpb1); mpf_pow_ui(magifpi, magifpi, 2); mpf_div_ui(magifpi, magifpi, 4); mpf_abs(mpt1, mpt1); mpf_div(magifpi, magifpi, mpt1); mpf_pow_ui(mpsft, mpsft, digits/2); mpf_mul(magifpi, magifpi, mpsft); mpz_set_f(magipi, magifpi); mpz_add(product,product,magipi); mpz_add(product,product,magisw); mpz_set_uint256(bns[0], (void*)(hash)); mpz_add(bns[7], bns[7], bns[0]); mpz_mul(product,product,bns[7]); mpz_cdiv_q (product, product, bns[0]); if (mpz_sgn(product) <= 0) mpz_set_ui(product,1); bytes = mpz_sizeinbase(product, 256); mpzscale=bytes; bdata = (uint8_t *)realloc(bdata, bytes); mpz_export(bdata, NULL, -1, 1, 0, 0, product); sph_sha256_init(&ctx_final_sha256); sph_sha256 (&ctx_final_sha256, bdata, bytes); sph_sha256_close(&ctx_final_sha256, (void*)(hash)); } mpz_clear(magipi); mpz_clear(magisw); mpf_clear(magifpi); mpf_clear(mpsft); mpf_clear(mpa1); mpf_clear(mpb1); mpf_clear(mpt1); mpf_clear(mpp1); mpf_clear(mpa2); mpf_clear(mpb2); mpf_clear(mpt2); mpf_clear(mpp2); rc = fulltest_m7hash(hash, ptarget); if (rc) { if (opt_debug) { bin2hex(hash_str, (unsigned char *)hash, 32); bin2hex(target_str, (unsigned char *)ptarget, 32); bin2hex(data_str, (unsigned char *)data, 80); applog(LOG_DEBUG, "DEBUG: [%d thread] Found share!\ndata %s\nhash %s\ntarget %s", thr_id, data_str, hash_str, target_str); } pdata[19] = data[19]; goto out; } } while (n < max_nonce && !work_restart[thr_id].restart); pdata[19] = n; out: for(int i=0; i < 8; i++){ mpz_clear(bns[i]); } mpz_clear(product); free(bdata); *hashes_done = n - first_nonce + 1; return rc; }
//#define SW_MAX 1000 void m7magi_hash(const char* input, char* output) { unsigned int nnNonce; uint32_t pdata[32]; memcpy(pdata, input, 80); // memcpy(&nnNonce, input+76, 4); int i, j, bytes, nnNonce2; nnNonce2 = (int)(pdata[19]/2); size_t sz = 80; uint8_t bhash[7][64]; uint32_t hash[8]; memset(bhash, 0, 7 * 64); sph_sha256_context ctx_final_sha256; sph_sha256_context ctx_sha256; sph_sha512_context ctx_sha512; sph_keccak512_context ctx_keccak; sph_whirlpool_context ctx_whirlpool; sph_haval256_5_context ctx_haval; sph_tiger_context ctx_tiger; sph_ripemd160_context ctx_ripemd; sph_sha256_init(&ctx_sha256); // ZSHA256; sph_sha256 (&ctx_sha256, input, sz); sph_sha256_close(&ctx_sha256, (void*)(bhash[0])); sph_sha512_init(&ctx_sha512); // ZSHA512; sph_sha512 (&ctx_sha512, input, sz); sph_sha512_close(&ctx_sha512, (void*)(bhash[1])); sph_keccak512_init(&ctx_keccak); // ZKECCAK; sph_keccak512 (&ctx_keccak, input, sz); sph_keccak512_close(&ctx_keccak, (void*)(bhash[2])); sph_whirlpool_init(&ctx_whirlpool); // ZWHIRLPOOL; sph_whirlpool (&ctx_whirlpool, input, sz); sph_whirlpool_close(&ctx_whirlpool, (void*)(bhash[3])); sph_haval256_5_init(&ctx_haval); // ZHAVAL; sph_haval256_5 (&ctx_haval, input, sz); sph_haval256_5_close(&ctx_haval, (void*)(bhash[4])); sph_tiger_init(&ctx_tiger); // ZTIGER; sph_tiger (&ctx_tiger, input, sz); sph_tiger_close(&ctx_tiger, (void*)(bhash[5])); sph_ripemd160_init(&ctx_ripemd); // ZRIPEMD; sph_ripemd160 (&ctx_ripemd, input, sz); sph_ripemd160_close(&ctx_ripemd, (void*)(bhash[6])); // printf("%s\n", hash[6].GetHex().c_str()); mpz_t bns[8]; for(i=0; i < 8; i++){ mpz_init(bns[i]); } //Take care of zeros and load gmp for(i=0; i < 7; i++){ set_one_if_zero(bhash[i]); mpz_set_uint512(bns[i],bhash[i]); } mpz_set_ui(bns[7],0); for(i=0; i < 7; i++) mpz_add(bns[7], bns[7], bns[i]); mpz_t product; mpz_init(product); mpz_set_ui(product,1); // mpz_pow_ui(bns[7], bns[7], 2); for(i=0; i < 8; i++){ mpz_mul(product,product,bns[i]); } mpz_pow_ui(product, product, 2); bytes = mpz_sizeinbase(product, 256); // printf("M7M data space: %iB\n", bytes); char *data = (char*)malloc(bytes); mpz_export(data, NULL, -1, 1, 0, 0, product); sph_sha256_init(&ctx_final_sha256); // ZSHA256; sph_sha256 (&ctx_final_sha256, data, bytes); sph_sha256_close(&ctx_final_sha256, (void*)(hash)); free(data); int digits=(int)((sqrt((double)(nnNonce2))*(1.+EPS))/9000+75); // int iterations=(int)((sqrt((double)(nnNonce2))+EPS)/500+350); // <= 500 // int digits=100; int iterations=20; // <= 500 mpf_set_default_prec((long int)(digits*BITS_PER_DIGIT+16)); mpz_t magipi; mpz_t magisw; mpf_t magifpi; mpf_t mpa1, mpb1, mpt1, mpp1; mpf_t mpa2, mpb2, mpt2, mpp2; mpf_t mpsft; mpz_init(magipi); mpz_init(magisw); mpf_init(magifpi); mpf_init(mpsft); mpf_init(mpa1); mpf_init(mpb1); mpf_init(mpt1); mpf_init(mpp1); mpf_init(mpa2); mpf_init(mpb2); mpf_init(mpt2); mpf_init(mpp2); uint32_t usw_; usw_ = sw_(nnNonce2, SW_DIVS); if (usw_ < 1) usw_ = 1; // if(fDebugMagi) printf("usw_: %d\n", usw_); mpz_set_ui(magisw, usw_); uint32_t mpzscale=mpz_size(magisw); for(i=0; i < NM7M; i++) { if (mpzscale > 1000) { mpzscale = 1000; } else if (mpzscale < 1) { mpzscale = 1; } // if(fDebugMagi) printf("mpzscale: %d\n", mpzscale); mpf_set_ui(mpa1, 1); mpf_set_ui(mpb1, 2); mpf_set_d(mpt1, 0.25*mpzscale); mpf_set_ui(mpp1, 1); mpf_sqrt(mpb1, mpb1); mpf_ui_div(mpb1, 1, mpb1); mpf_set_ui(mpsft, 10); for(j=0; j <= iterations; j++) { mpf_add(mpa2, mpa1, mpb1); mpf_div_ui(mpa2, mpa2, 2); mpf_mul(mpb2, mpa1, mpb1); mpf_abs(mpb2, mpb2); mpf_sqrt(mpb2, mpb2); mpf_sub(mpt2, mpa1, mpa2); mpf_abs(mpt2, mpt2); mpf_sqrt(mpt2, mpt2); mpf_mul(mpt2, mpt2, mpp1); mpf_sub(mpt2, mpt1, mpt2); mpf_mul_ui(mpp2, mpp1, 2); mpf_swap(mpa1, mpa2); mpf_swap(mpb1, mpb2); mpf_swap(mpt1, mpt2); mpf_swap(mpp1, mpp2); } mpf_add(magifpi, mpa1, mpb1); mpf_pow_ui(magifpi, magifpi, 2); mpf_div_ui(magifpi, magifpi, 4); mpf_abs(mpt1, mpt1); mpf_div(magifpi, magifpi, mpt1); // mpf_out_str(stdout, 10, digits+2, magifpi); mpf_pow_ui(mpsft, mpsft, digits/2); mpf_mul(magifpi, magifpi, mpsft); mpz_set_f(magipi, magifpi); //mpz_set_ui(magipi,1); mpz_add(product,product,magipi); mpz_add(product,product,magisw); mpz_set_uint256(bns[0], (void*)(hash)); mpz_add(bns[7], bns[7], bns[0]); mpz_mul(product,product,bns[7]); mpz_cdiv_q (product, product, bns[0]); if (mpz_sgn(product) <= 0) mpz_set_ui(product,1); bytes = mpz_sizeinbase(product, 256); mpzscale=bytes; // printf("M7M data space: %iB\n", bytes); char *bdata = (char*)malloc(bytes); mpz_export(bdata, NULL, -1, 1, 0, 0, product); sph_sha256_init(&ctx_final_sha256); // ZSHA256; sph_sha256 (&ctx_final_sha256, bdata, bytes); sph_sha256_close(&ctx_final_sha256, (void*)(hash)); free(bdata); } //Free the memory for(i=0; i < 8; i++){ mpz_clear(bns[i]); } // mpz_clear(dSpectralWeight); mpz_clear(product); mpz_clear(magipi); mpz_clear(magisw); mpf_clear(magifpi); mpf_clear(mpsft); mpf_clear(mpa1); mpf_clear(mpb1); mpf_clear(mpt1); mpf_clear(mpp1); mpf_clear(mpa2); mpf_clear(mpb2); mpf_clear(mpt2); mpf_clear(mpp2); memcpy(output, hash, 32); }
static int rsa_provable_prime (mpz_t p, unsigned *prime_seed_length, void *prime_seed, unsigned bits, unsigned seed_length, const void *seed, mpz_t e, void *progress_ctx, nettle_progress_func * progress) { mpz_t x, t, s, r1, r2, p0, sq; int ret; unsigned pcounter = 0; unsigned iterations; unsigned storage_length = 0, i; uint8_t *storage = NULL; uint8_t pseed[MAX_PVP_SEED_SIZE+1]; unsigned pseed_length = sizeof(pseed), tseed_length; unsigned max = bits*5; mpz_init(p0); mpz_init(sq); mpz_init(x); mpz_init(t); mpz_init(s); mpz_init(r1); mpz_init(r2); /* p1 = p2 = 1 */ ret = st_provable_prime(p0, &pseed_length, pseed, NULL, 1+div_ceil(bits,2), seed_length, seed, progress_ctx, progress); if (ret == 0) { goto cleanup; } iterations = div_ceil(bits, DIGEST_SIZE*8); mpz_set_ui(x, 0); if (iterations > 0) { storage_length = iterations * DIGEST_SIZE; storage = malloc(storage_length); if (storage == NULL) { goto fail; } nettle_mpz_set_str_256_u(s, pseed_length, pseed); for (i = 0; i < iterations; i++) { tseed_length = mpz_seed_sizeinbase_256_u(s, pseed_length); if (tseed_length > sizeof(pseed)) goto fail; nettle_mpz_get_str_256(tseed_length, pseed, s); hash(&storage[(iterations - i - 1) * DIGEST_SIZE], tseed_length, pseed); mpz_add_ui(s, s, 1); } nettle_mpz_set_str_256_u(x, storage_length, storage); } /* x = sqrt(2)*2^(bits-1) + (x mod 2^(bits) - sqrt(2)*2(bits-1)) */ /* sq = sqrt(2)*2^(bits-1) */ mpz_set_ui(r1, 1); mpz_mul_2exp(r1, r1, 2*bits-1); mpz_sqrt(sq, r1); /* r2 = 2^bits - sq */ mpz_set_ui(r2, 1); mpz_mul_2exp(r2, r2, bits); mpz_sub(r2, r2, sq); /* x = sqrt(2)*2^(bits-1) + (x mod (2^L - sqrt(2)*2^(bits-1)) */ mpz_mod(x, x, r2); mpz_add(x, x, sq); /* y = p2 = p1 = 1 */ /* r1 = (2 y p0 p1) */ mpz_mul_2exp(r1, p0, 1); /* r2 = 2 p0 p1 p2 (p2=y=1) */ mpz_set(r2, r1); /* r1 = (2 y p0 p1) + x */ mpz_add(r1, r1, x); /* t = ((2 y p0 p1) + x) / (2 p0 p1 p2) */ mpz_cdiv_q(t, r1, r2); retry: /* p = t p2 - y = t - 1 */ mpz_sub_ui(p, t, 1); /* p = 2(tp2-y)p0p1 */ mpz_mul(p, p, p0); mpz_mul_2exp(p, p, 1); /* p = 2(tp2-y)p0p1 + 1*/ mpz_add_ui(p, p, 1); mpz_set_ui(r2, 1); mpz_mul_2exp(r2, r2, bits); if (mpz_cmp(p, r2) > 0) { /* t = (2 y p0 p1) + sqrt(2)*2^(bits-1) / (2p0p1p2) */ mpz_set(r1, p0); /* r1 = (2 y p0 p1) */ mpz_mul_2exp(r1, r1, 1); /* sq = sqrt(2)*2^(bits-1) */ /* r1 = (2 y p0 p1) + sq */ mpz_add(r1, r1, sq); /* r2 = 2 p0 p1 p2 */ mpz_mul_2exp(r2, p0, 1); /* t = ((2 y p0 p1) + sq) / (2 p0 p1 p2) */ mpz_cdiv_q(t, r1, r2); } pcounter++; /* r2 = p - 1 */ mpz_sub_ui(r2, p, 1); /* r1 = GCD(p1, e) */ mpz_gcd(r1, e, r2); if (mpz_cmp_ui(r1, 1) == 0) { mpz_set_ui(x, 0); /* a = 0 */ if (iterations > 0) { for (i = 0; i < iterations; i++) { tseed_length = mpz_seed_sizeinbase_256_u(s, pseed_length); if (tseed_length > sizeof(pseed)) goto fail; nettle_mpz_get_str_256(tseed_length, pseed, s); hash(&storage[(iterations - i - 1) * DIGEST_SIZE], tseed_length, pseed); mpz_add_ui(s, s, 1); } nettle_mpz_set_str_256_u(x, storage_length, storage); } /* a = 2 + a mod p-3 */ mpz_sub_ui(r1, p, 3); /* p is too large to worry about negatives */ mpz_mod(x, x, r1); mpz_add_ui(x, x, 2); /* z = a^(2(tp2-y)p1) mod p */ /* r1 = (tp2-y) */ mpz_sub_ui(r1, t, 1); /* r1 = 2(tp2-y)p1 */ mpz_mul_2exp(r1, r1, 1); /* z = r2 = a^r1 mod p */ mpz_powm(r2, x, r1, p); mpz_sub_ui(r1, r2, 1); mpz_gcd(x, r1, p); if (mpz_cmp_ui(x, 1) == 0) { mpz_powm(r1, r2, p0, p); if (mpz_cmp_ui(r1, 1) == 0) { if (prime_seed_length != NULL) { tseed_length = mpz_seed_sizeinbase_256_u(s, pseed_length); if (tseed_length > sizeof(pseed)) goto fail; nettle_mpz_get_str_256(tseed_length, pseed, s); if (*prime_seed_length < tseed_length) { *prime_seed_length = tseed_length; goto fail; } *prime_seed_length = tseed_length; if (prime_seed != NULL) memcpy(prime_seed, pseed, tseed_length); } ret = 1; goto cleanup; } } } if (pcounter >= max) { goto fail; } mpz_add_ui(t, t, 1); goto retry; fail: ret = 0; cleanup: free(storage); mpz_clear(p0); mpz_clear(sq); mpz_clear(r1); mpz_clear(r2); mpz_clear(x); mpz_clear(t); mpz_clear(s); return ret; }
/* assuming slaves (workers)) are all homogenous, let them all do the calculations regarding primes sieving, calculating the smoothness base and the modular roots */ int main(int argc, char **argv) { MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); MPI_Comm_size(MPI_COMM_WORLD, &mpi_group_size); int len; MPI_Get_processor_name(processor_name, &len); gettimeofday(&start_global, NULL); print_lib_version(); mpz_init(N); mpz_t B; mpz_init(B); unsigned long int uBase; int64_t nb_primes; modular_root_t *modular_roots; uint64_t i, j; if (argc < 2) { PRINT(my_rank, "usage: %s Number_to_factorize\n", argv[0]); exit(2); } if (mpz_init_set_str(N, argv[1], 10) == -1) { PRINT(my_rank, "Cannot load N %s\n", argv[1]); exit(2); } mpz_t sqrtN, rem; mpz_init(sqrtN); mpz_init(rem); mpz_sqrtrem(sqrtN, rem, N); if (mpz_cmp_ui(rem, 0) != 0) /* if not perfect square, calculate the ceiling */ mpz_add_ui(sqrtN, sqrtN, 1); else /* N is a perfect square, factored! */ { PRINT(my_rank, "\n<<<[FACTOR]>>> %s\n", mpz_get_str(NULL, 10, sqrtN)); return 0; } if (mpz_probab_prime_p(N, 10) > 0) /* don't bother factoring */ { PRINT(my_rank, "N:%s is prime\n", mpz_get_str(NULL, 10, N)); exit(0); } OPEN_LOG_FILE("freq"); //-------------------------------------------------------- // calculate the smoothness base for the given N //-------------------------------------------------------- get_smoothness_base(B, N); /* if N is too small, the program will surely fail, please consider a pen and paper instead */ uBase = mpz_get_ui(B); PRINT(my_rank, "n: %s\tBase: %s\n", mpz_get_str(NULL, 10, N), mpz_get_str(NULL, 10, B)); //-------------------------------------------------------- // sieve primes that are less than the smoothness base using Eratosthenes sieve //-------------------------------------------------------- START_TIMER(); nb_primes = sieve_primes_up_to((int64_t) (uBase)); PRINT(my_rank, "\tPrimes found %" PRId64 " [Smoothness Base %lu]\n", nb_primes, uBase); STOP_TIMER_PRINT_TIME("\tEratosthenes Sieving done"); //-------------------------------------------------------- // fill the primes array with primes to which n is a quadratic residue //-------------------------------------------------------- START_TIMER(); primes = calloc(nb_primes, sizeof(int64_t)); nb_qr_primes = fill_primes_with_quadratic_residue(primes, N); /*for(i=0; i<nb_qr_primes; i++) PRINT(my_rank, "%" PRId64 "\n", primes[i]);*/ PRINT(my_rank, "\tN-Quadratic primes found %" PRId64 "\n", nb_qr_primes); STOP_TIMER_PRINT_TIME("\tQuadratic prime filtering done"); //-------------------------------------------------------- // calculate modular roots //-------------------------------------------------------- START_TIMER(); modular_roots = calloc(nb_qr_primes, sizeof(modular_root_t)); mpz_t tmp, r1, r2; mpz_init(tmp); mpz_init(r1); mpz_init(r2); for (i = 0; i < nb_qr_primes; i++) { mpz_set_ui(tmp, (unsigned long) primes[i]); mpz_sqrtm(r1, N, tmp); /* calculate the modular root */ mpz_neg(r2, r1); /* -q mod n */ mpz_mod(r2, r2, tmp); modular_roots[i].root1 = mpz_get_ui(r1); modular_roots[i].root2 = mpz_get_ui(r2); } mpz_clear(tmp); mpz_clear(r1); mpz_clear(r2); STOP_TIMER_PRINT_TIME("Modular roots calculation done"); //-------------------------------------------------------- // ***** initialize the matrix ***** //-------------------------------------------------------- if (my_rank == 0) /* only the master have the matrix */ { START_TIMER(); init_matrix(&matrix, nb_qr_primes + NB_VECTORS_OFFSET, nb_qr_primes); mpz_init2(tmp_matrix_row, nb_qr_primes); STOP_TIMER_PRINT_TIME("Matrix initialized"); } //-------------------------------------------------------- // [Sieving] - everyones sieves including the master //-------------------------------------------------------- START_TIMER(); mpz_t x, sieving_index, next_sieving_index, relative_start, global_step; unsigned long ui_index, SIEVING_STEP = 50000; /* we sieve for 50000 elements at each loop */ int LOCAL_SIEVING_ROUNDS = 10; /* number of iterations a worker sieves before communicating results to the master */ unsigned long sieving_round = 0; unsigned long nb_big_rounds = 0; uint64_t p_pow; smooth_number_t *x_squared; x_squared = calloc(SIEVING_STEP, sizeof(smooth_number_t)); if (my_rank == 0) smooth_numbers = calloc(nb_qr_primes + NB_VECTORS_OFFSET, sizeof(smooth_number_t)); else temp_slaves_smooth_numbers = calloc(500, sizeof(smooth_number_t)); /* TODO: this is not properly correct, using a linkedlist is better to keep track of temporary * smooth numbers at the slaves nodes however it's pretty rare to find 500 smooth numbers in * 50000 * 10 interval. */ mpz_init_set(x, sqrtN); mpz_init(global_step); mpz_init(relative_start); mpz_init(sieving_index); mpz_init(next_sieving_index); mpz_t p; mpz_init(p); mpz_t str; mpz_init_set(str, sieving_index); PRINT(my_rank, "\n[%s] Sieving ...\n", processor_name); //-------------------------------------------------------- // Init before sieving //-------------------------------------------------------- for (i = 0; i < SIEVING_STEP; i++) { mpz_init(x_squared[i].value_x); mpz_init(x_squared[i].value_x_squared); mpz_init2(x_squared[i].factors_vect, nb_qr_primes); mpz_add_ui(x, x, 1); } int nb_smooth_per_round = 0; char s[512]; //-------------------------------------------------------- // WHILE smooth numbers found less than the primes in the smooth base + NB_VECTORS_OFFSET for master // Or master asked for more smooth numbers from slaves //-------------------------------------------------------- while (1) { mpz_set_ui(global_step, nb_big_rounds); /* calculates the coordinate where the workers start sieving from */ mpz_mul_ui(global_step, global_step, (unsigned long) mpi_group_size); mpz_mul_ui(global_step, global_step, SIEVING_STEP); mpz_mul_ui(global_step, global_step, LOCAL_SIEVING_ROUNDS); mpz_add(global_step, global_step, sqrtN); mpz_set_ui(relative_start, SIEVING_STEP); mpz_mul_ui(relative_start, relative_start, LOCAL_SIEVING_ROUNDS); mpz_mul_ui(relative_start, relative_start, (unsigned long) my_rank); mpz_add(relative_start, relative_start, global_step); mpz_set(sieving_index, relative_start); mpz_set(next_sieving_index, relative_start); for (sieving_round = 0; sieving_round < LOCAL_SIEVING_ROUNDS; /* each slave sieves for LOCAL_SIEVING_ROUNDS rounds */ sieving_round++) { nb_smooth_per_round = 0; mpz_set(x, next_sieving_index); /* sieve numbers from sieving_index to sieving_index + sieving_step */ mpz_set(sieving_index, next_sieving_index); if (my_rank == 0) { printf("\r"); printf( "\t\tSieving at: %s30 <--> Smooth numbers found: %" PRId64 "/%" PRId64 "", mpz_get_str(NULL, 10, sieving_index), nb_global_smooth_numbers_found, nb_qr_primes); fflush(stdout); } for (i = 0; i < SIEVING_STEP; i++) { mpz_set(x_squared[i].value_x, x); mpz_pow_ui(x_squared[i].value_x_squared, x, 2); /* calculate value_x_squared <- x²-n */ mpz_sub(x_squared[i].value_x_squared, x_squared[i].value_x_squared, N); mpz_clear(x_squared[i].factors_vect); mpz_init2(x_squared[i].factors_vect, nb_qr_primes); /* reconstruct a new fresh 0ed vector of size nb_qr_primes bits */ mpz_add_ui(x, x, 1); } mpz_set(next_sieving_index, x); //-------------------------------------------------------- // eliminate factors in the x_squared array, those who are 'destructed' to 1 are smooth //-------------------------------------------------------- for (i = 0; i < nb_qr_primes; i++) { mpz_set_ui(p, (unsigned long) primes[i]); mpz_set(x, sieving_index); /* get the first multiple of p that is directly larger that sieving_index * Quadratic SIEVING: all elements from this number and in positions multiples of root1 and root2 * are also multiples of p */ get_sieving_start_index(x, x, p, modular_roots[i].root1); mpz_set(str, x); mpz_sub(x, x, sieving_index); /* x contains index of first number that is divisible by p */ for (j = mpz_get_ui(x); j < SIEVING_STEP; j += primes[i]) { p_pow = mpz_remove(x_squared[j].value_x_squared, x_squared[j].value_x_squared, p); /* eliminate all factors of p */ if (p_pow & 1) /* mark bit if odd power of p exists in this x_squared[j] */ { mpz_setbit(x_squared[j].factors_vect, i); } if (mpz_cmp_ui(x_squared[j].value_x_squared, 1) == 0) { save_smooth_number(x_squared[j]); nb_smooth_per_round++; } /* sieve next element located p steps from here */ } /* same goes for root2 */ if (modular_roots[i].root2 == modular_roots[i].root1) continue; mpz_set(x, sieving_index); get_sieving_start_index(x, x, p, modular_roots[i].root2); mpz_set(str, x); mpz_sub(x, x, sieving_index); for (j = mpz_get_ui(x); j < SIEVING_STEP; j += primes[i]) { p_pow = mpz_remove(x_squared[j].value_x_squared, x_squared[j].value_x_squared, p); if (p_pow & 1) { mpz_setbit(x_squared[j].factors_vect, i); } if (mpz_cmp_ui(x_squared[j].value_x_squared, 1) == 0) { save_smooth_number(x_squared[j]); nb_smooth_per_round++; } } } } if (my_rank == 0) /* master gathers smooth numbers from slaves */ { gather_smooth_numbers(); notify_slaves(); } else /* slaves send their smooth numbers to master */ { send_smooth_numbers_to_master(); nb_global_smooth_numbers_found = get_server_notification(); } if (nb_global_smooth_numbers_found >= nb_qr_primes + NB_VECTORS_OFFSET) break; nb_big_rounds++; } STOP_TIMER_PRINT_TIME("\nSieving DONE"); if (my_rank == 0) { uint64_t t = 0; //-------------------------------------------------------- //the matrix ready, start Gauss elimination. The Matrix is filled on the call of save_smooth_number() //-------------------------------------------------------- START_TIMER(); gauss_elimination(&matrix); STOP_TIMER_PRINT_TIME("\nGauss elimination done"); uint64_t row_index = nb_qr_primes + NB_VECTORS_OFFSET - 1; /* last row in the matrix */ int nb_linear_relations = 0; mpz_t linear_relation_z, solution_z; mpz_init(linear_relation_z); mpz_init(solution_z); get_matrix_row(linear_relation_z, &matrix, row_index--); /* get the last few rows in the Gauss eliminated matrix*/ while (mpz_cmp_ui(linear_relation_z, 0) == 0) { nb_linear_relations++; get_matrix_row(linear_relation_z, &matrix, row_index--); } PRINT(my_rank, "\tLinear dependent relations found : %d\n", nb_linear_relations); //-------------------------------------------------------- // Factor //-------------------------------------------------------- //We use the last linear relation to reconstruct our solution START_TIMER(); PRINT(my_rank, "%s", "\nFactorizing..\n"); mpz_t solution_X, solution_Y; mpz_init(solution_X); mpz_init(solution_Y); /* we start testing from the first linear relation encountered in the matrix */ for (j = nb_linear_relations; j > 0; j--) { PRINT(my_rank, "Trying %d..\n", nb_linear_relations - j + 1); mpz_set_ui(solution_X, 1); mpz_set_ui(solution_Y, 1); get_identity_row(solution_z, &matrix, nb_qr_primes + NB_VECTORS_OFFSET - j + 1); for (i = 0; i < nb_qr_primes; i++) { if (mpz_tstbit(solution_z, i)) { mpz_mul(solution_X, solution_X, smooth_numbers[i].value_x); mpz_mod(solution_X, solution_X, N); /* reduce x to modulo N */ mpz_mul(solution_Y, solution_Y, smooth_numbers[i].value_x_squared); /*TODO: handling huge stuff here, there is no modulo N like in the solution_X case! * eliminate squares as long as you go*/ } } mpz_sqrt(solution_Y, solution_Y); mpz_mod(solution_Y, solution_Y, N); /* y = sqrt(MUL(xi²-n)) mod N */ mpz_sub(solution_X, solution_X, solution_Y); mpz_gcd(solution_X, solution_X, N); if (mpz_cmp(solution_X, N) != 0 && mpz_cmp_ui(solution_X, 1) != 0) /* factor can be 1 or N, try another relation */ break; } mpz_cdiv_q(solution_Y, N, solution_X); PRINT(my_rank, "\n>>>>>>>>>>> FACTORED %s =\n", mpz_get_str(NULL, 10, N)); PRINT( my_rank, "\tFactor 1: %s \n\tFactor 2: %s", mpz_get_str(NULL, 10, solution_X), mpz_get_str(NULL, 10, solution_Y)); sprintf(s, "\n>>>>>>>>>>> FACTORED %s =\n", mpz_get_str(NULL, 10, N)); APPEND_TO_LOG_FILE(s); sprintf(s, "\tFactor 1: %s \n\tFactor 2: %s", mpz_get_str(NULL, 10, solution_X), mpz_get_str(NULL, 10, solution_Y)); APPEND_TO_LOG_FILE(s); gettimeofday(&end_global, NULL); timersub(&end_global, &start_global, &elapsed); sprintf(s, "****** TOTAL TIME: %.3f ms\n", elapsed.tv_sec * 1000 + elapsed.tv_usec / (double) 1000); APPEND_TO_LOG_FILE(s); STOP_TIMER_PRINT_TIME("\nFactorizing done"); } PRINT(my_rank, "%s", "\nCleaning memory..\n"); /********************** clear the x_squared array **********************/ for (i = 0; i < SIEVING_STEP; i++) { mpz_clear(x_squared[i].value_x); mpz_clear(x_squared[i].value_x_squared); //free(x_squared[i].factors_exp); mpz_clear(x_squared[i].factors_vect); } free(x_squared); /********************** clear the x_squared array **********************/ free(modular_roots); /********************** clear the smooth_numbers array **********************/ if (my_rank == 0) { for (i = 0; i < nb_qr_primes + NB_VECTORS_OFFSET; i++) { mpz_clear(smooth_numbers[i].value_x); mpz_clear(smooth_numbers[i].value_x_squared); mpz_clear(smooth_numbers[i].factors_vect); //free(smooth_numbers[i].factors_exp); } free(smooth_numbers); } else { for (i = 0; i < 500; i++) { mpz_clear(temp_slaves_smooth_numbers[i].value_x); mpz_clear(temp_slaves_smooth_numbers[i].value_x_squared); mpz_clear(temp_slaves_smooth_numbers[i].factors_vect); } free(temp_slaves_smooth_numbers); } /********************** clear the smooth_numbers array **********************/ free(primes); /********************** clear mpz _t **********************/mpz_clear(B); mpz_clear(N); sqrtN, rem; mpz_clear(x); mpz_clear(sieving_index); mpz_clear(next_sieving_index); mpz_clear(p); mpz_clear(str); /********************** clear mpz _t **********************/ free_matrix(&matrix); gettimeofday(&end_global, NULL); timersub(&end_global, &start_global, &elapsed); PRINT(my_rank, "****** TOTAL TIME: %.3f ms\n", elapsed.tv_sec * 1000 + elapsed.tv_usec / (double) 1000); show_mem_usage(); MPI_Finalize(); return 0; }
void BigNumberBase::setPrec(int32_t prec, PrecFlag flag) { if (prec == -1) { prec = Calc::PRECISE; } if (m_prec == prec) { return; } if (m_prec < prec) { GmpInt::TenExp(m_gmp->m_integer, (prec - m_prec)); m_prec = prec; return; } if (flag == BigNumberBase::HALF_ADJUST) { std::string result = toString(); if (result[result.size() - (m_prec - prec)] < '5') { setPrec(prec, BigNumberBase::ROUND_OFF); return; } if (BigNumberBase::Compare(*this, "0") == BigNumberCompare::BIG) { setPrec(prec, BigNumberBase::ROUND_UP); return; } setPrec(prec, BigNumberBase::ROUND_DOWN); return; } int32_t exp = m_prec - prec; char* szExp = (char*)malloc(exp + 2); memset(szExp, 48, exp + 1); szExp[exp + 1] = 0; szExp[0] = 49; mpz_t mpzExp; mpz_init_set_str(mpzExp, szExp, 10); switch (flag) { case BigNumberBase::ROUND_OFF: { mpz_tdiv_q(m_gmp->m_integer, m_gmp->m_integer, mpzExp); break; } case BigNumberBase::ROUND_UP: { mpz_cdiv_q(m_gmp->m_integer, m_gmp->m_integer, mpzExp); break; } case BigNumberBase::ROUND_DOWN: { mpz_fdiv_q(m_gmp->m_integer, m_gmp->m_integer, mpzExp); break; } default: break; } mpz_clear(mpzExp); ::free(szExp); m_prec = prec; }