xref: /netbsd-src/external/lgpl3/gmp/dist/tests/rand/t-urndmm.c (revision 87d689fb734c654d2486f87f7be32f1b53ecdbec)
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.h"
22 #include "gmp-impl.h"
23 #include "tests.h"
24 
25 #ifndef TRUE
26 #define TRUE (1)
27 #endif
28 #ifndef FALSE
29 #define FALSE (0)
30 #endif
31 
32 int
33 check_params (void)
34 {
35   gmp_randstate_t r1, r2;
36   mpz_t a, b, m;
37   int i;
38   int result;
39 
40   result = TRUE;
41 
42   mpz_init (a);
43   mpz_init (b);
44   mpz_init (m);
45 
46   if (result)
47     {
48       /* Test the consistency between urandomm and urandomb. */
49       gmp_randinit_default (r1);
50       gmp_randinit_default (r2);
51       gmp_randseed_ui (r1, 85L);
52       gmp_randseed_ui (r2, 85L);
53       mpz_set_ui (m, 0L);
54       mpz_setbit (m, 80L);
55       for (i = 0; i < 100; i++)
56 	{
57 	  mpz_urandomm (a, r1, m);
58 	  mpz_urandomb (b, r2, 80L);
59 	  if (mpz_cmp (a, b) != 0)
60 	    {
61 	      result = FALSE;
62 	      printf ("mpz_urandomm != mpz_urandomb\n");
63 	      break;
64 	    }
65 	}
66       gmp_randclear (r1);
67       gmp_randclear (r2);
68     }
69 
70   if (result)
71     {
72       /* Test that mpz_urandomm returns the correct result with a
73 	 broken LC.  */
74       mpz_set_ui (a, 0L);
75       gmp_randinit_lc_2exp (r1, a, 0xffL, 8L);
76       mpz_set_ui (m, 5L);
77       /* Warning: This code hangs in gmp 4.1 and below */
78       for (i = 0; i < 100; i++)
79 	{
80 	  mpz_urandomm (a, r1, m);
81 	  if (mpz_cmp_ui (a, 2L) != 0)
82 	    {
83 	      result = FALSE;
84 	      gmp_printf ("mpz_urandomm returns %Zd instead of 2\n", a);
85 	      break;
86 	    }
87 	}
88       gmp_randclear (r1);
89     }
90 
91   if (result)
92     {
93       /* Test that the results are always in range for either
94          positive or negative values of m.  */
95       gmp_randinit_default (r1);
96       mpz_set_ui (m, 5L);
97       mpz_set_si (b, -5L);
98       for (i = 0; i < 100; i++)
99 	{
100 	  mpz_urandomm (a, r1, m);
101 	  if (mpz_cmp_ui (a, 5L) >= 0 || mpz_sgn (a) < 0)
102 	    {
103 	      result = FALSE;
104 	      gmp_printf ("Out-of-range or non-positive value: %Zd\n", a);
105 	      break;
106 	    }
107 	  mpz_urandomm (a, r1, b);
108 	  if (mpz_cmp_ui (a, 5L) >= 0 || mpz_sgn (a) < 0)
109 	    {
110 	      result = FALSE;
111 	      gmp_printf ("Out-of-range or non-positive value (from negative modulus): %Zd\n", a);
112 	      break;
113 	    }
114 	}
115       gmp_randclear (r1);
116     }
117 
118   if (result)
119     {
120       /* Test that m=1 forces always result=0.  */
121       gmp_randinit_default (r1);
122       mpz_set_ui (m, 1L);
123       for (i = 0; i < 100; i++)
124 	{
125 	  mpz_urandomm (a, r1, m);
126 	  if (mpz_sgn (a) != 0)
127 	    {
128 	      result = FALSE;
129 	      gmp_printf ("mpz_urandomm fails with m=1 (result=%Zd)\n", a);
130 	      break;
131 	    }
132 	}
133       gmp_randclear (r1);
134     }
135 
136   mpz_clear (a);
137   mpz_clear (b);
138   mpz_clear (m);
139   return result;
140 }
141 
142 int
143 main (int argc, char *argv[])
144 {
145   int result = TRUE;
146 
147   tests_start ();
148 
149   if (result)
150     if (!check_params ())
151       result = FALSE;
152 
153   tests_end ();
154 
155   if (result)
156     return 0; /* pass */
157   else
158     return 1; /* fail */
159 }
160