static PyObject * GMPy_MPZ_bit_flip_function(PyObject *self, PyObject *args) { mp_bitcnt_t bit_index; MPZ_Object *result = NULL, *tempx = NULL; if (PyTuple_GET_SIZE(args) != 2) goto err; if (!(result = GMPy_MPZ_New(NULL))) return NULL; if (!(tempx = GMPy_MPZ_From_Integer(PyTuple_GET_ITEM(args, 0), NULL))) goto err; bit_index = mp_bitcnt_t_From_Integer(PyTuple_GET_ITEM(args, 1)); if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) goto err_index; mpz_set(result->z, tempx->z); mpz_combit(result->z, bit_index); err: TYPE_ERROR("bit_flip() requires 'mpz','int' arguments"); err_index: Py_XDECREF((PyObject*)result); Py_XDECREF((PyObject*)tempx); return NULL; }
extern "C" int _PyLong_AsByteArray(PyLongObject* v, unsigned char* bytes, size_t n, int little_endian, int is_signed) noexcept { const mpz_t* op = &((BoxedLong*)v)->n; mpz_t modified; int sign = mpz_sgn(*op); // If the value is zero, then mpz_export won't touch any of the memory, so handle that here: if (sign == 0) { memset(bytes, 0, n); return 0; } size_t max_bits = n * 8; if (is_signed) max_bits--; size_t bits; if (sign == -1) { if (!is_signed) { PyErr_SetString(PyExc_OverflowError, "can't convert negative long to unsigned"); return -1; } // GMP uses sign-magnitude representation, and mpz_export just returns the magnitude. // This is the easiest way I could think of to convert to two's complement. // Note: the common case for this function is n in 1/2/4/8, where we could potentially // just extract the value and then do the two's complement conversion ourselves. But // then we would have to worry about endianness, which we don't right now. mpz_init(modified); mpz_com(modified, *op); bits = mpz_sizeinbase(modified, 2); for (int i = 0; i < 8 * n; i++) { mpz_combit(modified, i); } op = &modified; } else { bits = mpz_sizeinbase(*op, 2); } if (bits > max_bits) { if (sign == -1) mpz_clear(modified); PyErr_SetString(PyExc_OverflowError, "long too big to convert"); return -1; } size_t count = 0; mpz_export(bytes, &count, 1, n, little_endian ? -1 : 1, 0, *op); ASSERT(count == 1, "overflow? (%ld %ld)", count, n); if (sign == -1) mpz_clear(modified); return 0; }
/* exercise the case where mpz_clrbit or mpz_combit ends up extending a value like -2^(k*GMP_NUMB_BITS-1) when clearing bit k*GMP_NUMB_BITS-1. */ void check_clr_extend (void) { mpz_t got, want; unsigned long i; int f; mpz_init (got); mpz_init (want); for (i = 1; i < 5; i++) { for (f = 0; f <= 1; f++) { /* lots of 1 bits in _mp_d */ mpz_set_ui (got, 1L); mpz_mul_2exp (got, got, 10*GMP_NUMB_BITS); mpz_sub_ui (got, got, 1L); /* value -2^(n-1) representing ..11100..00 */ mpz_set_si (got, -1L); mpz_mul_2exp (got, got, i*GMP_NUMB_BITS-1); /* complement bit n, giving ..11000..00 which is -2^n */ if (f == 0) mpz_clrbit (got, i*GMP_NUMB_BITS-1); else mpz_combit (got, i*GMP_NUMB_BITS-1); MPZ_CHECK_FORMAT (got); mpz_set_si (want, -1L); mpz_mul_2exp (want, want, i*GMP_NUMB_BITS); if (mpz_cmp (got, want) != 0) { if (f == 0) printf ("mpz_clrbit: "); else printf ("mpz_combit: "); printf ("wrong after extension\n"); mpz_trace ("got ", got); mpz_trace ("want", want); abort (); } } } mpz_clear (got); mpz_clear (want); }
void check_com_negs (void) { static const struct { unsigned long bit; mp_size_t inp_size; mp_limb_t inp_n[5]; mp_size_t want_size; mp_limb_t want_n[5]; } data[] = { { GMP_NUMB_BITS, 2, { 1, 1 }, 1, { 1 } }, { GMP_NUMB_BITS+1, 2, { 1, 1 }, 2, { 1, 3 } }, { GMP_NUMB_BITS, 2, { 0, 1 }, 2, { 0, 2 } }, { GMP_NUMB_BITS+1, 2, { 0, 1 }, 2, { 0, 3 } }, }; mpz_t inp, got, want; int i; mpz_init (got); mpz_init (want); mpz_init (inp); for (i = 0; i < numberof (data); i++) { mpz_set_n (inp, data[i].inp_n, data[i].inp_size); mpz_neg (inp, inp); mpz_set_n (want, data[i].want_n, data[i].want_size); mpz_neg (want, want); mpz_set (got, inp); mpz_combit (got, data[i].bit); if (mpz_cmp (got, want) != 0) { printf ("mpz_combit: wrong on neg data[%d]\n", i); mpz_trace ("inp ", inp); printf ("bit %lu\n", data[i].bit); mpz_trace ("got ", got); mpz_trace ("want", want); abort (); } } mpz_clear (inp); mpz_clear (got); mpz_clear (want); }
static PyObject * GMPy_MPZ_bit_flip_method(PyObject *self, PyObject *other) { mp_bitcnt_t bit_index; MPZ_Object *result = NULL; if (!(result = GMPy_MPZ_New(NULL))) return NULL; bit_index = mp_bitcnt_t_From_Integer(other); if (bit_index == (mp_bitcnt_t)(-1) && PyErr_Occurred()) return NULL; mpz_set(result->z, MPZ(self)); mpz_combit(result->z, bit_index); return (PyObject*)result; }
int asc_ssv_combit(ssv_t *z, mp_bitcnt_t j) { __mpz_struct *Z; mp_bitcnt_t l; int i; for (i = 0; i < z->N; i++) { if (asc_ssv_lo(z, i) <= j && j < asc_ssv_hi(z, i)) { l = asc_ssv_mod(j, z, i); Z = z->sub[i].z; mpz_combit(Z, l); return 0; } } assert(i < z->N); return 0; }
void hex_random_bit_op (enum hex_random_op op, unsigned long maxbits, char **ap, unsigned long *b, char **rp) { mpz_t a, r; unsigned long abits, bbits; unsigned signs; mpz_init (a); mpz_init (r); abits = gmp_urandomb_ui (state, 32) % maxbits; bbits = gmp_urandomb_ui (state, 32) % (maxbits + 100); mpz_rrandomb (a, state, abits); signs = gmp_urandomb_ui (state, 1); if (signs & 1) mpz_neg (a, a); switch (op) { default: abort (); case OP_SETBIT: mpz_set (r, a); mpz_setbit (r, bbits); break; case OP_CLRBIT: mpz_set (r, a); mpz_clrbit (r, bbits); break; case OP_COMBIT: mpz_set (r, a); mpz_combit (r, bbits); break; case OP_CDIV_Q_2: mpz_cdiv_q_2exp (r, a, bbits); break; case OP_CDIV_R_2: mpz_cdiv_r_2exp (r, a, bbits); break; case OP_FDIV_Q_2: mpz_fdiv_q_2exp (r, a, bbits); break; case OP_FDIV_R_2: mpz_fdiv_r_2exp (r, a, bbits); break; case OP_TDIV_Q_2: mpz_tdiv_q_2exp (r, a, bbits); break; case OP_TDIV_R_2: mpz_tdiv_r_2exp (r, a, bbits); break; } gmp_asprintf (ap, "%Zx", a); *b = bbits; gmp_asprintf (rp, "%Zx", r); mpz_clear (a); mpz_clear (r); }
void test_main (void) { unsigned i; struct knuth_lfib_ctx rctx; struct dsa_signature signature; struct tstring *digest; knuth_lfib_init (&rctx, 4711); dsa_signature_init (&signature); digest = SHEX (/* sha256("abc") */ "BA7816BF 8F01CFEA 414140DE 5DAE2223" "B00361A3 96177A9C B410FF61 F20015AD"); for (i = 0; ecc_curves[i]; i++) { const struct ecc_curve *ecc = ecc_curves[i]; struct ecc_point pub; struct ecc_scalar key; if (verbose) fprintf (stderr, "Curve %d\n", ecc->bit_size); ecc_point_init (&pub, ecc); ecc_scalar_init (&key, ecc); ecdsa_generate_keypair (&pub, &key, &rctx, (nettle_random_func *) knuth_lfib_random); if (verbose) { gmp_fprintf (stderr, "Public key:\nx = %Nx\ny = %Nx\n", pub.p, ecc->size, pub.p + ecc->size, ecc->size); gmp_fprintf (stderr, "Private key: %Nx\n", key.p, ecc->size); } if (!ecc_valid_p (&pub)) die ("ecdsa_generate_keypair produced an invalid point.\n"); ecdsa_sign (&key, &rctx, (nettle_random_func *) knuth_lfib_random, digest->length, digest->data, &signature); if (!ecdsa_verify (&pub, digest->length, digest->data, &signature)) die ("ecdsa_verify failed.\n"); digest->data[3] ^= 17; if (ecdsa_verify (&pub, digest->length, digest->data, &signature)) die ("ecdsa_verify returned success with invalid digest.\n"); digest->data[3] ^= 17; mpz_combit (signature.r, 117); if (ecdsa_verify (&pub, digest->length, digest->data, &signature)) die ("ecdsa_verify returned success with invalid signature.r.\n"); mpz_combit (signature.r, 117); mpz_combit (signature.s, 93); if (ecdsa_verify (&pub, digest->length, digest->data, &signature)) die ("ecdsa_verify returned success with invalid signature.s.\n"); ecc_point_clear (&pub); ecc_scalar_clear (&key); } dsa_signature_clear (&signature); }
void check_single (void) { mpz_t x; int limb, offset, initial; unsigned long bit; mpz_init (x); for (limb = 0; limb < 4; limb++) { for (offset = (limb==0 ? 0 : -2); offset <= 2; offset++) { for (initial = 0; initial >= -1; initial--) { mpz_set_si (x, (long) initial); bit = (unsigned long) limb*BITS_PER_MP_LIMB + offset; mpz_clrbit (x, bit); MPZ_CHECK_FORMAT (x); if (mpz_tstbit (x, bit) != 0) { printf ("check_single(): expected 0\n"); abort (); } mpz_setbit (x, bit); MPZ_CHECK_FORMAT (x); if (mpz_tstbit (x, bit) != 1) { printf ("check_single(): expected 1\n"); abort (); } mpz_clrbit (x, bit); MPZ_CHECK_FORMAT (x); if (mpz_tstbit (x, bit) != 0) { printf ("check_single(): expected 0\n"); abort (); } mpz_combit (x, bit); MPZ_CHECK_FORMAT (x); if (mpz_tstbit (x, bit) != 1) { printf ("check_single(): expected 1\n"); abort (); } mpz_combit (x, bit); MPZ_CHECK_FORMAT (x); if (mpz_tstbit (x, bit) != 0) { printf ("check_single(): expected 0\n"); abort (); } } } } mpz_clear (x); }