[RFC] Random Extension 3.0

  115918
September 2, 2021 15:10 zeriyoshi@gmail.com (Go Kudo)
Hi Internals.

Expanded from the previous RFC and changed it to an RFC that organizes the
whole PHP random number generator. Also, the target version has been
changed to 8.2.

https://wiki.php.net/rfc/rng_extension
https://github.com/php/php-src/pull/7453

Hopefully you will get some good responses.

Regards,
Go Kudo
  115922
September 2, 2021 18:26 larry@garfieldtech.com ("Larry Garfield")
On Thu, Sep 2, 2021, at 10:10 AM, Go Kudo wrote:
> Hi Internals. > > Expanded from the previous RFC and changed it to an RFC that organizes the > whole PHP random number generator. Also, the target version has been > changed to 8.2. > > https://wiki.php.net/rfc/rng_extension > https://github.com/php/php-src/pull/7453 > > Hopefully you will get some good responses. > > Regards, > Go Kudo
This looks pretty nice to my unskilled eye. Two questions. 1) Why is the number generator a parent class rather than an interface? It seems like an interface target. And either way it needs more clarity about how you'd write one for reals. (It returns an int, so does that mean getBytes() just derives from a series of ints?) 2) You don't mention the CSPRNG functions at all. Is there any intention to fold those into this model as well, or to leave those as is? Or is the Secure generator implementation intended to replace those? It's unclear here. --Larry Garfield
  115927
September 3, 2021 13:55 zeriyoshi@gmail.com (Go Kudo)
Thank you.

> Why is the number generator a parent class rather than an interface?
This is an implementation limitation. I could not find a way to define my own object handler in interface. As Nikita pointed out in a previous suggestion, the NumberGenerator now uses php_random_ng_algo_user to generate random numbers faster than before, even if it is a userland implementation.
> You don't mention the CSPRNG functions at all.
This is a mistake. I have corrected it. Thanks! I will keep an eye on it throughout the next week, and if there are no additional responses, I will start voting the week after next. Regards, Go Kudo 2021年9月3日(金) 3:26 Larry Garfield <larry@garfieldtech.com>:
> On Thu, Sep 2, 2021, at 10:10 AM, Go Kudo wrote: > > Hi Internals. > > > > Expanded from the previous RFC and changed it to an RFC that organizes > the > > whole PHP random number generator. Also, the target version has been > > changed to 8.2. > > > > https://wiki.php.net/rfc/rng_extension > > https://github.com/php/php-src/pull/7453 > > > > Hopefully you will get some good responses. > > > > Regards, > > Go Kudo > > This looks pretty nice to my unskilled eye. Two questions. > > 1) Why is the number generator a parent class rather than an interface? > It seems like an interface target. And either way it needs more clarity > about how you'd write one for reals. (It returns an int, so does that mean > getBytes() just derives from a series of ints?) > > 2) You don't mention the CSPRNG functions at all. Is there any intention > to fold those into this model as well, or to leave those as is? Or is the > Secure generator implementation intended to replace those? It's unclear > here. > > --Larry Garfield > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
  115929
September 3, 2021 14:03 larry@garfieldtech.com ("Larry Garfield")
On Fri, Sep 3, 2021, at 8:55 AM, Go Kudo wrote:
> Thank you. > > > Why is the number generator a parent class rather than an interface? > > This is an implementation limitation. I could not find a way to define my > own object handler in interface. > As Nikita pointed out in a previous suggestion, the NumberGenerator now > uses php_random_ng_algo_user to generate random numbers faster than before, > even if it is a userland implementation.
I'm still unclear how I'd write my own NumberGenerator right now. I mean, I can extend the class, but I don't have a sense for what I'd do with it for non-testing/trivial implementations. You say it's using an internal function to generate numbers, but in user space what would I do with that? And when/why would I?
> > You don't mention the CSPRNG functions at all. > > This is a mistake. I have corrected it. Thanks!
I'm still not clear on the intent here. Is the intent that I should stop using random_int()? And if so, replace it with... what? Do I have to supply a specific non-default generator? That makes the usability worse, and more likely to be gotten wrong. Also, in future scope you you have this sentence, which makes little sense:
>> Replace random_bytes() with random_bytes() for random numbers used in shuffle(), str_shuffle(), and array_rand().
--Larry Garfield
  115931
