This variant works much faster. The random_bool() and random_torus32() should be fine from the security standpoint, but I have some concerns about the generation of Gaussian numbers:
Since I need an open interval for floating-point randoms in (0, 1), I have to generate a 52-bit random integer instead of a 53-bit one and do a transform. If one represents all possible float values in [0, 1] (which are uniformly distributed, so the distance between each symbol including 0 and 1 is the same) as
0 x x x ... x x x 1
then the elements that can be generated with the transform are
0 x x x ... x x x 1
^ ^ ... ^ ^
which works out as uniform for the phase (because 0 and 1 are the same value), but I'm not sure about the radius.
Box-Muller generates pairs of random normals, which may be correlated if somehow the issue with the uniformness above matters for calculating the radius. We can drop one half of the numbers though, it is still pretty fast.
That said, the SystemRandom.normalvariate() implementation uses rejection sampling, so it's vulnerable to side-channel attacks.
This variant works much faster. The
random_bool()
andrandom_torus32()
should be fine from the security standpoint, but I have some concerns about the generation of Gaussian numbers:Since I need an open interval for floating-point randoms in (0, 1), I have to generate a 52-bit random integer instead of a 53-bit one and do a transform. If one represents all possible float values in [0, 1] (which are uniformly distributed, so the distance between each symbol including 0 and 1 is the same) as
0 x x x ... x x x 1
then the elements that can be generated with the transform are
0 x x x ... x x x 1 ^ ^ ... ^ ^
which works out as uniform for the phase (because 0 and 1 are the same value), but I'm not sure about the radius.
Box-Muller generates pairs of random normals, which may be correlated if somehow the issue with the uniformness above matters for calculating the radius. We can drop one half of the numbers though, it is still pretty fast.
That said, the
SystemRandom.normalvariate()
implementation uses rejection sampling, so it's vulnerable to side-channel attacks.