[PATCH] stdlib: Tuned down tst-arc4random-thread internal parameters

Yann Droneaud ydroneaud@opteya.com
Wed Jul 27 17:10:03 GMT 2022


Hi,

Le 27/07/2022 à 17:57, Adhemerval Zanella Netto via Libc-alpha a écrit :
>
> On 27/07/22 12:36, Florian Weimer wrote:
>> * Adhemerval Zanella Netto:
>>
>>>>>> By the way, I think we should switch to the standard arc4random_uniform
>>>>>> implementation that doesn't try to conserve bits.  It's cheaper to get a
>>>>>> larger number of bits once instead of obtaining 24 bits first, then 8
>>>>>> bits.
>>>>> Yeah, it should simpler indeed.  But I do not consider this urgent
>>>>> for 2.36.
>>>> Well, the standard way probably has more obvious statistical properties
>>>> and is harder to screw up. 8-/
>>> Right, do you consider this a blocker? I think I can send a patch to
>>> use a simpler algorithm.
>> I like it because it would minimize risk.  It's not a strict blocker.
>> I'm not sure if I'll be able to work on it this week.  Maybe I can
>> review a patch.
> Without trying to be clever, what about something like the below, adapted
> from Bitmask with Rejection [1].  It should be fast on most case since it
> avoid the modulo operation, and the last part that tries to reuse the
> extra entropy bits are not strictly required.
>
>
> uint32_t
> __arc4random_uniform (uint32_t n)
> {
>    if (n <= 1)
>      /* There is no valid return value for a zero limit, and 0 is the
>         only possible result for limit 1.  */
>      return 0;
>
>    /* mask is the smallest power of 2 minus 1 which is larger than n.  */
>    int z = __builtin_clz (n);


For the special case where n is power of two, I think it should be 
__builtin_clz (n - 1).

For example n = 8, arc4random_uniform() returns a value up to 7, but 
mask would be 0x1111, while 0x111 would have been enough.


>    int bits = CHAR_BIT * sizeof (uint32_t) - z;
>    uint32_t mask = ~UINT32_C(0) >> z;
>
>    while (1)
>      {
>        uint32_t value = __arc4random ();
>
>        /* Return is the lower power of 2 minus 1 satisfy the condition.  */
>        uint32_t r = value & mask;
>        if (r < n)
>          return r;
>
>        /* Otherwise check if remaining bits of entropy provides fits in the
>           bound.  */
>        int bits_left = z;
>        while (bits_left >= bits)
>          {
>            value >>= bits;
>            r = value & mask;
>            if (r < n)
>              return r;
>            bits_left -= bits;
>          }
>      }
> }
>
> [1] https://www.pcg-random.org/posts/bounded-rands.html

Thanks

-- 

Yann Droneaud

OPTEYA




More information about the Libc-alpha mailing list