September 3, 2021 14:26 zeriyoshi@gmail.com (Go Kudo)
> I'm still unclear how I'd write my own NumberGenerator right now. I mean, I can extend the class, but I don't have a sense for what I'd do with
it for non-testing/trivial implementations. You say it's using an internal function to generate numbers, but in user space what would I do with that? And when/why would I? For example, I will create an application that does a lottery. I need to estimate the load and test it. If I actually use random numbers to draw the lots, the test results will be different each time. It is true that this example can be solved by devising a better implementation of the userland. If this is the case, you may be wondering why we implement it this way. Currently, there are several implementations of random number generators written in PHP. https://github.com/savvot/random Although not in this library, I use an in-house interface that is completely replaceable with random_int() for load testing in my production brother. Also, JIT was implemented in PHP 8.0. which has the potential to make it possible to write in PHP what would otherwise have to be implemented in C due to execution speed issues. In fact, the random number generator written in PHP for my tests shows a significant performance improvement when JIT is enabled. The ability to have a workable random number implementation in userland should be useful for future extensions.
> Is the intent that I should stop using random_int()?
No, it's not. random_int() is a safe and easy CSPRNG, and is recommended for future use. The advantage of using Random\NumberGenerator\Secure is that it can shuffle strings/arrays using the same random number source as random_int(). Something that is not included in this RFC but that I would like to deprecate in the future is the mt_srand (srand) function. These have internal state and are very harmful for extensions such as Swoole: Also, shuffle() and str_shuffle() are very good functions, but I don't think they should use the random number source generated by mt_srand. The user may unintentionally use an unsecured random number. I apologize for the difficulty in conveying this message. I've revised the wording.
> Changes random source to php_random_int() in shuffle(), str_shuffle(), and array_rand() .
2021年9月3日(金) 23:04 Larry Garfield <larry@garfieldtech.com>:
> On Fri, Sep 3, 2021, at 8:55 AM, Go Kudo wrote: > > Thank you. > > > > > Why is the number generator a parent class rather than an interface? > > > > This is an implementation limitation. I could not find a way to define my > > own object handler in interface. > > As Nikita pointed out in a previous suggestion, the NumberGenerator now > > uses php_random_ng_algo_user to generate random numbers faster than > before, > > even if it is a userland implementation. > > I'm still unclear how I'd write my own NumberGenerator right now. I mean, > I can extend the class, but I don't have a sense for what I'd do with it > for non-testing/trivial implementations. You say it's using an internal > function to generate numbers, but in user space what would I do with that? > And when/why would I? > > > > You don't mention the CSPRNG functions at all. > > > > This is a mistake. I have corrected it. Thanks! > > I'm still not clear on the intent here. Is the intent that I should stop > using random_int()? And if so, replace it with... what? Do I have to > supply a specific non-default generator? That makes the usability worse, > and more likely to be gotten wrong. > > Also, in future scope you you have this sentence, which makes little sense: > > >> Replace random_bytes() with random_bytes() for random numbers used in > shuffle(), str_shuffle(), and array_rand(). > > --Larry Garfield > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
  115928
September 3, 2021 14:02 zeriyoshi@gmail.com (Go Kudo)
My apologies. I had skipped one.

> And either way it needs more clarity about how you'd write one for reals.
Added a simple example comparing it to mt_rand. What do you think of this? 2021年9月3日(金) 3:26 Larry Garfield <larry@garfieldtech.com>:
> On Thu, Sep 2, 2021, at 10:10 AM, Go Kudo wrote: > > Hi Internals. > > > > Expanded from the previous RFC and changed it to an RFC that organizes > the > > whole PHP random number generator. Also, the target version has been > > changed to 8.2. > > > > https://wiki.php.net/rfc/rng_extension > > https://github.com/php/php-src/pull/7453 > > > > Hopefully you will get some good responses. > > > > Regards, > > Go Kudo > > This looks pretty nice to my unskilled eye. Two questions. > > 1) Why is the number generator a parent class rather than an interface? > It seems like an interface target. And either way it needs more clarity > about how you'd write one for reals. (It returns an int, so does that mean > getBytes() just derives from a series of ints?) > > 2) You don't mention the CSPRNG functions at all. Is there any intention > to fold those into this model as well, or to leave those as is? Or is the > Secure generator implementation intended to replace those? It's unclear > here. > > --Larry Garfield > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > >
  115936
