Skip to content

Commit

Permalink
lib/csrand.c: Fix the lower part of the domain of csrand_uniform()
Browse files Browse the repository at this point in the history
I accidentally broke this code during an un-optimization.  We need to
start from a random value of the width of the limit, that is, 32 bits.

Thanks to Jason for pointing to his similar code in the kernel, which
made me see my mistake.

Fixes: 2a61122 ("Unoptimize the higher part of the domain of csrand_uniform()")
Closes: <#1015>
Reported-by: Michael Brunnbauer <https://github.com/michaelbrunnbauer>
Link: <https://git.zx2c4.com/linux-rng/tree/drivers/char/random.c#n535>
Cc: "Jason A. Donenfeld" <[email protected]>
Link: <#638>
Link: <#634>
Link: <#624>
Tested-by: Michael Brunnbauer <https://github.com/michaelbrunnbauer>
Reviewed-by: Michael Brunnbauer <https://github.com/michaelbrunnbauer>
Signed-off-by: Alejandro Colomar <[email protected]>
Cherry-picked-from: 4119a2dce564 ("lib/csrand.c: Fix the lower part of the domain of csrand_uniform()")
Cc: "Serge E. Hallyn" <[email protected]>
Link: <#1025>
Signed-off-by: Alejandro Colomar <[email protected]>
  • Loading branch information
alejandro-colomar committed Jun 21, 2024
1 parent 7ceeec8 commit ad0958b
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions lib/csrand.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include "shadowlog.h"


static uint32_t csrand32(void);
static uint32_t csrand_uniform32(uint32_t n);
static unsigned long csrand_uniform_slow(unsigned long n);

Expand Down Expand Up @@ -96,6 +97,13 @@ csrand_interval(unsigned long min, unsigned long max)
}


static uint32_t
csrand32(void)
{
return csrand();
}


/*
* Fast Random Integer Generation in an Interval
* ACM Transactions on Modeling and Computer Simulation 29 (1), 2019
Expand All @@ -108,12 +116,12 @@ csrand_uniform32(uint32_t n)
uint64_t r, mult;

if (n == 0)
return csrand();
return csrand32();

bound = -n % n; // analogous to `2^32 % n`, since `x % y == (x-y) % y`

do {
r = csrand();
r = csrand32();
mult = r * n;
rem = mult; // analogous to `mult % 2^32`
} while (rem < bound); // p = (2^32 % n) / 2^32; W.C.: n=2^31+1, p=0.5
Expand Down

0 comments on commit ad0958b

Please sign in to comment.