static void JS_JW(int PK, int PL, int PM, int P) { int I, J, K; for (I = 0; I < PL; I++) { for (J = 0; J < PL; J++) { K = (I + J) % PK; /* MontgomeryMult(aiJS[I], aiJW[J], biTmp); */ /* AddBigNbrModN(aiJX[K], biTmp, aiJX[K], TestNbr, NumberLength); */ mpz_mul(biTmp, aiJS[I], aiJW[J]); mpz_add(aiJX[K], aiJX[K], biTmp); } } for (I = 0; I < PK; I++) { /* aiJS[I] = aiJX[I]; */ /* aiJX[I] = 0; */ mpz_swap(aiJS[I], aiJX[I]); mpz_set_ui(aiJX[I], 0); } NormalizeJS(PK, PL, PM, P); }
string bbs(int N) { mpz_t A, B, r, n, tmp; mpz_init(tmp); mpz_init(n); mpz_init(r); mpz_init(A); mpz_init(B); mpz_set_str(A, "32372334488362947019304797379371153325410700999", 10); mpz_set_str(B, "541528607341564832259551", 10); mpz_mul(n, A, B); mpz_set_ui(r, rand() % 100000 + 1); string res; while (N) { mpz_powm_ui(r, r, 2, n); mpz_mod_ui(tmp, r, 2); res += to_string(mpz_get_ui(tmp)); N--; } return res; }
void burns::get(mpz_t X, const vector<uint64>& x) const { mpz_t Mi; mpz_init(Mi); mpz_set_ui(X, 0); for(int i=0; i < size(); i++) { const monty& m = mb.field(i); // Mi = M / m_i mpz_divexact_ui(Mi, M, m.modulus()); uint64 y = m.get(m.mul(x[i], mrc[i])); // X += Mi y mpz_addmul_ui(X, Mi, y); } mpz_clear(Mi); // Reduce mod M mpz_mod(X, X, M); }
void fib_compute (mpz_t result, mpz_t term) { if (mpz_cmp_ui (term, 0) == 0) { mpz_set_ui (result, 0); return; } mpz_t a, b, c, d; mpz_init_set_ui (a, 1); mpz_init_set_ui (b, 1); mpz_init_set_ui (c, 1); mpz_init_set_ui (d, 0); fib_matrix_pow (a, b, c, d, term); mpz_set (result, b); mpz_clear (a); mpz_clear (b); mpz_clear (c); mpz_clear (d); }
void RSA::setKey(const char* p, const char* q) { boost::recursive_mutex::scoped_lock lockClass(rsaLock); mpz_set_str(m_p, p, 10); mpz_set_str(m_q, q, 10); // e = 65537 mpz_set_ui(m_e, 65537); // n = p * q mpz_mul(m_n, m_p, m_q); // TODO, since n is too small we won't be able to decode big numbers. //if(mpz_sizeinbase(m_n, 2) <= 1024){ // std::cout << " WARNING: 2^1023 < n < 2^1024 "; //} // d = e^-1 mod (p - 1)(q - 1) mpz_t p_1, q_1, pq_1; mpz_init2(p_1, 1024); mpz_init2(q_1, 1024); mpz_init2(pq_1, 1024); mpz_sub_ui(p_1, m_p, 1); mpz_sub_ui(q_1, m_q, 1); // pq_1 = (p -1)(q - 1) mpz_mul(pq_1, p_1, q_1); // m_d = m_e^-1 mod (p - 1)(q - 1) mpz_invert(m_d, m_e, pq_1); mpz_clear(p_1); mpz_clear(q_1); mpz_clear(pq_1); }
void make_chain_operands (mpz_t ref, mpz_t a, mpz_t b, gmp_randstate_t rs, int nb1, int nb2, int chain_len) { mpz_t bs, temp1, temp2; int j; mpz_inits (bs, temp1, temp2, NULL); /* Generate a division chain backwards, allowing otherwise unlikely huge quotients. */ mpz_set_ui (a, 0); mpz_urandomb (bs, rs, 32); mpz_urandomb (bs, rs, mpz_get_ui (bs) % nb1 + 1); mpz_rrandomb (b, rs, mpz_get_ui (bs)); mpz_add_ui (b, b, 1); mpz_set (ref, b); for (j = 0; j < chain_len; j++) { mpz_urandomb (bs, rs, 32); mpz_urandomb (bs, rs, mpz_get_ui (bs) % nb2 + 1); mpz_rrandomb (temp2, rs, mpz_get_ui (bs) + 1); mpz_add_ui (temp2, temp2, 1); mpz_mul (temp1, b, temp2); mpz_add (a, a, temp1); mpz_urandomb (bs, rs, 32); mpz_urandomb (bs, rs, mpz_get_ui (bs) % nb2 + 1); mpz_rrandomb (temp2, rs, mpz_get_ui (bs) + 1); mpz_add_ui (temp2, temp2, 1); mpz_mul (temp1, a, temp2); mpz_add (b, b, temp1); } mpz_clears (bs, temp1, temp2, NULL); }
/// @jakob: overflow can be occured due to multiplication. use exact mpz for multiply and modulo operation instead! void ARingGF::power(ElementType &result, const ElementType a, const STT n) const { if (givaroField.isnzero(a)) { mpz_t mpz_a; mpz_t mpz_n; mpz_t mpz_tmp; mpz_init( mpz_a); mpz_init( mpz_n); mpz_init( mpz_tmp); mpz_set_si (mpz_n,n); mpz_set_ui (mpz_a,a); //std::cerr << "a = " << a << std::endl; //std::cerr << "mpz_a = " << mpz_a << std::endl; //std::cerr << "n = " << n << std::endl; //std::cerr << "mpz_n = " << mpz_n << std::endl; mpz_fdiv_r_ui(mpz_tmp, mpz_n, givaroField.cardinality() -1) ; mpz_mul(mpz_n, mpz_a, mpz_tmp); STT tmp = static_cast< STT>(mpz_fdiv_ui( mpz_n, givaroField.cardinality() -1)) ; if ( tmp==0 ) { tmp+=givaroField.cardinality()-1; // result=givaroField.one; } //std::cerr << "tmp = " << tmp << std::endl; assert(tmp>=0); // tmp<0 should never occur if (tmp < 0) tmp += givaroField.cardinality()-1 ; result = tmp; } else { if (n<0) ERROR(" division by zero"); result = 0; } }
/* Map a projective jacobian point back to affine space @param P [in/out] The point to map @param modulus The modulus of the field the ECC curve is in @param mp The "b" value from montgomery_setup() @return 0 on success */ int ecc_map (ecc_point * P, mpz_t modulus) { mpz_t t1, t2; int err; if (P == NULL) return -1; if ((err = mp_init_multi (&t1, &t2, NULL)) != 0) { return -1; } mpz_mod (P->z, P->z, modulus); /* get 1/z */ mpz_invert (t1, P->z, modulus); /* get 1/z^2 and 1/z^3 */ mpz_mul (t2, t1, t1); mpz_mod (t2, t2, modulus); mpz_mul (t1, t1, t2); mpz_mod (t1, t1, modulus); /* multiply against x/y */ mpz_mul (P->x, P->x, t2); mpz_mod (P->x, P->x, modulus); mpz_mul (P->y, P->y, t1); mpz_mod (P->y, P->y, modulus); mpz_set_ui (P->z, 1); err = 0; mp_clear_multi (&t1, &t2, NULL); return err; }
static void check (long i, mpfr_rnd_t rnd) { mpfr_t f; mpz_t z; mpfr_exp_t e; int inex; /* using CHAR_BIT * sizeof(long) bits of precision ensures that mpfr_set_z_2exp is exact below */ mpfr_init2 (f, CHAR_BIT * sizeof(long)); mpz_init (z); mpz_set_ui (z, i); /* the following loop ensures that no overflow occurs */ do e = randexp (); while (e > mpfr_get_emax () - CHAR_BIT * sizeof(long)); inex = mpfr_set_z_2exp (f, z, e, rnd); if (inex != 0) { printf ("Error in mpfr_set_z_2exp for i=%ld, e=%ld," " wrong ternary value\n", i, (long) e); printf ("expected 0, got %d\n", inex); exit (1); } mpfr_div_2si (f, f, e, rnd); if (mpfr_get_si (f, MPFR_RNDZ) != i) { printf ("Error in mpfr_set_z_2exp for i=%ld e=%ld rnd_mode=%d\n", i, e, rnd); printf ("expected %ld\n", i); mpfr_printf ("got %Re\n", f); exit (1); } mpfr_clear (f); mpz_clear (z); }
mp_exp_t mpfr_get_z_exp (mpz_ptr z, mpfr_srcptr f) { mp_size_t fn; int sh; MPFR_ASSERTD (MPFR_IS_FP (f)); if (MPFR_UNLIKELY (MPFR_IS_ZERO (f))) { mpz_set_ui (z, 0); return __gmpfr_emin; } fn = MPFR_LIMB_SIZE(f); /* check whether allocated space for z is enough */ if (MPFR_UNLIKELY (ALLOC (z) < fn)) MPZ_REALLOC (z, fn); MPFR_UNSIGNED_MINUS_MODULO (sh, MPFR_PREC (f)); if (MPFR_LIKELY (sh)) mpn_rshift (PTR (z), MPFR_MANT (f), fn, sh); else MPN_COPY (PTR (z), MPFR_MANT (f), fn); SIZ(z) = MPFR_IS_NEG (f) ? -fn : fn; /* Test if the result is representable. Later, we could choose to return MPFR_EXP_MIN if it isn't, or perhaps MPFR_EXP_MAX to signal an error. The mantissa would still be meaningful. */ MPFR_ASSERTD ((mp_exp_unsigned_t) MPFR_GET_EXP (f) - MPFR_EXP_MIN >= (mp_exp_unsigned_t) MPFR_PREC(f)); return MPFR_GET_EXP (f) - MPFR_PREC (f); }
static int generator_parser_TUPLE(Generator *gen, char c) { GeneratorState *next, *state; if (c != ')') { next = generator_push(gen); next->rule = GENERATOR_PARSER_TYPE; return generator_parser_TYPE(gen, c); } state = generator_pop(gen); if (state->rule != GENERATOR_PARSER_TUPLE) { /* unit type "()" */ mpz_set_ui(state->seed, _GENERATOR_BASIC_N + 1); return generator_fold(gen); } /* fold decision to end TUPLE */ mpz_mul_ui(state->seed, state->seed, 2); /* fold each decision to continue TUPLE */ for (next = generator_pop(gen); next->rule == GENERATOR_PARSER_TUPLE; next = generator_pop(gen)) { generator_pi(gen, state->seed, state->seed, next->seed); mpz_mul_ui(state->seed, state->seed, 2); mpz_add_ui(state->seed, state->seed, 1); } /* fold decision to use TUPLE */ mpz_mul_ui(state->seed, state->seed, _GENERATOR_COMPOUND_N); mpz_add_ui(state->seed, state->seed, GENERATOR_COMPOUND_r); mpz_add_ui(next->seed, state->seed, _GENERATOR_BASIC_N + 2); return generator_fold(gen); }
void mpz_mat_randajtai(mpz_mat_t mat, ulong r, ulong c, double alpha) { ulong i, j, d, bits; mpz_t tmp; r = mat->r; c = mat->c; d = r; if (c != r) { printf("Exception: mpz_mat_ajtai called on an ill-formed matrix\n"); abort(); } mpz_init(tmp); for (i = 0; i < d; i++) { bits = (ulong) pow((double) (2*d - i), alpha); mpz_rrandomb(mat->entries[i*c + i], randstate, bits); mpz_add_ui(mat->entries[i*c + i], mat->entries[i*c + i], 2); mpz_fdiv_q_2exp(mat->entries[i*c + i], mat->entries[i*c + i], 1); for (j = i + 1; j < d; j++) { mpz_rrandomb(mat->entries[j*c + i], randstate, bits); if (z_randint(2)) mpz_neg(mat->entries[j*c + i], mat->entries[j*c + i]); mpz_set_ui(mat->entries[i*c + j], 0L); } } mpz_clear(tmp); }
void check_onebit (void) { int i; mpz_t z; double got, want; /* FIXME: It'd be better to base this on the float format. */ #ifdef __vax int limit = 127; /* vax fp numbers have limited range */ #else int limit = 512; #endif mpz_init (z); mpz_set_ui (z, 1L); want = 1.0; for (i = 0; i < limit; i++) { got = mpz_get_d (z); if (got != want) { printf ("mpz_get_d wrong on 2**%d\n", i); mpz_trace (" z ", z); printf (" want %.20g\n", want); printf (" got %.20g\n", got); abort(); } mpz_mul_2exp (z, z, 1L); want *= 2.0; } mpz_clear (z); }
// Compute trace of Frobenius at q^n given trace at q. // See p.105 of Blake, Seroussi and Smart. void pbc_mpz_trace_n(mpz_t res, mpz_t q, mpz_t trace, int n) { int i; mpz_t c0, c1, c2; mpz_t t0; mpz_init(c0); mpz_init(c1); mpz_init(c2); mpz_init(t0); mpz_set_ui(c2, 2); mpz_set(c1, trace); for (i=2; i<=n; i++) { mpz_mul(c0, trace, c1); mpz_mul(t0, q, c2); mpz_sub(c0, c0, t0); mpz_set(c2, c1); mpz_set(c1, c0); } mpz_set(res, c1); mpz_clear(t0); mpz_clear(c2); mpz_clear(c1); mpz_clear(c0); }
int main(int argc, char const* argv[]) { mpz_t facN; unsigned int n = 200000; clock_t start, end; double runtime; mpz_init(facN); mpz_set_ui(facN, 1L); start = clock(); factorial(&facN, n); end = clock(); //printf("fac %u is ", n); //mpz_out_str(stdout, 10, facN); //printf("\n"); runtime = (double)(end-start) / CLOCKS_PER_SEC; printf ("runtime is %f\n", runtime); mpz_clear(facN); return 0; }
int is_dual_palendrome(int n) { mpz_t m; char* s; unsigned int i; size_t j; int r; mpz_init(m); mpz_set_ui(m, n); s = mpz_get_str(NULL, 10, m); i = 0; j = strlen(s) - 1; r = 1; while(i <= j && r) { if (s[i++] != s[j--]) { r = 0; } } free(s); s = mpz_get_str(NULL, 2, m); i = 0; j = strlen(s) - 1; while(i <= j && r) { if (s[i++] != s[j--]) { r = 0; } } free(s); mpz_clear(m); return r; }
static void tate_3(element_ptr out, element_ptr P, element_ptr Q, element_ptr R) { mpz_t six; mpz_init(six); mpz_set_ui(six, 6); element_t QR; element_t e0; element_init(QR, P->field); element_init(e0, out->field); element_add(QR, Q, R); //for subgroup size 3, -2P = P, hence //the tangent line at P has divisor 3(P) - 3(O) miller(out, P, QR, R, 3); element_pow_mpz(out, out, six); element_clear(QR); element_clear(e0); mpz_clear(six); }
void make_headers(void) { headers = malloc(sizeof(header)*(LEVELS + 1)); 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); }
/* Helper function for ref_zn_array_pack(). Sets x = 2^k * (op[0] + op[1]*2^b + ... + op[n-1]*2^((n-1)*b)). Running time is soft-linear in output length. */ void ref_zn_array_pack_helper (mpz_t x, const ulong* op, size_t n, unsigned b, unsigned k) { ZNP_ASSERT (n >= 1); if (n == 1) { // base case mpz_set_ui (x, op[0]); mpz_mul_2exp (x, x, k); } else { // recursively split into top and bottom halves mpz_t y; mpz_init (y); ref_zn_array_pack_helper (x, op, n / 2, b, k); ref_zn_array_pack_helper (y, op + n / 2, n - n / 2, b, 0); mpz_mul_2exp (y, y, (n / 2) * b + k); mpz_add (x, x, y); mpz_clear (y); } }
void randpoly(mpz_poly_t pol, unsigned long length, unsigned long maxbits) { unsigned long bits; mpz_t temp; mpz_init(temp); mpz_poly_zero(pol); for (unsigned long i = 0; i < length; i++) { bits = maxbits; if (bits == 0) mpz_set_ui(temp,0); else { mpz_urandomb(temp, randstate, bits); #if SIGNS if (randint(2)) mpz_neg(temp,temp); #endif } mpz_poly_set_coeff(pol, i, temp); } mpz_clear(temp); }
int mpfr_get_z (mpz_ptr z, mpfr_srcptr f, mpfr_rnd_t rnd) { int inex; mpfr_t r; mpfr_exp_t exp; if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (f))) { if (MPFR_UNLIKELY (MPFR_NOTZERO (f))) MPFR_SET_ERANGEFLAG (); mpz_set_ui (z, 0); /* The ternary value is 0 even for infinity. Giving the rounding direction in this case would not make much sense anyway, and the direction would not necessarily match rnd. */ return 0; } exp = MPFR_GET_EXP (f); /* if exp <= 0, then |f|<1, thus |o(f)|<=1 */ MPFR_ASSERTN (exp < 0 || exp <= MPFR_PREC_MAX); mpfr_init2 (r, (exp < (mpfr_exp_t) MPFR_PREC_MIN ? MPFR_PREC_MIN : (mpfr_prec_t) exp)); inex = mpfr_rint (r, f, rnd); MPFR_ASSERTN (inex != 1 && inex != -1); /* integral part of f is representable in r */ MPFR_ASSERTN (MPFR_IS_FP (r)); exp = mpfr_get_z_2exp (z, r); if (exp >= 0) mpz_mul_2exp (z, z, exp); else mpz_fdiv_q_2exp (z, z, -exp); mpfr_clear (r); return inex; }
// Finds smallest root greater than given lower bound. // Assumes there exists exactly one root with this property. // (Impossible to solve equations if roots have same integer part at // the moment. Don't do that.) // TODO: Rewrite so you choose if you want smaller or greater root. // or so it returns both solutions in an array. static void *newton(cf_t cf) { newton_data_ptr nd = cf_data(cf); abc_t p; abc_init(p); abc_set_coeff(p, nd->a); cf_t x = nd->x; mpz_t z, z0, z1, one, pow2, t0, t1, t2; mpz_init(z); mpz_init(z0); mpz_init(z1); mpz_init(pow2); mpz_init(t0); mpz_init(t1); mpz_init(t2); mpz_init(one); mpz_set_ui(one, 1); void move_right() { cf_get(z, x); mpz_mul(t0, z, p->b1); mpz_add(t0, t0, p->b0); mpz_set(p->b0, p->b1); mpz_set(p->b1, t0); mpz_mul(t0, z, p->a1); mpz_mul(t1, z, p->c1); mpz_add(t0, t0, p->a0); mpz_add(t1, t1, p->c0); mpz_set(p->a0, p->a1); mpz_set(p->c0, p->c1); mpz_set(p->a1, t0); mpz_set(p->c1, t1); }
void RSA::decrypt(char* msg, uint32 size) { mpz_t c,v1,v2,u2,tmp; mpz_init2(c, 1024); mpz_init2(v1, 1024); mpz_init2(v2, 1024); mpz_init2(u2, 1024); mpz_init2(tmp, 1024); mpz_import(c, size, 1, 1, 0, 0, msg); mpz_mod(tmp, c, m_p); mpz_powm(v1, tmp, m_dp, m_p); mpz_mod(tmp, c, m_q); mpz_powm(v2, tmp, m_dq, m_q); mpz_sub(u2, v2, v1); mpz_mul(tmp, u2, m_u); mpz_mod(u2, tmp, m_q); if(mpz_cmp_si(u2, 0) < 0){ mpz_add(tmp, u2, m_q); mpz_set(u2, tmp); } mpz_mul(tmp, u2, m_p); mpz_set_ui(c, 0); mpz_add(c, v1, tmp); size_t count = (mpz_sizeinbase(c, 2) + 7)/8; memset(msg, 0, size - count); mpz_export(&msg[size - count], NULL, 1, 1, 0, 0, c); mpz_clear(c); mpz_clear(v1); mpz_clear(v2); mpz_clear(u2); mpz_clear(tmp); }
int main() { /** Fm, where modulo = m */ mpz_t a, b, k, r, modulo; int i = 0; // loop variable Point p, next_p; p = init_point(p); mpz_init(a); mpz_init(b); mpz_init(k); mpz_init(r); // order mpz_init(modulo); /** Initialize parameters of ECC (F2p) */ mpz_set_str(a, a_v, 10); mpz_set_str(b, b_v, 16); mpz_set_str(modulo, p_v, 10); mpz_set_str(r, r_v, 10); mpz_set_str(p.x, gx_v, 16); mpz_set_str(p.y, gy_v, 16); mpz_t zero_value, k2; mpz_init(zero_value); mpz_init(k2); RDTSC_START(t1); sleep(1); // sleep for 1 second RDTSC_STOP(t2); uint64_t one_second = t2 - t1 - rdtscp_cycle; printf("Approximate number of cycles in 1 second: %lld\n\n", one_second); uint64_t one_us = one_second / 1e6; while (mpz_cmp(k, zero_value) == 0) { get_random(k, 32); // generate random test (256 bits) positive_modulo(k, k, modulo); } printf("Random k (in Binary): "); mpz_out_str(stdout, 2, k); printf("\n"); while (mpz_cmp(k2, zero_value) == 0) { get_random(k2, 32); // generate random test (256 bits) positive_modulo(k2, k2, modulo); } printf("Random k2 (in Binary): "); mpz_out_str(stdout, 2, k2); printf("\n"); /** Compare ADDITION, SHIFTING, MULTIPLICATION, and INVERSION */ if (TEST_MODULAR_OPERATION) { max_iteration = 10000; /** Addition */ i = 0; uint64_t total = 0; while (i < max_iteration) { RDTSC_START(t1); // start operation mpz_add(k, k, k2); positive_modulo(k, k, modulo); RDTSC_STOP(t2); // stop operation total += t2 - t1 - rdtscp_cycle; i++; } printf("--[ADDITION]--\n"); print_result(total, one_us); /** Shifting */ i = 0; uint64_t total2 = 0; mpz_t two; mpz_init(two); mpz_set_si(two, 2); while (i < max_iteration) { RDTSC_START(t1); // start operation mpz_mul_2exp(k, k, 1); // left shift positive_modulo(k, k, modulo); RDTSC_STOP(t2); // stop operation total2 += t2 - t1 - rdtscp_cycle; i++; } printf("--[SHIFTING 2 * k]--\n"); print_result(total2, one_us); /** Multiplication */ i = 0; uint64_t total3 = 0; while (i < max_iteration) { RDTSC_START(t1); // start operation mpz_mul(k, k, k2); positive_modulo(k, k, modulo); RDTSC_STOP(t2); // stop operation total3 += t2 - t1 - rdtscp_cycle; i++; } printf("--[MULTIPLICATION k * k2]--\n"); print_result(total3, one_us); /** Inversion */ i = 0; uint64_t total4 = 0; while (i < max_iteration) { RDTSC_START(t1); // start operation mpz_invert(k, k, modulo); RDTSC_STOP(t2); // stop operation total4 += t2 - t1 - rdtscp_cycle; i++; } printf("--[INVERSION]--\n"); print_result(total4, one_us); } /** -------------------------------------------------------------------------*/ // Convert Affine coordinate to Jacobian coordinate J_Point j_p, j_next_p; j_next_p = init_j_point(j_next_p); j_p = affine_to_jacobian(p); // Generator point if (TEST_SCALAR_OPERATION) { max_iteration = 100; Point p1, p2, p3; J_Point j_p1, j_p2, j_p3; /** Point preparation */ p1 = init_point(p1); p2 = init_point(p2); j_p1 = init_j_point(j_p1); j_p2 = init_j_point(j_p2); j_p1 = jacobian_affine_sliding_NAF(j_p, p, a, k, modulo, 4); j_p2 = jacobian_affine_sliding_NAF(j_p, p, a, k2, modulo, 4); p1 = jacobian_to_affine(j_p1, modulo); p2 = jacobian_to_affine(j_p2, modulo); /** Affine addition */ i = 0; uint64_t total = 0; while (i < max_iteration) { RDTSC_START(t1); // start operation p3 = affine_curve_addition(p1, p2, a, modulo); RDTSC_STOP(t2); // stop operation total += t2 - t1 - rdtscp_cycle; i++; } printf("--[ADDITION in AFFINE]--\n"); print_result(total, one_us); /** Affine doubling */ i = 0; uint64_t total2 = 0; while (i < max_iteration) { RDTSC_START(t1); // start operation p3 = affine_curve_doubling(p1, a, modulo); RDTSC_STOP(t2); // stop operation total2 += t2 - t1 - rdtscp_cycle; i++; } printf("--[DOUBLING in AFFINE]--\n"); print_result(total2, one_us); /** Jacobian addition */ i = 0; uint64_t total3 = 0; while (i < max_iteration) { RDTSC_START(t1); // start operation j_p3 = jacobian_curve_addition(j_p1, j_p2, a, modulo); RDTSC_STOP(t2); // stop operation total3 += t2 - t1 - rdtscp_cycle; i++; } printf("--[ADDITION in JACOBIAN]--\n"); print_result(total3, one_us); /** Jacobian doubling */ i = 0; uint64_t total4 = 0; while (i < max_iteration) { RDTSC_START(t1); // start operation j_p3 = jacobian_curve_doubling(j_p1, a, modulo); RDTSC_STOP(t2); // stop operation total4 += t2 - t1 - rdtscp_cycle; i++; } printf("--[DOUBLING in JACOBIAN]--\n"); print_result(total4, one_us); /** Affine-Jacobian addition */ i = 0; uint64_t total5 = 0; while (i < max_iteration) { RDTSC_START(t1); // start operation j_p3 = jacobian_affine_curve_addition(j_p1, p2, a, modulo); RDTSC_STOP(t2); // stop operation total5 += t2 - t1 - rdtscp_cycle; i++; } printf("--[ADDITION in JACOBIAN-AFFINE]--\n"); print_result(total5, one_us); } /** -------------------------------------------------------------------------*/ if (TEST_SCALAR_ALGORITHM) { max_iteration = 100; /** Test Left-to-right binary algorithm */ i = 0; uint64_t total = 0; while (i < max_iteration) { RDTSC_START(t1); // start operation next_p = affine_left_to_right_binary(p, a, k, modulo); // Q = [k]P // gmp_printf("%Zd %Zd\n", next_p.x, next_p.y); RDTSC_STOP(t2); // stop operation total += t2 - t1 - rdtscp_cycle; i++; } printf("--[AFFINE] Left to right binary algorithm--\n"); print_result(total, one_us); i = 0; uint64_t total2 = 0; while (i < max_iteration) { RDTSC_START(t1); // start operation j_next_p = jacobian_left_to_right_binary(j_p, a, k, modulo); // Q = [k]P // gmp_printf("%Zd %Zd\n", j_next_p.X, j_next_p.Y); next_p = jacobian_to_affine(j_next_p, modulo); // gmp_printf("%Zd %Zd\n", next_p.x, next_p.y); RDTSC_STOP(t2); // stop operation total2 += t2 - t1 - rdtscp_cycle; i++; } printf("--[JACOBIAN] Left to right binary algorithm--\n"); print_result(total2, one_us); i = 0; uint64_t total3 = 0; while (i < max_iteration) { RDTSC_START(t1); // start operation j_next_p = jacobian_affine_left_to_right_binary(j_p, p, a, k, modulo); // Q = [k]P // gmp_printf("%Zd %Zd\n", j_next_p.X, j_next_p.Y); next_p = jacobian_to_affine(j_next_p, modulo); // gmp_printf("%Zd %Zd\n", next_p.x, next_p.y); RDTSC_STOP(t2); // stop operation total3 += t2 - t1 - rdtscp_cycle; i++; } printf("--[JACOBIAN-AFFINE] Left to right binary algorithm--\n"); print_result(total3, one_us); int w = 4; // windows size i = 0; uint64_t total4 = 0; while (i < max_iteration) { RDTSC_START(t1); // start operation j_next_p = jacobian_affine_sliding_NAF(j_p, p, a, k, modulo, w); // Q = [k]P // gmp_printf("%Zd %Zd\n", j_next_p.X, j_next_p.Y); next_p = jacobian_to_affine(j_next_p, modulo); // gmp_printf("%Zd %Zd\n", next_p.x, next_p.y); RDTSC_STOP(t2); // stop operation total4 += t2 - t1 - rdtscp_cycle; i++; } printf("--[JACOBIAN-AFFINE] Sliding NAF Left to right binary algorithm (w = 4)--\n"); print_result(total4, one_us); w = 5; // windows size i = 0; uint64_t total5 = 0; while (i < max_iteration) { RDTSC_START(t1); // start operation j_next_p = jacobian_affine_sliding_NAF(j_p, p, a, k, modulo, w); // Q = [k]P // gmp_printf("%Zd %Zd\n", j_next_p.X, j_next_p.Y); next_p = jacobian_to_affine(j_next_p, modulo); // gmp_printf("%Zd %Zd\n", next_p.x, next_p.y); RDTSC_STOP(t2); // stop operation total5 += t2 - t1 - rdtscp_cycle; i++; } printf("--[JACOBIAN-AFFINE] Sliding NAF Left to right binary algorithm (w = 5)--\n"); print_result(total5, one_us); /** Test Right-to-left binary algorithm */ i = 0; uint64_t total6 = 0; while (i < max_iteration) { RDTSC_START(t1); // start operation next_p = affine_right_to_left_binary(p, a, k, modulo); // Q = [k]P // gmp_printf("%Zd %Zd\n", next_p.x, next_p.y); RDTSC_STOP(t2); // stop operation total6 += t2 - t1 - rdtscp_cycle; i++; } printf("--[AFFINE] Right to left binary algorithm--\n"); print_result(total6, one_us); /** Test Montgomery ladder algorithm (Against time-based attack) */ i = 0; uint64_t total7 = 0; while (i < max_iteration) { RDTSC_START(t1); // start operation j_next_p = jacobian_montgomery_ladder(j_p, a, k, modulo); // Q = [k]P // gmp_printf("%Zd %Zd\n", j_next_p.X, j_next_p.Y); next_p = jacobian_to_affine(j_next_p, modulo); // gmp_printf("%Zd %Zd\n", next_p.x, next_p.y); RDTSC_STOP(t2); // stop operation total7 += t2 - t1 - rdtscp_cycle; i++; } printf("--[JACOBIAN] Montgomery ladder algorithm--\n"); print_result(total7, one_us); } /** -------------------------------------------------------------------------*/ J_Point public_key_1, public_key_2, shared_key; mpz_t private_key_1, private_key_2; mpz_init(private_key_1); mpz_init(private_key_2); // TODO : Key should be padded to fixed size (serializable) // Note: (2^-256 chance of failure, can be ignored) while (mpz_cmp(private_key_1, zero_value) == 0) { get_random(private_key_1, 32); // 256 bit positive_modulo(private_key_1, private_key_1, modulo); } while (mpz_cmp(private_key_2, zero_value) == 0) { get_random(private_key_2, 32); // 256 bit positive_modulo(private_key_2, private_key_2, modulo); } gmp_printf("Private key [A B]: %Zd %Zd\n\n", private_key_1, private_key_2); public_key_1 = jacobian_left_to_right_binary(j_p, a, private_key_1, modulo); public_key_2 = jacobian_left_to_right_binary(j_p, a, private_key_2, modulo); gmp_printf("Public key 1 - Jacobian [X Y Z]: %Zd %Zd %Zd\n", public_key_1.X, public_key_1.Y, public_key_1.Z); gmp_printf("Public key 2 - Jacobian [X Y Z]: %Zd %Zd %Zd\n", public_key_2.X, public_key_2.Y, public_key_2.Z); Point public_key_1_decoded = jacobian_to_affine(public_key_1, modulo); Point public_key_2_decoded = jacobian_to_affine(public_key_2, modulo); gmp_printf("Public key 1 - Affine [X Y]: %Zd %Zd\n", public_key_1_decoded.x, public_key_1_decoded.y); gmp_printf("Public key 2 - Affine [X Y]: %Zd %Zd\n\n", public_key_2_decoded.x, public_key_2_decoded.y); /** -------------------------------------------------------------------------*/ if (TEST_ENCRYPT_DECRYPT) { // ElGamal Encrypt - Decrypt (Map message to chunk of points in EC) J_Point message, chosen_point, encoded_point, decoded_point; mpz_t k_message; mpz_init(k_message); mpz_set_ui(k_message, 123456789); message = jacobian_left_to_right_binary(j_p, a, k_message, modulo); Point message_decoded = jacobian_to_affine(message, modulo); gmp_printf("[Encrypt] Message - Affine [X Y] %Zd %Zd\n", message_decoded.x, message_decoded.y); gmp_printf("[Encrypt] Message - Jacobian [X Y Z]: %Zd %Zd %Zd\n", message.X, message.Y, message.Z); while (mpz_cmp(k_message, zero_value) == 0) { get_random(k_message, 32); positive_modulo(k_message, k_message, modulo); } // Encrypt example chosen_point = jacobian_left_to_right_binary(j_p, a, k_message, modulo); // chosen point (r) gmp_printf("[Encrypt] Chosen point - Jacobian [X Y Z]: %Zd %Zd %Zd\n", chosen_point.X, chosen_point.Y, chosen_point.Z); encoded_point = jacobian_left_to_right_binary(public_key_2, a, k_message, modulo); // r * Pu2 encoded_point = jacobian_curve_addition(message, encoded_point, a, modulo); // TODO : chosen_point & encoded_point should be padded to P-bit gmp_printf("[Decrypt] Encoded point - Jacobian [X Y Z]: %Zd %Zd %Zd\n", encoded_point.X, encoded_point.Y, encoded_point.Z); // Decrypt example (encoded_point - private_key * chosen_point) decoded_point = jacobian_left_to_right_binary(chosen_point, a, private_key_2, modulo); decoded_point = jacobian_curve_subtraction(encoded_point, decoded_point, a, modulo); gmp_printf("[Decrypt] Original message - Jacobian [X Y Z]: %Zd %Zd %Zd\n", decoded_point.X, decoded_point.Y, decoded_point.Z); message_decoded = jacobian_to_affine(decoded_point, modulo); gmp_printf("[Decrypt] Original message - Affine [X Y] %Zd %Zd\n\n", message_decoded.x, message_decoded.y); } /** -------------------------------------------------------------------------*/ if (TEST_SIMPLIFIED_ECIES) { // Simplified ECIES (Ref: Page 256 Cryptography Theory & Practice 2nd Ed. - Douglas) char* message_string = "hello"; // 0..9, a..z (base 36) mpz_t encrypted_message; mpz_init(encrypted_message); int partition = strlen(message_string) / 24; int partition_modulo = strlen(message_string) % 24; if (partition_modulo != 0) partition++; for (i = 0; i < partition; i++) { // 24 characters from message_string + 1 null-terminate char* chunked_message_string = (char*) malloc(25 * sizeof(char)); int size = 24; if ((i == partition - 1) && (partition_modulo != 0)) size = partition_modulo; strncpy(chunked_message_string, message_string + i*24, size); chunked_message_string[size] = '\0'; // null-terminate Point c_point = encrypt_ECIES(encrypted_message, chunked_message_string, public_key_2_decoded, p, a, modulo); gmp_printf("[SIMPLIFIED ECIES] Encrypted message: %Zd\n", encrypted_message); decrypt_ECIES(encrypted_message, c_point, private_key_2, p, a, modulo); } } /**-------------------------------------------------------------------------*/ // TODO : Public key validation! // Shared key (ECDH) - key secure exchange shared_key = jacobian_left_to_right_binary(public_key_2, a, private_key_1, modulo); gmp_printf("Shared key - Jacobian [X Y Z]: %Zd %Zd %Zd\n", shared_key.X, shared_key.Y, shared_key.Z); Point shared_key_decoded = jacobian_to_affine(shared_key, modulo); gmp_printf("Shared key - Affine [X Y]: %Zd %Zd\n", shared_key_decoded.x, shared_key_decoded.y); // TODO : ECDSA - digital signature algorithm /** Cleaning up */ mpz_clear(a); mpz_clear(b); mpz_clear(k); mpz_clear(r); mpz_clear(modulo); mpz_clear(private_key_1); mpz_clear(private_key_2); return EXIT_SUCCESS; }
int main(int argc, char **argv) { mpz_t min, rop, sievesize; unsigned long r; unsigned long loop_count = 0; FILE *fp = stdout; bool *sieve[128]; int *primes, *primes_start, *sieve_loc; size_t prime_size, loc_size; mpz_init(min); mpz_init(rop); mpz_init(sievesize); mpz_set_str(min, argv[1], 0); mpz_set_ui(sievesize, SIEVESIZE); r = mpz_fdiv_ui(min, PRIMORAL); r = (97 - r + PRIMORAL) % PRIMORAL; mpz_add_ui(rop, min, r); primes_start = (int *) primesieve_generate_primes(0, MAX_SIEVE_PRIME, &prime_size, INT_PRIMES); for (primes = primes_start; *primes <= 7; primes++); prime_size -= (primes - primes_start); //loc_size = 6 * prime_size; loc_size = 8 * prime_size; //padding sieve_loc = (int *) malloc(sizeof(int) * loc_size); struct timeval start_t; struct timeval end_t; gettimeofday(&start_t, NULL); #pragma omp parallel { mpz_t candidate_plus; mpz_init(candidate_plus); int tid = omp_get_thread_num(); sieve[tid] = (bool *) malloc(sizeof(bool) * SIEVESIZE); if(sieve[tid]==NULL) printf("%d nil\n", tid); memset(sieve[tid], true, SIEVESIZE); #pragma omp for schedule(static, 16) for (int i = 0; i < prime_size; i++) { //printf("%d:%d\n",tid,i); int p = primes[i]; int inv = modinv_i(PRIMORAL, p); for (int j = 0; j < 6; j++) { mpz_add_ui(candidate_plus, rop, offsets[j]); unsigned long cmodp = mpz_fdiv_ui(candidate_plus, p); int index = ((p - cmodp) * inv) % p; sieve_loc[i * 8 + j] = index; } } mpz_clear(candidate_plus); } gettimeofday(&end_t, NULL); float duration = (end_t.tv_sec - start_t.tv_sec) * 1E6 + (end_t.tv_usec - start_t.tv_usec); printf("running time:%f\n", duration); mpz_t tmp[4]; mpz_t candidate[4]; mpz_init(tmp[0]); mpz_init(tmp[1]); mpz_init(tmp[2]); mpz_init(tmp[3]); mpz_init(candidate[0]); mpz_init(candidate[1]); mpz_init(candidate[2]); mpz_init(candidate[3]); while (1) { //step 1 //printf("Sieving\n"); gettimeofday(&start_t, NULL); for (int i = 0; i < prime_size; i++) { //printf("thread %d:prime%d\n", tid, primes[i]); for (int j = 0; j < 6; j++) { //o = sieve_loc[sieve_loc_index]; unsigned int o = sieve_loc[8 * i + j]; while (o < SIEVESIZE) { sieve[0][o] = false; o += primes[i]; } sieve_loc[8 * i + j] = o - SIEVESIZE; } } /*for(int i=0;i<SIEVESIZE;i++) if(sieve[0][i]) printf("1\n"); else printf("0\n"); for(int i=0;i<prime_size;i++){ for(int j=0;j<6;j++) printf("%d:%d\n",primes[i], sieve_loc[8*i+j]); } break;*/ gettimeofday(&end_t, NULL); duration = (end_t.tv_sec - start_t.tv_sec) * 1E6 + (end_t.tv_usec - start_t.tv_usec); printf("running time1:%f\n", duration); gettimeofday(&start_t, NULL); #pragma omp parallel { int tid = omp_get_thread_num(); //int num = omp_get_num_threads(); /*#pragma omp for for (int i = 0; i < prime_size; i++) { //printf("thread %d:prime%d\n", tid, primes[i]); for (int j = 0; j < 6; j++) { //o = sieve_loc[sieve_loc_index]; unsigned int o = sieve_loc[8 * i + j]; while (o < SIEVESIZE) { sieve[tid][o] = false; o += primes[i]; } sieve_loc[8 * i + j] = o - SIEVESIZE; } }*/ //#pragma omp barrier #pragma omp for for (int i = 0; i < SIEVESIZE; i++) { /*bool flag = true; for (int j = 0; j < num; j++) { flag = flag && sieve[j][i]; sieve[j][i] = true; }*/ if (sieve[0][i]) { mpz_set_ui(tmp[tid], i); mpz_addmul_ui(tmp[tid], sievesize, loop_count); mpz_set(candidate[tid], rop); mpz_addmul_ui(candidate[tid], tmp[tid], PRIMORAL); if (is_fermat_valid(candidate[tid])) { mpz_out_str(fp, 16, candidate[tid]); exit(0); } } //printf("thread %d:i%d\n", tid, i); if(!sieve[0][i]) sieve[0][i] = true; } /*#pragma omp barrier #pragma omp for for (int i = 0; i < prime_size; i++) { for (int j = 0; j < 6; j++) sieve[tid][i*8+j]=true; }*/ } gettimeofday(&end_t, NULL); duration = (end_t.tv_sec - start_t.tv_sec) * 1E6 + (end_t.tv_usec - start_t.tv_usec); printf("running time2:%f\n", duration); loop_count++; } return 0; }
int main(int argc, char **argv) { FILE *fpairing, *ftag, *fdata, *fresult, *fplain, *fkey, *fcipher, *fpub; pairing_t pairing; paillier_pubkey_t *pub; paillier_prvkey_t *priv; element_t g, h, u, sig1, sig2, sig3, temp_pow, m, g1, g2; element_t public_key, tag, tag_prod; element_t secret_key; paillier_get_rand_t get_rand; paillier_ciphertext_t *cipher1, *cipher2; paillier_plaintext_t *plain1, *plain2; mpz_t pub_n, a, b, data2, nsquare; int count = 0, val=5; pairing_init_set_str(pairing, param_str); //mpz_init_set_str(data_sum, "0", 10); plain1 = (paillier_plaintext_t*) malloc(sizeof(paillier_plaintext_t)); plain2 = (paillier_plaintext_t*) malloc(sizeof(paillier_plaintext_t)); cipher1 = (paillier_ciphertext_t*) malloc(sizeof(paillier_ciphertext_t)); cipher2 = (paillier_ciphertext_t*) malloc(sizeof(paillier_ciphertext_t)); //pbc_demo_pairing_init(pairing, argc, argv); element_init_G1(g1, pairing); element_init_G1(g2, pairing); element_init_G2(g, pairing); element_init_G2(public_key, pairing); element_init_G1(u, pairing); element_init_G1(temp_pow, pairing); element_init_G2(public_key, pairing); element_init_G1(h, pairing); element_init_G1(m, pairing); element_init_G1(sig1, pairing); element_init_G1(sig2, pairing); element_init_G1(sig3, pairing); element_init_G1(tag, pairing); element_init_G1(tag_prod, pairing); element_init_Zr(secret_key, pairing); // mpz_init(pub_n); char *len; mpz_init(a); mpz_init(b); mpz_init(data2); printf("Short signature test\n"); len = (char *)malloc(2048*sizeof(char)); if((fpub = fopen("pub.txt", "r"))) { pub = (paillier_pubkey_t*) malloc(sizeof(paillier_pubkey_t)); priv = (paillier_prvkey_t*) malloc(sizeof(paillier_prvkey_t)); mpz_init(pub->n_squared); mpz_init(pub->n); fgets(len, 1000, fpub); mpz_init_set_str(pub->p, len, 10); fgets(len, 1000, fpub); mpz_init_set_str(pub->q, len, 10); fgets(len, 1000, fpub); mpz_init_set_str(pub->n_plusone, len, 10); //printf("value of nplusone : \n"); //mpz_out_str(stdout, 10, pub->n_plusone); paillier_keygen(&pub, &priv, get_rand, 0); pub->bits = mpz_sizeinbase(pub->n, 2); fclose(fpub); } //setting already known pairing parameters if((fpairing = fopen("pairing.txt", "r"))) { fgets(len, 1000, fpairing); //printf("\n %s\n", len); element_set_str(g, len, 10); //element_printf(" g = %B\n", g); fgets(len, 1000, fpairing); //printf("\n %s\n", len); element_set_str(u, len, 10); //element_printf("\n u= %B\n", u); fgets(len, 1000, fpairing); element_set_str(secret_key, len, 10); //element_printf(" secretkey %B\n",secret_key); fgets(len, 1000, fpairing); element_set_str(public_key, len, 10); //element_printf(" publickey %B\n", public_key); fgets(len, 1000, fpairing); element_set_str(h, len, 10); //element_printf(" \nh = %B\n", h); fgets(len, 1000, fpairing); mpz_init_set_str(pub_n, len, 10); //printf("\n n = "); //mpz_out_str(stdout, 10, pub_n); fclose(fpairing); } element_set1(tag_prod); ftag = fopen("./tag/output5.txt", "r"); fgets(len, 1000, ftag); element_set_str(g1, len, 10); element_printf("\ng1 = %B\n", g1); fclose(ftag); ftag = fopen("./tag/output6.txt", "r"); fgets(len, 1000, ftag); element_set_str(g2, len, 10); element_printf("\ng2 = %B\n", g2); fclose(ftag); fplain = fopen("./split/output5.txt", "r"); fgets(len, 1000, fplain); // printf("\nlen %s", len); mpz_set_str(a, len, 10); //element_printf("\na = %Zd\n", a); fclose(fplain); fplain = fopen("./split/output6.txt", "r"); fgets(len, 1000, fplain); mpz_set_str(b, len, 10); fcipher = fopen("./cipher/copy1/output5.txt", "r"); fgets(len, 1000, fcipher); mpz_init_set_str(cipher1->c, len, 10); fclose(fcipher); fcipher = fopen("./cipher/copy1/output6.txt", "r"); fgets(len, 1000, fcipher); mpz_init_set_str(cipher2->c, len, 10); fclose(fcipher); paillier_mul(pub, cipher2, cipher2, cipher1); plain1 = paillier_dec(plain1, pub, priv, cipher2); //tag mpz_t an; mpz_init(an); mpz_init(nsquare); // mpz_mul(an, a, pub_n); mpz_mul(nsquare, pub_n, pub_n); element_pow_mpz(temp_pow,u, plain1->m); element_mul(temp_pow, temp_pow, h); element_pow_zn(sig1, temp_pow, secret_key); element_printf("\n signature of plain = %B\n", sig1); //mpz_mul(an, b, pub_n); // mpz_mul(nsquare, pub_n, pub_n); element_pow_mpz(temp_pow,u, b); element_mul(temp_pow, temp_pow, h); element_pow_zn(sig2, temp_pow, secret_key); element_printf("\n signature of b = %B\n", sig2); //element_printf("\nb = %Zd\n", b); fclose(fplain); mpz_add(a, a, b); // mpz_mod(a, a, pub_n); // mpz_mul(a, a, pub_n); // mpz_mod(a, a, nsquare); count = 2; element_pow_mpz(temp_pow,u, a); mpz_set_ui(data2, count); // itoa(count, len, 10);+ //element_printf(" \nh = %B\n", h); element_pow_mpz(h, h, data2); element_mul(temp_pow, temp_pow, h); //element_printf("\n h. u^bN = %B\n", temp_pow); element_pow_zn(sig3, temp_pow, secret_key); element_printf("\n sig 3 %B\n", sig3); element_mul(g2, g2, g1); element_printf("\n Direct Product %B\n", g2); element_mul(sig2, sig1, sig2); element_printf("\n Direct Product %B\n", sig2); return 0; }
int main(void) { int result = 1; ulong i, j; mp_limb_t p; mpz_t i_m; printf("compute_primes...."); fflush(stdout); n_compute_primes(500UL); if (flint_num_primes < (500UL)) { printf("FAIL:\n"); printf("Not enough primes computed, flint_num_primes = %lu\n", flint_num_primes); abort(); } n_compute_primes(10000UL); if (flint_num_primes < (10000UL)) { printf("FAIL:\n"); printf("Not enough primes computed, flint_num_primes = %lu\n", flint_num_primes); abort(); } n_compute_primes(20000UL); if (flint_num_primes < (20000UL)) { printf("FAIL:\n"); printf("Not enough primes computed, flint_num_primes = %lu\n", flint_num_primes); abort(); } n_compute_primes(74000UL); if (flint_num_primes < (74000UL)) { printf("FAIL:\n"); printf("Not enough primes computed, flint_num_primes = %lu\n", flint_num_primes); abort(); } p = flint_primes[0]; j = 0; mpz_init(i_m); for (i = 0; i < flint_primes_cutoff; i++) /* Test that primes pass the test */ { mpz_set_ui(i_m, i); if (mpz_probab_prime_p(i_m, 20)) { result = (p == i); if (!result) { printf("FAIL:\n"); printf("%lu, %lu\n", i, p); abort(); } j++; if (j < flint_num_primes) p = flint_primes[j]; } } mpz_clear(i_m); printf("PASS\n"); return 0; }
void spectral_test (mpf_t rop[], unsigned int T, mpz_t a, mpz_t m) { /* Knuth "Seminumerical Algorithms, Third Edition", section 3.3.4 (pp. 101-103). */ /* v[t] = min { sqrt (x[1]^2 + ... + x[t]^2) | x[1] + a*x[2] + ... + pow (a, t-1) * x[t] is congruent to 0 (mod m) } */ /* Variables. */ unsigned int ui_t; unsigned int ui_i, ui_j, ui_k, ui_l; mpf_t f_tmp1, f_tmp2; mpz_t tmp1, tmp2, tmp3; mpz_t U[GMP_SPECT_MAXT][GMP_SPECT_MAXT], V[GMP_SPECT_MAXT][GMP_SPECT_MAXT], X[GMP_SPECT_MAXT], Y[GMP_SPECT_MAXT], Z[GMP_SPECT_MAXT]; mpz_t h, hp, r, s, p, pp, q, u, v; /* GMP inits. */ mpf_init (f_tmp1); mpf_init (f_tmp2); for (ui_i = 0; ui_i < GMP_SPECT_MAXT; ui_i++) { for (ui_j = 0; ui_j < GMP_SPECT_MAXT; ui_j++) { mpz_init_set_ui (U[ui_i][ui_j], 0); mpz_init_set_ui (V[ui_i][ui_j], 0); } mpz_init_set_ui (X[ui_i], 0); mpz_init_set_ui (Y[ui_i], 0); mpz_init (Z[ui_i]); } mpz_init (tmp1); mpz_init (tmp2); mpz_init (tmp3); mpz_init (h); mpz_init (hp); mpz_init (r); mpz_init (s); mpz_init (p); mpz_init (pp); mpz_init (q); mpz_init (u); mpz_init (v); /* Implementation inits. */ if (T > GMP_SPECT_MAXT) T = GMP_SPECT_MAXT; /* FIXME: Lazy. */ /* S1 [Initialize.] */ ui_t = 2 - 1; /* NOTE: `t' in description == ui_t + 1 for easy indexing */ mpz_set (h, a); mpz_set (hp, m); mpz_set_ui (p, 1); mpz_set_ui (pp, 0); mpz_set (r, a); mpz_pow_ui (s, a, 2); mpz_add_ui (s, s, 1); /* s = 1 + a^2 */ /* S2 [Euclidean step.] */ while (1) { if (g_debug > DEBUG_1) { mpz_mul (tmp1, h, pp); mpz_mul (tmp2, hp, p); mpz_sub (tmp1, tmp1, tmp2); if (mpz_cmpabs (m, tmp1)) { printf ("***BUG***: h*pp - hp*p = "); mpz_out_str (stdout, 10, tmp1); printf ("\n"); } } if (g_debug > DEBUG_2) { printf ("hp = "); mpz_out_str (stdout, 10, hp); printf ("\nh = "); mpz_out_str (stdout, 10, h); printf ("\n"); fflush (stdout); } if (mpz_sgn (h)) mpz_tdiv_q (q, hp, h); /* q = floor(hp/h) */ else mpz_set_ui (q, 1); if (g_debug > DEBUG_2) { printf ("q = "); mpz_out_str (stdout, 10, q); printf ("\n"); fflush (stdout); } mpz_mul (tmp1, q, h); mpz_sub (u, hp, tmp1); /* u = hp - q*h */ mpz_mul (tmp1, q, p); mpz_sub (v, pp, tmp1); /* v = pp - q*p */ mpz_pow_ui (tmp1, u, 2); mpz_pow_ui (tmp2, v, 2); mpz_add (tmp1, tmp1, tmp2); if (mpz_cmp (tmp1, s) < 0) { mpz_set (s, tmp1); /* s = u^2 + v^2 */ mpz_set (hp, h); /* hp = h */ mpz_set (h, u); /* h = u */ mpz_set (pp, p); /* pp = p */ mpz_set (p, v); /* p = v */ } else break; } /* S3 [Compute v2.] */ mpz_sub (u, u, h); mpz_sub (v, v, p); mpz_pow_ui (tmp1, u, 2); mpz_pow_ui (tmp2, v, 2); mpz_add (tmp1, tmp1, tmp2); if (mpz_cmp (tmp1, s) < 0) { mpz_set (s, tmp1); /* s = u^2 + v^2 */ mpz_set (hp, u); mpz_set (pp, v); } mpf_set_z (f_tmp1, s); mpf_sqrt (rop[ui_t - 1], f_tmp1); /* S4 [Advance t.] */ mpz_neg (U[0][0], h); mpz_set (U[0][1], p); mpz_neg (U[1][0], hp); mpz_set (U[1][1], pp); mpz_set (V[0][0], pp); mpz_set (V[0][1], hp); mpz_neg (V[1][0], p); mpz_neg (V[1][1], h); if (mpz_cmp_ui (pp, 0) > 0) { mpz_neg (V[0][0], V[0][0]); mpz_neg (V[0][1], V[0][1]); mpz_neg (V[1][0], V[1][0]); mpz_neg (V[1][1], V[1][1]); } while (ui_t + 1 != T) /* S4 loop */ { ui_t++; mpz_mul (r, a, r); mpz_mod (r, r, m); /* Add new row and column to U and V. They are initialized with all elements set to zero, so clearing is not necessary. */ mpz_neg (U[ui_t][0], r); /* U: First col in new row. */ mpz_set_ui (U[ui_t][ui_t], 1); /* U: Last col in new row. */ mpz_set (V[ui_t][ui_t], m); /* V: Last col in new row. */ /* "Finally, for 1 <= i < t, set q = round (vi1 * r / m), vit = vi1*r - q*m, and Ut=Ut+q*Ui */ for (ui_i = 0; ui_i < ui_t; ui_i++) { mpz_mul (tmp1, V[ui_i][0], r); /* tmp1=vi1*r */ zdiv_round (q, tmp1, m); /* q=round(vi1*r/m) */ mpz_mul (tmp2, q, m); /* tmp2=q*m */ mpz_sub (V[ui_i][ui_t], tmp1, tmp2); for (ui_j = 0; ui_j <= ui_t; ui_j++) /* U[t] = U[t] + q*U[i] */ { mpz_mul (tmp1, q, U[ui_i][ui_j]); /* tmp=q*uij */ mpz_add (U[ui_t][ui_j], U[ui_t][ui_j], tmp1); /* utj = utj + q*uij */ } } /* s = min (s, zdot (U[t], U[t]) */ vz_dot (tmp1, U[ui_t], U[ui_t], ui_t + 1); if (mpz_cmp (tmp1, s) < 0) mpz_set (s, tmp1); ui_k = ui_t; ui_j = 0; /* WARNING: ui_j no longer a temp. */ /* S5 [Transform.] */ if (g_debug > DEBUG_2) printf ("(t, k, j, q1, q2, ...)\n"); do { if (g_debug > DEBUG_2) printf ("(%u, %u, %u", ui_t + 1, ui_k + 1, ui_j + 1); for (ui_i = 0; ui_i <= ui_t; ui_i++) { if (ui_i != ui_j) { vz_dot (tmp1, V[ui_i], V[ui_j], ui_t + 1); /* tmp1=dot(Vi,Vj). */ mpz_abs (tmp2, tmp1); mpz_mul_ui (tmp2, tmp2, 2); /* tmp2 = 2*abs(dot(Vi,Vj) */ vz_dot (tmp3, V[ui_j], V[ui_j], ui_t + 1); /* tmp3=dot(Vj,Vj). */ if (mpz_cmp (tmp2, tmp3) > 0) { zdiv_round (q, tmp1, tmp3); /* q=round(Vi.Vj/Vj.Vj) */ if (g_debug > DEBUG_2) { printf (", "); mpz_out_str (stdout, 10, q); } for (ui_l = 0; ui_l <= ui_t; ui_l++) { mpz_mul (tmp1, q, V[ui_j][ui_l]); mpz_sub (V[ui_i][ui_l], V[ui_i][ui_l], tmp1); /* Vi=Vi-q*Vj */ mpz_mul (tmp1, q, U[ui_i][ui_l]); mpz_add (U[ui_j][ui_l], U[ui_j][ui_l], tmp1); /* Uj=Uj+q*Ui */ } vz_dot (tmp1, U[ui_j], U[ui_j], ui_t + 1); /* tmp1=dot(Uj,Uj) */ if (mpz_cmp (tmp1, s) < 0) /* s = min(s,dot(Uj,Uj)) */ mpz_set (s, tmp1); ui_k = ui_j; } else if (g_debug > DEBUG_2) printf (", #"); /* 2|Vi.Vj| <= Vj.Vj */ } else if (g_debug > DEBUG_2) printf (", *"); /* i == j */ } if (g_debug > DEBUG_2) printf (")\n"); /* S6 [Advance j.] */ if (ui_j == ui_t) ui_j = 0; else ui_j++; } while (ui_j != ui_k); /* S5 */ /* From Knuth p. 104: "The exhaustive search in steps S8-S10 reduces the value of s only rarely." */ #ifdef DO_SEARCH /* S7 [Prepare for search.] */ /* Find minimum in (x[1], ..., x[t]) satisfying condition x[k]^2 <= f(y[1], ...,y[t]) * dot(V[k],V[k]) */ ui_k = ui_t; if (g_debug > DEBUG_2) { printf ("searching..."); /*for (f = 0; f < ui_t*/ fflush (stdout); } /* Z[i] = floor (sqrt (floor (dot(V[i],V[i]) * s / m^2))); */ mpz_pow_ui (tmp1, m, 2); mpf_set_z (f_tmp1, tmp1); mpf_set_z (f_tmp2, s); mpf_div (f_tmp1, f_tmp2, f_tmp1); /* f_tmp1 = s/m^2 */ for (ui_i = 0; ui_i <= ui_t; ui_i++) { vz_dot (tmp1, V[ui_i], V[ui_i], ui_t + 1); mpf_set_z (f_tmp2, tmp1); mpf_mul (f_tmp2, f_tmp2, f_tmp1); f_floor (f_tmp2, f_tmp2); mpf_sqrt (f_tmp2, f_tmp2); mpz_set_f (Z[ui_i], f_tmp2); } /* S8 [Advance X[k].] */ do { if (g_debug > DEBUG_2) { printf ("X[%u] = ", ui_k); mpz_out_str (stdout, 10, X[ui_k]); printf ("\tZ[%u] = ", ui_k); mpz_out_str (stdout, 10, Z[ui_k]); printf ("\n"); fflush (stdout); } if (mpz_cmp (X[ui_k], Z[ui_k])) { mpz_add_ui (X[ui_k], X[ui_k], 1); for (ui_i = 0; ui_i <= ui_t; ui_i++) mpz_add (Y[ui_i], Y[ui_i], U[ui_k][ui_i]); /* S9 [Advance k.] */ while (++ui_k <= ui_t) { mpz_neg (X[ui_k], Z[ui_k]); mpz_mul_ui (tmp1, Z[ui_k], 2); for (ui_i = 0; ui_i <= ui_t; ui_i++) { mpz_mul (tmp2, tmp1, U[ui_k][ui_i]); mpz_sub (Y[ui_i], Y[ui_i], tmp2); } } vz_dot (tmp1, Y, Y, ui_t + 1); if (mpz_cmp (tmp1, s) < 0) mpz_set (s, tmp1); } } while (--ui_k); #endif /* DO_SEARCH */ mpf_set_z (f_tmp1, s); mpf_sqrt (rop[ui_t - 1], f_tmp1); #ifdef DO_SEARCH if (g_debug > DEBUG_2) printf ("done.\n"); #endif /* DO_SEARCH */ } /* S4 loop */ /* Clear GMP variables. */ mpf_clear (f_tmp1); mpf_clear (f_tmp2); for (ui_i = 0; ui_i < GMP_SPECT_MAXT; ui_i++) { for (ui_j = 0; ui_j < GMP_SPECT_MAXT; ui_j++) { mpz_clear (U[ui_i][ui_j]); mpz_clear (V[ui_i][ui_j]); } mpz_clear (X[ui_i]); mpz_clear (Y[ui_i]); mpz_clear (Z[ui_i]); } mpz_clear (tmp1); mpz_clear (tmp2); mpz_clear (tmp3); mpz_clear (h); mpz_clear (hp); mpz_clear (r); mpz_clear (s); mpz_clear (p); mpz_clear (pp); mpz_clear (q); mpz_clear (u); mpz_clear (v); return; }
int main (int argc, char **argv) { mpz_t op1, op2, ref; int i, j, chain_len; gmp_randstate_ptr rands; mpz_t bs; unsigned long bsi, size_range; int reps = 200; if (argc == 2) reps = atoi (argv[1]); tests_start (); rands = RANDS; check_data (); mpz_init (bs); mpz_init (op1); mpz_init (op2); mpz_init (ref); mpz_init (gcd1); mpz_init (gcd2); mpz_init (temp1); mpz_init (temp2); mpz_init (s); mpz_init (t); for (i = 0; i < reps; i++) { /* Generate plain operands with unknown gcd. These types of operands have proven to trigger certain bugs in development versions of the gcd code. The "hgcd->row[3].rsize > M" ASSERT is not triggered by the division chain code below, but that is most likely just a result of that other ASSERTs are triggered before it. */ mpz_urandomb (bs, rands, 32); size_range = mpz_get_ui (bs) % 13 + 2; mpz_urandomb (bs, rands, size_range); mpz_urandomb (op1, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE); mpz_urandomb (bs, rands, size_range); mpz_urandomb (op2, rands, mpz_get_ui (bs) + MIN_OPERAND_BITSIZE); mpz_urandomb (bs, rands, 2); bsi = mpz_get_ui (bs); if ((bsi & 1) != 0) mpz_neg (op1, op1); if ((bsi & 2) != 0) mpz_neg (op2, op2); one_test (op1, op2, NULL, i); /* Generate a division chain backwards, allowing otherwise unlikely huge quotients. */ mpz_set_ui (op1, 0); mpz_urandomb (bs, rands, 32); mpz_urandomb (bs, rands, mpz_get_ui (bs) % 16 + 1); mpz_rrandomb (op2, rands, mpz_get_ui (bs)); mpz_add_ui (op2, op2, 1); mpz_set (ref, op2); mpz_urandomb (bs, rands, 32); chain_len = mpz_get_ui (bs) % 50; for (j = 0; j < chain_len; j++) { mpz_urandomb (bs, rands, 32); mpz_urandomb (bs, rands, mpz_get_ui (bs) % 12 + 1); mpz_rrandomb (temp2, rands, mpz_get_ui (bs) + 1); mpz_add_ui (temp2, temp2, 1); mpz_mul (temp1, op2, temp2); mpz_add (op1, op1, temp1); /* Don't generate overly huge operands. */ if (SIZ (op1) > 400) break; mpz_urandomb (bs, rands, 32); mpz_urandomb (bs, rands, mpz_get_ui (bs) % 12 + 1); mpz_rrandomb (temp2, rands, mpz_get_ui (bs) + 1); mpz_add_ui (temp2, temp2, 1); mpz_mul (temp1, op1, temp2); mpz_add (op2, op2, temp1); /* Don't generate overly huge operands. */ if (SIZ (op2) > 400) break; } one_test (op1, op2, ref, i); } mpz_clear (bs); mpz_clear (op1); mpz_clear (op2); mpz_clear (ref); mpz_clear (gcd1); mpz_clear (gcd2); mpz_clear (temp1); mpz_clear (temp2); mpz_clear (s); mpz_clear (t); tests_end (); exit (0); }
void RSA::setEncryptKey(const char* mod) { mpz_set_ui(m_e, 65537); mpz_set_str(m_mod2, mod, 10); }