September 3, 2021 16:02 nikita.ppv@gmail.com (Nikita Popov)
On Thu, Sep 2, 2021 at 5:10 PM Go Kudo <zeriyoshi@gmail.com> wrote:

> Hi Internals. > > Expanded from the previous RFC and changed it to an RFC that organizes the > whole PHP random number generator. Also, the target version has been > changed to 8.2. > > https://wiki.php.net/rfc/rng_extension > https://github.com/php/php-src/pull/7453 > > Hopefully you will get some good responses. >
This looks pretty nice to me. A few bits of feedback: * Unlike the previous versions of the RFC, this one also moves all of the existing RNG-related functionality from ext/standard to ext/random. Why does it do this? This doesn't really seem related to the problem this RFC is solving. * Regarding the abstract class Random\NumberGenerator: You currently need the abstract class, because php_random_ng is tied to the object. An alternative design that would allow Random\NumberGenerator to be an interface would be to make it independent of the object, such that the structure can be allocated in the Random constructor for userland implementations. Of course, internal implementations could still embed it as part of their objects -- just don't make it a requirement. * The future scope mentions: "Changes random source to php_random_int() a shuffle(), str_shuffle(), and array_rand()". I don't think it makes sense to switch these functions to use cryptographic randomness by default... Regards, Nikita
  115939
September 3, 2021 17:41 zeriyoshi@gmail.com (Go Kudo)
Thanks nikita.

> ext/standard to ext/random. Why does it do this?
There are several reasons for this. - The `random` extension name is already used by ext/standard and may interfere with the build system. - Due to the namespace rules for new extensions, it is inappropriate to rename an extension. - Due to history, the rand / mt_rand dependency is tricky and I thought it was time to sort it out. - I don't think it's a good idea to have multiple header files for a single domain feature. - As stated in the Future Scope, I wanted to be in a position to eliminate module global random number state in the future. - The existing implementation and the object implementation share most of the same logic. It was necessary to merge them into one to make them common.. I certainly didn't want to require a workaround for PHP 8.2 or later for extensions that depended on ext/standard respectively, but I decided that I had no choice for the above reasons.
> just don't make it a requirement.
I would like to modify the design.
> I don't think it makes sense to switch these functions to use cryptographic randomness by default...
While these may not need to be cryptographically secure, I don't think they need to be state-dependent as well. Probably no one would look at the function name and think that it depends on the module global state. php_random_int() doesn't have any state anywhere (except OS) and can generate the requested random number. I don't see any problem with these functions using php_random_int() as a random number source. Regards, Go Kudo 2021年9月4日(土) 1:02 Nikita Popov ppv@gmail.com>:
> On Thu, Sep 2, 2021 at 5:10 PM Go Kudo <zeriyoshi@gmail.com> wrote: > >> Hi Internals. >> >> Expanded from the previous RFC and changed it to an RFC that organizes the >> whole PHP random number generator. Also, the target version has been >> changed to 8.2. >> >> https://wiki.php.net/rfc/rng_extension >> https://github.com/php/php-src/pull/7453 >> >> Hopefully you will get some good responses. >> > > This looks pretty nice to me. A few bits of feedback: > > * Unlike the previous versions of the RFC, this one also moves all of the > existing RNG-related functionality from ext/standard to ext/random. Why > does it do this? This doesn't really seem related to the problem this RFC > is solving. > > * Regarding the abstract class Random\NumberGenerator: You currently need > the abstract class, because php_random_ng is tied to the object. An > alternative design that would allow Random\NumberGenerator to be an > interface would be to make it independent of the object, such that the > structure can be allocated in the Random constructor for userland > implementations. Of course, internal implementations could still embed it > as part of their objects -- just don't make it a requirement. > > * The future scope mentions: "Changes random source to php_random_int() a > shuffle(), str_shuffle(), and array_rand()". I don't think it makes sense > to switch these functions to use cryptographic randomness by default... > > Regards, > Nikita >
  115947
