103
/* Allocate a bit string consisting of '0' and '1' from the MPI A. Do
104
not return any leading zero bits. Caller needs to xfree the
107
mpi2bitstr_nlz (gcry_mpi_t a)
110
size_t length = gcry_mpi_get_nbits (a);
112
buf = p = xmalloc (length + 1);
114
*p++ = gcry_mpi_test_bit (a, length) ? '1':'0';
115
*p++ = gcry_mpi_test_bit (a, 0) ? '1':'0';
103
121
/* Shift a bit string to the right. */
105
123
rshiftbitstring (char *string, size_t n)
113
131
memset (string, '0', n);
134
/* Shift a bit string to the left. Caller needs to free the result. */
136
lshiftbitstring (const char *string, size_t n)
138
size_t len = strlen (string);
142
die ("internal overflow\n");
143
/* Allocate enough space. */
144
result = xmalloc (len+n+1);
145
for (; *string == '0' && string[1]; string++, len--)
147
memcpy (result, string, len);
148
if (*string == '0' && !string[1])
149
n = 0; /* Avoid extra nulls for an only 0 string. */
151
memset (result+len, '0', n);
117
157
/* This is to check a bug reported by bpgcrypt at itaparica.org on
118
158
2006-07-31 against libgcrypt 1.2.2. */
210
249
gcry_mpi_release (a);
252
/* Check that the left shifting. */
254
test_lshift (int pass)
256
static int size_list[] = {1, 31, 32, 63, 64, 65, 70, 0};
259
char *tmpstr, *result, *result2;
262
wherestr = "test_lshift";
263
show ("checking that lshift works as expected (pass %d)\n", pass);
265
for (size_idx=0; size_list[size_idx]; size_idx++)
267
a = gcry_mpi_new (0);
268
b = gcry_mpi_new (0);
270
/* gcry_mpi_randomize rounds up to full bytes, thus we need to
271
use gcry_mpi_clear_highbit to fix that. */
272
gcry_mpi_randomize (a, size_list[size_idx], GCRY_WEAK_RANDOM);
273
gcry_mpi_clear_highbit (a, size_list[size_idx]);
275
for (i=0; i < 75; i++)
277
gcry_mpi_lshift (b, a, i);
279
result = mpi2bitstr_nlz (b);
280
tmpstr = mpi2bitstr_nlz (a);
281
result2 = lshiftbitstring (tmpstr, i);
283
if (strcmp (result, result2))
285
show ("got =%s\n", result);
286
show ("want=%s\n", result2);
287
fail ("lshift by %d failed\n", i);
293
/* Again. This time using in-place operation. */
294
gcry_mpi_randomize (a, size_list[size_idx], GCRY_WEAK_RANDOM);
295
gcry_mpi_clear_highbit (a, size_list[size_idx]);
297
for (i=0; i < 75; i++)
299
gcry_mpi_release (b);
300
b = gcry_mpi_copy (a);
301
gcry_mpi_lshift (b, b, i);
303
result = mpi2bitstr_nlz (b);
304
tmpstr = mpi2bitstr_nlz (a);
305
result2 = lshiftbitstring (tmpstr, i);
307
if (strcmp (result, result2))
309
show ("got =%s\n", result);
310
show ("want=%s\n", result2);
311
fail ("in-place lshift by %d failed\n", i);
317
gcry_mpi_release (b);
318
gcry_mpi_release (a);
215
324
main (int argc, char **argv)
226
335
die ("version mismatch\n");
228
337
gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
229
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
338
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
231
340
gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
232
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
342
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
234
344
one_bit_only (0);
235
345
one_bit_only (1);
236
346
for (i=0; i < 5; i++)
237
347
test_rshift (i); /* Run several times due to random initializations. */
349
for (i=0; i < 5; i++)
350
test_lshift (i); /* Run several times due to random initializations. */
239
352
show ("All tests completed. Errors: %d\n", error_count);
240
353
return error_count ? 1 : 0;