static void mpz_randomize (gcry_mpi_t n, unsigned int nbits, struct GNUNET_HashCode * rnd) { struct GNUNET_HashCode hc; struct GNUNET_HashCode tmp; int bits_per_hc = sizeof (struct GNUNET_HashCode) * 8; int cnt; int i; GNUNET_assert (nbits > 0); cnt = (nbits + bits_per_hc - 1) / bits_per_hc; gcry_mpi_set_ui (n, 0); tmp = *rnd; for (i = 0; i < cnt; i++) { int j; if (i > 0) GNUNET_CRYPTO_hash (&hc, sizeof (struct GNUNET_HashCode), &tmp); for (j = 0; j < sizeof (struct GNUNET_HashCode) / sizeof (uint32_t); j++) { #if HAVE_GCRY_MPI_LSHIFT gcry_mpi_lshift (n, n, sizeof (uint32_t) * 8); #else gcry_mpi_mul_ui (n, n, 1 << (sizeof (uint32_t) * 4)); gcry_mpi_mul_ui (n, n, 1 << (sizeof (uint32_t) * 4)); #endif gcry_mpi_add_ui (n, n, ntohl (((uint32_t *) & tmp)[j])); } hc = tmp; } GNUNET_CRYPTO_hash (&hc, sizeof (struct GNUNET_HashCode), rnd); i = gcry_mpi_get_nbits (n); while (i > nbits) gcry_mpi_clear_bit (n, --i); }
/* Check that left shifting works correctly. */ static void test_lshift (int pass) { static int size_list[] = {1, 31, 32, 63, 64, 65, 70, 0}; int size_idx; gcry_mpi_t a, b; char *tmpstr, *result, *result2; int i; wherestr = "test_lshift"; show ("checking that lshift works as expected (pass %d)\n", pass); for (size_idx=0; size_list[size_idx]; size_idx++) { a = gcry_mpi_new (0); b = gcry_mpi_new (0); /* gcry_mpi_randomize rounds up to full bytes, thus we need to use gcry_mpi_clear_highbit to fix that. */ gcry_mpi_randomize (a, size_list[size_idx], GCRY_WEAK_RANDOM); gcry_mpi_clear_highbit (a, size_list[size_idx]); for (i=0; i < 75; i++) { gcry_mpi_lshift (b, a, i); result = mpi2bitstr_nlz (b); tmpstr = mpi2bitstr_nlz (a); result2 = lshiftbitstring (tmpstr, i); xfree (tmpstr); if (strcmp (result, result2)) { show ("got =%s\n", result); show ("want=%s\n", result2); fail ("lshift by %d failed\n", i); } xfree (result); xfree (result2); } /* Again. This time using in-place operation. */ gcry_mpi_randomize (a, size_list[size_idx], GCRY_WEAK_RANDOM); gcry_mpi_clear_highbit (a, size_list[size_idx]); for (i=0; i < 75; i++) { gcry_mpi_release (b); b = gcry_mpi_copy (a); gcry_mpi_lshift (b, b, i); result = mpi2bitstr_nlz (b); tmpstr = mpi2bitstr_nlz (a); result2 = lshiftbitstring (tmpstr, i); xfree (tmpstr); if (strcmp (result, result2)) { show ("got =%s\n", result); show ("want=%s\n", result2); fail ("in-place lshift by %d failed\n", i); } xfree (result2); xfree (result); } gcry_mpi_release (b); gcry_mpi_release (a); } }