static PyObject * GMPy_MPZ_Function_IsOdd(PyObject *self, PyObject *other) { int res; MPZ_Object *tempx; if (CHECK_MPZANY(other)) { res = mpz_odd_p(MPZ(other)); } else { if (!(tempx = GMPy_MPZ_From_Integer(other, NULL))) { TYPE_ERROR("is_odd() requires 'mpz' argument"); return NULL; } else { res = mpz_odd_p(tempx->z); Py_DECREF((PyObject*)tempx); } } if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; }
/* See Cohen 1.5.3 */ int modified_cornacchia(mpz_t x, mpz_t y, mpz_t D, mpz_t p) { int result = 0; mpz_t a, b, c, d; if (mpz_cmp_ui(p, 2) == 0) { mpz_add_ui(x, D, 8); if (mpz_perfect_square_p(x)) { mpz_sqrt(x, x); mpz_set_ui(y, 1); result = 1; } return result; } if (mpz_jacobi(D, p) == -1) /* No solution */ return 0; mpz_init(a); mpz_init(b); mpz_init(c); mpz_init(d); sqrtmod(x, D, p, a, b, c, d); if ( (mpz_even_p(D) && mpz_odd_p(x)) || (mpz_odd_p(D) && mpz_even_p(x)) ) mpz_sub(x, p, x); mpz_mul_ui(a, p, 2); mpz_set(b, x); mpz_sqrt(c, p); mpz_mul_ui(c, c, 2); /* Euclidean algorithm */ while (mpz_cmp(b, c) > 0) { mpz_set(d, a); mpz_set(a, b); mpz_mod(b, d, b); } mpz_mul_ui(c, p, 4); mpz_mul(a, b, b); mpz_sub(a, c, a); /* a = 4p - b^2 */ mpz_abs(d, D); /* d = |D| */ if (mpz_divisible_p(a, d)) { mpz_divexact(c, a, d); if (mpz_perfect_square_p(c)) { mpz_set(x, b); mpz_sqrt(y, c); result = 1; } } mpz_clear(a); mpz_clear(b); mpz_clear(c); mpz_clear(d); return result; }
/* Calculate r satisfying r*d == 1 mod 2^n. */ void mpz_invert_2exp (mpz_t r, mpz_t a, unsigned long n) { unsigned long i; mpz_t inv, prod; assert (mpz_odd_p (a)); mpz_init_set_ui (inv, 1L); mpz_init (prod); for (i = 1; i < n; i++) { mpz_mul (prod, inv, a); if (mpz_tstbit (prod, i) != 0) mpz_setbit (inv, i); } mpz_mul (prod, inv, a); mpz_tdiv_r_2exp (prod, prod, n); assert (mpz_cmp_ui (prod, 1L) == 0); mpz_set (r, inv); mpz_clear (inv); mpz_clear (prod); }
void mpfr_squaring_int_exp(mpfr_t R, mpfr_t x, mpz_t a) { if(mpz_cmp_ui(a, 0) < 0) { mpz_t b; mpz_init_set(b, a); mpz_neg(b, b); mpfr_squaring_int_exp(R, x, b); mpfr_ui_div(R, 1, R, MPFR_RNDN); } else { mpfr_t y; mpz_t n; mpfr_init_set(y, x, MPFR_RNDN); mpfr_set_ui(R, 1, MPFR_RNDN); mpz_init_set(n, a); while(mpz_cmp_ui(n, 0) > 0) { if(mpz_odd_p(n)) { mpfr_mul(R, R, y, MPFR_RNDN); mpz_sub_ui(n, n, 1); } mpfr_mul(y, y, y, MPFR_RNDN); mpz_div_ui(n, n, 2); } } }
static void zp_halve(element_ptr n, element_ptr a) { mpz_ptr z = a->data; if (mpz_odd_p(z)) { mpz_add(n->data, z, a->field->order); mpz_tdiv_q_2exp(n->data, n->data, 1); } else { mpz_tdiv_q_2exp(n->data, a->data, 1); } }
void gmp_halve(mpz_ptr value, mpz_ptr order) { if (mpz_odd_p(value)) { mpz_add(value, value, order); mpz_tdiv_q_2exp(value, value, 1); } else { mpz_tdiv_q_2exp(value, value, 1); } }
/* * \brief Encrypts/decrypts a message using the RSA algorithm. * * \param result a field to populate with the result of your RSA calculation. * \param message the message to perform RSA on. (probably a cert in this case) * \param e the encryption key from the key_file passed in through the * command-line arguments * \param n the modulus for RSA from the modulus_file passed in through * the command-line arguments * * Fill in this function with your proj0 solution or see staff solutions. */ static void perform_rsa(mpz_t result, mpz_t message, mpz_t e, mpz_t n) { int odd_num; mpz_set_str(result, "1", 10); odd_num = mpz_odd_p(e); while (mpz_cmp_ui(e, 0) > 0) { if (odd_num) { mpz_mul(result, result, message); mpz_mod(result, result, n); mpz_sub_ui(e, e, 1); } mpz_mul(message, message, message); mpz_mod(message, message, n); mpz_div_ui(e, e, 2); odd_num = mpz_odd_p(e); } }
static PyObject * GMPy_MPZ_Method_IsOdd(PyObject *self, PyObject *other) { int res; res = mpz_odd_p(MPZ(self)); if (res) Py_RETURN_TRUE; else Py_RETURN_FALSE; }
static int fp_sgn_odd(element_ptr a) { eptr ad = (eptr)a->data; if (!ad->flag) return 0; else { mpz_t z; mpz_init(z); int res; fp_to_mpz(z, a); res = mpz_odd_p(z) ? 1 : -1; mpz_clear(z); return res; } }
static PyObject * GMPy_MPZ_Method_Round(PyObject *self, PyObject *args) { Py_ssize_t round_digits; MPZ_Object *result; mpz_t temp, rem; if (PyTuple_GET_SIZE(args) == 0) { Py_INCREF(self); return self; } round_digits = ssize_t_From_Integer(PyTuple_GET_ITEM(args, 0)); if (round_digits == -1 && PyErr_Occurred()) { TYPE_ERROR("__round__() requires 'int' argument"); return NULL; } if (round_digits >= 0) { Py_INCREF(self); return self; } round_digits = -round_digits; if ((result = GMPy_MPZ_New(NULL))) { if (round_digits >= mpz_sizeinbase(MPZ(self), 10)) { mpz_set_ui(result->z, 0); } else { mpz_inoc(temp); mpz_inoc(rem); mpz_ui_pow_ui(temp, 10, round_digits); mpz_fdiv_qr(result->z, rem, MPZ(self), temp); mpz_mul_2exp(rem, rem, 1); if (mpz_cmp(rem, temp) > 0) { mpz_add_ui(result->z, result->z, 1); } else if (mpz_cmp(rem, temp) == 0) { if (mpz_odd_p(result->z)) { mpz_add_ui(result->z, result->z, 1); } } mpz_mul(result->z, result->z, temp); mpz_cloc(rem); mpz_cloc(temp); } } return (PyObject*)result; }
void field_init_fp(field_ptr f, mpz_t modulus) { if (mpz_fits_ulong_p(modulus)) { // If this case mattered, I'd have written a F_p implementation specialized // for moduli that fits into machine words. field_init_naive_fp(f, modulus); } else { if (mpz_odd_p(modulus)) { option_fpinit(f, modulus); } else { // montfp.c only supports odd moduli. field_init_faster_fp(f, modulus); } } }
void field_init_fast_fp(field_ptr f, mpz_t prime) { PBC_ASSERT(!mpz_fits_ulong_p(prime), "modulus too small"); fp_field_data_ptr p; field_init(f); f->init = fp_init; f->clear = fp_clear; f->set_si = fp_set_si; f->set_mpz = fp_set_mpz; f->out_str = fp_out_str; f->add = fp_add; f->sub = fp_sub; f->set = fp_set; f->mul = fp_mul; f->mul_si = fp_mul_si; f->square = fp_square; f->doub = fp_double; f->halve = fp_halve; f->pow_mpz = fp_pow_mpz; f->neg = fp_neg; f->cmp = fp_cmp; f->sign = mpz_odd_p(prime) ? fp_sgn_odd : fp_sgn_even; f->invert = fp_invert; f->random = fp_random; f->from_hash = fp_from_hash; f->is1 = fp_is1; f->is0 = fp_is0; f->set0 = fp_set0; f->set1 = fp_set1; f->is_sqr = fp_is_sqr; f->sqrt = element_tonelli; f->field_clear = fp_field_clear; f->to_bytes = fp_to_bytes; f->from_bytes = fp_from_bytes; f->to_mpz = fp_to_mpz; p = f->data = pbc_malloc(sizeof(fp_field_data_t)); p->limbs = mpz_size(prime); p->bytes = p->limbs * sizeof(mp_limb_t); p->primelimbs = pbc_malloc(p->bytes); mpz_export(p->primelimbs, &p->limbs, -1, sizeof(mp_limb_t), 0, 0, prime); mpz_set(f->order, prime); f->fixed_length_in_bytes = (mpz_sizeinbase(prime, 2) + 7) / 8; }
void field_init_naive_fp(field_ptr f, mpz_t prime) { field_init(f); f->init = zp_init; f->clear = zp_clear; f->set_si = zp_set_si; f->set_mpz = zp_set_mpz; f->out_str = zp_out_str; f->snprint = zp_snprint; f->set_str = zp_set_str; f->sign = mpz_odd_p(prime) ? zp_sgn_odd : zp_sgn_even; f->add = zp_add; f->sub = zp_sub; f->set = zp_set; f->square = zp_square; f->doub = zp_double; f->halve = zp_halve; f->mul = zp_mul; f->mul_mpz = zp_mul_mpz; f->mul_si = zp_mul_si; f->pow_mpz = zp_pow_mpz; f->neg = zp_neg; f->cmp = zp_cmp; f->invert = zp_invert; f->random = zp_random; f->from_hash = zp_from_hash; f->is1 = zp_is1; f->is0 = zp_is0; f->set0 = zp_set0; f->set1 = zp_set1; f->is_sqr = zp_is_sqr; f->sqrt = element_tonelli; f->field_clear = zp_field_clear; f->to_bytes = zp_to_bytes; f->from_bytes = zp_from_bytes; f->to_mpz = zp_to_mpz; f->out_info = zp_out_info; mpz_set(f->order, prime); f->data = NULL; f->fixed_length_in_bytes = (mpz_sizeinbase(prime, 2) + 7) / 8; }
void mpfr_naive_exp(mpfr_t R, mpfr_t x, mpz_t n) { assert(mpz_cmp_ui(n, 0) >= 0); mpfr_t z; mpfr_init_set(z, x, MPFR_RNDN); mpfr_div_z(z, z, n, MPFR_RNDN); mpfr_add_ui(z, z, 1, MPFR_RNDN); if(mpfr_cmp_ui(z, 0) > 0) mpfr_squaring_int_exp(R, z, n); else { mpfr_neg(z, z, MPFR_RNDN); mpfr_squaring_int_exp(R, z, n); if(mpz_odd_p(n)) mpfr_neg(R, R, MPFR_RNDN); } }
//------------------------------------------------------------------------------ // Name: is_odd //------------------------------------------------------------------------------ bool knumber_integer::is_odd() const { return mpz_odd_p(mpz_); }
int chpl_mpz_odd_p(const mpz_t op) { return mpz_odd_p(op); }
/* Add two ECC points @param P The point to add @param Q The point to add @param R [out] The destination of the double @param a Curve's a value @param modulus The modulus of the field the ECC curve is in @return GNUTLS_E_SUCCESS on success */ int ecc_projective_add_point (ecc_point * P, ecc_point * Q, ecc_point * R, mpz_t a, mpz_t modulus) { /* Using "(m)add-2004-hmv" algorithm * It costs 12M + 4S + half. */ mpz_t t1, t2, x, y, z; int err; if (P == NULL || Q == NULL || R == NULL || modulus == NULL) return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; /* check for neutral points */ if ( (err = ecc_projective_isneutral(Q, modulus)) == 0 ) { /* P + Q = P + neutral = P */ mpz_set (R->x, P->x); mpz_set (R->y, P->y); mpz_set (R->z, P->z); return GNUTLS_E_SUCCESS; } else if (err < 0) { return err; } if ( (err = ecc_projective_isneutral(P, modulus)) == 0 ) { /* P + Q = neutral + Q = Q */ mpz_set (R->x, Q->x); mpz_set (R->y, Q->y); mpz_set (R->z, Q->z); return GNUTLS_E_SUCCESS; } else if (err < 0) { return err; } if ((err = mp_init_multi (&t1, &t2, &x, &y, &z, NULL)) != 0) { return err; } /* Check if P == Q and do doubling in that case * If Q == -P then P + Q = neutral element */ if ((mpz_cmp (P->x, Q->x) == 0) && (mpz_cmp (P->z, Q->z) == 0)) { /* x and z coordinates match. Check if P->y = Q->y, or P->y = -Q->y */ if (mpz_cmp (P->y, Q->y) == 0) { mp_clear_multi (&t1, &t2, &x, &y, &z, NULL); return ecc_projective_dbl_point (P, R, a, modulus); } mpz_sub (t1, modulus, Q->y); if (mpz_cmp (P->y, t1) == 0) { mp_clear_multi (&t1, &t2, &x, &y, &z, NULL); mpz_set_ui(R->x, 1); mpz_set_ui(R->y, 1); mpz_set_ui(R->z, 0); return GNUTLS_E_SUCCESS; } } mpz_set (x, P->x); mpz_set (y, P->y); mpz_set (z, P->z); /* if Z is one then these are no-operations */ if (mpz_cmp_ui (Q->z, 1) != 0) { /* T1 = Z' * Z' */ mpz_mul (t1, Q->z, Q->z); mpz_mod (t1, t1, modulus); /* X = X * T1 */ mpz_mul (x, x, t1); mpz_mod (x, x, modulus); /* T1 = Z' * T1 */ mpz_mul (t1, t1, Q->z); mpz_mod (t1, t1, modulus); /* Y = Y * T1 */ mpz_mul (y, y, t1); mpz_mod (y, y, modulus); } /* T1 = Z*Z */ mpz_mul (t1, z, z); mpz_mod (t1, t1, modulus); /* T2 = X' * T1 */ mpz_mul (t2, t1, Q->x); mpz_mod (t2, t2, modulus); /* T1 = Z * T1 */ mpz_mul (t1, t1, z); mpz_mod (t1, t1, modulus); /* T1 = Y' * T1 */ mpz_mul (t1, t1, Q->y); mpz_mod (t1, t1, modulus); /* Y = Y - T1 */ mpz_sub (y, y, t1); if (mpz_cmp_ui (y, 0) < 0) { mpz_add (y, y, modulus); } /* T1 = 2T1 */ mpz_add (t1, t1, t1); if (mpz_cmp (t1, modulus) >= 0) { mpz_sub (t1, t1, modulus); } /* T1 = Y + T1 */ mpz_add (t1, t1, y); if (mpz_cmp (t1, modulus) >= 0) { mpz_sub (t1, t1, modulus); } /* X = X - T2 */ mpz_sub (x, x, t2); if (mpz_cmp_ui (x, 0) < 0) { mpz_add (x, x, modulus); } /* T2 = 2T2 */ mpz_add (t2, t2, t2); if (mpz_cmp (t2, modulus) >= 0) { mpz_sub (t2, t2, modulus); } /* T2 = X + T2 */ mpz_add (t2, t2, x); if (mpz_cmp (t2, modulus) >= 0) { mpz_sub (t2, t2, modulus); } /* if Z' != 1 */ if (mpz_cmp_ui (Q->z, 1) != 0) { /* Z = Z * Z' */ mpz_mul (z, z, Q->z); mpz_mod (z, z, modulus); } /* Z = Z * X */ mpz_mul (z, z, x); mpz_mod (z, z, modulus); /* T1 = T1 * X */ mpz_mul (t1, t1, x); mpz_mod (t1, t1, modulus); /* X = X * X */ mpz_mul (x, x, x); mpz_mod (x, x, modulus); /* T2 = T2 * x */ mpz_mul (t2, t2, x); mpz_mod (t2, t2, modulus); /* T1 = T1 * X */ mpz_mul (t1, t1, x); mpz_mod (t1, t1, modulus); /* X = Y*Y */ mpz_mul (x, y, y); mpz_mod (x, x, modulus); /* X = X - T2 */ mpz_sub (x, x, t2); if (mpz_cmp_ui (x, 0) < 0) { mpz_add (x, x, modulus); } /* T2 = T2 - X */ mpz_sub (t2, t2, x); if (mpz_cmp_ui (t2, 0) < 0) { mpz_add (t2, t2, modulus); } /* T2 = T2 - X */ mpz_sub (t2, t2, x); if (mpz_cmp_ui (t2, 0) < 0) { mpz_add (t2, t2, modulus); } /* T2 = T2 * Y */ mpz_mul (t2, t2, y); mpz_mod (t2, t2, modulus); /* Y = T2 - T1 */ mpz_sub (y, t2, t1); if (mpz_cmp_ui (y, 0) < 0) { mpz_add (y, y, modulus); } /* Y = Y/2 */ if (mpz_odd_p (y)) { mpz_add (y, y, modulus); } mpz_divexact_ui (y, y, 2); mpz_set (R->x, x); mpz_set (R->y, y); mpz_set (R->z, z); err = GNUTLS_E_SUCCESS; mp_clear_multi (&t1, &t2, &x, &y, &z, NULL); return err; }
static PyObject * Pympz_mpmath_normalize(PyObject *self, PyObject *args) { long sign = 0; mpir_si bc = 0, prec = 0, shift, zbits, carry = 0; PyObject *exp = 0, *newexp = 0, *newexp2 = 0, *tmp = 0, *rndstr = 0; PympzObject *man = 0, *upper = 0, *lower = 0; char rnd = 0; if (PyTuple_GET_SIZE(args) == 6) { /* Need better error-checking here. Under Python 3.0, overflow into C-long is possible. */ sign = clong_From_Integer(PyTuple_GET_ITEM(args, 0)); man = (PympzObject *)PyTuple_GET_ITEM(args, 1); exp = PyTuple_GET_ITEM(args, 2); bc = SI_From_Integer(PyTuple_GET_ITEM(args, 3)); prec = SI_From_Integer(PyTuple_GET_ITEM(args, 4)); rndstr = PyTuple_GET_ITEM(args, 5); if (PyErr_Occurred()) { TYPE_ERROR("arguments long, PympzObject*, PyObject*, long, long, char needed"); return NULL; } } else { TYPE_ERROR("6 arguments required"); return NULL; } if (!Pympz_Check(man)) { TYPE_ERROR("argument is not an mpz"); return NULL; } /* If rndstr really is a string, extract the first character. */ if (Py2or3String_Check(rndstr)) { rnd = Py2or3String_AsString(rndstr)[0]; } else { VALUE_ERROR("invalid rounding mode specified"); return NULL; } /* If the mantissa is 0, return the normalized representation. */ if (!mpz_sgn(man->z)) { Py_INCREF((PyObject*)man); return mpmath_build_mpf(0, man, 0, 0); } /* if bc <= prec and the number is odd return it */ if ((bc <= prec) && mpz_odd_p(man->z)) { Py_INCREF((PyObject*)man); Py_INCREF((PyObject*)exp); return mpmath_build_mpf(sign, man, exp, bc); } if (!(upper = (PympzObject*)Pympz_new()) || !(lower = (PympzObject*)Pympz_new())) { Py_XDECREF((PyObject*)upper); Py_XDECREF((PyObject*)lower); } shift = bc - prec; if (shift>0) { switch (rnd) { case 'f': if(sign) { mpz_cdiv_q_2exp(upper->z, man->z, shift); } else { mpz_fdiv_q_2exp(upper->z, man->z, shift); } break; case 'c': if(sign) { mpz_fdiv_q_2exp(upper->z, man->z, shift); } else { mpz_cdiv_q_2exp(upper->z, man->z, shift); } break; case 'd': mpz_fdiv_q_2exp(upper->z, man->z, shift); break; case 'u': mpz_cdiv_q_2exp(upper->z, man->z, shift); break; case 'n': default: mpz_tdiv_r_2exp(lower->z, man->z, shift); mpz_tdiv_q_2exp(upper->z, man->z, shift); if (mpz_sgn(lower->z)) { /* lower is not 0 so it must have at least 1 bit set */ if (mpz_sizeinbase(lower->z, 2) == shift) { /* lower is >= 1/2 */ if (mpz_scan1(lower->z, 0) == shift-1) { /* lower is exactly 1/2 */ if (mpz_odd_p(upper->z)) carry = 1; } else { carry = 1; } } } if (carry) mpz_add_ui(upper->z, upper->z, 1); } if (!(tmp = PyIntOrLong_FromSI(shift))) { Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); return NULL; } if (!(newexp = PyNumber_Add(exp, tmp))) { Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(tmp); return NULL; } Py_DECREF(tmp); bc = prec; } else { mpz_set(upper->z, man->z); newexp = exp; Py_INCREF(newexp); } /* Strip trailing 0 bits. */ if ((zbits = mpz_scan1(upper->z, 0))) mpz_tdiv_q_2exp(upper->z, upper->z, zbits); if (!(tmp = PyIntOrLong_FromSI(zbits))) { Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(newexp); return NULL; } if (!(newexp2 = PyNumber_Add(newexp, tmp))) { Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(tmp); Py_DECREF(newexp); return NULL; } Py_DECREF(newexp); Py_DECREF(tmp); bc -= zbits; /* Check if one less than a power of 2 was rounded up. */ if (!mpz_cmp_ui(upper->z, 1)) bc = 1; Py_DECREF((PyObject*)lower); return mpmath_build_mpf(sign, upper, newexp2, bc); }
static PyObject * Pympz_mpmath_create(PyObject *self, PyObject *args) { long sign; mpir_si bc, shift, zbits, carry = 0, prec = 0; PyObject *exp = 0, *newexp = 0, *newexp2 = 0, *tmp = 0; PympzObject *man = 0, *upper = 0, *lower = 0; const char *rnd = "f"; if (PyTuple_GET_SIZE(args) < 2) { TYPE_ERROR("mpmath_create() expects 'mpz','int'[,'int','str'] arguments"); return NULL; } switch (PyTuple_GET_SIZE(args)) { case 4: rnd = Py2or3String_AsString(PyTuple_GET_ITEM(args, 3)); case 3: prec = SI_From_Integer(PyTuple_GET_ITEM(args, 2)); if (prec == -1 && PyErr_Occurred()) return NULL; prec = ABS(prec); case 2: exp = PyTuple_GET_ITEM(args, 1); case 1: man = Pympz_From_Integer(PyTuple_GET_ITEM(args, 0)); if (!man) { TYPE_ERROR("mpmath_create() expects 'mpz','int'[,'int','str'] arguments"); return NULL; } } /* If the mantissa is 0, return the normalized representation. */ if (!mpz_sgn(man->z)) { return mpmath_build_mpf(0, man, 0, 0); } upper = (PympzObject*)Pympz_new(); lower = (PympzObject*)Pympz_new(); if (!upper || !lower) { Py_DECREF((PyObject*)man); Py_XDECREF((PyObject*)upper); Py_XDECREF((PyObject*)lower); return NULL; } /* Extract sign, make man positive, and set bit count */ sign = (mpz_sgn(man->z) == -1); mpz_abs(upper->z, man->z); bc = mpz_sizeinbase(upper->z, 2); if (!prec) prec = bc; shift = bc - prec; if (shift > 0) { switch (rnd[0]) { case 'f': if(sign) { mpz_cdiv_q_2exp(upper->z, upper->z, shift); } else { mpz_fdiv_q_2exp(upper->z, upper->z, shift); } break; case 'c': if(sign) { mpz_fdiv_q_2exp(upper->z, upper->z, shift); } else { mpz_cdiv_q_2exp(upper->z, upper->z, shift); } break; case 'd': mpz_fdiv_q_2exp(upper->z, upper->z, shift); break; case 'u': mpz_cdiv_q_2exp(upper->z, upper->z, shift); break; case 'n': default: mpz_tdiv_r_2exp(lower->z, upper->z, shift); mpz_tdiv_q_2exp(upper->z, upper->z, shift); if (mpz_sgn(lower->z)) { /* lower is not 0 so it must have at least 1 bit set */ if (mpz_sizeinbase(lower->z, 2)==shift) { /* lower is >= 1/2 */ if (mpz_scan1(lower->z, 0)==shift-1) { /* lower is exactly 1/2 */ if (mpz_odd_p(upper->z)) carry = 1; } else { carry = 1; } } } if (carry) mpz_add_ui(upper->z, upper->z, 1); } if (!(tmp = PyIntOrLong_FromSI(shift))) { Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); return NULL; } if (!(newexp = PyNumber_Add(exp, tmp))) { Py_DECREF((PyObject*)man); Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(tmp); return NULL; } Py_DECREF(tmp); bc = prec; } else { newexp = exp; Py_INCREF(newexp); } /* Strip trailing 0 bits. */ if ((zbits = mpz_scan1(upper->z, 0))) mpz_tdiv_q_2exp(upper->z, upper->z, zbits); if (!(tmp = PyIntOrLong_FromSI(zbits))) { Py_DECREF((PyObject*)man); Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(newexp); return NULL; } if (!(newexp2 = PyNumber_Add(newexp, tmp))) { Py_DECREF((PyObject*)man); Py_DECREF((PyObject*)upper); Py_DECREF((PyObject*)lower); Py_DECREF(tmp); Py_DECREF(newexp); return NULL; } Py_DECREF(newexp); Py_DECREF(tmp); bc -= zbits; /* Check if one less than a power of 2 was rounded up. */ if (!mpz_cmp_ui(upper->z, 1)) bc = 1; Py_DECREF((PyObject*)lower); Py_DECREF((PyObject*)man); return mpmath_build_mpf(sign, upper, newexp2, bc); }
static int zp_sgn_odd(element_ptr a) { mpz_ptr z = a->data; return mpz_is0(z) ? 0 : (mpz_odd_p(z) ? 1 : -1); }
bool is_odd<mpz_class>(const mpz_class &x) { return mpz_odd_p(x.get_mpz_t()); }
void field_init_curve_ab(field_ptr f, element_ptr a, element_ptr b, mpz_t order, mpz_t cofac) { /* if (element_is0(a)) { c->double_nocheck = cc_double_no_check_ais0; } else { c->double_nocheck = cc_double_no_check; } */ curve_data_ptr cdp; field_init(f); mpz_set(f->order, order); f->data = pbc_malloc(sizeof(*cdp)); cdp = (curve_data_ptr)f->data; cdp->field = a->field; element_init(cdp->a, cdp->field); element_init(cdp->b, cdp->field); element_set(cdp->a, a); element_set(cdp->b, b); f->init = curve_init; f->clear = curve_clear; f->neg = f->invert = curve_invert; f->square = f->doub = curve_double; f->multi_doub = multi_double; f->add = f->mul = curve_mul; f->multi_add = multi_add; f->mul_mpz = element_pow_mpz; f->cmp = curve_cmp; f->set0 = f->set1 = curve_set1; f->is0 = f->is1 = curve_is1; f->sign = curve_sign; f->set = curve_set; f->random = curve_random_pointmul; //f->random = curve_random_solvefory; f->from_hash = curve_from_hash; f->out_str = curve_out_str; f->snprint = curve_snprint; f->set_multiz = curve_set_multiz; f->set_str = curve_set_str; f->field_clear = field_clear_curve; if (cdp->field->fixed_length_in_bytes < 0) { f->length_in_bytes = curve_length_in_bytes; } else { f->fixed_length_in_bytes = 2 * cdp->field->fixed_length_in_bytes; } f->to_bytes = curve_to_bytes; f->from_bytes = curve_from_bytes; f->out_info = curve_out_info; f->item_count = curve_item_count; f->item = curve_item; f->get_x = curve_get_x; f->get_y = curve_get_y; if (mpz_odd_p(order)) { f->is_sqr = odd_curve_is_sqr; } else { f->is_sqr = even_curve_is_sqr; } element_init(cdp->gen_no_cofac, f); element_init(cdp->gen, f); curve_random_no_cofac_solvefory(cdp->gen_no_cofac); if (cofac) { cdp->cofac = (mpz_ptr)pbc_malloc(sizeof(mpz_t)); mpz_init(cdp->cofac); mpz_set(cdp->cofac, cofac); element_mul_mpz(cdp->gen, cdp->gen_no_cofac, cofac); } else{ cdp->cofac = NULL; element_set(cdp->gen, cdp->gen_no_cofac); } cdp->quotient_cmp = NULL; }
static int e_mpz_odd_p (mpz_srcptr x) { return mpz_odd_p (x); }
static PyObject * Pympq_round(PyObject *self, PyObject *args) { Py_ssize_t round_digits = 0; PympqObject *resultq; PympzObject *resultz; mpz_t temp, rem; /* If args is NULL or the size of args is 0, we just return an mpz. */ if (!args || PyTuple_GET_SIZE(args) == 0) { if (!(resultz = (PympzObject*)Pympz_new())) return NULL; mpz_inoc(rem); mpz_fdiv_qr(resultz->z, rem, mpq_numref(Pympq_AS_MPQ(self)), mpq_denref(Pympq_AS_MPQ(self))); mpz_mul_2exp(rem, rem, 1); if (mpz_cmp(rem, mpq_denref(Pympq_AS_MPQ(self))) > 0) { mpz_add_ui(resultz->z, resultz->z, 1); } else if (mpz_cmp(rem, mpq_denref(Pympq_AS_MPQ(self))) == 0) { if (mpz_odd_p(resultz->z)) { mpz_add_ui(resultz->z, resultz->z, 1); } } mpz_cloc(rem); return (PyObject*)resultz; } if (PyTuple_GET_SIZE(args) > 1) { TYPE_ERROR("Too many arguments for __round__()."); return NULL; } if (PyTuple_GET_SIZE(args) == 1) { round_digits = ssize_t_From_Integer(PyTuple_GET_ITEM(args, 0)); if (round_digits == -1 && PyErr_Occurred()) { TYPE_ERROR("__round__() requires 'int' argument"); return NULL; } } if (!(resultq = (PympqObject*)Pympq_new())) return NULL; mpz_inoc(temp); mpz_ui_pow_ui(temp, 10, round_digits > 0 ? round_digits : -round_digits); mpq_set(resultq->q, Pympq_AS_MPQ(self)); if (round_digits > 0) { mpz_mul(mpq_numref(resultq->q), mpq_numref(resultq->q), temp); mpq_canonicalize(resultq->q); if (!(resultz = (PympzObject*)Pympq_round((PyObject*)resultq, NULL))) { mpz_cloc(temp); return NULL; } mpz_set(mpq_numref(resultq->q), resultz->z); Py_DECREF((PyObject*)resultz); mpz_set(mpq_denref(resultq->q), temp); mpz_cloc(temp); mpq_canonicalize(resultq->q); } else { mpz_mul(mpq_denref(resultq->q), mpq_denref(resultq->q), temp); mpq_canonicalize(resultq->q); if (!(resultz = (PympzObject*)Pympq_round((PyObject*)resultq, NULL))) { mpz_cloc(temp); return NULL; } mpq_set_ui(resultq->q, 0, 1); mpz_mul(mpq_numref(resultq->q), resultz->z, temp); Py_DECREF((PyObject*)resultz); mpz_cloc(temp); mpq_canonicalize(resultq->q); } return (PyObject*)resultq; }
/* Double an ECC point @param P The point to double @param R [out] The destination of the double @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_projective_dbl_point (ecc_point * P, ecc_point * R, mpz_t a /* a is -3 */, mpz_t modulus) { mpz_t t1, t2; int err; if (P == NULL || R == NULL || modulus == NULL) return -1; if ((err = mp_init_multi(&t1, &t2, NULL)) != 0) { return err; } if (P != R) { mpz_set(R->x, P->x); mpz_set(R->y, P->y); mpz_set(R->z, P->z); } /* t1 = Z * Z */ mpz_mul(t1, R->z, R->z); mpz_mod(t1, t1, modulus); /* Z = Y * Z */ mpz_mul(R->z, R->y, R->z); mpz_mod(R->z, R->z, modulus); /* Z = 2Z */ mpz_add(R->z, R->z, R->z); if (mpz_cmp(R->z, modulus) >= 0) { mpz_sub(R->z, R->z, modulus); } /* T2 = X - T1 */ mpz_sub(t2, R->x, t1); if (mpz_cmp_ui(t2, 0) < 0) { mpz_add(t2, t2, modulus); } /* T1 = X + T1 */ mpz_add(t1, t1, R->x); if (mpz_cmp(t1, modulus) >= 0) { mpz_sub(t1, t1, modulus); } /* T2 = T1 * T2 */ mpz_mul(t2, t1, t2); mpz_mod(t2, t2, modulus); /* T1 = 2T2 */ mpz_add(t1, t2, t2); if (mpz_cmp(t1, modulus) >= 0) { mpz_sub(t1, t1, modulus); } /* T1 = T1 + T2 */ mpz_add(t1, t1, t2); if (mpz_cmp(t1, modulus) >= 0) { mpz_sub(t1, t1, modulus); } /* Y = 2Y */ mpz_add(R->y, R->y, R->y); if (mpz_cmp(R->y, modulus) >= 0) { mpz_sub(R->y, R->y, modulus); } /* Y = Y * Y */ mpz_mul(R->y, R->y, R->y); mpz_mod(R->y, R->y, modulus); /* T2 = Y * Y */ mpz_mul(t2, R->y, R->y); mpz_mod(t2, t2, modulus); /* T2 = T2/2 */ if (mpz_odd_p(t2)) { mpz_add(t2, t2, modulus); } mpz_divexact_ui(t2, t2, 2); /* Y = Y * X */ mpz_mul(R->y, R->y, R->x); mpz_mod(R->y, R->y, modulus); /* X = T1 * T1 */ mpz_mul(R->x, t1, t1); mpz_mod(R->x, R->x, modulus); /* X = X - Y */ mpz_sub(R->x, R->x, R->y); if (mpz_cmp_ui(R->x, 0) < 0) { mpz_add(R->x, R->x, modulus); } /* X = X - Y */ mpz_sub(R->x, R->x, R->y); if (mpz_cmp_ui(R->x, 0) < 0) { mpz_add(R->x, R->x, modulus); } /* Y = Y - X */ mpz_sub(R->y, R->y, R->x); if (mpz_cmp_ui(R->y, 0) < 0) { mpz_add(R->y, R->y, modulus); } /* Y = Y * T1 */ mpz_mul(R->y, R->y, t1); mpz_mod(R->y, R->y, modulus); /* Y = Y - T2 */ mpz_sub(R->y, R->y, t2); if (mpz_cmp_ui(R->y, 0) < 0) { mpz_add( R->y, R->y, modulus); } err = 0; mp_clear_multi(&t1, &t2, NULL); return err; }
/* Add two ECC points @param P The point to add @param Q The point to add @param R [out] The destination of the double @param a Curve's a value @param modulus The modulus of the field the ECC curve is in @return 0 on success */ int ecc_projective_add_point (ecc_point * P, ecc_point * Q, ecc_point * R, mpz_t a, mpz_t modulus) { mpz_t t1, t2, x, y, z; int err; if (P == NULL || Q == NULL || R == NULL || modulus == NULL) return -1; if ((err = mp_init_multi (&t1, &t2, &x, &y, &z, NULL)) != 0) { return err; } /* Check if P == Q and do doubling in that case * If Q == -P then P+Q=point at infinity */ if ((mpz_cmp (P->x, Q->x) == 0) && (mpz_cmp (P->z, Q->z) == 0)) { /* x and z coordinates match. Check if P->y = Q->y, or P->y = -Q->y */ if (mpz_cmp (P->y, Q->y) == 0) { mp_clear_multi (&t1, &t2, &x, &y, &z, NULL); return ecc_projective_dbl_point (P, R, a, modulus); } mpz_sub (t1, modulus, Q->y); if (mpz_cmp (P->y, t1) == 0) { mp_clear_multi (&t1, &t2, &x, &y, &z, NULL); mpz_set_ui(R->x, 1); mpz_set_ui(R->y, 1); mpz_set_ui(R->z, 0); return 0; } } mpz_set (x, P->x); mpz_set (y, P->y); mpz_set (z, P->z); /* if Z is one then these are no-operations */ if (mpz_cmp_ui (Q->z, 1) != 0) { /* T1 = Z' * Z' */ mpz_mul (t1, Q->z, Q->z); mpz_mod (t1, t1, modulus); /* X = X * T1 */ mpz_mul (x, x, t1); mpz_mod (x, x, modulus); /* T1 = Z' * T1 */ mpz_mul (t1, t1, Q->z); mpz_mod (t1, t1, modulus); /* Y = Y * T1 */ mpz_mul (y, y, t1); mpz_mod (y, y, modulus); } /* T1 = Z*Z */ mpz_mul (t1, z, z); mpz_mod (t1, t1, modulus); /* T2 = X' * T1 */ mpz_mul (t2, t1, Q->x); mpz_mod (t2, t2, modulus); /* T1 = Z * T1 */ mpz_mul (t1, t1, z); mpz_mod (t1, t1, modulus); /* T1 = Y' * T1 */ mpz_mul (t1, t1, Q->y); mpz_mod (t1, t1, modulus); /* Y = Y - T1 */ mpz_sub (y, y, t1); if (mpz_cmp_ui (y, 0) < 0) { mpz_add (y, y, modulus); } /* T1 = 2T1 */ mpz_add (t1, t1, t1); if (mpz_cmp (t1, modulus) >= 0) { mpz_sub (t1, t1, modulus); } /* T1 = Y + T1 */ mpz_add (t1, t1, y); if (mpz_cmp (t1, modulus) >= 0) { mpz_sub (t1, t1, modulus); } /* X = X - T2 */ mpz_sub (x, x, t2); if (mpz_cmp_ui (x, 0) < 0) { mpz_add (x, x, modulus); } /* T2 = 2T2 */ mpz_add (t2, t2, t2); if (mpz_cmp (t2, modulus) >= 0) { mpz_sub (t2, t2, modulus); } /* T2 = X + T2 */ mpz_add (t2, t2, x); if (mpz_cmp (t2, modulus) >= 0) { mpz_sub (t2, t2, modulus); } /* if Z' != 1 */ if (mpz_cmp_ui (Q->z, 1) != 0) { /* Z = Z * Z' */ mpz_mul (z, z, Q->z); mpz_mod (z, z, modulus); } /* Z = Z * X */ mpz_mul (z, z, x); mpz_mod (z, z, modulus); /* T1 = T1 * X */ mpz_mul (t1, t1, x); mpz_mod (t1, t1, modulus); /* X = X * X */ mpz_mul (x, x, x); mpz_mod (x, x, modulus); /* T2 = T2 * x */ mpz_mul (t2, t2, x); mpz_mod (t2, t2, modulus); /* T1 = T1 * X */ mpz_mul (t1, t1, x); mpz_mod (t1, t1, modulus); /* X = Y*Y */ mpz_mul (x, y, y); mpz_mod (x, x, modulus); /* X = X - T2 */ mpz_sub (x, x, t2); if (mpz_cmp_ui (x, 0) < 0) { mpz_add (x, x, modulus); } /* T2 = T2 - X */ mpz_sub (t2, t2, x); if (mpz_cmp_ui (t2, 0) < 0) { mpz_add (t2, t2, modulus); } /* T2 = T2 - X */ mpz_sub (t2, t2, x); if (mpz_cmp_ui (t2, 0) < 0) { mpz_add (t2, t2, modulus); } /* T2 = T2 * Y */ mpz_mul (t2, t2, y); mpz_mod (t2, t2, modulus); /* Y = T2 - T1 */ mpz_sub (y, t2, t1); if (mpz_cmp_ui (y, 0) < 0) { mpz_add (y, y, modulus); } /* Y = Y/2 */ if (mpz_odd_p (y)) { mpz_add (y, y, modulus); } mpz_divexact_ui (y, y, 2); mpz_set (R->x, x); mpz_set (R->y, y); mpz_set (R->z, z); err = 0; mp_clear_multi (&t1, &t2, &x, &y, &z, NULL); return err; }
void mpz_sqrtmp_r (mpz_ptr root, mpz_srcptr a, mpz_srcptr p) { /* ? a \neq 0 */ if (mpz_get_ui(a) != 0) { /* ? p = 3 (mod 4) */ if (mpz_congruent_ui_p(p, 3L, 4L)) { mpz_t foo; mpz_init_set(foo, p); mpz_add_ui(foo, foo, 1L); mpz_fdiv_q_2exp(foo, foo, 2L); mpz_powm(root, a, foo, p); mpz_clear(foo); return; } /* ! p = 1 (mod 4) */ else { /* ! s = (p-1)/4 */ mpz_t s; mpz_init_set(s, p); mpz_sub_ui(s, s, 1L); mpz_fdiv_q_2exp(s, s, 2L); /* ? p = 5 (mod 8) */ if (mpz_congruent_ui_p(p, 5L, 8L)) { mpz_t foo, b; mpz_init(foo); mpz_powm(foo, a, s, p); mpz_init_set(b, p); mpz_add_ui(b, b, 3L); mpz_fdiv_q_2exp(b, b, 3L); mpz_powm(root, a, b, p); /* ? a^{(p-1)/4} = 1 (mod p) */ if (mpz_cmp_ui(foo, 1L) == 0) { mpz_clear(foo), mpz_clear(s), mpz_clear(b); return; } /* ! a^{(p-1)/4} = -1 (mod p) */ else { do mpz_wrandomm(b, p); while (mpz_jacobi(b, p) != -1); mpz_powm(b, b, s, p); mpz_mul(root, root, b); mpz_mod(root, root, p); mpz_clear(foo), mpz_clear(s), mpz_clear(b); return; } } /* ! p = 1 (mod 8) */ else { mpz_t foo, bar, b, t; mpz_init(foo), mpz_init(bar); mpz_powm(foo, a, s, p); /* while a^s = 1 (mod p) */ while (mpz_cmp_ui(foo, 1L) == 0) { /* ? s odd */ if (mpz_odd_p(s)) { mpz_add_ui(s, s, 1L); mpz_fdiv_q_2exp(s, s, 1L); mpz_powm(root, a, s, p); mpz_clear(foo), mpz_clear(s); return; } /* ! s even */ else { mpz_fdiv_q_2exp(s, s, 1L); } mpz_powm(foo, a, s, p); } /* ! a^s = -1 (mod p) */ mpz_init(b); do mpz_wrandomm(b, p); while (mpz_jacobi(b, p) != -1); mpz_init_set(t, p); mpz_sub_ui(t, t, 1L); mpz_fdiv_q_2exp(t, t, 1L); /* while s even */ while (mpz_even_p(s)) { mpz_fdiv_q_2exp(s, s, 1L); mpz_fdiv_q_2exp(t, t, 1L); mpz_powm(foo, a, s, p); mpz_powm(bar, b, t, p); mpz_mul(foo, foo, bar); mpz_mod(foo, foo, p); mpz_set_si(bar, -1L); /* ? a^s * b^t = -1 (mod p) */ if (mpz_congruent_p(foo, bar, p)) { mpz_set(bar, p); mpz_sub_ui(bar, bar, 1L); mpz_fdiv_q_2exp(bar, bar, 1L); mpz_add(t, t, bar); } } mpz_add_ui(s, s, 1L); mpz_fdiv_q_2exp(s, s, 1L); mpz_fdiv_q_2exp(t, t, 1L); mpz_powm(foo, a, s, p); mpz_powm(bar, b, t, p); mpz_mul(root, foo, bar); mpz_mod(root, root, p); mpz_clear(foo), mpz_clear(bar); mpz_clear(s), mpz_clear(b), mpz_clear(t); return; } } } /* error, return zero root */ mpz_set_ui(root, 0L); }
/* Double an ECC point @param P The point to double @param R [out] The destination of the double @param a Curve's a value @param modulus The modulus of the field the ECC curve is in @return GNUTLS_E_SUCCESS on success */ int ecc_projective_dbl_point (ecc_point * P, ecc_point * R, mpz_t a, mpz_t modulus) { /* Using "dbl-2004-hmv" algorithm. * It costs 4M + 4S + half. */ mpz_t t1, t2; int err; if (P == NULL || R == NULL || modulus == NULL) return GNUTLS_E_RECEIVED_ILLEGAL_PARAMETER; if ( (err = ecc_projective_isneutral(P, modulus)) == 1 ) { if ((err = mp_init_multi(&t1, &t2, NULL)) != 0) { return err; } if (P != R) { mpz_set(R->x, P->x); mpz_set(R->y, P->y); mpz_set(R->z, P->z); } if (mpz_cmp_ui (P->z, 1) != 0) { /* t1 = Z * Z */ mpz_mul(t1, R->z, R->z); mpz_mod(t1, t1, modulus); /* Z = Y * Z */ mpz_mul(R->z, R->y, R->z); mpz_mod(R->z, R->z, modulus); /* Z = 2Z */ mpz_add(R->z, R->z, R->z); if (mpz_cmp(R->z, modulus) >= 0) { mpz_sub(R->z, R->z, modulus); } } else { /* t1 = 1 */ mpz_set(t1, P->z); /* Z = 2Y */ mpz_add(R->z, R->y, R->y); if (mpz_cmp(R->z, modulus) >= 0) { mpz_sub(R->z, R->z, modulus); } } /* T2 = X - T1 */ mpz_sub(t2, R->x, t1); if (mpz_cmp_ui(t2, 0) < 0) { mpz_add(t2, t2, modulus); } /* T1 = X + T1 */ mpz_add(t1, t1, R->x); if (mpz_cmp(t1, modulus) >= 0) { mpz_sub(t1, t1, modulus); } /* T2 = T1 * T2 */ mpz_mul(t2, t1, t2); mpz_mod(t2, t2, modulus); /* T1 = 2T2 */ mpz_add(t1, t2, t2); if (mpz_cmp(t1, modulus) >= 0) { mpz_sub(t1, t1, modulus); } /* T1 = T1 + T2 */ mpz_add(t1, t1, t2); if (mpz_cmp(t1, modulus) >= 0) { mpz_sub(t1, t1, modulus); } /* Y = 2Y */ mpz_add(R->y, R->y, R->y); if (mpz_cmp(R->y, modulus) >= 0) { mpz_sub(R->y, R->y, modulus); } /* Y = Y * Y */ mpz_mul(R->y, R->y, R->y); mpz_mod(R->y, R->y, modulus); /* T2 = Y * Y */ mpz_mul(t2, R->y, R->y); mpz_mod(t2, t2, modulus); /* T2 = T2/2 */ if (mpz_odd_p(t2)) { mpz_add(t2, t2, modulus); } mpz_divexact_ui(t2, t2, 2); /* Y = Y * X */ mpz_mul(R->y, R->y, R->x); mpz_mod(R->y, R->y, modulus); /* X = T1 * T1 */ mpz_mul(R->x, t1, t1); mpz_mod(R->x, R->x, modulus); /* X = X - Y */ mpz_sub(R->x, R->x, R->y); if (mpz_cmp_ui(R->x, 0) < 0) { mpz_add(R->x, R->x, modulus); } /* X = X - Y */ mpz_sub(R->x, R->x, R->y); if (mpz_cmp_ui(R->x, 0) < 0) { mpz_add(R->x, R->x, modulus); } /* Y = Y - X */ mpz_sub(R->y, R->y, R->x); if (mpz_cmp_ui(R->y, 0) < 0) { mpz_add(R->y, R->y, modulus); } /* Y = Y * T1 */ mpz_mul(R->y, R->y, t1); mpz_mod(R->y, R->y, modulus); /* Y = Y - T2 */ mpz_sub(R->y, R->y, t2); if (mpz_cmp_ui(R->y, 0) < 0) { mpz_add( R->y, R->y, modulus); } err = GNUTLS_E_SUCCESS; mp_clear_multi(&t1, &t2, NULL); return err; } else if (err == 0) { /* 2*neutral = neutral */ mpz_set_ui(R->x, 1); mpz_set_ui(R->y, 1); mpz_set_ui(R->z, 0); return GNUTLS_E_SUCCESS; } else { return err; } }