summaryrefslogtreecommitdiffstats
path: root/3rd_party/libsrp6a-sha512/t_truerand.c
diff options
context:
space:
mode:
Diffstat (limited to '3rd_party/libsrp6a-sha512/t_truerand.c')
-rw-r--r--3rd_party/libsrp6a-sha512/t_truerand.c241
1 files changed, 241 insertions, 0 deletions
diff --git a/3rd_party/libsrp6a-sha512/t_truerand.c b/3rd_party/libsrp6a-sha512/t_truerand.c
new file mode 100644
index 0000000..f995ed7
--- /dev/null
+++ b/3rd_party/libsrp6a-sha512/t_truerand.c
@@ -0,0 +1,241 @@
1/*
2 * Physically random numbers (very nearly uniform)
3 * D. P. Mitchell
4 * Modified by Matt Blaze 7/95
5 */
6/*
7 * The authors of this software are Don Mitchell and Matt Blaze.
8 * Copyright (c) 1995 by AT&T.
9 * Permission to use, copy, and modify this software without fee
10 * is hereby granted, provided that this entire notice is included in
11 * all copies of any software which is or includes a copy or
12 * modification of this software and in all copies of the supporting
13 * documentation for such software.
14 *
15 * This software may be subject to United States export controls.
16 *
17 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED
18 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR AT&T MAKE ANY
19 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY
20 * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE.
21 */
22
23/*
24 * WARNING: depending on the particular platform, raw_truerand()
25 * output may be biased or correlated. In general, you can expect
26 * about 16 bits of "pseudo-entropy" out of each 32 bit word returned
27 * by truerand(), but it may not be uniformly diffused. You should
28 * raw_therefore run the output through some post-whitening function
29 * (like MD5 or DES or whatever) before using it to generate key
30 * material. (RSAREF's random package does this for you when you feed
31 * raw_truerand() bits to the seed input function.)
32 *
33 * The application interface, for 8, 16, and 32 bit properly "whitened"
34 * random numbers, can be found in trand8(), trand16(), and trand32().
35 * Use those instead of calling raw_truerand() directly.
36 *
37 * The basic idea here is that between clock "skew" and various
38 * hard-to-predict OS event arrivals, counting a tight loop will yield
39 * a little (maybe a third of a bit or so) of "good" randomness per
40 * interval clock tick. This seems to work well even on unloaded
41 * machines. If there is a human operator at the machine, you should
42 * augment truerand with other measure, like keyboard event timing.
43 * On server machines (e.g., when you need to generate a
44 * Diffie-Hellman secret) truerand alone may be good enough.
45 *
46 * Test these assumptions on your own platform before fielding a
47 * system based on this software or these techniques.
48 *
49 * This software seems to work well (at 10 or so bits per
50 * raw_truerand() call) on a Sun Sparc-20 under SunOS 4.1.3 and on a
51 * P100 under BSDI 2.0. You're on your own elsewhere.
52 *
53 */
54
55#include "t_defines.h"
56
57#ifdef WIN32
58
59# ifdef CRYPTOLIB
60
61/* Cryptolib contains its own truerand() on both UNIX and Windows. */
62/* Only use cryptolib's truerand under Windows */
63
64# include "libcrypt.h"
65
66unsigned long
67raw_truerand()
68{
69 return truerand();
70}
71
72# else /* !CRYPTOLIB && WIN32 */
73
74#include <windows.h>
75#include <wtypes.h>
76#include <winbase.h>
77#include <windef.h>
78#include <winnt.h>
79#include <winuser.h>
80#include <process.h>
81
82volatile unsigned long count, ocount, randbuf;
83volatile int dontstop;
84char outbuf[1024], *bufp;
85
86static void counter() {
87 while (dontstop)
88 count++;
89 _endthread();
90}
91
92
93static unsigned long roulette() {
94 unsigned long thread;
95
96 count = 0;
97 dontstop= 1;
98 while ((thread = _beginthread((void *)counter, 1024, NULL)) < 0)
99 ;
100
101 Sleep(16);
102 dontstop = 0;
103 Sleep(1);
104
105 count ^= (count>>3) ^ (count>>6) ^ (ocount);
106 count &= 0x7;
107 ocount = count;
108 randbuf = (randbuf<<3) ^ count;
109 return randbuf;
110}
111
112
113unsigned long
114raw_truerand() {
115
116 roulette();
117 roulette();
118 roulette();
119 roulette();
120 roulette();
121 roulette();
122 roulette();
123 roulette();
124 roulette();
125 roulette();
126 return roulette();
127}
128
129# endif /* CRYPTOLIB */
130
131#else /* !WIN32 */
132
133#include <signal.h>
134#include <setjmp.h>
135#include <sys/time.h>
136#include <math.h>
137#include <stdio.h>
138
139#ifdef OLD_TRUERAND
140static jmp_buf env;
141#endif
142static unsigned volatile count
143#ifndef OLD_TRUERAND
144 , done = 0
145#endif
146;
147
148static unsigned ocount;
149static unsigned buffer;
150
151static void
152tick()
153{
154 struct itimerval it, oit;
155
156 it.it_interval.tv_sec = 0;
157 it.it_interval.tv_usec = 0;
158 it.it_value.tv_sec = 0;
159 it.it_value.tv_usec = 16665;
160 if (setitimer(ITIMER_REAL, &it, &oit) < 0)
161 perror("tick");
162}
163
164static void
165interrupt()
166{
167 if (count) {
168#ifdef OLD_TRUERAND
169 longjmp(env, 1);
170#else
171 ++done;
172 return;
173#endif
174 }
175
176 (void) signal(SIGALRM, interrupt);
177 tick();
178}
179
180static unsigned long
181roulette()
182{
183#ifdef OLD_TRUERAND
184 if (setjmp(env)) {
185 count ^= (count>>3) ^ (count>>6) ^ ocount;
186 count &= 0x7;
187 ocount=count;
188 buffer = (buffer<<3) ^ count;
189 return buffer;
190 }
191#else
192 done = 0;
193#endif
194 (void) signal(SIGALRM, interrupt);
195 count = 0;
196 tick();
197#ifdef OLD_TRUERAND
198 for (;;)
199#else
200 while(done == 0)
201#endif
202 count++; /* about 1 MHz on VAX 11/780 */
203#ifndef OLD_TRUERAND
204 count ^= (count>>3) ^ (count>>6) ^ ocount;
205 count &= 0x7;
206 ocount=count;
207 buffer = (buffer<<3) ^ count;
208 return buffer;
209#endif
210}
211
212unsigned long
213raw_truerand()
214{
215 count=0;
216 (void) roulette();
217 (void) roulette();
218 (void) roulette();
219 (void) roulette();
220 (void) roulette();
221 (void) roulette();
222 (void) roulette();
223 (void) roulette();
224 (void) roulette();
225 (void) roulette();
226 return roulette();
227}
228
229int
230raw_n_truerand(int n)
231{
232 int slop, v;
233
234 slop = 0x7FFFFFFF % n;
235 do {
236 v = raw_truerand() >> 1;
237 } while (v <= slop);
238 return v % n;
239}
240
241#endif /* !CRYPTOLIB || !WIN32 */