1 /* Test mpz_urandomm.
2
3 Copyright 2002 Free Software Foundation, Inc.
4
5 This file is part of the GNU MP Library test suite.
6
7 The GNU MP Library test suite is free software; you can redistribute it
8 and/or modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 3 of the License,
10 or (at your option) any later version.
11
12 The GNU MP Library test suite is distributed in the hope that it will be
13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
15 Public License for more details.
16
17 You should have received a copy of the GNU General Public License along with
18 the 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
31 int
check_params(void)32 check_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
141 int
main(int argc,char * argv[])142 main (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 }
159