public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Adhemerval Zanella <adhemerval.zanella@linaro.org>
To: Yann Droneaud <ydroneaud@opteya.com>, libc-alpha@sourceware.org
Cc: Florian Weimer <fweimer@redhat.com>
Subject: Re: [PATCH v3 1/9] stdlib: Add arc4random, arc4random_buf, and arc4random_uniform (BZ #4417)
Date: Mon, 25 Apr 2022 09:20:15 -0300	[thread overview]
Message-ID: <245c297d-3f1d-d938-2071-e9c7720aabd8@linaro.org> (raw)
In-Reply-To: <cc0e4295-c201-4346-90e5-70bf095e7f2f@linaro.org>



On 25/04/2022 09:15, Adhemerval Zanella wrote:
> 
> 
> On 22/04/2022 10:54, Yann Droneaud wrote:
>> Le 19/04/2022 à 23:28, Adhemerval Zanella via Libc-alpha a écrit :
>>> The implementation is based on scalar Chacha20, with global cache and
>>> locking.  It uses getrandom or /dev/urandom as fallback to get the
>>> initial entropy, and reseeds the internal state on every 16MB of
>>> consumed buffer.
>>>
>>> It maintains an internal buffer which consumes at maximum one page on
>>> most systems (assuming minimum of 4k pages).  The internal buf optimizes
>>> the cipher encrypt calls, by amortize arc4random calls (where both
>>> function call and locks cost are the dominating factor).
>>>
>>> The ChaCha20 implementation is based on the RFC8439 [1], with last
>>> step that XOR with the input omited.  Since the input stream will either
>>> zero bytes (initial state) or the PRNG output itself this step does not
>>> add any extra entropy.
>>
>>
>> This can also state the implementation is following OpenBSD arc4random current implementation.
>>
>>
> 
> Agree, it is worth to add it.
> 
>>> +
>>> +/* Besides the cipher state 'ctx', it keeps two counters: 'have' is the
>>> +   current valid bytes not yet consumed in 'buf', while 'count' is the maximum
>>> +   number of bytes until a reseed.
>>> +
>>> +   Both the initial seed an reseed tries to obtain entropy from the kernel
>>
>> an ->  and
> 
> Ack.
> 
>>> +
>>> +static void
>>> +arc4random_rekey (uint8_t *rnd, size_t rndlen)
>>> +{
>>> +  memset (state->buf, 0, sizeof state->buf);
>>
>> There's no need to clear buf as call to chacha20_crypt() will overwrite it (since it doesn't XOR with it anymore).
>>
>> See https://github.com/openbsd/src/blob/master/lib/libc/crypt/arc4random.c#L121
> 
> Ack, I have removed it.
> 
> 
>>> +
>>> +      /* Extract a bit and append it to c.  c remains less than v and
>>> +         thus 2**33.  */
>>> +      c = (c << 1) | (bits & 1);
>>> +      bits >>= 1;
>>> +      --bits_length;
>>> +
>>> +      /* At this point, c is uniformly distributed on [0, v) again,
>>> +         and v < 2n < 2**33.  */
>>> +    }
>>
>> I'm not familiar with this method.
>>
>> It's not one reviewed at https://www.pcg-random.org/posts/bounded-rands.html
>>
>> In this patch I used what's called by PCG author,the "Bitmask with Rejection (Unbiased) — Apple's Method"
>>
>> https://github.com/Parrot-Developers/libfutils/commit/9dc7243ae2f2059b4590a702be2ca9c03578067f
>>
>> I like it because it doesn't uses modulo at all :)
>>
>> But the OpenBSD's arc4random_uniform() is even more simple in term of C code.
>>
> 
> You can find the reference paper on arxiv [1].  The main advantage of this
> method is the that the unit of randomness is not the uniform random variable
> (uint32_t), but a random bit.  It optimizes the internal buffer sampling by
> initially consuming a 32-bit random variable and then sampling byte per byte.
> Depending of the upper bound requested, it might lead to better CPU utilization.
> 
> From the article:
> 
>   But unexpectedly, it turns out that the extra buffering inherent in consuming
>   randomness random-bit-by-random-bit, although time consuming, is more than
>   compensated by the increased efficiency in using random bits compared with most
>   common methods.
> 
> It is specially true if you consider that both chacha20 block generation and
> getting kernel entropy (through either getrandom or /dev/urandom) are way
> more time consuming than bit twiddling. 
> 
> [1] https://arxiv.org/pdf/1304.1916.pdf
> 

And you can see that this method does not use modulo as well.  It does use 
arc4random_buf internally, what might add some overhead. One possible
optimization could to add a internal function to consume only one byte,
but I am not sure if this really pays off.

  reply	other threads:[~2022-04-25 12:20 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-04-19 21:28 [PATCH v3 0/9] Add arc4random support Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 1/9] stdlib: Add arc4random, arc4random_buf, and arc4random_uniform (BZ #4417) Adhemerval Zanella
2022-04-19 21:52   ` H.J. Lu
2022-04-20 12:38     ` Adhemerval Zanella
2022-04-22 13:54   ` Yann Droneaud
2022-04-25 12:15     ` Adhemerval Zanella
2022-04-25 12:20       ` Adhemerval Zanella [this message]
2022-04-25  2:22   ` Mark Harris
2022-04-25 12:26     ` Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 2/9] stdlib: Add arc4random tests Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 3/9] benchtests: Add arc4random benchtest Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 4/9] aarch64: Add optimized chacha20 Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 5/9] x86: Add SSE2 " Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 6/9] x86: Add AVX2 " Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 7/9] powerpc64: Add " Adhemerval Zanella
2022-04-20 18:38   ` Paul E Murphy
2022-04-20 19:23     ` Adhemerval Zanella
2022-04-22 21:09       ` Paul E Murphy
2022-04-19 21:28 ` [PATCH v3 8/9] s390x: " Adhemerval Zanella
2022-04-19 21:28 ` [PATCH v3 9/9] stdlib: Add TLS optimization to arc4random Adhemerval Zanella
2022-04-22 16:02   ` Yann Droneaud
2022-04-25 12:36     ` Adhemerval Zanella

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=245c297d-3f1d-d938-2071-e9c7720aabd8@linaro.org \
    --to=adhemerval.zanella@linaro.org \
    --cc=fweimer@redhat.com \
    --cc=libc-alpha@sourceware.org \
    --cc=ydroneaud@opteya.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).