September 4, 2021 19:24 Danack@basereality.com (Dan Ackroyd)
On Fri, 3 Sept 2021 at 18:41, Go Kudo <zeriyoshi@gmail.com> wrote:
> > Nikita wrote: >> this one also moves all of the existing RNG-related functionality >> from ext/standard to ext/random. > > There are several reasons for this. > > - The `random` extension name is already used by ext/standard and may > interfere with the build system. > - Due to the namespace rules for new extensions, it is inappropriate to > rename an extension. > - Due to history, the rand / mt_rand dependency is tricky and I thought it > was time to sort it out. > - I don't think it's a good idea to have multiple header files for a single > domain feature.
Have you considered how much work that is going to incur on downstream projects? If there's a good reason for moving stuff around then it can be appropriate, but the RFC phrasing of: "At the same time, the following internal APIs will also be relocated. If you want to use them, you can _simply_ include ext/random/random.h." sounds pretty dismissive of causing possibly unneeded work for downstream projects. cheers Dan Ack
  115953
September 5, 2021 04:06 zeriyoshi@gmail.com (Go Kudo)
This may not have been the best way to put it. The point I was trying to
make was that while BC Breaks do occur, they are very easy to solve.

The impact on downstream projects will be significant, and there may be
many extensions affected, since this change concerns a frequently used RNG
feature. However, in other words, it may need to be sorted out as soon as
possible.

However, I also understand the theory that this should be done in
conjunction with a major language change. Perhaps I should have suggested
this for PHP 8.0.

Either way, I'll try to separate these suggestions if necessary, but if we
were to try to provide an OOP API without BC Break, what do you think would
be the ideal form?

Regards,
Go Kudo

2021年9月5日(日) 4:24 Dan Ackroyd <Danack@basereality.com>:

> On Fri, 3 Sept 2021 at 18:41, Go Kudo <zeriyoshi@gmail.com> wrote: > > > > Nikita wrote: > >> this one also moves all of the existing RNG-related functionality > >> from ext/standard to ext/random. > > > > There are several reasons for this. > > > > - The `random` extension name is already used by ext/standard and may > > interfere with the build system. > > - Due to the namespace rules for new extensions, it is inappropriate to > > rename an extension. > > - Due to history, the rand / mt_rand dependency is tricky and I thought > it > > was time to sort it out. > > - I don't think it's a good idea to have multiple header files for a > single > > domain feature. > > Have you considered how much work that is going to incur on downstream > projects? > > If there's a good reason for moving stuff around then it can be > appropriate, but the RFC phrasing of: "At the same time, the > following internal APIs will also be relocated. If you want to use > them, you can _simply_ include ext/random/random.h." sounds pretty > dismissive of causing possibly unneeded work for downstream projects. > > cheers > Dan > Ack >
  116139
September 22, 2021 17:05 Danack@basereality.com (Dan Ackroyd)
Go Kudo wrote:
> Dan Ackroyd wrote: >> you can _simply_ include ext/random/random.h." sounds pretty >> dismissive of causing possibly unneeded work for downstream projects. > > The point I was trying to make was that while BC Breaks do occur, they are very easy to solve.
I've found it useful to think about "value = benefit minus cost". I was calling out that it seems to be that this is a change you want to do for aesthetic reasons and are justifying it by trivialising the work involved. i.e. it has a tiny benefit that only has a positive value if the cost is also tiny. Although the change is simple: * Any code base that includes standard/php_rand.h won't compile, and people will have to find out what changed. Even though the fix may be easy to implement, each of those people will have to figure it out for themselves. * quite a few people will have to learn (or relearn) how to use #if to compare PHP version to include either standard/php_rand.h or random/php_random.h if they want their code to work on more than 1 PHP version. * it makes more work for downstream distributors of PHP, as their patches (including security patches) will need to be moved around. If there's a good reason to move stuff around, then fine, but avoiding creating extra work downstream is worth doing. And possibly is a hot topic right now. You could probably avoid a lot of downstream work by leaving a stub file at standard/php_rand.h that includes random/php_random.h. cheers Dan Ack btw, if you could please avoid top-posting, that would be appreciated: https://github.com/php/php-src/blob/master/docs/mailinglist-rules.md "Do not top post. Place your answer underneath anyone you wish to quote and remove any previous comment that is not relevant to your post."
  115946
September 4, 2021 16:11 ramsey@php.net (Ben Ramsey)
--xy3uIZruLmhMg9EhUgH5u6fGg88jYmAAx
Content-Type: text/plain; charset=utf-8
Content-Language: en-US
Content-Transfer-Encoding: quoted-printable

