github.com/aergoio/aergo@v1.3.1/libtool/src/gmp-6.1.2/tests/mpz/t-powm_ui.c (about)

     1  /* Test mpz_powm_ui, mpz_mul, mpz_mod.
     2  
     3  Copyright 1991, 1993, 1994, 1996, 1997, 2000-2002, 2013 Free Software
     4  Foundation, Inc.
     5  
     6  This file is part of the GNU MP Library test suite.
     7  
     8  The GNU MP Library test suite is free software; you can redistribute it
     9  and/or modify it under the terms of the GNU General Public License as
    10  published by the Free Software Foundation; either version 3 of the License,
    11  or (at your option) any later version.
    12  
    13  The GNU MP Library test suite is distributed in the hope that it will be
    14  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
    16  Public License for more details.
    17  
    18  You should have received a copy of the GNU General Public License along with
    19  the GNU MP Library test suite.  If not, see https://www.gnu.org/licenses/.  */
    20  
    21  #include <stdio.h>
    22  #include <stdlib.h>
    23  
    24  #include "gmp.h"
    25  #include "gmp-impl.h"
    26  #include "tests.h"
    27  
    28  int
    29  main (int argc, char **argv)
    30  {
    31    mpz_t base, exp, mod;
    32    mpz_t r1, r2, base2;
    33    mp_size_t base_size, exp_size, mod_size;
    34    unsigned long int exp2;
    35    int i;
    36    int reps = 100;
    37    gmp_randstate_ptr rands;
    38    mpz_t bs;
    39    unsigned long bsi, size_range;
    40  
    41    tests_start ();
    42    rands = RANDS;
    43  
    44    TESTS_REPS (reps, argv, argc);
    45  
    46    mpz_inits (bs, base, exp, mod, r1, r2, base2, NULL);
    47  
    48    for (i = 0; i < reps; i++)
    49      {
    50        mpz_urandomb (bs, rands, 32);
    51        size_range = mpz_get_ui (bs) % 18 + 2;
    52  
    53        do  /* Loop until mathematically well-defined.  */
    54  	{
    55  	  mpz_urandomb (bs, rands, size_range);
    56  	  base_size = mpz_get_ui (bs);
    57  	  mpz_rrandomb (base, rands, base_size);
    58  
    59  	  mpz_urandomb (bs, rands, 6L);
    60  	  exp_size = mpz_get_ui (bs);
    61  	  mpz_rrandomb (exp, rands, exp_size);
    62  	  exp2 = mpz_getlimbn (exp, (mp_size_t) 0);
    63  	}
    64        while (mpz_cmp_ui (base, 0) == 0 && exp2 == 0);
    65  
    66        do
    67          {
    68  	  mpz_urandomb (bs, rands, size_range);
    69  	  mod_size = mpz_get_ui (bs);
    70  	  mpz_rrandomb (mod, rands, mod_size);
    71  	}
    72        while (mpz_cmp_ui (mod, 0) == 0);
    73  
    74        mpz_urandomb (bs, rands, 2);
    75        bsi = mpz_get_ui (bs);
    76        if ((bsi & 1) != 0)
    77  	mpz_neg (base, base);
    78  
    79        /* printf ("%ld %ld\n", SIZ (base), SIZ (mod)); */
    80  
    81  #if 0
    82        putc ('\n', stderr);
    83        gmp_fprintf (stderr, "B = 0x%Zx\n", base);
    84        gmp_fprintf (stderr, "M = 0x%Zx\n", mod);
    85  #endif
    86  
    87        exp2 = mpz_getlimbn (exp, (mp_size_t) 0);
    88        mpz_set_ui (r2, 1);
    89        mpz_set (base2, base);
    90        mpz_mod (r2, r2, mod);	/* needed when exp==0 and mod==1 */
    91        while (exp2 != 0)
    92  	{
    93  	  if (exp2 % 2 != 0)
    94  	    {
    95  	      mpz_mul (r2, r2, base2);
    96  	      mpz_mod (r2, r2, mod);
    97  	    }
    98  	  mpz_mul (base2, base2, base2);
    99  	  mpz_mod (base2, base2, mod);
   100  	  exp2 = exp2 / 2;
   101  	}
   102  
   103        exp2 = mpz_getlimbn (exp, (mp_size_t) 0);
   104        mpz_powm_ui (r1, base, exp2, mod);
   105        MPZ_CHECK_FORMAT (r1);
   106  
   107  #if 0
   108        gmp_fprintf (stderr, "R   = 0x%Zx\n", r1);
   109        gmp_fprintf (stderr, "REF = 0x%Zx\n", r2);
   110  #endif
   111  
   112        if (mpz_cmp (r1, r2) != 0)
   113  	{
   114  	  fprintf (stderr, "\ntest %d: Incorrect results for operands:\n", i);
   115  	  gmp_fprintf (stderr, "B = 0x%Zx\n", base);
   116  	  gmp_fprintf (stderr, "E = 0x%Zx\n", exp);
   117  	  gmp_fprintf (stderr, "M = 0x%Zx\n", mod);
   118  	  gmp_fprintf (stderr, "R   = 0x%Zx\n", r1);
   119  	  gmp_fprintf (stderr, "REF = 0x%Zx\n", r2);
   120  	  abort ();
   121  	}
   122      }
   123  
   124    mpz_clears (bs, base, exp, mod, r1, r2, base2, NULL);
   125  
   126    tests_end ();
   127    exit (0);
   128  }