[swift-evolution] [Proposal] Random Unification

Xiaodi Wu xiaodi.wu at gmail.com
Sat Sep 30 10:22:34 CDT 2017


On Thu, Sep 28, 2017 at 12:16 PM, Félix Cloutier <felixcloutier at icloud.com>
wrote:

>
>
> Le 27 sept. 2017 à 17:29, Xiaodi Wu <xiaodi.wu at gmail.com> a écrit :
>
> What I was trying to respond to, by contrast, is the design of a hierarchy
> of protocols CSPRNG : PRNG (or, in Alejandro's proposal, UnsafeRandomSource
> : RandomSource) and the appropriate APIs to expose on each. This is
> entirely inapplicable to your examples. It stands to reason that a
> non-instantiable source of random numbers does not require a protocol of
> its own (a hypothetical RNG : CSPRNG), since there is no reason to
> implement (if done correctly) more than a single publicly non-instantiable
> singleton type that could conform to it. For that matter, the concrete type
> itself probably doesn't need *any* public API at all. Instead, extensions
> to standard library types such as Int that implement conformance to the
> protocol that Alejandro names "Randomizable" could call internal APIs to
> provide all the necessary functionality, and third-party types that need to
> conform to "Randomizable" could then in turn use `Int.random()` or
> `Double.random()` to implement their own conformance. In fact, the concrete
> random number generator type doesn't need to be public at all. All public
> interaction could be through APIs such as `Int.random()`.
>
>
> If there is globally-available CSPRNG that people are encouraged to use,
> what is the benefit of a CSPRNG : PRNG hierarchy?
>

There are plenty of use cases that do not require cryptographically secure
pseudorandom sequences but can benefit from the speed of an algorithm like
xoroshiro128+. For instance, suppose I want to simulate Brownian motion in
an animation; I do not care about the cryptographic properties of my random
number source. However, the underlying function to generate a normally
distributed random number can rely on either a source of cyptographically
secure or cryptographically insecure uniformly distributed random numbers.
Put another way, a protocol hierarchy is justified because useful functions
that produce random values in various desired distributions can be written
that work with any PRNG, while there are (obviously) uses that are suitable
for CSPRNGs only.


> What is the benefit of clearly identifying an algorithm as crypto-secure
> if the recommendation is that you use *the* crypto-secure object/functions?
>

The default source of random numbers is unseedable, but the user may
instead require repeatable generation of a sequence of random numbers. The
user may have a use case that requires the use of a particular specified
CSPRNG.

> Again, I'm not only talking about urandom. As far as I'm aware, every API
> to retrieve cryptographically secure sequences of random bits on every
> platform for which Swift is distributed can potentially return an error
> instead of random bits. The question is, what design for our API is the
> most sensible way to deal with this contingency? On rethinking, I do
> believe that consistently returning an Optional is the best way to go about
> it, allowing the user to either (a) supply a deterministic fallback; (b)
> raise an error of their own choosing; or (c) trap--all with a minimum of
> fuss. This seems very Swifty to me.
>
>
> With Linux's getrandom, if you read from urandom (the default) and ask for
> as much or less than 256 bytes, the only possible error is that urandom
> hasn't been seeded <http://man7.org/linux/man-pages/man2/getrandom.2.html>.
> (With more than 256 bytes, it also becomes possible for the system call to
> be interrupted by a signal.) OpenBSD's getentropy is literally just
> arc4random running in the kernel
> <https://github.com/openbsd/src/blob/master/sys/dev/rnd.c#L889>, and will
> only fail if you ask for more than 256 bytes because it is a hard-coded
> limit.
>

Yes, but again, what do you think of the possible Swift API design choices
to accommodate these errors? We have to pick one, but none of them are very
appealing.

Meanwhile, getentropy() has the problem that, if there is insufficient
randomness to initialize the entropy pool, it will block; on systems where
there is never going to be sufficient randomness (i.e. a VM), it will block
forever. By contrast, getrandom() permits a flag that will make this
scenario non-blocking.

Ironically, I don't know how you get entropy on Darwin. If it's more
> failable that this, I'd argue that it's time to improve a bit...
>
> Félix
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170930/09bf0e4d/attachment.html>


More information about the swift-evolution mailing list