1 /* 2 3 Copyright 2011, Free Software Foundation, Inc. 4 5 This file is part of the GNU MP Library test suite. 6 7 The GNU MP Library test suite is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 3 of the License, 10 or (at your option) any later version. 11 12 The GNU MP Library test suite is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 15 Public License for more details. 16 17 You should have received a copy of the GNU General Public License along with 18 the GNU MP Library test suite. If not, see http://www.gnu.org/licenses/. */ 19 20 #include <stdio.h> 21 #include <stdlib.h> 22 23 #include <time.h> 24 #include <unistd.h> 25 26 #include "gmp.h" 27 28 #include "hex-random.h" 29 30 static gmp_randstate_t state; 31 32 void 33 hex_random_init (void) 34 { 35 unsigned long seed; 36 char *env_seed; 37 38 env_seed = getenv("GMP_CHECK_RANDOMIZE"); 39 if (env_seed && env_seed[0]) 40 { 41 seed = strtoul (env_seed, NULL, 0); 42 if (seed) 43 printf ("Re-seeding with GMP_CHECK_RANDOMIZE=%lu\n", seed); 44 else 45 { 46 seed = time(NULL) + getpid(); 47 printf ("Seed GMP_CHECK_RANDOMIZE=%lu (include this in bug reports)\n", seed); 48 } 49 } 50 else 51 seed = 4711; 52 53 gmp_randinit_default (state); 54 gmp_randseed_ui (state, seed); 55 } 56 57 char * 58 hex_urandomb (unsigned long bits) 59 { 60 char *res; 61 mpz_t x; 62 63 mpz_init (x); 64 mpz_urandomb (x, state, bits); 65 gmp_asprintf (&res, "%Zx", x); 66 mpz_clear (x); 67 return res; 68 } 69 70 char * 71 hex_rrandomb (unsigned long bits) 72 { 73 char *res; 74 mpz_t x; 75 76 mpz_init (x); 77 mpz_rrandomb (x, state, bits); 78 gmp_asprintf (&res, "%Zx", x); 79 mpz_clear (x); 80 return res; 81 } 82 83 char * 84 hex_rrandomb_export (void *dst, size_t *countp, 85 int order, size_t size, int endian, unsigned long bits) 86 { 87 char *res; 88 mpz_t x; 89 mpz_init (x); 90 mpz_rrandomb (x, state, bits); 91 gmp_asprintf (&res, "%Zx", x); 92 mpz_export (dst, countp, order, size, endian, 0, x); 93 mpz_clear (x); 94 return res; 95 } 96 97 void hex_random_op2 (enum hex_random_op op, unsigned long maxbits, 98 char **ap, char **rp) 99 { 100 mpz_t a, r; 101 unsigned long abits; 102 unsigned signs; 103 104 mpz_init (a); 105 mpz_init (r); 106 107 abits = gmp_urandomb_ui (state, 32) % maxbits; 108 109 mpz_rrandomb (a, state, abits); 110 111 signs = gmp_urandomb_ui (state, 1); 112 if (signs & 1) 113 mpz_neg (a, a); 114 115 switch (op) 116 { 117 default: 118 abort (); 119 case OP_SQR: 120 mpz_mul (r, a, a); 121 break; 122 } 123 124 gmp_asprintf (ap, "%Zx", a); 125 gmp_asprintf (rp, "%Zx", r); 126 127 mpz_clear (a); 128 mpz_clear (r); 129 } 130 131 void 132 hex_random_op3 (enum hex_random_op op, unsigned long maxbits, 133 char **ap, char **bp, char **rp) 134 { 135 mpz_t a, b, r; 136 unsigned long abits, bbits; 137 unsigned signs; 138 139 mpz_init (a); 140 mpz_init (b); 141 mpz_init (r); 142 143 abits = gmp_urandomb_ui (state, 32) % maxbits; 144 bbits = gmp_urandomb_ui (state, 32) % maxbits; 145 146 mpz_rrandomb (a, state, abits); 147 mpz_rrandomb (b, state, bbits); 148 149 signs = gmp_urandomb_ui (state, 3); 150 if (signs & 1) 151 mpz_neg (a, a); 152 if (signs & 2) 153 mpz_neg (b, b); 154 155 switch (op) 156 { 157 default: 158 abort (); 159 case OP_ADD: 160 mpz_add (r, a, b); 161 break; 162 case OP_SUB: 163 mpz_sub (r, a, b); 164 break; 165 case OP_MUL: 166 mpz_mul (r, a, b); 167 break; 168 case OP_GCD: 169 if (signs & 4) 170 { 171 /* Produce a large gcd */ 172 unsigned long gbits = gmp_urandomb_ui (state, 32) % maxbits; 173 mpz_rrandomb (r, state, gbits); 174 mpz_mul (a, a, r); 175 mpz_mul (b, b, r); 176 } 177 mpz_gcd (r, a, b); 178 break; 179 case OP_LCM: 180 if (signs & 4) 181 { 182 /* Produce a large gcd */ 183 unsigned long gbits = gmp_urandomb_ui (state, 32) % maxbits; 184 mpz_rrandomb (r, state, gbits); 185 mpz_mul (a, a, r); 186 mpz_mul (b, b, r); 187 } 188 mpz_lcm (r, a, b); 189 break; 190 case OP_AND: 191 mpz_and (r, a, b); 192 break; 193 case OP_IOR: 194 mpz_ior (r, a, b); 195 break; 196 case OP_XOR: 197 mpz_xor (r, a, b); 198 break; 199 } 200 201 gmp_asprintf (ap, "%Zx", a); 202 gmp_asprintf (bp, "%Zx", b); 203 gmp_asprintf (rp, "%Zx", r); 204 205 mpz_clear (a); 206 mpz_clear (b); 207 mpz_clear (r); 208 } 209 210 void 211 hex_random_op4 (enum hex_random_op op, unsigned long maxbits, 212 char **ap, char **bp, char **cp, char **dp) 213 { 214 mpz_t a, b, c, d; 215 unsigned long abits, bbits; 216 unsigned signs; 217 218 mpz_init (a); 219 mpz_init (b); 220 mpz_init (c); 221 mpz_init (d); 222 223 if (op == OP_POWM) 224 { 225 unsigned long cbits; 226 abits = gmp_urandomb_ui (state, 32) % maxbits; 227 bbits = 1 + gmp_urandomb_ui (state, 32) % maxbits; 228 cbits = 2 + gmp_urandomb_ui (state, 32) % maxbits; 229 230 mpz_rrandomb (a, state, abits); 231 mpz_rrandomb (b, state, bbits); 232 mpz_rrandomb (c, state, cbits); 233 234 signs = gmp_urandomb_ui (state, 3); 235 if (signs & 1) 236 mpz_neg (a, a); 237 if (signs & 2) 238 { 239 mpz_t g; 240 241 /* If we negate the exponent, must make sure that gcd(a, c) = 1 */ 242 if (mpz_sgn (a) == 0) 243 mpz_set_ui (a, 1); 244 else 245 { 246 mpz_init (g); 247 248 for (;;) 249 { 250 mpz_gcd (g, a, c); 251 if (mpz_cmp_ui (g, 1) == 0) 252 break; 253 mpz_divexact (a, a, g); 254 } 255 mpz_clear (g); 256 } 257 mpz_neg (b, b); 258 } 259 if (signs & 4) 260 mpz_neg (c, c); 261 262 mpz_powm (d, a, b, c); 263 } 264 else 265 { 266 unsigned long qbits; 267 bbits = 1 + gmp_urandomb_ui (state, 32) % maxbits; 268 qbits = gmp_urandomb_ui (state, 32) % maxbits; 269 abits = bbits + qbits; 270 if (abits > 30) 271 abits -= 30; 272 else 273 abits = 0; 274 275 mpz_rrandomb (a, state, abits); 276 mpz_rrandomb (b, state, bbits); 277 278 signs = gmp_urandomb_ui (state, 2); 279 if (signs & 1) 280 mpz_neg (a, a); 281 if (signs & 2) 282 mpz_neg (b, b); 283 284 switch (op) 285 { 286 default: 287 abort (); 288 case OP_CDIV: 289 mpz_cdiv_qr (c, d, a, b); 290 break; 291 case OP_FDIV: 292 mpz_fdiv_qr (c, d, a, b); 293 break; 294 case OP_TDIV: 295 mpz_tdiv_qr (c, d, a, b); 296 break; 297 } 298 } 299 gmp_asprintf (ap, "%Zx", a); 300 gmp_asprintf (bp, "%Zx", b); 301 gmp_asprintf (cp, "%Zx", c); 302 gmp_asprintf (dp, "%Zx", d); 303 304 mpz_clear (a); 305 mpz_clear (b); 306 mpz_clear (c); 307 mpz_clear (d); 308 } 309 310 void 311 hex_random_bit_op (enum hex_random_op op, unsigned long maxbits, 312 char **ap, unsigned long *b, char **rp) 313 { 314 mpz_t a, r; 315 unsigned long abits, bbits; 316 unsigned signs; 317 318 mpz_init (a); 319 mpz_init (r); 320 321 abits = gmp_urandomb_ui (state, 32) % maxbits; 322 bbits = gmp_urandomb_ui (state, 32) % (maxbits + 100); 323 324 mpz_rrandomb (a, state, abits); 325 326 signs = gmp_urandomb_ui (state, 1); 327 if (signs & 1) 328 mpz_neg (a, a); 329 330 switch (op) 331 { 332 default: 333 abort (); 334 335 case OP_SETBIT: 336 mpz_set (r, a); 337 mpz_setbit (r, bbits); 338 break; 339 case OP_CLRBIT: 340 mpz_set (r, a); 341 mpz_clrbit (r, bbits); 342 break; 343 case OP_COMBIT: 344 mpz_set (r, a); 345 mpz_combit (r, bbits); 346 break; 347 case OP_CDIV_Q_2: 348 mpz_cdiv_q_2exp (r, a, bbits); 349 break; 350 case OP_CDIV_R_2: 351 mpz_cdiv_r_2exp (r, a, bbits); 352 break; 353 case OP_FDIV_Q_2: 354 mpz_fdiv_q_2exp (r, a, bbits); 355 break; 356 case OP_FDIV_R_2: 357 mpz_fdiv_r_2exp (r, a, bbits); 358 break; 359 case OP_TDIV_Q_2: 360 mpz_tdiv_q_2exp (r, a, bbits); 361 break; 362 case OP_TDIV_R_2: 363 mpz_tdiv_r_2exp (r, a, bbits); 364 break; 365 } 366 367 gmp_asprintf (ap, "%Zx", a); 368 *b = bbits; 369 gmp_asprintf (rp, "%Zx", r); 370 371 mpz_clear (a); 372 mpz_clear (r); 373 } 374 375 void 376 hex_random_scan_op (enum hex_random_op op, unsigned long maxbits, 377 char **ap, unsigned long *b, unsigned long *r) 378 { 379 mpz_t a; 380 unsigned long abits, bbits; 381 unsigned signs; 382 383 mpz_init (a); 384 385 abits = gmp_urandomb_ui (state, 32) % maxbits; 386 bbits = gmp_urandomb_ui (state, 32) % (maxbits + 100); 387 388 mpz_rrandomb (a, state, abits); 389 390 signs = gmp_urandomb_ui (state, 1); 391 if (signs & 1) 392 mpz_neg (a, a); 393 394 switch (op) 395 { 396 default: 397 abort (); 398 399 case OP_SCAN0: 400 *r = mpz_scan0 (a, bbits); 401 break; 402 case OP_SCAN1: 403 *r = mpz_scan1 (a, bbits); 404 break; 405 } 406 gmp_asprintf (ap, "%Zx", a); 407 *b = bbits; 408 409 mpz_clear (a); 410 } 411 412 void 413 hex_random_str_op (unsigned long maxbits, 414 int base, char **ap, char **rp) 415 { 416 mpz_t a; 417 unsigned long abits; 418 unsigned signs; 419 420 mpz_init (a); 421 422 abits = gmp_urandomb_ui (state, 32) % maxbits; 423 424 mpz_rrandomb (a, state, abits); 425 426 signs = gmp_urandomb_ui (state, 2); 427 if (signs & 1) 428 mpz_neg (a, a); 429 430 *ap = mpz_get_str (NULL, 16, a); 431 *rp = mpz_get_str (NULL, base, a); 432 433 mpz_clear (a); 434 } 435