xref: /openbsd-src/regress/lib/libcrypto/rand/randtest.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /* crypto/rand/randtest.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  *
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  *
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  *
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  *
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58 
59 #include <stdio.h>
60 #include <stdlib.h>
61 #include <openssl/rand.h>
62 
63 /* some FIPS 140-1 random number test */
64 /* some simple tests */
65 
66 int main(int argc,char **argv)
67 	{
68 	unsigned char buf[2500];
69 	int i,j,k,s,sign,nsign,err=0;
70 	unsigned long n1;
71 	unsigned long n2[16];
72 	unsigned long runs[2][34];
73 	/*double d; */
74 	long d;
75 
76 	i = RAND_pseudo_bytes(buf,2500);
77 	if (i < 0)
78 		{
79 		printf ("init failed, the rand method is not properly installed\n");
80 		err++;
81 		goto err;
82 		}
83 
84 	n1=0;
85 	for (i=0; i<16; i++) n2[i]=0;
86 	for (i=0; i<34; i++) runs[0][i]=runs[1][i]=0;
87 
88 	/* test 1 and 2 */
89 	sign=0;
90 	nsign=0;
91 	for (i=0; i<2500; i++)
92 		{
93 		j=buf[i];
94 
95 		n2[j&0x0f]++;
96 		n2[(j>>4)&0x0f]++;
97 
98 		for (k=0; k<8; k++)
99 			{
100 			s=(j&0x01);
101 			if (s == sign)
102 				nsign++;
103 			else
104 				{
105 				if (nsign > 34) nsign=34;
106 				if (nsign != 0)
107 					{
108 					runs[sign][nsign-1]++;
109 					if (nsign > 6)
110 						runs[sign][5]++;
111 					}
112 				sign=s;
113 				nsign=1;
114 				}
115 
116 			if (s) n1++;
117 			j>>=1;
118 			}
119 		}
120 		if (nsign > 34) nsign=34;
121 		if (nsign != 0) runs[sign][nsign-1]++;
122 
123 	/* test 1 */
124 	if (!((9654 < n1) && (n1 < 10346)))
125 		{
126 		printf("test 1 failed, X=%lu\n",n1);
127 		err++;
128 		}
129 	printf("test 1 done\n");
130 
131 	/* test 2 */
132 	d=0;
133 	for (i=0; i<16; i++)
134 		d+=n2[i]*n2[i];
135 	d=(d*8)/25-500000;
136 	if (!((103 < d) && (d < 5740)))
137 		{
138 		printf("test 2 failed, X=%ld.%02ld\n",d/100L,d%100L);
139 		err++;
140 		}
141 	printf("test 2 done\n");
142 
143 	/* test 3 */
144 	for (i=0; i<2; i++)
145 		{
146 		if (!((2267 < runs[i][0]) && (runs[i][0] < 2733)))
147 			{
148 			printf("test 3 failed, bit=%d run=%d num=%lu\n",
149 				i,1,runs[i][0]);
150 			err++;
151 			}
152 		if (!((1079 < runs[i][1]) && (runs[i][1] < 1421)))
153 			{
154 			printf("test 3 failed, bit=%d run=%d num=%lu\n",
155 				i,2,runs[i][1]);
156 			err++;
157 			}
158 		if (!(( 502 < runs[i][2]) && (runs[i][2] <  748)))
159 			{
160 			printf("test 3 failed, bit=%d run=%d num=%lu\n",
161 				i,3,runs[i][2]);
162 			err++;
163 			}
164 		if (!(( 223 < runs[i][3]) && (runs[i][3] <  402)))
165 			{
166 			printf("test 3 failed, bit=%d run=%d num=%lu\n",
167 				i,4,runs[i][3]);
168 			err++;
169 			}
170 		if (!((  90 < runs[i][4]) && (runs[i][4] <  223)))
171 			{
172 			printf("test 3 failed, bit=%d run=%d num=%lu\n",
173 				i,5,runs[i][4]);
174 			err++;
175 			}
176 		if (!((  90 < runs[i][5]) && (runs[i][5] <  223)))
177 			{
178 			printf("test 3 failed, bit=%d run=%d num=%lu\n",
179 				i,6,runs[i][5]);
180 			err++;
181 			}
182 		}
183 	printf("test 3 done\n");
184 
185 	/* test 4 */
186 	if (runs[0][33] != 0)
187 		{
188 		printf("test 4 failed, bit=%d run=%d num=%lu\n",
189 			0,34,runs[0][33]);
190 		err++;
191 		}
192 	if (runs[1][33] != 0)
193 		{
194 		printf("test 4 failed, bit=%d run=%d num=%lu\n",
195 			1,34,runs[1][33]);
196 		err++;
197 		}
198 	printf("test 4 done\n");
199  err:
200 	err=((err)?1:0);
201 	exit(err);
202 	}
203