Home | History | Annotate | Line # | Download | only in mpz
t-invert.c revision 1.1.1.1.8.2
      1  1.1.1.1.8.2  tls /* Test mpz_invert.
      2  1.1.1.1.8.2  tls 
      3  1.1.1.1.8.2  tls Copyright 1991, 1993, 1994, 1996, 1997, 2000, 2001, 2002, 2003, 2004, 2005,
      4  1.1.1.1.8.2  tls 2008, 2009, 2012 Free Software Foundation, Inc.
      5  1.1.1.1.8.2  tls 
      6  1.1.1.1.8.2  tls This file is part of the GNU MP Library test suite.
      7  1.1.1.1.8.2  tls 
      8  1.1.1.1.8.2  tls The GNU MP Library test suite is free software; you can redistribute it
      9  1.1.1.1.8.2  tls and/or modify it under the terms of the GNU General Public License as
     10  1.1.1.1.8.2  tls published by the Free Software Foundation; either version 3 of the License,
     11  1.1.1.1.8.2  tls or (at your option) any later version.
     12  1.1.1.1.8.2  tls 
     13  1.1.1.1.8.2  tls The GNU MP Library test suite is distributed in the hope that it will be
     14  1.1.1.1.8.2  tls useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  1.1.1.1.8.2  tls MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
     16  1.1.1.1.8.2  tls Public License for more details.
     17  1.1.1.1.8.2  tls 
     18  1.1.1.1.8.2  tls You should have received a copy of the GNU General Public License along with
     19  1.1.1.1.8.2  tls the GNU MP Library test suite.  If not, see http://www.gnu.org/licenses/.  */
     20  1.1.1.1.8.2  tls 
     21  1.1.1.1.8.2  tls #include <stdio.h>
     22  1.1.1.1.8.2  tls #include <stdlib.h>
     23  1.1.1.1.8.2  tls 
     24  1.1.1.1.8.2  tls #include "gmp.h"
     25  1.1.1.1.8.2  tls #include "gmp-impl.h"
     26  1.1.1.1.8.2  tls #include "tests.h"
     27  1.1.1.1.8.2  tls 
     28  1.1.1.1.8.2  tls int
     29  1.1.1.1.8.2  tls main (int argc, char **argv)
     30  1.1.1.1.8.2  tls {
     31  1.1.1.1.8.2  tls   mpz_t a, m, ainv, t;
     32  1.1.1.1.8.2  tls   int test, r;
     33  1.1.1.1.8.2  tls   gmp_randstate_ptr rands;
     34  1.1.1.1.8.2  tls   mpz_t bs;
     35  1.1.1.1.8.2  tls   unsigned long bsi, size_range;
     36  1.1.1.1.8.2  tls   int reps = 1000;
     37  1.1.1.1.8.2  tls 
     38  1.1.1.1.8.2  tls   tests_start ();
     39  1.1.1.1.8.2  tls   TESTS_REPS (reps, argv, argc);
     40  1.1.1.1.8.2  tls 
     41  1.1.1.1.8.2  tls   rands = RANDS;
     42  1.1.1.1.8.2  tls 
     43  1.1.1.1.8.2  tls   mpz_init (bs);
     44  1.1.1.1.8.2  tls   mpz_init (a);
     45  1.1.1.1.8.2  tls   mpz_init (m);
     46  1.1.1.1.8.2  tls   mpz_init (ainv);
     47  1.1.1.1.8.2  tls   mpz_init (t);
     48  1.1.1.1.8.2  tls 
     49  1.1.1.1.8.2  tls   for (test = 0; test < reps; test++)
     50  1.1.1.1.8.2  tls     {
     51  1.1.1.1.8.2  tls       mpz_urandomb (bs, rands, 32);
     52  1.1.1.1.8.2  tls       size_range = mpz_get_ui (bs) % 16 + 2;
     53  1.1.1.1.8.2  tls 
     54  1.1.1.1.8.2  tls       mpz_urandomb (bs, rands, size_range);
     55  1.1.1.1.8.2  tls       mpz_rrandomb (a, rands, mpz_get_ui (bs));
     56  1.1.1.1.8.2  tls       do {
     57  1.1.1.1.8.2  tls 	mpz_urandomb (bs, rands, size_range);
     58  1.1.1.1.8.2  tls 	mpz_rrandomb (m, rands, mpz_get_ui (bs));
     59  1.1.1.1.8.2  tls       } while (mpz_sgn (m) == 0);
     60  1.1.1.1.8.2  tls 
     61  1.1.1.1.8.2  tls       mpz_urandomb (bs, rands, 8);
     62  1.1.1.1.8.2  tls       bsi = mpz_get_ui (bs);
     63  1.1.1.1.8.2  tls 
     64  1.1.1.1.8.2  tls       if ((bsi & 1) != 0)
     65  1.1.1.1.8.2  tls 	mpz_neg (a, a);
     66  1.1.1.1.8.2  tls       if ((bsi & 2) != 0)
     67  1.1.1.1.8.2  tls 	mpz_neg (m, m);
     68  1.1.1.1.8.2  tls 
     69  1.1.1.1.8.2  tls       r = mpz_invert (ainv, a, m);
     70  1.1.1.1.8.2  tls       if (r != 0)
     71  1.1.1.1.8.2  tls 	{
     72  1.1.1.1.8.2  tls 	  MPZ_CHECK_FORMAT (ainv);
     73  1.1.1.1.8.2  tls 
     74  1.1.1.1.8.2  tls 	  if (mpz_cmp_ui (ainv, 0) <= 0 || mpz_cmpabs (ainv, m) >= 0)
     75  1.1.1.1.8.2  tls 	    {
     76  1.1.1.1.8.2  tls 	      fprintf (stderr, "ERROR in test %d\n", test);
     77  1.1.1.1.8.2  tls 	      gmp_fprintf (stderr, "Inverse out of range.\n");
     78  1.1.1.1.8.2  tls 	      gmp_fprintf (stderr, "a = %Zx\n", a);
     79  1.1.1.1.8.2  tls 	      gmp_fprintf (stderr, "m = %Zx\n", m);
     80  1.1.1.1.8.2  tls 	      abort ();
     81  1.1.1.1.8.2  tls 	    }
     82  1.1.1.1.8.2  tls 
     83  1.1.1.1.8.2  tls 	  mpz_mul (t, ainv, a);
     84  1.1.1.1.8.2  tls 	  mpz_mod (t, t, m);
     85  1.1.1.1.8.2  tls 
     86  1.1.1.1.8.2  tls 	  if (mpz_cmp_ui (t, 1) != 0)
     87  1.1.1.1.8.2  tls 	    {
     88  1.1.1.1.8.2  tls 	      fprintf (stderr, "ERROR in test %d\n", test);
     89  1.1.1.1.8.2  tls 	      gmp_fprintf (stderr, "a^(-1)*a != 1 (mod m)\n");
     90  1.1.1.1.8.2  tls 	      gmp_fprintf (stderr, "a = %Zx\n", a);
     91  1.1.1.1.8.2  tls 	      gmp_fprintf (stderr, "m = %Zx\n", m);
     92  1.1.1.1.8.2  tls 	      abort ();
     93  1.1.1.1.8.2  tls 	    }
     94  1.1.1.1.8.2  tls 	}
     95  1.1.1.1.8.2  tls       else /* Inverse deos not exist */
     96  1.1.1.1.8.2  tls 	{
     97  1.1.1.1.8.2  tls 	  if (mpz_cmpabs_ui (m, 1) <= 0)
     98  1.1.1.1.8.2  tls 	    continue; /* OK */
     99  1.1.1.1.8.2  tls 
    100  1.1.1.1.8.2  tls 	  mpz_gcd (t, a, m);
    101  1.1.1.1.8.2  tls 	  if (mpz_cmp_ui (t, 1) == 0)
    102  1.1.1.1.8.2  tls 	    {
    103  1.1.1.1.8.2  tls 	      fprintf (stderr, "ERROR in test %d\n", test);
    104  1.1.1.1.8.2  tls 	      gmp_fprintf (stderr, "Inverse exists, but was not found.\n");
    105  1.1.1.1.8.2  tls 	      gmp_fprintf (stderr, "a = %Zx\n", a);
    106  1.1.1.1.8.2  tls 	      gmp_fprintf (stderr, "m = %Zx\n", m);
    107  1.1.1.1.8.2  tls 	      abort ();
    108  1.1.1.1.8.2  tls 	    }
    109  1.1.1.1.8.2  tls 	}
    110  1.1.1.1.8.2  tls     }
    111  1.1.1.1.8.2  tls 
    112  1.1.1.1.8.2  tls   mpz_clear (bs);
    113  1.1.1.1.8.2  tls   mpz_clear (a);
    114  1.1.1.1.8.2  tls   mpz_clear (m);
    115  1.1.1.1.8.2  tls   mpz_clear (ainv);
    116  1.1.1.1.8.2  tls   mpz_clear (t);
    117  1.1.1.1.8.2  tls 
    118  1.1.1.1.8.2  tls   tests_end ();
    119  1.1.1.1.8.2  tls   exit (0);
    120  1.1.1.1.8.2  tls }
    121