Update random API and docs.

This commit is contained in:
Dillon Kearns 2023-01-29 16:52:03 -08:00
parent f30fded37e
commit 75be4e121f
2 changed files with 24 additions and 12 deletions

File diff suppressed because one or more lines are too long

View File

@ -34,29 +34,41 @@ to generate a single 32-bit Integer. That 32-bit Integer is then used with `Rand
Then that `Seed` used to run the `Generator`.
Note that this is different than `elm/random`'s `Random.generate`. This difference shouldn't be problematic, and in fact the `BackendTask`
random seed generation is more suitable for cryptographically secure random generation because you can't determine the
random seed generation is more cryptographically independent because you can't determine the
random seed based solely on the time at which it is run. Each time you call `BackendTask.generate` it uses a newly
generated random seed to run the `Random.Generator` that is passed in. In contrast, `elm/random`'s `Random.generate`
generates an initial seed using `Time.now`, and then continues with that same seed using using [`Random.step`](https://package.elm-lang.org/packages/elm/random/latest/Random#step)
to get new random values after that. You can [see the implementation here](https://github.com/elm/random/blob/c1c9da4d861363cee1c93382d2687880279ed0dd/src/Random.elm#L865-L896).
However, `elm/random` is still not suitable in general for cryptographic uses of random because it uses 32-bits for when it
steps through new seeds while running a single `Random.Generator`.
-}
generate : Random.Generator value -> BackendTask error value
generate generator =
randomSeed
int32
|> BackendTask.map
(\seed ->
Random.step generator seed |> Tuple.first
(Random.initialSeed
>> Random.step generator
>> Tuple.first
)
randomSeed : BackendTask error Random.Seed
randomSeed =
{-| Gives a random 32-bit Int. This can be useful if you want to do low-level things with a cryptographically sound
random 32-bit integer.
The value comes from running this code in Node using <https://developer.mozilla.org/en-US/docs/Web/API/Crypto/getRandomValues>:
```js
import * as crypto from "node:crypto";
crypto.getRandomValues(new Uint32Array(1))[0]
```
-}
int32 : BackendTask error Int
int32 =
BackendTask.Internal.Request.request
{ name = "randomSeed"
, body =
BackendTask.Http.jsonBody Encode.null
, expect =
BackendTask.Http.expectJson
(Decode.int |> Decode.map Random.initialSeed)
, body = BackendTask.Http.jsonBody Encode.null
, expect = BackendTask.Http.expectJson Decode.int
}