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