> On Oct 3, 2017, at 11:44 PM, Jonathan Hull via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> I like the idea of splitting it into 2 separate “Random” proposals.
> 
> The first would have Xiaodi’s built-in CSPRNG which only has the interface:
> 
> On FixedWidthInteger:
>       static func random()throws -> Self
>       static func random(in range: ClosedRange<Self>)throws -> Self
> 
> On Double:
>       static func random()throws -> Double
>       static func random(in range: ClosedRange<Double>)throws -> Double
> 
> (Everything else we want, like shuffled(), could be built in later proposals 
> by calling those functions)
> 
> The other option would be to remove the ‘throws’ from the above functions 
> (perhaps fatalError-ing), and provide an additional function which can be 
> used to check that there is enough entropy (so as to avoid the crash or fall 
> back to a worse source when the CSPRNG is unavailable).

> 

> Then a second proposal would bring in the concept of RandomSources (whatever 
> we call them), which can return however many random bytes you ask for… and a 
> protocol for types which know how to initialize themselves from those bytes.  
> That might be spelled like 'static func random(using: RandomSource)->Self'.  
> As a convenience, the source would also be able to create FixedWidthIntegers 
> and Doubles (both with and without a range), and would also have the 
> coinFlip() and oneIn(UInt)->Bool functions. Most types should be able to 
> build themselves off of that.  There would be a default source which is built 
> from the first protocol.
> 
> I also really think we should have a concept of Repeatably-Random as a 
> subprotocol for the second proposal.  I see far too many shipping apps which 
> have bugs due to using arc4Random when they really needed a repeatable source 
> (e.g. patterns and lines jump around when you resize things). If it was an 
> easy option, people would use it when appropriate. This would just mean a 
> sub-protocol which has an initializer which takes a seed, and the ability to 
> save/restore state (similar to CGContexts).


I like this kind of layering of functionality and proposals. I would 
additionally separate the fundamental CSPRNG interface from the fool-proof easy 
functions that naive users will find on Stack Overflow.

The "easy" functions should:

* Trap on any error without throwing. Sophisticated users may be able to do 
something about entropy failure, so the fundamental CSPRNG interface needs to 
provide errors, but the easy function should either degrade somewhat (if 
entropy is present but insufficient) or just die (if entropy is wholly absent 
or nearly so).

* Remove the range-less function. Naive users often write things like 
`Int.random() % 100`, which unbeknownst to them is biased. Providing only the 
ranged interface nudges naive users toward correct usage. 

* Provide an "easy" way to get some random bytes instead of a random number. 
Perhaps a Data initializer that returns random-filled bytes of the requested 
length. This helps make up for the lack of a range-less function on 
FixedWidthInteger.

The "easy" functions should get the best names: Int.random(in:), 
Data.random(length:), etc. The fundamental CSPRNG interface should have an 
interface that is less friendly and less discoverable.


-- 
Greg Parker     gpar...@apple.com <mailto:gpar...@apple.com>     Runtime 
Wrangler


_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to