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