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