3 The "lagged fibonacci" pseudorandomness generator, described in
6 Copyright (C) 2002 Niels Möller
8 This file is part of GNU Nettle.
10 GNU Nettle is free software: you can redistribute it and/or
11 modify it under the terms of either:
13 * the GNU Lesser General Public License as published by the Free
14 Software Foundation; either version 3 of the License, or (at your
15 option) any later version.
19 * the GNU General Public License as published by the Free
20 Software Foundation; either version 2 of the License, or (at your
21 option) any later version.
23 or both in parallel, as here.
25 GNU Nettle is distributed in the hope that it will be useful,
26 but WITHOUT ANY WARRANTY; without even the implied warranty of
27 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
28 General Public License for more details.
30 You should have received copies of the GNU General Public License and
31 the GNU Lesser General Public License along with this program. If
32 not, see http://www.gnu.org/licenses/.
35 /* This file includes code copied verbatim from Knuth's TAoCP.
36 Technically, doing that probably requires asking for the author's
37 explicit permission. I'd expect such a request to be granted, but I
38 haven't asked, because I don't want to distract him from more
39 important and interesting work. */
43 /* NOTE: This generator is totally inappropriate for cryptographic
44 * applications. It is useful for generating deterministic but
45 * random-looking test data, and is used by the Nettle testsuite. */
54 #include "knuth-lfib.h"
58 #define KK _KNUTH_LFIB_KK
60 #define MM (1UL << 30)
64 knuth_lfib_init(struct knuth_lfib_ctx *ctx, uint32_t seed)
68 uint32_t ss = (seed + 2) & (MM-2);
70 for (j = 0; j<KK; j++)
73 ss <<= 1; if (ss >= MM) ss -= (MM-2);
83 for (j = KK-1; j>0; j--)
85 for (j = 2*KK-2; j > KK-LL; j-= 2)
86 x[2*KK-1-j] = x[j] & ~1;
87 for (j = 2*KK-2; j>=KK; j--)
90 x[j-(KK-LL)] = (x[j - (KK-LL)] - x[j]) & (MM-1);
91 x[j-KK] = (x[j-KK] - x[j]) & (MM-1);
99 x[LL] = (x[LL] - x[KK]) & (MM-1);
107 ctx->x[j+KK-LL] = x[j];
114 /* Get's a single number in the range 0 ... 2^30-1 */
116 knuth_lfib_get(struct knuth_lfib_ctx *ctx)
119 assert(ctx->index < KK);
121 value = ctx->x[ctx->index];
122 ctx->x[ctx->index] -= ctx->x[(ctx->index + KK - LL) % KK];
123 ctx->x[ctx->index] &= (MM-1);
125 ctx->index = (ctx->index + 1) % KK;
130 /* NOTE: Not at all optimized. */
132 knuth_lfib_get_array(struct knuth_lfib_ctx *ctx,
133 size_t n, uint32_t *a)
137 for (i = 0; i<n; i++)
138 a[i] = knuth_lfib_get(ctx);
141 /* NOTE: Not at all optimized. */
143 knuth_lfib_random(struct knuth_lfib_ctx *ctx,
144 size_t n, uint8_t *dst)
146 /* Use 24 bits from each number, xoring together some of the
149 for (; n >= 3; n-=3, dst += 3)
151 uint32_t value = knuth_lfib_get(ctx);
153 /* Xor the most significant octet (containing 6 significant bits)
154 * into the lower octet. */
155 value ^= (value >> 24);
157 WRITE_UINT24(dst, value);
161 /* We need one or two octets more */
162 uint32_t value = knuth_lfib_get(ctx);
166 *dst++ = value & 0xff;
169 WRITE_UINT16(dst, value);