mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Add runtime.Random_Generator interface
This commit is contained in:
@@ -397,11 +397,30 @@ Logger :: struct {
|
|||||||
options: Logger_Options,
|
options: Logger_Options,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Random_Generator_Mode :: enum {
|
||||||
|
Read,
|
||||||
|
Query_Info,
|
||||||
|
}
|
||||||
|
|
||||||
|
Random_Generator_Query_Info_Flag :: enum u32 {
|
||||||
|
Cryptographic,
|
||||||
|
Uniform,
|
||||||
|
External_Entropy,
|
||||||
|
}
|
||||||
|
Random_Generator_Query_Info :: distinct bit_set[Random_Generator_Query_Info_Flag; u32]
|
||||||
|
|
||||||
|
Random_Generator :: struct {
|
||||||
|
procedure: proc(data: rawptr, mode: Random_Generator_Mode, p: []byte),
|
||||||
|
data: rawptr,
|
||||||
|
}
|
||||||
|
|
||||||
Context :: struct {
|
Context :: struct {
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
temp_allocator: Allocator,
|
temp_allocator: Allocator,
|
||||||
assertion_failure_proc: Assertion_Failure_Proc,
|
assertion_failure_proc: Assertion_Failure_Proc,
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
|
random_generator: Random_Generator,
|
||||||
|
|
||||||
user_ptr: rawptr,
|
user_ptr: rawptr,
|
||||||
user_index: int,
|
user_index: int,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ helper routines.
|
|||||||
*/
|
*/
|
||||||
package crypto
|
package crypto
|
||||||
|
|
||||||
|
import "base:runtime"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
|
|
||||||
// compare_constant_time returns 1 iff a and b are equal, 0 otherwise.
|
// compare_constant_time returns 1 iff a and b are equal, 0 otherwise.
|
||||||
@@ -58,3 +59,22 @@ rand_bytes :: proc (dst: []byte) {
|
|||||||
|
|
||||||
_rand_bytes(dst)
|
_rand_bytes(dst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
to_random_generator :: proc() -> runtime.Random_Generator {
|
||||||
|
return {
|
||||||
|
procedure = proc(data: rawptr, mode: runtime.Random_Generator_Mode, p: []byte) {
|
||||||
|
switch mode {
|
||||||
|
case .Read:
|
||||||
|
rand_bytes(p)
|
||||||
|
case .Query_Info:
|
||||||
|
if len(p) != size_of(runtime.Random_Generator_Query_Info) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
info := (^runtime.Random_Generator_Query_Info)(raw_data(p))
|
||||||
|
info^ += {.Uniform, .Cryptographic, .External_Entropy}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data = nil,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ Package core:math/rand implements various random number generators
|
|||||||
package rand
|
package rand
|
||||||
|
|
||||||
import "base:intrinsics"
|
import "base:intrinsics"
|
||||||
|
import "base:runtime"
|
||||||
import "core:crypto"
|
import "core:crypto"
|
||||||
import "core:math"
|
import "core:math"
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
@@ -15,6 +16,28 @@ Rand :: struct {
|
|||||||
is_system: bool,
|
is_system: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
to_random_generator :: proc(r: ^Rand) -> runtime.Random_Generator {
|
||||||
|
return {
|
||||||
|
procedure = proc(data: rawptr, mode: runtime.Random_Generator_Mode, p: []byte) {
|
||||||
|
r := (^Rand)(data)
|
||||||
|
switch mode {
|
||||||
|
case .Read:
|
||||||
|
_ = read(p, r)
|
||||||
|
case .Query_Info:
|
||||||
|
if len(p) != size_of(runtime.Random_Generator_Query_Info) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
info := (^runtime.Random_Generator_Query_Info)(raw_data(p))
|
||||||
|
info^ += {.Uniform}
|
||||||
|
if r.is_system {
|
||||||
|
info^ += {.External_Entropy}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data = r,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@(private)
|
@(private)
|
||||||
global_rand := create(u64(intrinsics.read_cycle_counter()))
|
global_rand := create(u64(intrinsics.read_cycle_counter()))
|
||||||
@@ -150,6 +173,10 @@ _random_u64 :: proc(r: ^Rand) -> u64 {
|
|||||||
r := r
|
r := r
|
||||||
switch {
|
switch {
|
||||||
case r == nil:
|
case r == nil:
|
||||||
|
if res: u64; runtime.random_generator_read_ptr(context.random_generator, &res, size_of(res)) {
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
r = &global_rand
|
r = &global_rand
|
||||||
case r.is_system:
|
case r.is_system:
|
||||||
value: u64
|
value: u64
|
||||||
|
|||||||
Reference in New Issue
Block a user