blob: ae700ddcb3a3fe117025e0d3b94144db51ed8234 [file] [log] [blame]
Austin Schuhdace2a62020-08-18 10:56:48 -07001/* Test mpz_urandomm.
2
3Copyright 2002 Free Software Foundation, Inc.
4
5This file is part of the GNU MP Library test suite.
6
7The GNU MP Library test suite is free software; you can redistribute it
8and/or modify it under the terms of the GNU General Public License as
9published by the Free Software Foundation; either version 3 of the License,
10or (at your option) any later version.
11
12The GNU MP Library test suite is distributed in the hope that it will be
13useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15Public License for more details.
16
17You should have received a copy of the GNU General Public License along with
18the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
19
20#include <stdio.h>
21#include "gmp-impl.h"
22#include "tests.h"
23
24#ifndef TRUE
25#define TRUE (1)
26#endif
27#ifndef FALSE
28#define FALSE (0)
29#endif
30
31int
32check_params (void)
33{
34 gmp_randstate_t r1, r2;
35 mpz_t a, b, m;
36 int i;
37 int result;
38
39 result = TRUE;
40
41 mpz_init (a);
42 mpz_init (b);
43 mpz_init (m);
44
45 if (result)
46 {
47 /* Test the consistency between urandomm and urandomb. */
48 gmp_randinit_default (r1);
49 gmp_randinit_default (r2);
50 gmp_randseed_ui (r1, 85L);
51 gmp_randseed_ui (r2, 85L);
52 mpz_set_ui (m, 0L);
53 mpz_setbit (m, 80L);
54 for (i = 0; i < 100; i++)
55 {
56 mpz_urandomm (a, r1, m);
57 mpz_urandomb (b, r2, 80L);
58 if (mpz_cmp (a, b) != 0)
59 {
60 result = FALSE;
61 printf ("mpz_urandomm != mpz_urandomb\n");
62 break;
63 }
64 }
65 gmp_randclear (r1);
66 gmp_randclear (r2);
67 }
68
69 if (result)
70 {
71 /* Test that mpz_urandomm returns the correct result with a
72 broken LC. */
73 mpz_set_ui (a, 0L);
74 gmp_randinit_lc_2exp (r1, a, 0xffL, 8L);
75 mpz_set_ui (m, 5L);
76 /* Warning: This code hangs in gmp 4.1 and below */
77 for (i = 0; i < 100; i++)
78 {
79 mpz_urandomm (a, r1, m);
80 if (mpz_cmp_ui (a, 2L) != 0)
81 {
82 result = FALSE;
83 gmp_printf ("mpz_urandomm returns %Zd instead of 2\n", a);
84 break;
85 }
86 }
87 gmp_randclear (r1);
88 }
89
90 if (result)
91 {
92 /* Test that the results are always in range for either
93 positive or negative values of m. */
94 gmp_randinit_default (r1);
95 mpz_set_ui (m, 5L);
96 mpz_set_si (b, -5L);
97 for (i = 0; i < 100; i++)
98 {
99 mpz_urandomm (a, r1, m);
100 if (mpz_cmp_ui (a, 5L) >= 0 || mpz_sgn (a) < 0)
101 {
102 result = FALSE;
103 gmp_printf ("Out-of-range or non-positive value: %Zd\n", a);
104 break;
105 }
106 mpz_urandomm (a, r1, b);
107 if (mpz_cmp_ui (a, 5L) >= 0 || mpz_sgn (a) < 0)
108 {
109 result = FALSE;
110 gmp_printf ("Out-of-range or non-positive value (from negative modulus): %Zd\n", a);
111 break;
112 }
113 }
114 gmp_randclear (r1);
115 }
116
117 if (result)
118 {
119 /* Test that m=1 forces always result=0. */
120 gmp_randinit_default (r1);
121 mpz_set_ui (m, 1L);
122 for (i = 0; i < 100; i++)
123 {
124 mpz_urandomm (a, r1, m);
125 if (mpz_sgn (a) != 0)
126 {
127 result = FALSE;
128 gmp_printf ("mpz_urandomm fails with m=1 (result=%Zd)\n", a);
129 break;
130 }
131 }
132 gmp_randclear (r1);
133 }
134
135 mpz_clear (a);
136 mpz_clear (b);
137 mpz_clear (m);
138 return result;
139}
140
141int
142main (int argc, char *argv[])
143{
144 int result = TRUE;
145
146 tests_start ();
147
148 if (result)
149 if (!check_params ())
150 result = FALSE;
151
152 tests_end ();
153
154 if (result)
155 return 0; /* pass */
156 else
157 return 1; /* fail */
158}