2006-08-08 22:22:47 +00:00
|
|
|
/* Generate buffers of random data.
|
|
|
|
|
|
2021-01-01 16:36:09 +00:00
|
|
|
Copyright (C) 2006-2021 Free Software Foundation, Inc.
|
2006-08-08 22:22:47 +00:00
|
|
|
|
2007-07-23 14:35:58 +02:00
|
|
|
This program is free software: you can redistribute it and/or modify
|
2006-08-08 22:22:47 +00:00
|
|
|
it under the terms of the GNU General Public License as published by
|
2007-07-23 14:35:58 +02:00
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
(at your option) any later version.
|
2006-08-08 22:22:47 +00:00
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
2017-09-19 01:13:23 -07:00
|
|
|
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
2006-08-08 22:22:47 +00:00
|
|
|
|
|
|
|
|
/* Written by Paul Eggert. */
|
|
|
|
|
|
2011-09-17 08:53:45 -07:00
|
|
|
/* FIXME: Improve performance by adding support for the RDRAND machine
|
|
|
|
|
instruction if available (e.g., Ivy Bridge processors). */
|
|
|
|
|
|
2006-08-26 06:55:57 +00:00
|
|
|
#include <config.h>
|
2006-08-08 22:22:47 +00:00
|
|
|
|
|
|
|
|
#include "randread.h"
|
|
|
|
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
#include <error.h>
|
|
|
|
|
#include <exitfail.h>
|
2010-07-20 09:50:37 -07:00
|
|
|
#include <fcntl.h>
|
2015-10-28 13:02:31 +00:00
|
|
|
#include <quote.h>
|
2011-10-30 22:31:17 +01:00
|
|
|
#include <stdalign.h>
|
2006-08-08 22:22:47 +00:00
|
|
|
#include <stdbool.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <string.h>
|
2020-06-01 15:53:27 -07:00
|
|
|
#include <sys/random.h>
|
2006-08-08 22:22:47 +00:00
|
|
|
|
|
|
|
|
#include "gettext.h"
|
|
|
|
|
#define _(msgid) gettext (msgid)
|
|
|
|
|
|
|
|
|
|
#include "rand-isaac.h"
|
|
|
|
|
#include "stdio-safer.h"
|
|
|
|
|
#include "unlocked-io.h"
|
|
|
|
|
#include "xalloc.h"
|
|
|
|
|
|
2009-04-06 12:23:26 +01:00
|
|
|
#ifndef __attribute__
|
|
|
|
|
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
|
|
|
|
|
# define __attribute__(x) /* empty */
|
|
|
|
|
# endif
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#ifndef ATTRIBUTE_NORETURN
|
|
|
|
|
# define ATTRIBUTE_NORETURN __attribute__ ((__noreturn__))
|
|
|
|
|
#endif
|
|
|
|
|
|
2006-08-08 22:22:47 +00:00
|
|
|
#ifndef MIN
|
|
|
|
|
# define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
|
|
|
#endif
|
|
|
|
|
|
2016-11-25 22:10:20 +00:00
|
|
|
#if _STRING_ARCH_unaligned || _STRING_INLINE_unaligned
|
2006-08-08 22:22:47 +00:00
|
|
|
# define ALIGNED_POINTER(ptr, type) true
|
|
|
|
|
#else
|
|
|
|
|
# define ALIGNED_POINTER(ptr, type) ((size_t) (ptr) % alignof (type) == 0)
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* The maximum buffer size used for reads of random data. Using the
|
|
|
|
|
value 2 * ISAAC_BYTES makes this the largest power of two that
|
|
|
|
|
would not otherwise cause struct randread_source to grow. */
|
|
|
|
|
#define RANDREAD_BUFFER_SIZE (2 * ISAAC_BYTES)
|
|
|
|
|
|
|
|
|
|
/* A source of random data for generating random buffers. */
|
|
|
|
|
struct randread_source
|
|
|
|
|
{
|
2009-04-06 08:42:15 +01:00
|
|
|
/* Stream to read random bytes from. If null, the current
|
|
|
|
|
implementation uses an internal PRNG (ISAAC). */
|
2006-08-08 22:22:47 +00:00
|
|
|
FILE *source;
|
|
|
|
|
|
|
|
|
|
/* Function to call, and its argument, if there is an input error or
|
|
|
|
|
end of file when reading from the stream; errno is nonzero if
|
|
|
|
|
there was an error. If this function returns, it should fix the
|
|
|
|
|
problem before returning. The default handler assumes that
|
|
|
|
|
handler_arg is the file name of the source. */
|
2006-10-06 14:37:48 +00:00
|
|
|
void (*handler) (void const *);
|
|
|
|
|
void const *handler_arg;
|
2006-08-08 22:22:47 +00:00
|
|
|
|
|
|
|
|
/* The buffer for SOURCE. It's kept here to simplify storage
|
|
|
|
|
allocation and to make it easier to clear out buffered random
|
|
|
|
|
data. */
|
|
|
|
|
union
|
|
|
|
|
{
|
|
|
|
|
/* The stream buffer, if SOURCE is not null. */
|
|
|
|
|
char c[RANDREAD_BUFFER_SIZE];
|
|
|
|
|
|
|
|
|
|
/* The buffered ISAAC pseudorandom buffer, if SOURCE is null. */
|
|
|
|
|
struct isaac
|
|
|
|
|
{
|
|
|
|
|
/* The number of bytes that are buffered at the end of data.b. */
|
|
|
|
|
size_t buffered;
|
|
|
|
|
|
|
|
|
|
/* State of the ISAAC generator. */
|
|
|
|
|
struct isaac_state state;
|
|
|
|
|
|
|
|
|
|
/* Up to a buffer's worth of pseudorandom data. */
|
|
|
|
|
union
|
|
|
|
|
{
|
randread: run 2x faster on 64-bit hosts, don't assume no padding bits
* gl/lib/rand-isaac.c: Remove the I/O; this belongs elsewhere.
Add support for ISAAC64. Port to hosts with padding bits.
Add self to author list. Include <limits.h>, for CHAR_BIT.
Don't include string.h, sys/time.h, unistd.h.
(min, just): New functions.
(IF32): New macros.
(ind, ISAAC_STEP, isaac_refill, mix, isaac_init, isaac_seed):
Add support for ISAAC64. Port to hosts with padding bits.
(ind): Now an inline function rather than a macro; no need for it
to be a macro with modern compilers.
(ISAAC_STEP): Renamed from isaac_step, since it's not function-like.
Don't bother to pass args that are always the same. All uses changed.
(ISAAC_STEP, ISAAC_SEED): Move to inside the only function body
that can use it.
(ISAAC_MIX): Renamed from isaac_mix, since it's now a macro and is
no longer function-like. Don't bother saving and restoring state;
no longer needed now that we're not a function. All uses changed.
(isaac_seed_start, isaac_seed_data, isaac_seed_finish): Remove.
(isaac_seed): Take just the one arg; the caller now sets s->m.
* gl/lib/rand-isaac.h: Use _GL_RAND_ISAAC_H to protect, instead
of RAND_ISAAC_H. Try out " #" rather than "# " for indenting.
(ISAAC_BITS_LOG, ISAAC_BITS): New macros.
(ISAAC_WORDS_LOG): Renamed from ISAAC_LOG.
(isaac_word): New type. All uses of uint32_t changed to isaac_word,
to support ISAAC64.
(struct isaac_state): Rename member MM to M, and make it public.
(isaac_seed, isaac_refill): Adjust to new API.
* gl/lib/randread.c: Include sys/time.h.
(get_nonce): New function, containing the nonce stuff that used
to be in rand-isaac.c but better belongs here.
(randread_new): Use it.
* gl/modules/randread (Depends-on): Add inline.
* gl/modules/randread-tests: New file.
* gl/tests/test-rand-isaac.c: New file.
2010-07-23 15:07:27 -07:00
|
|
|
isaac_word w[ISAAC_WORDS];
|
2009-08-22 18:56:06 +02:00
|
|
|
unsigned char b[ISAAC_BYTES];
|
2006-08-08 22:22:47 +00:00
|
|
|
} data;
|
|
|
|
|
} isaac;
|
|
|
|
|
} buf;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* The default error handler. */
|
|
|
|
|
|
2009-04-06 12:23:26 +01:00
|
|
|
static void ATTRIBUTE_NORETURN
|
2006-10-06 14:37:48 +00:00
|
|
|
randread_error (void const *file_name)
|
2006-08-08 22:22:47 +00:00
|
|
|
{
|
|
|
|
|
if (file_name)
|
|
|
|
|
error (exit_failure, errno,
|
2014-07-19 07:55:41 -07:00
|
|
|
errno == 0 ? _("%s: end of file") : _("%s: read error"),
|
2015-10-28 13:02:31 +00:00
|
|
|
quote (file_name));
|
2006-08-08 22:22:47 +00:00
|
|
|
abort ();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Simply return a new randread_source object with the default error
|
|
|
|
|
handler. */
|
|
|
|
|
|
|
|
|
|
static struct randread_source *
|
2006-10-06 14:37:48 +00:00
|
|
|
simple_new (FILE *source, void const *handler_arg)
|
2006-08-08 22:22:47 +00:00
|
|
|
{
|
|
|
|
|
struct randread_source *s = xmalloc (sizeof *s);
|
|
|
|
|
s->source = source;
|
|
|
|
|
s->handler = randread_error;
|
|
|
|
|
s->handler_arg = handler_arg;
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
|
2020-05-31 22:21:34 -07:00
|
|
|
/* Put a nonce value into BUFFER, with size BUFSIZE.
|
|
|
|
|
Return true on success, false (setting errno) on failure. */
|
randread: run 2x faster on 64-bit hosts, don't assume no padding bits
* gl/lib/rand-isaac.c: Remove the I/O; this belongs elsewhere.
Add support for ISAAC64. Port to hosts with padding bits.
Add self to author list. Include <limits.h>, for CHAR_BIT.
Don't include string.h, sys/time.h, unistd.h.
(min, just): New functions.
(IF32): New macros.
(ind, ISAAC_STEP, isaac_refill, mix, isaac_init, isaac_seed):
Add support for ISAAC64. Port to hosts with padding bits.
(ind): Now an inline function rather than a macro; no need for it
to be a macro with modern compilers.
(ISAAC_STEP): Renamed from isaac_step, since it's not function-like.
Don't bother to pass args that are always the same. All uses changed.
(ISAAC_STEP, ISAAC_SEED): Move to inside the only function body
that can use it.
(ISAAC_MIX): Renamed from isaac_mix, since it's now a macro and is
no longer function-like. Don't bother saving and restoring state;
no longer needed now that we're not a function. All uses changed.
(isaac_seed_start, isaac_seed_data, isaac_seed_finish): Remove.
(isaac_seed): Take just the one arg; the caller now sets s->m.
* gl/lib/rand-isaac.h: Use _GL_RAND_ISAAC_H to protect, instead
of RAND_ISAAC_H. Try out " #" rather than "# " for indenting.
(ISAAC_BITS_LOG, ISAAC_BITS): New macros.
(ISAAC_WORDS_LOG): Renamed from ISAAC_LOG.
(isaac_word): New type. All uses of uint32_t changed to isaac_word,
to support ISAAC64.
(struct isaac_state): Rename member MM to M, and make it public.
(isaac_seed, isaac_refill): Adjust to new API.
* gl/lib/randread.c: Include sys/time.h.
(get_nonce): New function, containing the nonce stuff that used
to be in rand-isaac.c but better belongs here.
(randread_new): Use it.
* gl/modules/randread (Depends-on): Add inline.
* gl/modules/randread-tests: New file.
* gl/tests/test-rand-isaac.c: New file.
2010-07-23 15:07:27 -07:00
|
|
|
|
2020-05-31 22:21:34 -07:00
|
|
|
static bool
|
|
|
|
|
get_nonce (void *buffer, size_t bufsize)
|
randread: run 2x faster on 64-bit hosts, don't assume no padding bits
* gl/lib/rand-isaac.c: Remove the I/O; this belongs elsewhere.
Add support for ISAAC64. Port to hosts with padding bits.
Add self to author list. Include <limits.h>, for CHAR_BIT.
Don't include string.h, sys/time.h, unistd.h.
(min, just): New functions.
(IF32): New macros.
(ind, ISAAC_STEP, isaac_refill, mix, isaac_init, isaac_seed):
Add support for ISAAC64. Port to hosts with padding bits.
(ind): Now an inline function rather than a macro; no need for it
to be a macro with modern compilers.
(ISAAC_STEP): Renamed from isaac_step, since it's not function-like.
Don't bother to pass args that are always the same. All uses changed.
(ISAAC_STEP, ISAAC_SEED): Move to inside the only function body
that can use it.
(ISAAC_MIX): Renamed from isaac_mix, since it's now a macro and is
no longer function-like. Don't bother saving and restoring state;
no longer needed now that we're not a function. All uses changed.
(isaac_seed_start, isaac_seed_data, isaac_seed_finish): Remove.
(isaac_seed): Take just the one arg; the caller now sets s->m.
* gl/lib/rand-isaac.h: Use _GL_RAND_ISAAC_H to protect, instead
of RAND_ISAAC_H. Try out " #" rather than "# " for indenting.
(ISAAC_BITS_LOG, ISAAC_BITS): New macros.
(ISAAC_WORDS_LOG): Renamed from ISAAC_LOG.
(isaac_word): New type. All uses of uint32_t changed to isaac_word,
to support ISAAC64.
(struct isaac_state): Rename member MM to M, and make it public.
(isaac_seed, isaac_refill): Adjust to new API.
* gl/lib/randread.c: Include sys/time.h.
(get_nonce): New function, containing the nonce stuff that used
to be in rand-isaac.c but better belongs here.
(randread_new): Use it.
* gl/modules/randread (Depends-on): Add inline.
* gl/modules/randread-tests: New file.
* gl/tests/test-rand-isaac.c: New file.
2010-07-23 15:07:27 -07:00
|
|
|
{
|
2020-05-31 22:21:34 -07:00
|
|
|
char *buf = buffer, *buflim = buf + bufsize;
|
|
|
|
|
while (buf < buflim)
|
randread: run 2x faster on 64-bit hosts, don't assume no padding bits
* gl/lib/rand-isaac.c: Remove the I/O; this belongs elsewhere.
Add support for ISAAC64. Port to hosts with padding bits.
Add self to author list. Include <limits.h>, for CHAR_BIT.
Don't include string.h, sys/time.h, unistd.h.
(min, just): New functions.
(IF32): New macros.
(ind, ISAAC_STEP, isaac_refill, mix, isaac_init, isaac_seed):
Add support for ISAAC64. Port to hosts with padding bits.
(ind): Now an inline function rather than a macro; no need for it
to be a macro with modern compilers.
(ISAAC_STEP): Renamed from isaac_step, since it's not function-like.
Don't bother to pass args that are always the same. All uses changed.
(ISAAC_STEP, ISAAC_SEED): Move to inside the only function body
that can use it.
(ISAAC_MIX): Renamed from isaac_mix, since it's now a macro and is
no longer function-like. Don't bother saving and restoring state;
no longer needed now that we're not a function. All uses changed.
(isaac_seed_start, isaac_seed_data, isaac_seed_finish): Remove.
(isaac_seed): Take just the one arg; the caller now sets s->m.
* gl/lib/rand-isaac.h: Use _GL_RAND_ISAAC_H to protect, instead
of RAND_ISAAC_H. Try out " #" rather than "# " for indenting.
(ISAAC_BITS_LOG, ISAAC_BITS): New macros.
(ISAAC_WORDS_LOG): Renamed from ISAAC_LOG.
(isaac_word): New type. All uses of uint32_t changed to isaac_word,
to support ISAAC64.
(struct isaac_state): Rename member MM to M, and make it public.
(isaac_seed, isaac_refill): Adjust to new API.
* gl/lib/randread.c: Include sys/time.h.
(get_nonce): New function, containing the nonce stuff that used
to be in rand-isaac.c but better belongs here.
(randread_new): Use it.
* gl/modules/randread (Depends-on): Add inline.
* gl/modules/randread-tests: New file.
* gl/tests/test-rand-isaac.c: New file.
2010-07-23 15:07:27 -07:00
|
|
|
{
|
2020-06-01 15:53:27 -07:00
|
|
|
ssize_t nbytes = getrandom (buf, buflim - buf, 0);
|
|
|
|
|
if (0 <= nbytes)
|
|
|
|
|
buf += nbytes;
|
|
|
|
|
else if (errno != EINTR)
|
2020-05-31 22:21:34 -07:00
|
|
|
return false;
|
randread: run 2x faster on 64-bit hosts, don't assume no padding bits
* gl/lib/rand-isaac.c: Remove the I/O; this belongs elsewhere.
Add support for ISAAC64. Port to hosts with padding bits.
Add self to author list. Include <limits.h>, for CHAR_BIT.
Don't include string.h, sys/time.h, unistd.h.
(min, just): New functions.
(IF32): New macros.
(ind, ISAAC_STEP, isaac_refill, mix, isaac_init, isaac_seed):
Add support for ISAAC64. Port to hosts with padding bits.
(ind): Now an inline function rather than a macro; no need for it
to be a macro with modern compilers.
(ISAAC_STEP): Renamed from isaac_step, since it's not function-like.
Don't bother to pass args that are always the same. All uses changed.
(ISAAC_STEP, ISAAC_SEED): Move to inside the only function body
that can use it.
(ISAAC_MIX): Renamed from isaac_mix, since it's now a macro and is
no longer function-like. Don't bother saving and restoring state;
no longer needed now that we're not a function. All uses changed.
(isaac_seed_start, isaac_seed_data, isaac_seed_finish): Remove.
(isaac_seed): Take just the one arg; the caller now sets s->m.
* gl/lib/rand-isaac.h: Use _GL_RAND_ISAAC_H to protect, instead
of RAND_ISAAC_H. Try out " #" rather than "# " for indenting.
(ISAAC_BITS_LOG, ISAAC_BITS): New macros.
(ISAAC_WORDS_LOG): Renamed from ISAAC_LOG.
(isaac_word): New type. All uses of uint32_t changed to isaac_word,
to support ISAAC64.
(struct isaac_state): Rename member MM to M, and make it public.
(isaac_seed, isaac_refill): Adjust to new API.
* gl/lib/randread.c: Include sys/time.h.
(get_nonce): New function, containing the nonce stuff that used
to be in rand-isaac.c but better belongs here.
(randread_new): Use it.
* gl/modules/randread (Depends-on): Add inline.
* gl/modules/randread-tests: New file.
* gl/tests/test-rand-isaac.c: New file.
2010-07-23 15:07:27 -07:00
|
|
|
}
|
2020-05-31 22:21:34 -07:00
|
|
|
return true;
|
randread: run 2x faster on 64-bit hosts, don't assume no padding bits
* gl/lib/rand-isaac.c: Remove the I/O; this belongs elsewhere.
Add support for ISAAC64. Port to hosts with padding bits.
Add self to author list. Include <limits.h>, for CHAR_BIT.
Don't include string.h, sys/time.h, unistd.h.
(min, just): New functions.
(IF32): New macros.
(ind, ISAAC_STEP, isaac_refill, mix, isaac_init, isaac_seed):
Add support for ISAAC64. Port to hosts with padding bits.
(ind): Now an inline function rather than a macro; no need for it
to be a macro with modern compilers.
(ISAAC_STEP): Renamed from isaac_step, since it's not function-like.
Don't bother to pass args that are always the same. All uses changed.
(ISAAC_STEP, ISAAC_SEED): Move to inside the only function body
that can use it.
(ISAAC_MIX): Renamed from isaac_mix, since it's now a macro and is
no longer function-like. Don't bother saving and restoring state;
no longer needed now that we're not a function. All uses changed.
(isaac_seed_start, isaac_seed_data, isaac_seed_finish): Remove.
(isaac_seed): Take just the one arg; the caller now sets s->m.
* gl/lib/rand-isaac.h: Use _GL_RAND_ISAAC_H to protect, instead
of RAND_ISAAC_H. Try out " #" rather than "# " for indenting.
(ISAAC_BITS_LOG, ISAAC_BITS): New macros.
(ISAAC_WORDS_LOG): Renamed from ISAAC_LOG.
(isaac_word): New type. All uses of uint32_t changed to isaac_word,
to support ISAAC64.
(struct isaac_state): Rename member MM to M, and make it public.
(isaac_seed, isaac_refill): Adjust to new API.
* gl/lib/randread.c: Include sys/time.h.
(get_nonce): New function, containing the nonce stuff that used
to be in rand-isaac.c but better belongs here.
(randread_new): Use it.
* gl/modules/randread (Depends-on): Add inline.
* gl/modules/randread-tests: New file.
* gl/tests/test-rand-isaac.c: New file.
2010-07-23 15:07:27 -07:00
|
|
|
}
|
|
|
|
|
|
2006-08-08 22:22:47 +00:00
|
|
|
/* Create and initialize a random data source from NAME, or use a
|
|
|
|
|
reasonable default source if NAME is null. BYTES_BOUND is an upper
|
|
|
|
|
bound on the number of bytes that will be needed. If zero, it is a
|
|
|
|
|
hard bound; otherwise it is just an estimate.
|
|
|
|
|
|
|
|
|
|
If NAME is not null, NAME is saved for use as the argument of the
|
|
|
|
|
default handler. Unless a non-default handler is used, NAME's
|
|
|
|
|
lifetime should be at least that of the returned value.
|
|
|
|
|
|
|
|
|
|
Return NULL (setting errno) on failure. */
|
|
|
|
|
|
|
|
|
|
struct randread_source *
|
|
|
|
|
randread_new (char const *name, size_t bytes_bound)
|
|
|
|
|
{
|
|
|
|
|
if (bytes_bound == 0)
|
|
|
|
|
return simple_new (NULL, NULL);
|
|
|
|
|
else
|
|
|
|
|
{
|
2009-04-06 08:42:15 +01:00
|
|
|
FILE *source = NULL;
|
2006-08-08 22:22:47 +00:00
|
|
|
struct randread_source *s;
|
|
|
|
|
|
2009-04-06 08:42:15 +01:00
|
|
|
if (name)
|
2009-08-22 18:56:06 +02:00
|
|
|
if (! (source = fopen_safer (name, "rb")))
|
|
|
|
|
return NULL;
|
2006-08-08 22:22:47 +00:00
|
|
|
|
2009-04-06 08:42:15 +01:00
|
|
|
s = simple_new (source, name);
|
2006-08-08 22:22:47 +00:00
|
|
|
|
|
|
|
|
if (source)
|
2009-08-22 18:56:06 +02:00
|
|
|
setvbuf (source, s->buf.c, _IOFBF, MIN (sizeof s->buf.c, bytes_bound));
|
2006-08-08 22:22:47 +00:00
|
|
|
else
|
2009-08-22 18:56:06 +02:00
|
|
|
{
|
|
|
|
|
s->buf.isaac.buffered = 0;
|
2020-05-31 22:21:34 -07:00
|
|
|
if (! get_nonce (s->buf.isaac.state.m,
|
|
|
|
|
MIN (sizeof s->buf.isaac.state.m, bytes_bound)))
|
|
|
|
|
{
|
|
|
|
|
int e = errno;
|
|
|
|
|
randread_free (s);
|
|
|
|
|
errno = e;
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
randread: run 2x faster on 64-bit hosts, don't assume no padding bits
* gl/lib/rand-isaac.c: Remove the I/O; this belongs elsewhere.
Add support for ISAAC64. Port to hosts with padding bits.
Add self to author list. Include <limits.h>, for CHAR_BIT.
Don't include string.h, sys/time.h, unistd.h.
(min, just): New functions.
(IF32): New macros.
(ind, ISAAC_STEP, isaac_refill, mix, isaac_init, isaac_seed):
Add support for ISAAC64. Port to hosts with padding bits.
(ind): Now an inline function rather than a macro; no need for it
to be a macro with modern compilers.
(ISAAC_STEP): Renamed from isaac_step, since it's not function-like.
Don't bother to pass args that are always the same. All uses changed.
(ISAAC_STEP, ISAAC_SEED): Move to inside the only function body
that can use it.
(ISAAC_MIX): Renamed from isaac_mix, since it's now a macro and is
no longer function-like. Don't bother saving and restoring state;
no longer needed now that we're not a function. All uses changed.
(isaac_seed_start, isaac_seed_data, isaac_seed_finish): Remove.
(isaac_seed): Take just the one arg; the caller now sets s->m.
* gl/lib/rand-isaac.h: Use _GL_RAND_ISAAC_H to protect, instead
of RAND_ISAAC_H. Try out " #" rather than "# " for indenting.
(ISAAC_BITS_LOG, ISAAC_BITS): New macros.
(ISAAC_WORDS_LOG): Renamed from ISAAC_LOG.
(isaac_word): New type. All uses of uint32_t changed to isaac_word,
to support ISAAC64.
(struct isaac_state): Rename member MM to M, and make it public.
(isaac_seed, isaac_refill): Adjust to new API.
* gl/lib/randread.c: Include sys/time.h.
(get_nonce): New function, containing the nonce stuff that used
to be in rand-isaac.c but better belongs here.
(randread_new): Use it.
* gl/modules/randread (Depends-on): Add inline.
* gl/modules/randread-tests: New file.
* gl/tests/test-rand-isaac.c: New file.
2010-07-23 15:07:27 -07:00
|
|
|
isaac_seed (&s->buf.isaac.state);
|
2009-08-22 18:56:06 +02:00
|
|
|
}
|
2006-08-08 22:22:47 +00:00
|
|
|
|
|
|
|
|
return s;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Set S's handler and its argument. HANDLER (HANDLER_ARG) is called
|
|
|
|
|
when there is a read error or end of file from the random data
|
|
|
|
|
source; errno is nonzero if there was an error. If HANDLER
|
|
|
|
|
returns, it should fix the problem before returning. The default
|
|
|
|
|
handler assumes that handler_arg is the file name of the source; it
|
|
|
|
|
does not return. */
|
|
|
|
|
|
|
|
|
|
void
|
2006-10-06 14:37:48 +00:00
|
|
|
randread_set_handler (struct randread_source *s, void (*handler) (void const *))
|
2006-08-08 22:22:47 +00:00
|
|
|
{
|
|
|
|
|
s->handler = handler;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
2006-10-06 14:37:48 +00:00
|
|
|
randread_set_handler_arg (struct randread_source *s, void const *handler_arg)
|
2006-08-08 22:22:47 +00:00
|
|
|
{
|
|
|
|
|
s->handler_arg = handler_arg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Place SIZE random bytes into the buffer beginning at P, using
|
|
|
|
|
the stream in S. */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
readsource (struct randread_source *s, unsigned char *p, size_t size)
|
|
|
|
|
{
|
maint: replace each "for (;;)" with "while (true)"
Run this command:
git ls-files | grep '\.[ch]$' \
| xargs perl -pi -e 's/for \(;;\)/while (true)/g'
...except for randint.c, which does not include stdbool.h.
In that case, use "while (1)".
* gl/lib/randint.c (randint_genmax): Use "while (1)" for infloops.
* src/cat.c (simple_cat, cat): Use "while (true)" for infloops.
* gl/lib/randread.c (readsource, readisaac): Likewise.
* src/copy.c (copy_reg): Likewise.
* src/csplit.c (record_line_starts, process_regexp): Likewise.
* src/cut.c (set_fields): Likewise.
* src/dd.c (iread, parse_symbols): Likewise.
* src/df.c (find_mount_point, main): Likewise.
* src/du.c (main): Likewise.
* src/expand.c (expand): Likewise.
* src/factor.c (factor_using_division, do_stdin): Likewise.
* src/fmt.c (get_space): Likewise.
* src/ls.c (decode_switches): Likewise.
* src/od.c (main): Likewise.
* src/pr.c (main, read_line): Likewise.
* src/shred.c (dopass, genpattern): Likewise.
* src/sort.c (initbuf, fillbuf, getmonth, keycompare): Likewise.
* src/split.c (bytes_split, lines_split): Likewise.
* src/tac.c (tac_seekable): Likewise.
* src/test.c (and, or): Likewise.
* src/tr.c (squeeze_filter, main): Likewise.
* src/tsort.c (search_item): Likewise.
* src/unexpand.c (unexpand): Likewise.
* src/uniq.c (main): Likewise.
* src/yes.c (main): Likewise.
2010-05-01 14:24:35 +02:00
|
|
|
while (true)
|
2006-08-08 22:22:47 +00:00
|
|
|
{
|
|
|
|
|
size_t inbytes = fread (p, sizeof *p, size, s->source);
|
|
|
|
|
int fread_errno = errno;
|
|
|
|
|
p += inbytes;
|
|
|
|
|
size -= inbytes;
|
|
|
|
|
if (size == 0)
|
2009-08-22 18:56:06 +02:00
|
|
|
break;
|
2006-08-08 22:22:47 +00:00
|
|
|
errno = (ferror (s->source) ? fread_errno : 0);
|
|
|
|
|
s->handler (s->handler_arg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Place SIZE pseudorandom bytes into the buffer beginning at P, using
|
|
|
|
|
the buffered ISAAC generator in ISAAC. */
|
|
|
|
|
|
|
|
|
|
static void
|
2013-05-18 17:49:32 -07:00
|
|
|
readisaac (struct isaac *isaac, void *p, size_t size)
|
2006-08-08 22:22:47 +00:00
|
|
|
{
|
|
|
|
|
size_t inbytes = isaac->buffered;
|
|
|
|
|
|
maint: replace each "for (;;)" with "while (true)"
Run this command:
git ls-files | grep '\.[ch]$' \
| xargs perl -pi -e 's/for \(;;\)/while (true)/g'
...except for randint.c, which does not include stdbool.h.
In that case, use "while (1)".
* gl/lib/randint.c (randint_genmax): Use "while (1)" for infloops.
* src/cat.c (simple_cat, cat): Use "while (true)" for infloops.
* gl/lib/randread.c (readsource, readisaac): Likewise.
* src/copy.c (copy_reg): Likewise.
* src/csplit.c (record_line_starts, process_regexp): Likewise.
* src/cut.c (set_fields): Likewise.
* src/dd.c (iread, parse_symbols): Likewise.
* src/df.c (find_mount_point, main): Likewise.
* src/du.c (main): Likewise.
* src/expand.c (expand): Likewise.
* src/factor.c (factor_using_division, do_stdin): Likewise.
* src/fmt.c (get_space): Likewise.
* src/ls.c (decode_switches): Likewise.
* src/od.c (main): Likewise.
* src/pr.c (main, read_line): Likewise.
* src/shred.c (dopass, genpattern): Likewise.
* src/sort.c (initbuf, fillbuf, getmonth, keycompare): Likewise.
* src/split.c (bytes_split, lines_split): Likewise.
* src/tac.c (tac_seekable): Likewise.
* src/test.c (and, or): Likewise.
* src/tr.c (squeeze_filter, main): Likewise.
* src/tsort.c (search_item): Likewise.
* src/unexpand.c (unexpand): Likewise.
* src/uniq.c (main): Likewise.
* src/yes.c (main): Likewise.
2010-05-01 14:24:35 +02:00
|
|
|
while (true)
|
2006-08-08 22:22:47 +00:00
|
|
|
{
|
2013-05-18 17:49:32 -07:00
|
|
|
char *char_p = p;
|
|
|
|
|
|
2006-08-08 22:22:47 +00:00
|
|
|
if (size <= inbytes)
|
2009-08-22 18:56:06 +02:00
|
|
|
{
|
|
|
|
|
memcpy (p, isaac->data.b + ISAAC_BYTES - inbytes, size);
|
|
|
|
|
isaac->buffered = inbytes - size;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2006-08-08 22:22:47 +00:00
|
|
|
|
|
|
|
|
memcpy (p, isaac->data.b + ISAAC_BYTES - inbytes, inbytes);
|
2013-05-18 17:49:32 -07:00
|
|
|
p = char_p + inbytes;
|
2006-08-08 22:22:47 +00:00
|
|
|
size -= inbytes;
|
|
|
|
|
|
|
|
|
|
/* If P is aligned, write to *P directly to avoid the overhead
|
2009-08-22 18:56:06 +02:00
|
|
|
of copying from the buffer. */
|
randread: run 2x faster on 64-bit hosts, don't assume no padding bits
* gl/lib/rand-isaac.c: Remove the I/O; this belongs elsewhere.
Add support for ISAAC64. Port to hosts with padding bits.
Add self to author list. Include <limits.h>, for CHAR_BIT.
Don't include string.h, sys/time.h, unistd.h.
(min, just): New functions.
(IF32): New macros.
(ind, ISAAC_STEP, isaac_refill, mix, isaac_init, isaac_seed):
Add support for ISAAC64. Port to hosts with padding bits.
(ind): Now an inline function rather than a macro; no need for it
to be a macro with modern compilers.
(ISAAC_STEP): Renamed from isaac_step, since it's not function-like.
Don't bother to pass args that are always the same. All uses changed.
(ISAAC_STEP, ISAAC_SEED): Move to inside the only function body
that can use it.
(ISAAC_MIX): Renamed from isaac_mix, since it's now a macro and is
no longer function-like. Don't bother saving and restoring state;
no longer needed now that we're not a function. All uses changed.
(isaac_seed_start, isaac_seed_data, isaac_seed_finish): Remove.
(isaac_seed): Take just the one arg; the caller now sets s->m.
* gl/lib/rand-isaac.h: Use _GL_RAND_ISAAC_H to protect, instead
of RAND_ISAAC_H. Try out " #" rather than "# " for indenting.
(ISAAC_BITS_LOG, ISAAC_BITS): New macros.
(ISAAC_WORDS_LOG): Renamed from ISAAC_LOG.
(isaac_word): New type. All uses of uint32_t changed to isaac_word,
to support ISAAC64.
(struct isaac_state): Rename member MM to M, and make it public.
(isaac_seed, isaac_refill): Adjust to new API.
* gl/lib/randread.c: Include sys/time.h.
(get_nonce): New function, containing the nonce stuff that used
to be in rand-isaac.c but better belongs here.
(randread_new): Use it.
* gl/modules/randread (Depends-on): Add inline.
* gl/modules/randread-tests: New file.
* gl/tests/test-rand-isaac.c: New file.
2010-07-23 15:07:27 -07:00
|
|
|
if (ALIGNED_POINTER (p, isaac_word))
|
2009-08-22 18:56:06 +02:00
|
|
|
{
|
2013-05-18 17:49:32 -07:00
|
|
|
isaac_word *wp = p;
|
2009-08-22 18:56:06 +02:00
|
|
|
while (ISAAC_BYTES <= size)
|
|
|
|
|
{
|
|
|
|
|
isaac_refill (&isaac->state, wp);
|
|
|
|
|
wp += ISAAC_WORDS;
|
|
|
|
|
size -= ISAAC_BYTES;
|
|
|
|
|
if (size == 0)
|
|
|
|
|
{
|
|
|
|
|
isaac->buffered = 0;
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
2013-05-18 17:49:32 -07:00
|
|
|
p = wp;
|
2009-08-22 18:56:06 +02:00
|
|
|
}
|
2006-08-08 22:22:47 +00:00
|
|
|
|
|
|
|
|
isaac_refill (&isaac->state, isaac->data.w);
|
|
|
|
|
inbytes = ISAAC_BYTES;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Consume random data from *S to generate a random buffer BUF of size
|
|
|
|
|
SIZE. */
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
randread (struct randread_source *s, void *buf, size_t size)
|
|
|
|
|
{
|
|
|
|
|
if (s->source)
|
|
|
|
|
readsource (s, buf, size);
|
|
|
|
|
else
|
|
|
|
|
readisaac (&s->buf.isaac, buf, size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Clear *S so that it no longer contains undelivered random data, and
|
|
|
|
|
deallocate any system resources associated with *S. Return 0 if
|
|
|
|
|
successful, a negative number (setting errno) if not (this is rare,
|
|
|
|
|
but can occur in theory if there is an input error). */
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
randread_free (struct randread_source *s)
|
|
|
|
|
{
|
|
|
|
|
FILE *source = s->source;
|
2017-07-20 14:01:14 -07:00
|
|
|
explicit_bzero (s, sizeof *s);
|
2006-08-08 22:22:47 +00:00
|
|
|
free (s);
|
|
|
|
|
return (source ? fclose (source) : 0);
|
|
|
|
|
}
|