3 * A "lagged fibonacci" pseudorandomness generator.
5 * Described in Knuth, TAOCP, 3.6
8 /* nettle, low-level cryptographics library
10 * Copyright (C) 2002 Niels Möller
12 * Includes code copied verbatim from Knuth's TAOCP.
14 * The nettle library is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License as published by
16 * the Free Software Foundation; either version 2.1 of the License, or (at your
17 * option) any later version.
19 * The nettle library is distributed in the hope that it will be useful, but
20 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
22 * License for more details.
24 * You should have received a copy of the GNU Lesser General Public License
25 * along with the nettle library; see the file COPYING.LIB. If not, write to
26 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
30 /* NOTE: This generator is totally inappropriate for cryptographic
31 * applications. It is useful for generating deterministic but
32 * random-looking test data, and is used by the Nettle testsuite. */
41 #include "knuth-lfib.h"
45 #define KK _KNUTH_LFIB_KK
47 #define MM (1UL << 30)
51 knuth_lfib_init(struct knuth_lfib_ctx
*ctx
, uint32_t seed
)
55 uint32_t ss
= (seed
+ 2) & (MM
-2);
57 for (j
= 0; j
<KK
; j
++)
60 ss
<<= 1; if (ss
>= MM
) ss
-= (MM
-2);
70 for (j
= KK
-1; j
>0; j
--)
72 for (j
= 2*KK
-2; j
> KK
-LL
; j
-= 2)
73 x
[2*KK
-1-j
] = x
[j
] & ~1;
74 for (j
= 2*KK
-2; j
>=KK
; j
--)
77 x
[j
-(KK
-LL
)] = (x
[j
- (KK
-LL
)] - x
[j
]) & (MM
-1);
78 x
[j
-KK
] = (x
[j
-KK
] - x
[j
]) & (MM
-1);
86 x
[LL
] = (x
[LL
] - x
[KK
]) & (MM
-1);
94 ctx
->x
[j
+KK
-LL
] = x
[j
];
101 /* Get's a single number in the range 0 ... 2^30-1 */
103 knuth_lfib_get(struct knuth_lfib_ctx
*ctx
)
106 assert(ctx
->index
< KK
);
108 value
= ctx
->x
[ctx
->index
];
109 ctx
->x
[ctx
->index
] -= ctx
->x
[(ctx
->index
+ KK
- LL
) % KK
];
110 ctx
->x
[ctx
->index
] &= (MM
-1);
112 ctx
->index
= (ctx
->index
+ 1) % KK
;
117 /* NOTE: Not at all optimized. */
119 knuth_lfib_get_array(struct knuth_lfib_ctx
*ctx
,
120 unsigned n
, uint32_t *a
)
124 for (i
= 0; i
<n
; i
++)
125 a
[i
] = knuth_lfib_get(ctx
);
128 /* NOTE: Not at all optimized. */
130 knuth_lfib_random(struct knuth_lfib_ctx
*ctx
,
131 unsigned n
, uint8_t *dst
)
133 /* Use 24 bits from each number, xoring together some of the
136 for (; n
>= 3; n
-=3, dst
+= 3)
138 uint32_t value
= knuth_lfib_get(ctx
);
140 /* Xor the most significant octet (containing 6 significant bits)
141 * into the lower octet. */
142 value
^= (value
>> 24);
144 WRITE_UINT24(dst
, value
);
148 /* We need one or two octets more */
149 uint32_t value
= knuth_lfib_get(ctx
);
153 *dst
++ = value
& 0xff;
156 WRITE_UINT16(dst
, value
);