Go Kudo wrote on 9/2/21 10:10:
> Hi Internals. >=20 > Expanded from the previous RFC and changed it to an RFC that organizes = the
> whole PHP random number generator. Also, the target version has been > changed to 8.2. >=20 > https://wiki.php.net/rfc/rng_extension > https://github.com/php/php-src/pull/7453 >=20 > Hopefully you will get some good responses. >=20 > Regards, > Go Kudo >=20
This proposal seems like two different proposals to me: - The first consolidates and cleans up RNG functions for internals - The second exposes an OOP API for working with RNGs Personally, I don't see the benefit of including this OOP API in the core. I don't think it provides any benefits over similar abstractions in userland, and in fact, I think this kind of API is best suited for iteration in userland. Cheers, Ben --xy3uIZruLmhMg9EhUgH5u6fGg88jYmAAx--
  115948
September 4, 2021 20:57 marc@mabe.berlin (Marc)
On 9/2/21 5:10 PM, Go Kudo wrote:
> Hi Internals. > > Expanded from the previous RFC and changed it to an RFC that organizes the > whole PHP random number generator. Also, the target version has been > changed to 8.2. > > https://wiki.php.net/rfc/rng_extension > https://github.com/php/php-src/pull/7453 > > Hopefully you will get some good responses.
For me (user land developer with no voting power) your RFC looks pretty :) Beside the abstract vs interface question I have some other notes: On the one hand you define "getBytes()" which returns a string and on the other hand you define "shuffleString()" - is the first one a binary string and the other a charset dependent string? I guess here "shuffleString()" works on byte level and so it should be "shuffleBytes()". Why are there no default values for min/max on "getInt()" - It seems unnecessary to me to pass min/max arguments if you are just interested in a random integer or passing max as well if you are interested in a positive integer only. Thanks for the nice RFC!
> Regards, > Go Kudo Marc
  115954
September 5, 2021 04:13 zeriyoshi@gmail.com (Go Kudo)
Thanks marc.

> "shuffleString()" works on byte level and so it should be "shuffleBytes()".
Hmm. This may be a difficult problem related to the PHP language specification. As with `str_shuffle()`, most people will probably use it to shuffle strings. People who want to shuffle binaries are likely to understand that in PHP it is synonymous with `shuffleBytes()`.
> Why are there no default values for min/max on "getInt()" - It seems unnecessary to me to pass min/max arguments
My apologies. I completely forgot that I needed this. Add this along with a fix for the RNG\NumberGenerator implementation. Regards, Go Kudo 2021年9月5日(日) 5:57 Marc <marc@mabe.berlin>:
> > On 9/2/21 5:10 PM, Go Kudo wrote: > > Hi Internals. > > > > Expanded from the previous RFC and changed it to an RFC that organizes > the > > whole PHP random number generator. Also, the target version has been > > changed to 8.2. > > > > https://wiki.php.net/rfc/rng_extension > > https://github.com/php/php-src/pull/7453 > > > > Hopefully you will get some good responses. > > For me (user land developer with no voting power) your RFC looks pretty :) > > Beside the abstract vs interface question I have some other notes: > > On the one hand you define "getBytes()" which returns a string and on > the other hand you define "shuffleString()" - is the first one a binary > string and the other a charset dependent string? I guess here > "shuffleString()" works on byte level and so it should be "shuffleBytes()". > > Why are there no default values for min/max on "getInt()" - It seems > unnecessary to me to pass min/max arguments if you are just interested > in a random integer or passing max as well if you are interested in a > positive integer only. > > Thanks for the nice RFC! > > > Regards, > > Go Kudo > Marc >
  115981
September 7, 2021 08:21 nikita.ppv@gmail.com (Nikita Popov)
On Sat, Sep 4, 2021 at 10:57 PM Marc <marc@mabe.berlin> wrote:

