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  }