1ea906c41SOllivier Robert /*
2ea906c41SOllivier Robert * Copyright (c) 1983, 1993
3ea906c41SOllivier Robert * The Regents of the University of California. All rights reserved.
4ea906c41SOllivier Robert *
5ea906c41SOllivier Robert * Redistribution and use in source and binary forms, with or without
6ea906c41SOllivier Robert * modification, are permitted provided that the following conditions
7ea906c41SOllivier Robert * are met:
8ea906c41SOllivier Robert * 1. Redistributions of source code must retain the above copyright
9ea906c41SOllivier Robert * notice, this list of conditions and the following disclaimer.
10ea906c41SOllivier Robert * 2. Redistributions in binary form must reproduce the above copyright
11ea906c41SOllivier Robert * notice, this list of conditions and the following disclaimer in the
12ea906c41SOllivier Robert * documentation and/or other materials provided with the distribution.
13ea906c41SOllivier Robert * 3. All advertising materials mentioning features or use of this software
14ea906c41SOllivier Robert * must display the following acknowledgement:
15ea906c41SOllivier Robert * This product includes software developed by the University of
16ea906c41SOllivier Robert * California, Berkeley and its contributors.
17ea906c41SOllivier Robert * 4. Neither the name of the University nor the names of its contributors
18ea906c41SOllivier Robert * may be used to endorse or promote products derived from this software
19ea906c41SOllivier Robert * without specific prior written permission.
20ea906c41SOllivier Robert *
21ea906c41SOllivier Robert * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22ea906c41SOllivier Robert * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23ea906c41SOllivier Robert * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24ea906c41SOllivier Robert * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25ea906c41SOllivier Robert * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26ea906c41SOllivier Robert * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27ea906c41SOllivier Robert * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28ea906c41SOllivier Robert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29ea906c41SOllivier Robert * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30ea906c41SOllivier Robert * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31ea906c41SOllivier Robert * SUCH DAMAGE.
32ea906c41SOllivier Robert *
33ea906c41SOllivier Robert * $FreeBSD: src/lib/libc/stdlib/random.c,v 1.4.2.2 1999/09/05 11:16:45 peter Exp $
34ea906c41SOllivier Robert *
35ea906c41SOllivier Robert */
36ea906c41SOllivier Robert
37ea906c41SOllivier Robert #if defined(LIBC_SCCS) && !defined(lint)
38ea906c41SOllivier Robert static char sccsid[] = "@(#)random.c 8.2 (Berkeley) 5/19/95";
39ea906c41SOllivier Robert #endif /* LIBC_SCCS and not lint */
40ea906c41SOllivier Robert
41ea906c41SOllivier Robert #include "config.h"
42ea906c41SOllivier Robert #include <sys/types.h>
43ea906c41SOllivier Robert #ifdef HAVE_UNISTD_H
44ea906c41SOllivier Robert # include <unistd.h>
45ea906c41SOllivier Robert #endif
46ea906c41SOllivier Robert #include <stdio.h>
47ea906c41SOllivier Robert
482b15cb3dSCy Schubert #include <l_stdlib.h>
49ea906c41SOllivier Robert #include <ntp_random.h>
50ea906c41SOllivier Robert #include <ntp_unixtime.h>
51ea906c41SOllivier Robert
52ea906c41SOllivier Robert /*
53ea906c41SOllivier Robert * random.c:
54ea906c41SOllivier Robert *
55ea906c41SOllivier Robert * An improved random number generation package. In addition to the standard
56ea906c41SOllivier Robert * rand()/srand() like interface, this package also has a special state info
57ea906c41SOllivier Robert * interface. The initstate() routine is called with a seed, an array of
58ea906c41SOllivier Robert * bytes, and a count of how many bytes are being passed in; this array is
59ea906c41SOllivier Robert * then initialized to contain information for random number generation with
60ea906c41SOllivier Robert * that much state information. Good sizes for the amount of state
61ea906c41SOllivier Robert * information are 32, 64, 128, and 256 bytes. The state can be switched by
62ea906c41SOllivier Robert * calling the setstate() routine with the same array as was initiallized
63ea906c41SOllivier Robert * with initstate(). By default, the package runs with 128 bytes of state
64ea906c41SOllivier Robert * information and generates far better random numbers than a linear
65ea906c41SOllivier Robert * congruential generator. If the amount of state information is less than
66ea906c41SOllivier Robert * 32 bytes, a simple linear congruential R.N.G. is used.
67ea906c41SOllivier Robert *
68ea906c41SOllivier Robert * Internally, the state information is treated as an array of longs; the
69ea906c41SOllivier Robert * zeroeth element of the array is the type of R.N.G. being used (small
70ea906c41SOllivier Robert * integer); the remainder of the array is the state information for the
71ea906c41SOllivier Robert * R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
72ea906c41SOllivier Robert * state information, which will allow a degree seven polynomial. (Note:
73ea906c41SOllivier Robert * the zeroeth word of state information also has some other information
74ea906c41SOllivier Robert * stored in it -- see setstate() for details).
75ea906c41SOllivier Robert *
76ea906c41SOllivier Robert * The random number generation technique is a linear feedback shift register
77ea906c41SOllivier Robert * approach, employing trinomials (since there are fewer terms to sum up that
78ea906c41SOllivier Robert * way). In this approach, the least significant bit of all the numbers in
79ea906c41SOllivier Robert * the state table will act as a linear feedback shift register, and will
80ea906c41SOllivier Robert * have period 2^deg - 1 (where deg is the degree of the polynomial being
81ea906c41SOllivier Robert * used, assuming that the polynomial is irreducible and primitive). The
82ea906c41SOllivier Robert * higher order bits will have longer periods, since their values are also
83ea906c41SOllivier Robert * influenced by pseudo-random carries out of the lower bits. The total
84ea906c41SOllivier Robert * period of the generator is approximately deg*(2**deg - 1); thus doubling
85ea906c41SOllivier Robert * the amount of state information has a vast influence on the period of the
86ea906c41SOllivier Robert * generator. Note: the deg*(2**deg - 1) is an approximation only good for
87ea906c41SOllivier Robert * large deg, when the period of the shift register is the dominant factor.
88ea906c41SOllivier Robert * With deg equal to seven, the period is actually much longer than the
89ea906c41SOllivier Robert * 7*(2**7 - 1) predicted by this formula.
90ea906c41SOllivier Robert *
91ea906c41SOllivier Robert * Modified 28 December 1994 by Jacob S. Rosenberg.
92ea906c41SOllivier Robert * The following changes have been made:
93ea906c41SOllivier Robert * All references to the type u_int have been changed to unsigned long.
94ea906c41SOllivier Robert * All references to type int have been changed to type long. Other
95ea906c41SOllivier Robert * cleanups have been made as well. A warning for both initstate and
96ea906c41SOllivier Robert * setstate has been inserted to the effect that on Sparc platforms
97ea906c41SOllivier Robert * the 'arg_state' variable must be forced to begin on word boundaries.
98ea906c41SOllivier Robert * This can be easily done by casting a long integer array to char *.
99ea906c41SOllivier Robert * The overall logic has been left STRICTLY alone. This software was
100ea906c41SOllivier Robert * tested on both a VAX and Sun SpacsStation with exactly the same
101ea906c41SOllivier Robert * results. The new version and the original give IDENTICAL results.
102ea906c41SOllivier Robert * The new version is somewhat faster than the original. As the
103ea906c41SOllivier Robert * documentation says: "By default, the package runs with 128 bytes of
104ea906c41SOllivier Robert * state information and generates far better random numbers than a linear
105ea906c41SOllivier Robert * congruential generator. If the amount of state information is less than
106ea906c41SOllivier Robert * 32 bytes, a simple linear congruential R.N.G. is used." For a buffer of
107ea906c41SOllivier Robert * 128 bytes, this new version runs about 19 percent faster and for a 16
108ea906c41SOllivier Robert * byte buffer it is about 5 percent faster.
109ea906c41SOllivier Robert */
110ea906c41SOllivier Robert
111ea906c41SOllivier Robert /*
112ea906c41SOllivier Robert * For each of the currently supported random number generators, we have a
113ea906c41SOllivier Robert * break value on the amount of state information (you need at least this
114ea906c41SOllivier Robert * many bytes of state info to support this random number generator), a degree
115ea906c41SOllivier Robert * for the polynomial (actually a trinomial) that the R.N.G. is based on, and
116ea906c41SOllivier Robert * the separation between the two lower order coefficients of the trinomial.
117ea906c41SOllivier Robert */
118ea906c41SOllivier Robert #define TYPE_0 0 /* linear congruential */
119ea906c41SOllivier Robert #define BREAK_0 8
120ea906c41SOllivier Robert #define DEG_0 0
121ea906c41SOllivier Robert #define SEP_0 0
122ea906c41SOllivier Robert
123ea906c41SOllivier Robert #define TYPE_1 1 /* x**7 + x**3 + 1 */
124ea906c41SOllivier Robert #define BREAK_1 32
125ea906c41SOllivier Robert #define DEG_1 7
126ea906c41SOllivier Robert #define SEP_1 3
127ea906c41SOllivier Robert
128ea906c41SOllivier Robert #define TYPE_2 2 /* x**15 + x + 1 */
129ea906c41SOllivier Robert #define BREAK_2 64
130ea906c41SOllivier Robert #define DEG_2 15
131ea906c41SOllivier Robert #define SEP_2 1
132ea906c41SOllivier Robert
133ea906c41SOllivier Robert #define TYPE_3 3 /* x**31 + x**3 + 1 */
134ea906c41SOllivier Robert #define BREAK_3 128
135ea906c41SOllivier Robert #define DEG_3 31
136ea906c41SOllivier Robert #define SEP_3 3
137ea906c41SOllivier Robert
138ea906c41SOllivier Robert #define TYPE_4 4 /* x**63 + x + 1 */
139ea906c41SOllivier Robert #define BREAK_4 256
140ea906c41SOllivier Robert #define DEG_4 63
141ea906c41SOllivier Robert #define SEP_4 1
142ea906c41SOllivier Robert
143ea906c41SOllivier Robert #define MAX_TYPES 5 /* max number of types above */
144ea906c41SOllivier Robert
145ea906c41SOllivier Robert /*
146ea906c41SOllivier Robert * Initially, everything is set up as if from:
147ea906c41SOllivier Robert *
148ea906c41SOllivier Robert * initstate(1, randtbl, 128);
149ea906c41SOllivier Robert *
150ea906c41SOllivier Robert * Note that this initialization takes advantage of the fact that srandom()
151ea906c41SOllivier Robert * advances the front and rear pointers 10*rand_deg times, and hence the
152ea906c41SOllivier Robert * rear pointer which starts at 0 will also end up at zero; thus the zeroeth
153ea906c41SOllivier Robert * element of the state information, which contains info about the current
154ea906c41SOllivier Robert * position of the rear pointer is just
155ea906c41SOllivier Robert *
156ea906c41SOllivier Robert * MAX_TYPES * (rptr - state) + TYPE_3 == TYPE_3.
157ea906c41SOllivier Robert */
158ea906c41SOllivier Robert
1592b15cb3dSCy Schubert static unsigned long randtbl[DEG_3 + 1] = {
160ea906c41SOllivier Robert TYPE_3,
161ea906c41SOllivier Robert #ifdef USE_WEAK_SEEDING
162ea906c41SOllivier Robert /* Historic implementation compatibility */
163ea906c41SOllivier Robert /* The random sequences do not vary much with the seed */
164ea906c41SOllivier Robert 0x9a319039, 0x32d9c024, 0x9b663182, 0x5da1f342, 0xde3b81e0, 0xdf0a6fb5,
165ea906c41SOllivier Robert 0xf103bc02, 0x48f340fb, 0x7449e56b, 0xbeb1dbb0, 0xab5c5918, 0x946554fd,
166ea906c41SOllivier Robert 0x8c2e680f, 0xeb3d799f, 0xb11ee0b7, 0x2d436b86, 0xda672e2a, 0x1588ca88,
167ea906c41SOllivier Robert 0xe369735d, 0x904f35f7, 0xd7158fd6, 0x6fa6f051, 0x616e6b96, 0xac94efdc,
168ea906c41SOllivier Robert 0x36413f93, 0xc622c298, 0xf5a42ab8, 0x8a88d77b, 0xf5ad9d0e, 0x8999220b,
169ea906c41SOllivier Robert 0x27fb47b9,
170ea906c41SOllivier Robert #else /* !USE_WEAK_SEEDING */
171ea906c41SOllivier Robert 0x991539b1, 0x16a5bce3, 0x6774a4cd, 0x3e01511e, 0x4e508aaa, 0x61048c05,
172ea906c41SOllivier Robert 0xf5500617, 0x846b7115, 0x6a19892c, 0x896a97af, 0xdb48f936, 0x14898454,
173ea906c41SOllivier Robert 0x37ffd106, 0xb58bff9c, 0x59e17104, 0xcf918a49, 0x09378c83, 0x52c7a471,
174ea906c41SOllivier Robert 0x8d293ea9, 0x1f4fc301, 0xc3db71be, 0x39b44e1c, 0xf8a44ef9, 0x4c8b80b1,
175ea906c41SOllivier Robert 0x19edc328, 0x87bf4bdd, 0xc9b240e5, 0xe9ee4b1b, 0x4382aee7, 0x535b6b41,
176ea906c41SOllivier Robert 0xf3bec5da
177ea906c41SOllivier Robert #endif /* !USE_WEAK_SEEDING */
178ea906c41SOllivier Robert };
179ea906c41SOllivier Robert
180ea906c41SOllivier Robert /*
181ea906c41SOllivier Robert * fptr and rptr are two pointers into the state info, a front and a rear
182ea906c41SOllivier Robert * pointer. These two pointers are always rand_sep places aparts, as they
183ea906c41SOllivier Robert * cycle cyclically through the state information. (Yes, this does mean we
184ea906c41SOllivier Robert * could get away with just one pointer, but the code for random() is more
185ea906c41SOllivier Robert * efficient this way). The pointers are left positioned as they would be
186ea906c41SOllivier Robert * from the call
187ea906c41SOllivier Robert *
188ea906c41SOllivier Robert * initstate(1, randtbl, 128);
189ea906c41SOllivier Robert *
190ea906c41SOllivier Robert * (The position of the rear pointer, rptr, is really 0 (as explained above
191ea906c41SOllivier Robert * in the initialization of randtbl) because the state table pointer is set
192ea906c41SOllivier Robert * to point to randtbl[1] (as explained below).
193ea906c41SOllivier Robert */
1942b15cb3dSCy Schubert static unsigned long *fptr = &randtbl[SEP_3 + 1];
1952b15cb3dSCy Schubert static unsigned long *rptr = &randtbl[1];
196ea906c41SOllivier Robert
197ea906c41SOllivier Robert /*
198ea906c41SOllivier Robert * The following things are the pointer to the state information table, the
199ea906c41SOllivier Robert * type of the current generator, the degree of the current polynomial being
200ea906c41SOllivier Robert * used, and the separation between the two pointers. Note that for efficiency
201ea906c41SOllivier Robert * of random(), we remember the first location of the state information, not
202ea906c41SOllivier Robert * the zeroeth. Hence it is valid to access state[-1], which is used to
203ea906c41SOllivier Robert * store the type of the R.N.G. Also, we remember the last location, since
204ea906c41SOllivier Robert * this is more efficient than indexing every time to find the address of
205ea906c41SOllivier Robert * the last element to see if the front and rear pointers have wrapped.
206ea906c41SOllivier Robert */
2072b15cb3dSCy Schubert static unsigned long *state = &randtbl[1];
208ea906c41SOllivier Robert static long rand_type = TYPE_3;
209ea906c41SOllivier Robert static long rand_deg = DEG_3;
210ea906c41SOllivier Robert static long rand_sep = SEP_3;
2112b15cb3dSCy Schubert static unsigned long *end_ptr = &randtbl[DEG_3 + 1];
212ea906c41SOllivier Robert
2132b15cb3dSCy Schubert static inline long good_rand (long);
214ea906c41SOllivier Robert
215ea906c41SOllivier Robert static inline long
good_rand(register long x)216ea906c41SOllivier Robert good_rand (
217ea906c41SOllivier Robert register long x
218ea906c41SOllivier Robert )
219ea906c41SOllivier Robert {
220ea906c41SOllivier Robert #ifdef USE_WEAK_SEEDING
221ea906c41SOllivier Robert /*
222ea906c41SOllivier Robert * Historic implementation compatibility.
223ea906c41SOllivier Robert * The random sequences do not vary much with the seed,
224ea906c41SOllivier Robert * even with overflowing.
225ea906c41SOllivier Robert */
226ea906c41SOllivier Robert return (1103515245 * x + 12345);
227ea906c41SOllivier Robert #else /* !USE_WEAK_SEEDING */
228ea906c41SOllivier Robert /*
229ea906c41SOllivier Robert * Compute x = (7^5 * x) mod (2^31 - 1)
230ea906c41SOllivier Robert * wihout overflowing 31 bits:
231ea906c41SOllivier Robert * (2^31 - 1) = 127773 * (7^5) + 2836
232ea906c41SOllivier Robert * From "Random number generators: good ones are hard to find",
233ea906c41SOllivier Robert * Park and Miller, Communications of the ACM, vol. 31, no. 10,
234ea906c41SOllivier Robert * October 1988, p. 1195.
235ea906c41SOllivier Robert */
236ea906c41SOllivier Robert register long hi, lo;
237ea906c41SOllivier Robert
238ea906c41SOllivier Robert hi = x / 127773;
239ea906c41SOllivier Robert lo = x % 127773;
240ea906c41SOllivier Robert x = 16807 * lo - 2836 * hi;
241ea906c41SOllivier Robert if (x <= 0)
242ea906c41SOllivier Robert x += 0x7fffffff;
243ea906c41SOllivier Robert return (x);
244ea906c41SOllivier Robert #endif /* !USE_WEAK_SEEDING */
245ea906c41SOllivier Robert }
246ea906c41SOllivier Robert
247ea906c41SOllivier Robert /*
248ea906c41SOllivier Robert * srandom:
249ea906c41SOllivier Robert *
250ea906c41SOllivier Robert * Initialize the random number generator based on the given seed. If the
251ea906c41SOllivier Robert * type is the trivial no-state-information type, just remember the seed.
252ea906c41SOllivier Robert * Otherwise, initializes state[] based on the given "seed" via a linear
253ea906c41SOllivier Robert * congruential generator. Then, the pointers are set to known locations
254ea906c41SOllivier Robert * that are exactly rand_sep places apart. Lastly, it cycles the state
255ea906c41SOllivier Robert * information a given number of times to get rid of any initial dependencies
256ea906c41SOllivier Robert * introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
257ea906c41SOllivier Robert * for default usage relies on values produced by this routine.
258ea906c41SOllivier Robert */
259ea906c41SOllivier Robert void
ntp_srandom(unsigned long x)260ea906c41SOllivier Robert ntp_srandom(
261ea906c41SOllivier Robert unsigned long x
262ea906c41SOllivier Robert )
263ea906c41SOllivier Robert {
2642b15cb3dSCy Schubert long i;
265ea906c41SOllivier Robert
2662b15cb3dSCy Schubert if (rand_type == TYPE_0) {
267ea906c41SOllivier Robert state[0] = x;
2682b15cb3dSCy Schubert } else {
269ea906c41SOllivier Robert state[0] = x;
270ea906c41SOllivier Robert for (i = 1; i < rand_deg; i++)
271ea906c41SOllivier Robert state[i] = good_rand(state[i - 1]);
272ea906c41SOllivier Robert fptr = &state[rand_sep];
273ea906c41SOllivier Robert rptr = &state[0];
274ea906c41SOllivier Robert for (i = 0; i < 10 * rand_deg; i++)
2752b15cb3dSCy Schubert x = ntp_random();
276ea906c41SOllivier Robert }
2772b15cb3dSCy Schubert
2782b15cb3dSCy Schubert /* seed the likely faster (and poorer) rand() as well */
2792b15cb3dSCy Schubert srand((u_int)x);
280ea906c41SOllivier Robert }
281ea906c41SOllivier Robert
282ea906c41SOllivier Robert /*
283ea906c41SOllivier Robert * srandomdev:
284ea906c41SOllivier Robert *
285ea906c41SOllivier Robert * Many programs choose the seed value in a totally predictable manner.
286ea906c41SOllivier Robert * This often causes problems. We seed the generator using the much more
287ea906c41SOllivier Robert * secure urandom(4) interface. Note that this particular seeding
288ea906c41SOllivier Robert * procedure can generate states which are impossible to reproduce by
289ea906c41SOllivier Robert * calling srandom() with any value, since the succeeding terms in the
290ea906c41SOllivier Robert * state buffer are no longer derived from the LC algorithm applied to
291ea906c41SOllivier Robert * a fixed seed.
292ea906c41SOllivier Robert */
293ea906c41SOllivier Robert #ifdef NEED_SRANDOMDEV
294ea906c41SOllivier Robert void
ntp_srandomdev(void)295ea906c41SOllivier Robert ntp_srandomdev( void )
296ea906c41SOllivier Robert {
297ea906c41SOllivier Robert struct timeval tv;
298ea906c41SOllivier Robert unsigned long junk; /* Purposely used uninitialized */
299ea906c41SOllivier Robert
300ea906c41SOllivier Robert GETTIMEOFDAY(&tv, NULL);
301ea906c41SOllivier Robert ntp_srandom(getpid() ^ tv.tv_sec ^ tv.tv_usec ^ junk);
302ea906c41SOllivier Robert return;
303ea906c41SOllivier Robert }
304ea906c41SOllivier Robert #endif
305ea906c41SOllivier Robert
3062b15cb3dSCy Schubert
3072b15cb3dSCy Schubert /*
3082b15cb3dSCy Schubert * ntp_initstate() and ntp_setstate() are unused in our codebase and
3092b15cb3dSCy Schubert * trigger warnings due to casting to a more-strictly-aligned pointer
3102b15cb3dSCy Schubert * on alignment-sensitive platforms. #ifdef them away to save noise,
3112b15cb3dSCy Schubert * build time, and binary space, but retain the code in case we find a
3122b15cb3dSCy Schubert * use.
3132b15cb3dSCy Schubert */
3142b15cb3dSCy Schubert #ifdef COMPILE_UNUSED_FUNCTIONS
3152b15cb3dSCy Schubert /*
3162b15cb3dSCy Schubert * Array versions of the above information to make code run faster --
3172b15cb3dSCy Schubert * relies on fact that TYPE_i == i.
3182b15cb3dSCy Schubert */
3192b15cb3dSCy Schubert #define MAX_TYPES 5 /* max number of types above */
3202b15cb3dSCy Schubert
3212b15cb3dSCy Schubert static long degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
3222b15cb3dSCy Schubert static long seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
3232b15cb3dSCy Schubert
324ea906c41SOllivier Robert /*
325ea906c41SOllivier Robert * initstate:
326ea906c41SOllivier Robert *
327ea906c41SOllivier Robert * Initialize the state information in the given array of n bytes for future
328ea906c41SOllivier Robert * random number generation. Based on the number of bytes we are given, and
329ea906c41SOllivier Robert * the break values for the different R.N.G.'s, we choose the best (largest)
330ea906c41SOllivier Robert * one we can and set things up for it. srandom() is then called to
331ea906c41SOllivier Robert * initialize the state information.
332ea906c41SOllivier Robert *
333ea906c41SOllivier Robert * Note that on return from srandom(), we set state[-1] to be the type
334ea906c41SOllivier Robert * multiplexed with the current value of the rear pointer; this is so
335ea906c41SOllivier Robert * successive calls to initstate() won't lose this information and will be
336ea906c41SOllivier Robert * able to restart with setstate().
337ea906c41SOllivier Robert *
338ea906c41SOllivier Robert * Note: the first thing we do is save the current state, if any, just like
339ea906c41SOllivier Robert * setstate() so that it doesn't matter when initstate is called.
340ea906c41SOllivier Robert *
341ea906c41SOllivier Robert * Returns a pointer to the old state.
342ea906c41SOllivier Robert *
343ea906c41SOllivier Robert * Note: The Sparc platform requires that arg_state begin on a long
344ea906c41SOllivier Robert * word boundary; otherwise a bus error will occur. Even so, lint will
345ea906c41SOllivier Robert * complain about mis-alignment, but you should disregard these messages.
346ea906c41SOllivier Robert */
347ea906c41SOllivier Robert char *
ntp_initstate(unsigned long seed,char * arg_state,long n)348ea906c41SOllivier Robert ntp_initstate(
349ea906c41SOllivier Robert unsigned long seed, /* seed for R.N.G. */
350ea906c41SOllivier Robert char *arg_state, /* pointer to state array */
351ea906c41SOllivier Robert long n /* # bytes of state info */
352ea906c41SOllivier Robert )
353ea906c41SOllivier Robert {
354ea906c41SOllivier Robert register char *ostate = (char *)(&state[-1]);
355ea906c41SOllivier Robert register long *long_arg_state = (long *) arg_state;
356ea906c41SOllivier Robert
357ea906c41SOllivier Robert if (rand_type == TYPE_0)
358ea906c41SOllivier Robert state[-1] = rand_type;
359ea906c41SOllivier Robert else
360ea906c41SOllivier Robert state[-1] = MAX_TYPES * (rptr - state) + rand_type;
361ea906c41SOllivier Robert if (n < BREAK_0) {
362ea906c41SOllivier Robert (void)fprintf(stderr,
363ea906c41SOllivier Robert "random: not enough state (%ld bytes); ignored.\n", n);
364ea906c41SOllivier Robert return(0);
365ea906c41SOllivier Robert }
366ea906c41SOllivier Robert if (n < BREAK_1) {
367ea906c41SOllivier Robert rand_type = TYPE_0;
368ea906c41SOllivier Robert rand_deg = DEG_0;
369ea906c41SOllivier Robert rand_sep = SEP_0;
370ea906c41SOllivier Robert } else if (n < BREAK_2) {
371ea906c41SOllivier Robert rand_type = TYPE_1;
372ea906c41SOllivier Robert rand_deg = DEG_1;
373ea906c41SOllivier Robert rand_sep = SEP_1;
374ea906c41SOllivier Robert } else if (n < BREAK_3) {
375ea906c41SOllivier Robert rand_type = TYPE_2;
376ea906c41SOllivier Robert rand_deg = DEG_2;
377ea906c41SOllivier Robert rand_sep = SEP_2;
378ea906c41SOllivier Robert } else if (n < BREAK_4) {
379ea906c41SOllivier Robert rand_type = TYPE_3;
380ea906c41SOllivier Robert rand_deg = DEG_3;
381ea906c41SOllivier Robert rand_sep = SEP_3;
382ea906c41SOllivier Robert } else {
383ea906c41SOllivier Robert rand_type = TYPE_4;
384ea906c41SOllivier Robert rand_deg = DEG_4;
385ea906c41SOllivier Robert rand_sep = SEP_4;
386ea906c41SOllivier Robert }
3872b15cb3dSCy Schubert state = (unsigned long *) (long_arg_state + 1); /* first location */
388ea906c41SOllivier Robert end_ptr = &state[rand_deg]; /* must set end_ptr before srandom */
389ea906c41SOllivier Robert ntp_srandom(seed);
390ea906c41SOllivier Robert if (rand_type == TYPE_0)
391ea906c41SOllivier Robert long_arg_state[0] = rand_type;
392ea906c41SOllivier Robert else
393ea906c41SOllivier Robert long_arg_state[0] = MAX_TYPES * (rptr - state) + rand_type;
394ea906c41SOllivier Robert return(ostate);
395ea906c41SOllivier Robert }
396ea906c41SOllivier Robert
397ea906c41SOllivier Robert /*
398ea906c41SOllivier Robert * setstate:
399ea906c41SOllivier Robert *
400ea906c41SOllivier Robert * Restore the state from the given state array.
401ea906c41SOllivier Robert *
402ea906c41SOllivier Robert * Note: it is important that we also remember the locations of the pointers
403ea906c41SOllivier Robert * in the current state information, and restore the locations of the pointers
404ea906c41SOllivier Robert * from the old state information. This is done by multiplexing the pointer
405ea906c41SOllivier Robert * location into the zeroeth word of the state information.
406ea906c41SOllivier Robert *
407ea906c41SOllivier Robert * Note that due to the order in which things are done, it is OK to call
408ea906c41SOllivier Robert * setstate() with the same state as the current state.
409ea906c41SOllivier Robert *
410ea906c41SOllivier Robert * Returns a pointer to the old state information.
411ea906c41SOllivier Robert *
412ea906c41SOllivier Robert * Note: The Sparc platform requires that arg_state begin on a long
413ea906c41SOllivier Robert * word boundary; otherwise a bus error will occur. Even so, lint will
414ea906c41SOllivier Robert * complain about mis-alignment, but you should disregard these messages.
415ea906c41SOllivier Robert */
416ea906c41SOllivier Robert char *
ntp_setstate(char * arg_state)417ea906c41SOllivier Robert ntp_setstate(
418ea906c41SOllivier Robert char *arg_state /* pointer to state array */
419ea906c41SOllivier Robert )
420ea906c41SOllivier Robert {
4212b15cb3dSCy Schubert register unsigned long *new_state = (unsigned long *) arg_state;
422ea906c41SOllivier Robert register long type = new_state[0] % MAX_TYPES;
423ea906c41SOllivier Robert register long rear = new_state[0] / MAX_TYPES;
424ea906c41SOllivier Robert char *ostate = (char *)(&state[-1]);
425ea906c41SOllivier Robert
426ea906c41SOllivier Robert if (rand_type == TYPE_0)
427ea906c41SOllivier Robert state[-1] = rand_type;
428ea906c41SOllivier Robert else
429ea906c41SOllivier Robert state[-1] = MAX_TYPES * (rptr - state) + rand_type;
430ea906c41SOllivier Robert switch(type) {
431ea906c41SOllivier Robert case TYPE_0:
432ea906c41SOllivier Robert case TYPE_1:
433ea906c41SOllivier Robert case TYPE_2:
434ea906c41SOllivier Robert case TYPE_3:
435ea906c41SOllivier Robert case TYPE_4:
436ea906c41SOllivier Robert rand_type = type;
437ea906c41SOllivier Robert rand_deg = degrees[type];
438ea906c41SOllivier Robert rand_sep = seps[type];
439ea906c41SOllivier Robert break;
440ea906c41SOllivier Robert default:
441ea906c41SOllivier Robert (void)fprintf(stderr,
442ea906c41SOllivier Robert "random: state info corrupted; not changed.\n");
443ea906c41SOllivier Robert }
4442b15cb3dSCy Schubert state = (new_state + 1);
445ea906c41SOllivier Robert if (rand_type != TYPE_0) {
446ea906c41SOllivier Robert rptr = &state[rear];
447ea906c41SOllivier Robert fptr = &state[(rear + rand_sep) % rand_deg];
448ea906c41SOllivier Robert }
449ea906c41SOllivier Robert end_ptr = &state[rand_deg]; /* set end_ptr too */
450ea906c41SOllivier Robert return(ostate);
451ea906c41SOllivier Robert }
4522b15cb3dSCy Schubert #endif /* COMPILE_UNUSED_FUNCTIONS */
4532b15cb3dSCy Schubert
454ea906c41SOllivier Robert
455ea906c41SOllivier Robert /*
456ea906c41SOllivier Robert * random:
457ea906c41SOllivier Robert *
458ea906c41SOllivier Robert * If we are using the trivial TYPE_0 R.N.G., just do the old linear
459ea906c41SOllivier Robert * congruential bit. Otherwise, we do our fancy trinomial stuff, which is
460ea906c41SOllivier Robert * the same in all the other cases due to all the global variables that have
461ea906c41SOllivier Robert * been set up. The basic operation is to add the number at the rear pointer
462ea906c41SOllivier Robert * into the one at the front pointer. Then both pointers are advanced to
463ea906c41SOllivier Robert * the next location cyclically in the table. The value returned is the sum
464ea906c41SOllivier Robert * generated, reduced to 31 bits by throwing away the "least random" low bit.
465ea906c41SOllivier Robert *
466ea906c41SOllivier Robert * Note: the code takes advantage of the fact that both the front and
467ea906c41SOllivier Robert * rear pointers can't wrap on the same call by not testing the rear
468ea906c41SOllivier Robert * pointer if the front one has wrapped.
469ea906c41SOllivier Robert *
470ea906c41SOllivier Robert * Returns a 31-bit random number.
471ea906c41SOllivier Robert */
472ea906c41SOllivier Robert long
ntp_random(void)473ea906c41SOllivier Robert ntp_random( void )
474ea906c41SOllivier Robert {
475ea906c41SOllivier Robert register long i;
4762b15cb3dSCy Schubert register unsigned long *f, *r;
477ea906c41SOllivier Robert
478ea906c41SOllivier Robert if (rand_type == TYPE_0) {
479ea906c41SOllivier Robert i = state[0];
480ea906c41SOllivier Robert state[0] = i = (good_rand(i)) & 0x7fffffff;
481ea906c41SOllivier Robert } else {
482ea906c41SOllivier Robert /*
483ea906c41SOllivier Robert * Use local variables rather than static variables for speed.
484ea906c41SOllivier Robert */
485ea906c41SOllivier Robert f = fptr; r = rptr;
486ea906c41SOllivier Robert *f += *r;
487ea906c41SOllivier Robert i = (*f >> 1) & 0x7fffffff; /* chucking least random bit */
488ea906c41SOllivier Robert if (++f >= end_ptr) {
489ea906c41SOllivier Robert f = state;
490ea906c41SOllivier Robert ++r;
491ea906c41SOllivier Robert }
492ea906c41SOllivier Robert else if (++r >= end_ptr) {
493ea906c41SOllivier Robert r = state;
494ea906c41SOllivier Robert }
495ea906c41SOllivier Robert
496ea906c41SOllivier Robert fptr = f; rptr = r;
497ea906c41SOllivier Robert }
498ea906c41SOllivier Robert return(i);
499ea906c41SOllivier Robert }
500*a466cc55SCy Schubert
501*a466cc55SCy Schubert /*
502*a466cc55SCy Schubert * ntp_uurandom()
503*a466cc55SCy Schubert *
504*a466cc55SCy Schubert * Generate a Uniform-distributed Unity based random number. Replaces a
505*a466cc55SCy Schubert * few locations where the transformation was made in an ad-hoc style
506*a466cc55SCy Schubert * (and in one instance, wrong...)
507*a466cc55SCy Schubert *
508*a466cc55SCy Schubert * returns a number in [0.0 .. 1.0], both ends inclusive
509*a466cc55SCy Schubert */
510*a466cc55SCy Schubert double
ntp_uurandom(void)511*a466cc55SCy Schubert ntp_uurandom( void )
512*a466cc55SCy Schubert {
513*a466cc55SCy Schubert return (double)ntp_random() / 0x7FFFFFFFu;
514*a466cc55SCy Schubert }
515