/* * 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); }
static PyObject * Pygmpy_c_mod(PyObject *self, PyObject *args) { PyObject *x, *y; PympzObject *r, *tempx, *tempy; if (PyTuple_GET_SIZE(args) != 2) { TYPE_ERROR("c_mod() requires 'mpz','mpz' arguments"); return NULL; } x = PyTuple_GET_ITEM(args, 0); y = PyTuple_GET_ITEM(args, 1); if (!(r = Pympz_new())) return NULL; if (CHECK_MPZANY(x) && CHECK_MPZANY(y)) { if(mpz_sgn(Pympz_AS_MPZ(y)) == 0) { ZERO_ERROR("c_mod() division by 0"); Py_DECREF((PyObject*)r); return NULL; } mpz_cdiv_r(r->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_mod() requires 'mpz','mpz' arguments"); Py_XDECREF((PyObject*)tempx); Py_XDECREF((PyObject*)tempy); Py_DECREF((PyObject*)r); return NULL; } if (mpz_sgn(Pympz_AS_MPZ(tempy)) == 0) { ZERO_ERROR("c_mod() division by 0"); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); Py_DECREF((PyObject*)r); return NULL; } mpz_cdiv_r(r->z, tempx->z, tempy->z); Py_DECREF((PyObject*)tempx); Py_DECREF((PyObject*)tempy); } return (PyObject*)r; }
static Variant HHVM_FUNCTION(gmp_div_r, 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_R, gmpDataA, dataA)) { return false; } if (!variantToGMPData(cs_GMP_FUNC_NAME_GMP_DIV_R, 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_R); return false; } mpz_init(gmpReturn); switch (round) { case GMP_ROUND_ZERO: mpz_tdiv_r(gmpReturn, gmpDataA, gmpDataB); break; case GMP_ROUND_PLUSINF: mpz_cdiv_r(gmpReturn, gmpDataA, gmpDataB); break; case GMP_ROUND_MINUSINF: mpz_fdiv_r(gmpReturn, gmpDataA, gmpDataB); break; default: mpz_clear(gmpDataA); mpz_clear(gmpDataB); mpz_clear(gmpReturn); return null_variant; } mpz_clear(gmpDataA); mpz_clear(gmpDataB); Variant ret; if (dataB.isInteger() && dataB.getInt64() >= 0) { ret = (int64_t)mpz_get_ui(gmpReturn); } else { ret = NEWOBJ(GMPResource)(gmpReturn); } mpz_clear(gmpReturn); return ret; }
/* * It is a function that to perform GCD for large numbers * input: mpz_t a, mpz_t b * output: mpz_t a */ void GCDlarge(mpz_t a, mpz_t b){ mpz_t c; mpz_t neg; mpz_init(c); mpz_init_set_str(neg, "-1", 10); while(mpz_cmp_ui(b,0) != 0){ mpz_cdiv_r(c, a, b); mpz_set(a, b); mpz_set(b, c); } if(mpz_cmp_ui(a, 0) < 0){ mpz_mul(a, a, neg); } }
int isPrime(const char *s) { mpz_t maxValue; mpz_t iterator; mpz_t maxIterator; mpz_t remainder; mpz_init_set_str(maxValue, s, 10); mpz_init(remainder); mpz_init(iterator); mpz_init(maxIterator); mpz_cdiv_q_ui(maxIterator, maxValue, 2); for (mpz_set_ui(iterator, 2); mpz_cmp(iterator, maxIterator) <= 0; mpz_add_ui(iterator, iterator, 1)) { mpz_cdiv_r(remainder, maxValue, iterator); if (mpz_cmp_ui(remainder, 0) == 0) return 0; } return 1; }
int isPrime(mpz_t n) { mpz_t iterator; mpz_t maxIterator; mpz_t remainder; if (mpz_cmp_ui(n, 1) <= 0) // negatives, zero, 1 : not prime return 0; if (mpz_cmp_ui(n, 2) == 0) // 2 : prime return 1; mpz_init(remainder); mpz_init(iterator); mpz_init(maxIterator); mpz_sqrt(maxIterator, n); mpz_add_ui(maxIterator, maxIterator, 1); // round up for (mpz_set_ui(iterator, 2); mpz_cmp(iterator, maxIterator) <= 0; mpz_add_ui(iterator, iterator, 1)) { mpz_cdiv_r(remainder, n, iterator); if (mpz_cmp_ui(remainder, 0) == 0) return 0; } return 1; }
/* * 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; }