github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/mini-gmp/tests/hex-random.c (about) 1 /* 2 3 Copyright 2011, 2016 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 https://www.gnu.org/licenses/. */ 19 20 #include <stdio.h> 21 #include <stdlib.h> 22 23 #include <time.h> 24 25 #ifdef __unix__ 26 # include <unistd.h> 27 # include <sys/time.h> 28 #endif 29 30 #include "gmp.h" 31 32 #include "hex-random.h" 33 34 static gmp_randstate_t state; 35 36 static void 37 mkseed (mpz_t seed) 38 { 39 FILE *f = fopen ("/dev/urandom", "rb"); 40 if (f) 41 { 42 unsigned char buf[6]; 43 size_t res; 44 45 setbuf (f, NULL); 46 res = fread (buf, sizeof(buf), 1, f); 47 fclose (f); 48 49 if (res == 1) 50 { 51 mpz_import (seed, sizeof(buf), 1, 1, 0, 0, buf); 52 return; 53 } 54 } 55 56 #ifdef __unix__ 57 { 58 struct timeval tv; 59 mpz_t usec; 60 mpz_init (usec); 61 62 gettimeofday (&tv, NULL); 63 mpz_set_ui (seed, tv.tv_sec); 64 mpz_set_ui (usec, tv.tv_usec); 65 /* usec fits in 20 bits, shift left to make it 48 bits. */ 66 mpz_mul_2exp (usec, usec, 28); 67 mpz_xor (seed, seed, usec); 68 69 mpz_clear (usec); 70 } 71 #else 72 mpz_set_ui (seed, time (NULL)); 73 #endif 74 } 75 76 void 77 hex_random_init (void) 78 { 79 mpz_t seed; 80 char *env_seed; 81 82 mpz_init (seed); 83 84 env_seed = getenv ("GMP_CHECK_RANDOMIZE"); 85 if (env_seed && env_seed[0]) 86 { 87 mpz_set_str (seed, env_seed, 0); 88 if (mpz_cmp_ui (seed, 0) != 0) 89 gmp_printf ("Re-seeding with GMP_CHECK_RANDOMIZE=%Zd\n", seed); 90 else 91 { 92 mkseed (seed); 93 gmp_printf ("Seed GMP_CHECK_RANDOMIZE=%Zd (include this in bug reports)\n", seed); 94 } 95 fflush (stdout); 96 } 97 else 98 mpz_set_ui (seed, 4711); 99 100 gmp_randinit_default (state); 101 gmp_randseed (state, seed); 102 103 mpz_clear (seed); 104 } 105 106 char * 107 hex_urandomb (unsigned long bits) 108 { 109 char *res; 110 mpz_t x; 111 112 mpz_init (x); 113 mpz_urandomb (x, state, bits); 114 gmp_asprintf (&res, "%Zx", x); 115 mpz_clear (x); 116 return res; 117 } 118 119 char * 120 hex_rrandomb (unsigned long bits) 121 { 122 char *res; 123 mpz_t x; 124 125 mpz_init (x); 126 mpz_rrandomb (x, state, bits); 127 gmp_asprintf (&res, "%Zx", x); 128 mpz_clear (x); 129 return res; 130 } 131 132 char * 133 hex_rrandomb_export (void *dst, size_t *countp, 134 int order, size_t size, int endian, unsigned long bits) 135 { 136 char *res; 137 mpz_t x; 138 mpz_init (x); 139 mpz_rrandomb (x, state, bits); 140 gmp_asprintf (&res, "%Zx", x); 141 mpz_export (dst, countp, order, size, endian, 0, x); 142 mpz_clear (x); 143 return res; 144 } 145 146 void hex_random_op2 (enum hex_random_op op, unsigned long maxbits, 147 char **ap, char **rp) 148 { 149 mpz_t a, r; 150 unsigned long abits; 151 unsigned signs; 152 153 mpz_init (a); 154 mpz_init (r); 155 156 abits = gmp_urandomb_ui (state, 32) % maxbits; 157 158 mpz_rrandomb (a, state, abits); 159 160 signs = gmp_urandomb_ui (state, 1); 161 if (signs & 1) 162 mpz_neg (a, a); 163 164 switch (op) 165 { 166 default: 167 abort (); 168 case OP_SQR: 169 mpz_mul (r, a, a); 170 break; 171 } 172 173 gmp_asprintf (ap, "%Zx", a); 174 gmp_asprintf (rp, "%Zx", r); 175 176 mpz_clear (a); 177 mpz_clear (r); 178 } 179 180 void 181 hex_random_op3 (enum hex_random_op op, unsigned long maxbits, 182 char **ap, char **bp, char **rp) 183 { 184 mpz_t a, b, r; 185 unsigned long abits, bbits; 186 unsigned signs; 187 188 mpz_init (a); 189 mpz_init (b); 190 mpz_init (r); 191 192 abits = gmp_urandomb_ui (state, 32) % maxbits; 193 bbits = gmp_urandomb_ui (state, 32) % maxbits; 194 195 mpz_rrandomb (a, state, abits); 196 mpz_rrandomb (b, state, bbits); 197 198 signs = gmp_urandomb_ui (state, 3); 199 if (signs & 1) 200 mpz_neg (a, a); 201 if (signs & 2) 202 mpz_neg (b, b); 203 204 switch (op) 205 { 206 default: 207 abort (); 208 case OP_ADD: 209 mpz_add (r, a, b); 210 break; 211 case OP_SUB: 212 mpz_sub (r, a, b); 213 break; 214 case OP_MUL: 215 mpz_mul (r, a, b); 216 break; 217 case OP_GCD: 218 if (signs & 4) 219 { 220 /* Produce a large gcd */ 221 unsigned long gbits = gmp_urandomb_ui (state, 32) % maxbits; 222 mpz_rrandomb (r, state, gbits); 223 mpz_mul (a, a, r); 224 mpz_mul (b, b, r); 225 } 226 mpz_gcd (r, a, b); 227 break; 228 case OP_LCM: 229 if (signs & 4) 230 { 231 /* Produce a large gcd */ 232 unsigned long gbits = gmp_urandomb_ui (state, 32) % maxbits; 233 mpz_rrandomb (r, state, gbits); 234 mpz_mul (a, a, r); 235 mpz_mul (b, b, r); 236 } 237 mpz_lcm (r, a, b); 238 break; 239 case OP_AND: 240 mpz_and (r, a, b); 241 break; 242 case OP_IOR: 243 mpz_ior (r, a, b); 244 break; 245 case OP_XOR: 246 mpz_xor (r, a, b); 247 break; 248 } 249 250 gmp_asprintf (ap, "%Zx", a); 251 gmp_asprintf (bp, "%Zx", b); 252 gmp_asprintf (rp, "%Zx", r); 253 254 mpz_clear (a); 255 mpz_clear (b); 256 mpz_clear (r); 257 } 258 259 void 260 hex_random_op4 (enum hex_random_op op, unsigned long maxbits, 261 char **ap, char **bp, char **cp, char **dp) 262 { 263 mpz_t a, b, c, d; 264 unsigned long abits, bbits; 265 unsigned signs; 266 267 mpz_init (a); 268 mpz_init (b); 269 mpz_init (c); 270 mpz_init (d); 271 272 if (op == OP_POWM) 273 { 274 unsigned long cbits; 275 abits = gmp_urandomb_ui (state, 32) % maxbits; 276 bbits = 1 + gmp_urandomb_ui (state, 32) % maxbits; 277 cbits = 2 + gmp_urandomb_ui (state, 32) % maxbits; 278 279 mpz_rrandomb (a, state, abits); 280 mpz_rrandomb (b, state, bbits); 281 mpz_rrandomb (c, state, cbits); 282 283 signs = gmp_urandomb_ui (state, 3); 284 if (signs & 1) 285 mpz_neg (a, a); 286 if (signs & 2) 287 { 288 mpz_t g; 289 290 /* If we negate the exponent, must make sure that gcd(a, c) = 1 */ 291 if (mpz_sgn (a) == 0) 292 mpz_set_ui (a, 1); 293 else 294 { 295 mpz_init (g); 296 297 for (;;) 298 { 299 mpz_gcd (g, a, c); 300 if (mpz_cmp_ui (g, 1) == 0) 301 break; 302 mpz_divexact (a, a, g); 303 } 304 mpz_clear (g); 305 } 306 mpz_neg (b, b); 307 } 308 if (signs & 4) 309 mpz_neg (c, c); 310 311 mpz_powm (d, a, b, c); 312 } 313 else 314 { 315 unsigned long qbits; 316 bbits = 1 + gmp_urandomb_ui (state, 32) % maxbits; 317 qbits = gmp_urandomb_ui (state, 32) % maxbits; 318 abits = bbits + qbits; 319 if (abits > 30) 320 abits -= 30; 321 else 322 abits = 0; 323 324 mpz_rrandomb (a, state, abits); 325 mpz_rrandomb (b, state, bbits); 326 327 signs = gmp_urandomb_ui (state, 2); 328 if (signs & 1) 329 mpz_neg (a, a); 330 if (signs & 2) 331 mpz_neg (b, b); 332 333 switch (op) 334 { 335 default: 336 abort (); 337 case OP_CDIV: 338 mpz_cdiv_qr (c, d, a, b); 339 break; 340 case OP_FDIV: 341 mpz_fdiv_qr (c, d, a, b); 342 break; 343 case OP_TDIV: 344 mpz_tdiv_qr (c, d, a, b); 345 break; 346 } 347 } 348 gmp_asprintf (ap, "%Zx", a); 349 gmp_asprintf (bp, "%Zx", b); 350 gmp_asprintf (cp, "%Zx", c); 351 gmp_asprintf (dp, "%Zx", d); 352 353 mpz_clear (a); 354 mpz_clear (b); 355 mpz_clear (c); 356 mpz_clear (d); 357 } 358 359 void 360 hex_random_bit_op (enum hex_random_op op, unsigned long maxbits, 361 char **ap, unsigned long *b, char **rp) 362 { 363 mpz_t a, r; 364 unsigned long abits, bbits; 365 unsigned signs; 366 367 mpz_init (a); 368 mpz_init (r); 369 370 abits = gmp_urandomb_ui (state, 32) % maxbits; 371 bbits = gmp_urandomb_ui (state, 32) % (maxbits + 100); 372 373 mpz_rrandomb (a, state, abits); 374 375 signs = gmp_urandomb_ui (state, 1); 376 if (signs & 1) 377 mpz_neg (a, a); 378 379 switch (op) 380 { 381 default: 382 abort (); 383 384 case OP_SETBIT: 385 mpz_set (r, a); 386 mpz_setbit (r, bbits); 387 break; 388 case OP_CLRBIT: 389 mpz_set (r, a); 390 mpz_clrbit (r, bbits); 391 break; 392 case OP_COMBIT: 393 mpz_set (r, a); 394 mpz_combit (r, bbits); 395 break; 396 case OP_CDIV_Q_2: 397 mpz_cdiv_q_2exp (r, a, bbits); 398 break; 399 case OP_CDIV_R_2: 400 mpz_cdiv_r_2exp (r, a, bbits); 401 break; 402 case OP_FDIV_Q_2: 403 mpz_fdiv_q_2exp (r, a, bbits); 404 break; 405 case OP_FDIV_R_2: 406 mpz_fdiv_r_2exp (r, a, bbits); 407 break; 408 case OP_TDIV_Q_2: 409 mpz_tdiv_q_2exp (r, a, bbits); 410 break; 411 case OP_TDIV_R_2: 412 mpz_tdiv_r_2exp (r, a, bbits); 413 break; 414 } 415 416 gmp_asprintf (ap, "%Zx", a); 417 *b = bbits; 418 gmp_asprintf (rp, "%Zx", r); 419 420 mpz_clear (a); 421 mpz_clear (r); 422 } 423 424 void 425 hex_random_scan_op (enum hex_random_op op, unsigned long maxbits, 426 char **ap, unsigned long *b, unsigned long *r) 427 { 428 mpz_t a; 429 unsigned long abits, bbits; 430 unsigned signs; 431 432 mpz_init (a); 433 434 abits = gmp_urandomb_ui (state, 32) % maxbits; 435 bbits = gmp_urandomb_ui (state, 32) % (maxbits + 100); 436 437 mpz_rrandomb (a, state, abits); 438 439 signs = gmp_urandomb_ui (state, 1); 440 if (signs & 1) 441 mpz_neg (a, a); 442 443 switch (op) 444 { 445 default: 446 abort (); 447 448 case OP_SCAN0: 449 *r = mpz_scan0 (a, bbits); 450 break; 451 case OP_SCAN1: 452 *r = mpz_scan1 (a, bbits); 453 break; 454 } 455 gmp_asprintf (ap, "%Zx", a); 456 *b = bbits; 457 458 mpz_clear (a); 459 } 460 461 void 462 hex_random_str_op (unsigned long maxbits, 463 int base, char **ap, char **rp) 464 { 465 mpz_t a; 466 unsigned long abits; 467 unsigned signs; 468 469 mpz_init (a); 470 471 abits = gmp_urandomb_ui (state, 32) % maxbits; 472 473 mpz_rrandomb (a, state, abits); 474 475 signs = gmp_urandomb_ui (state, 2); 476 if (signs & 1) 477 mpz_neg (a, a); 478 479 *ap = mpz_get_str (NULL, 16, a); 480 *rp = mpz_get_str (NULL, base, a); 481 482 mpz_clear (a); 483 }