> > On 9/2/21 5:10 PM, Go Kudo wrote: > > Hi Internals. > > > > Expanded from the previous RFC and changed it to an RFC that organizes > the > > whole PHP random number generator. Also, the target version has been > > changed to 8.2. > > > > https://wiki.php.net/rfc/rng_extension > > https://github.com/php/php-src/pull/7453 > > > > Hopefully you will get some good responses. > > For me (user land developer with no voting power) your RFC looks pretty :) > > Beside the abstract vs interface question I have some other notes: > > On the one hand you define "getBytes()" which returns a string and on > the other hand you define "shuffleString()" - is the first one a binary > string and the other a charset dependent string? I guess here > "shuffleString()" works on byte level and so it should be "shuffleBytes()". > > Why are there no default values for min/max on "getInt()" - It seems > unnecessary to me to pass min/max arguments if you are just interested > in a random integer or passing max as well if you are interested in a > positive integer only. >
Because the default range is not obvious. For example mt_rand() without min/max will actually return only non-negative integers, so someone might expect $random->getInt() to do the same, even though it makes very little sense. $random->getInt($n) could be interpreted either as a number in $n..PHP_INT_MAX (if we just see it as leaving $max at the default value), or 0..$n-1 (a very common convention for single-argument random integer functions). Requiring both arguments makes the meaning unambiguous. Regards, Nikita
  115982
September 7, 2021 08:28 nikita.ppv@gmail.com (Nikita Popov)
On Thu, Sep 2, 2021 at 5:10 PM Go Kudo <zeriyoshi@gmail.com> wrote:

> Hi Internals. > > Expanded from the previous RFC and changed it to an RFC that organizes the > whole PHP random number generator. Also, the target version has been > changed to 8.2. > > https://wiki.php.net/rfc/rng_extension > https://github.com/php/php-src/pull/7453 > > Hopefully you will get some good responses. >
This RFC currently tries to keep some semblance of compatibility with the existing mt_rand() algorithm by retaining the same implementation for mapping the raw random number stream into a range. However, the algorithm we use for that is not exactly state of the art and requires two full-width divisions at minimum. There are more efficient scaling algorithms based on fixed-point multiplication, which are "nearly divisionless" ( https://arxiv.org/pdf/1805.10941.pdf). The variant at https://github.com/apple/swift/pull/39143 is entirely divisionless. Doing this would improve performance (though I'm not sure by how much -- maybe once we add up our call overhead, it isn't important anymore?) but it would provide a different sequence than mt_rand(). Something we might want to consider. Regards, Nikita
  116023
September 9, 2021 04:30 zeriyoshi@gmail.com (Go Kudo)
Hi Nikita, sorry for the late reply.

This is a difficult problem. For now, MT19937 is left for compatibility. In
other words, if you don't need compatibility, there is no benefit to using
it.

What about implementing both a new MT and a compatible MT? A compatible MT
would have the following signature

```php

use Random\NumberGenerator\Numbergenerator;

/* for legacy compatibility */
class MT19937 implements NumberGenerator
{
    public function __construct(int $mode = MT_RAND_MT19937, int $seed) {}
}

/* a new implementation */
class MersenneTwister implements NumberGenerator
{
    public function __construct(int $seed) {}
}
```

I had originally removed the MT_RAND_PHP implementation on the grounds that
legacy implementations should not be retained, but if the regular Mersenne
twister is to be retained for compatibility, I think it should be as well.

Also, maybe we should opt for a more SIMD friendly RNG.

Regards,
Go Kudo

2021年9月7日(火) 17:28 Nikita Popov ppv@gmail.com>:

> On Thu, Sep 2, 2021 at 5:10 PM Go Kudo <zeriyoshi@gmail.com> wrote: > >> Hi Internals. >> >> Expanded from the previous RFC and changed it to an RFC that organizes the >> whole PHP random number generator. Also, the target version has been >> changed to 8.2. >> >> https://wiki.php.net/rfc/rng_extension >> https://github.com/php/php-src/pull/7453 >> >> Hopefully you will get some good responses. >> > > This RFC currently tries to keep some semblance of compatibility with the > existing mt_rand() algorithm by retaining the same implementation for > mapping the raw random number stream into a range. However, the algorithm > we use for that is not exactly state of the art and requires two full-width > divisions at minimum. There are more efficient scaling algorithms based on > fixed-point multiplication, which are "nearly divisionless" ( > https://arxiv.org/pdf/1805.10941.pdf). The variant at > https://github.com/apple/swift/pull/39143 is entirely divisionless. > > Doing this would improve performance (though I'm not sure by how much -- > maybe once we add up our call overhead, it isn't important anymore?) but it > would provide a different sequence than mt_rand(). Something we might want > to consider. > > Regards, > Nikita >