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