From bfbb3ec7f798b179d7fa7b42673e068b18048899 Mon Sep 17 00:00:00 2001
From: Paul Eggert <eggert@cs.ucla.edu>
Date: Sat, 3 Aug 2024 22:31:20 -0700
Subject: [PATCH] shuf: fix randomness bug

Problem reported by Daniel Carpenter <https://bugs.gnu.org/72445>.
* gl/lib/randread.c (randread_new): Fill the ISAAC buffer
instead of storing at most BYTES_BOUND bytes into it.

Reference:https://github.com/coreutils/coreutils/commit/bfbb3ec7f798b179d7fa7b42673e068b18048899
Conflict:delete NEWS and THANKS.in; changelog gl/lib/randread.c to lib/randread.c

---
 lib/randread.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/lib/randread.c b/lib/randread.c
index 7124e3d..c99f1a1 100644
--- a/lib/randread.c
+++ b/lib/randread.c
@@ -187,9 +187,19 @@ randread_new (char const *name, size_t bytes_bound)
         setvbuf (source, s->buf.c, _IOFBF, MIN (sizeof s->buf.c, bytes_bound));
       else
         {
+          /* Fill the ISAAC buffer.  Although it is tempting to read at
+             most BYTES_BOUND bytes, this is incorrect for two reasons.
+             First, BYTES_BOUND is just an estimate.
+             Second, even if the estimate is correct
+             ISAAC64 poorly randomizes when BYTES_BOUND is small
+             and just the first few bytes of s->buf.isaac.state.m
+             are random while the other bytes are all zero.  See:
+             Aumasson J-P. On the pseudo-random generator ISAAC.
+             Cryptology ePrint Archive. 2006;438.
+             <https://eprint.iacr.org/2006/438>.  */
           s->buf.isaac.buffered = 0;
           if (! get_nonce (s->buf.isaac.state.m,
-                           MIN (sizeof s->buf.isaac.state.m, bytes_bound)))
+                           sizeof s->buf.isaac.state.m))
             {
               int e = errno;
               randread_free (s);
-- 
2.43.0

