2023-05-10 13:50:04 +00:00
|
|
|
# nim-eth
|
|
|
|
# Copyright (c) 2020-2023 Status Research & Development GmbH
|
|
|
|
# Licensed and distributed under either of
|
|
|
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
|
|
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
#
|
|
|
|
|
|
|
|
{.push raises: [].}
|
|
|
|
|
2022-06-17 20:45:37 +00:00
|
|
|
import
|
|
|
|
bearssl/rand
|
2020-07-13 12:34:53 +00:00
|
|
|
|
2022-06-17 20:45:37 +00:00
|
|
|
export rand
|
|
|
|
|
|
|
|
## Random helpers: similar as in stdlib, but with HmacDrbgContext rng
|
2020-07-13 12:34:53 +00:00
|
|
|
# TODO: Move these somewhere else?
|
|
|
|
const randMax = 18_446_744_073_709_551_615'u64
|
|
|
|
|
2022-06-17 20:45:37 +00:00
|
|
|
proc rand*(rng: var HmacDrbgContext, max: Natural): int =
|
2020-07-13 12:34:53 +00:00
|
|
|
if max == 0: return 0
|
|
|
|
|
|
|
|
var x: uint64
|
|
|
|
while true:
|
2022-06-17 20:45:37 +00:00
|
|
|
rng.generate(x)
|
2020-07-13 12:34:53 +00:00
|
|
|
if x < randMax - (randMax mod (uint64(max) + 1'u64)): # against modulo bias
|
|
|
|
return int(x mod (uint64(max) + 1'u64))
|
|
|
|
|
2022-06-17 20:45:37 +00:00
|
|
|
proc sample*[T](rng: var HmacDrbgContext, a: openArray[T]): T =
|
|
|
|
a[rng.rand(a.high)]
|
2020-07-13 12:34:53 +00:00
|
|
|
|
2022-06-17 20:45:37 +00:00
|
|
|
proc shuffle*[T](rng: var HmacDrbgContext, a: var openArray[T]) =
|
2020-07-13 12:34:53 +00:00
|
|
|
for i in countdown(a.high, 1):
|
|
|
|
let j = rng.rand(i)
|
|
|
|
swap(a[i], a[j])
|