xref: /netbsd-src/external/lgpl3/gmp/dist/tests/rand/t-urndmm.c (revision 72c7faa4dbb41dbb0238d6b4a109da0d4b236dd4)
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