From 3469c605c6c50b338318a5b42b5002c7c170a1ef Mon Sep 17 00:00:00 2001 From: "a.stevan" <antoine.stevan@isae-supaero.fr> Date: Wed, 29 May 2024 16:02:14 +0200 Subject: [PATCH 1/9] take 32-byte-seed in `rng` --- bins/rng/Cargo.toml | 1 + bins/rng/src/main.rs | 21 ++++++++++++++++----- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/bins/rng/Cargo.toml b/bins/rng/Cargo.toml index 39f70a07..f209c7e3 100644 --- a/bins/rng/Cargo.toml +++ b/bins/rng/Cargo.toml @@ -8,4 +8,5 @@ description = "Generate random numbers from a seed." [dependencies] clap = { version = "4.5.4", features = ["derive"] } +hex = "0.4.3" rand = "0.8.5" diff --git a/bins/rng/src/main.rs b/bins/rng/src/main.rs index 04f7e40a..d1c15748 100644 --- a/bins/rng/src/main.rs +++ b/bins/rng/src/main.rs @@ -1,22 +1,33 @@ use clap::Parser; use rand::{rngs::StdRng, Rng, SeedableRng}; +fn parse_hex_string(s: &str) -> Result<[u8; 32], String> { + if s.len() != 64 { + return Err("Input string must be exactly 64 characters long".to_string()); + } + + match hex::decode(s) { + // `bytes` will be a `Vec<u8>` of size `32`, so it's safe to `unwrap` + // the conversion to `[u8: 32]` + Ok(bytes) => Ok(bytes.try_into().unwrap()), + Err(e) => Err(format!("Failed to decode hex string: {}", e)), + } +} + #[derive(Parser)] #[command(version, about, long_about = None)] struct Cli { #[arg(short)] n: usize, - #[arg(long)] - prng_seed: u8, + #[arg(long, value_parser = parse_hex_string)] + prng_seed: [u8; 32], } fn main() { let cli = Cli::parse(); - let mut seed: [u8; 32] = [0; 32]; - seed[0] = cli.prng_seed; - let mut rng = StdRng::from_seed(seed); + let mut rng = StdRng::from_seed(cli.prng_seed.into()); for _ in 0..cli.n { println!("{}", rng.gen::<u8>()); -- GitLab From d4776ea940abbe087dfeca7bd60d1f16d6b43599 Mon Sep 17 00:00:00 2001 From: "a.stevan" <antoine.stevan@isae-supaero.fr> Date: Wed, 29 May 2024 16:03:20 +0200 Subject: [PATCH 2/9] same in inbreeding --- bins/inbreeding/src/main.rs | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/bins/inbreeding/src/main.rs b/bins/inbreeding/src/main.rs index 51f2d08b..47ace20f 100644 --- a/bins/inbreeding/src/main.rs +++ b/bins/inbreeding/src/main.rs @@ -149,6 +149,19 @@ where Ok(()) } +fn parse_hex_string(s: &str) -> Result<[u8; 32], String> { + if s.len() != 64 { + return Err("Input string must be exactly 64 characters long".to_string()); + } + + match hex::decode(s) { + // `bytes` will be a `Vec<u8>` of size `32`, so it's safe to `unwrap` + // the conversion to `[u8: 32]` + Ok(bytes) => Ok(bytes.try_into().unwrap()), + Err(e) => Err(format!("Failed to decode hex string: {}", e)), + } +} + #[derive(ValueEnum, Clone)] enum TestCase { EndToEnd, @@ -190,8 +203,8 @@ struct Cli { #[arg(long)] measurement_schedule_start: usize, - #[arg(long)] - prng_seed: u8, + #[arg(long, value_parser = parse_hex_string)] + prng_seed: [u8; 32], } fn main() { @@ -205,9 +218,7 @@ fn main() { exit(1); } - let mut seed: [u8; 32] = [0; 32]; - seed[0] = cli.prng_seed; - let mut rng = StdRng::from_seed(seed); + let mut rng = StdRng::from_seed(cli.prng_seed); let bytes = random_bytes(cli.nb_bytes, &mut rng); -- GitLab From 5f6f0f21b209ef43804cb3bf35c5f90eefb3e174 Mon Sep 17 00:00:00 2001 From: "a.stevan" <antoine.stevan@isae-supaero.fr> Date: Wed, 29 May 2024 16:22:24 +0200 Subject: [PATCH 3/9] add optional `$.help` to `error throw` --- .nushell/error.nu | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.nushell/error.nu b/.nushell/error.nu index 34e30b9b..9e6a4aeb 100644 --- a/.nushell/error.nu +++ b/.nushell/error.nu @@ -1,9 +1,15 @@ -export def "error throw" [err: record<err: string, label: string, span: record<start: int, end: int>>] { +export def "error throw" [err: record< + err: string, + label: string, + span: record<start: int, end: int>, + # help: string?, +>] { error make { msg: $"(ansi red_bold)($err.err)(ansi reset)", label: { text: $err.label, span: $err.span, }, + help: $err.help?, } } -- GitLab From d9eb1772e52625ec465b1fe117c81434c2fa3d99 Mon Sep 17 00:00:00 2001 From: "a.stevan" <antoine.stevan@isae-supaero.fr> Date: Wed, 29 May 2024 16:23:10 +0200 Subject: [PATCH 4/9] check PRNG seed in `inbreeding run` --- bins/inbreeding/run.nu | 50 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/bins/inbreeding/run.nu b/bins/inbreeding/run.nu index 5b01dfce..c9cfbd04 100644 --- a/bins/inbreeding/run.nu +++ b/bins/inbreeding/run.nu @@ -1,5 +1,43 @@ use consts.nu use ../../.nushell cargo "cargo bin" +use ../../.nushell error "error throw" + +const VALID_HEX_CHARS = "abcdefABCDEF0123456789" + +def check-hex [-n: int]: [ + string -> record< + ok: bool, + err: record<msg: string, label: string, help: string>, + > +] { + let s = $in + + if ($s | str length) != $n { + return { + ok: false, + err: { + msg: "invalid HEX length" + label : $"length is ($s | str length)", + help: "length should be 64", + }, + } + } + + for c in ($s | split chars | enumerate) { + if not ($VALID_HEX_CHARS | str contains $c.item) { + return { + ok: false, + err: { + msg: "bad HEX character", + label: $"found '($c.item)' at ($c.index)", + help: $"expected one of '($VALID_HEX_CHARS)'", + }, + } + } + } + + { ok: true, err: {} } +} export def main [ --options: record< @@ -14,7 +52,7 @@ export def main [ strategies: list<string>, environment: string, >, - --prng-seed: int = 0, + --prng-seed: string = "0000000000000000000000000000000000000000000000000000000000000000", ] { if $options.measurement_schedule_start > $options.max_t { error make --unspanned { @@ -22,6 +60,16 @@ export def main [ } } + let res = $prng_seed | check-hex -n 64 + if not $res.ok { + error throw { + err: $res.err.msg, + label: $res.err.label, + span: (metadata $prng_seed).span, + help: $res.err.help, + } + } + let now = date now | format date "%s%f" for s in $options.strategies { -- GitLab From 051699cac46def72a4e0fecca91c041eb5aeb411 Mon Sep 17 00:00:00 2001 From: "a.stevan" <antoine.stevan@isae-supaero.fr> Date: Wed, 29 May 2024 16:23:49 +0200 Subject: [PATCH 5/9] update README --- bins/inbreeding/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bins/inbreeding/README.md b/bins/inbreeding/README.md index dc77e786..1b27f8c0 100644 --- a/bins/inbreeding/README.md +++ b/bins/inbreeding/README.md @@ -7,7 +7,7 @@ use ./bins/inbreeding ``` ```bash -const PRNG_SEED = 123 +const PRNG_SEED = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" const OPTS = { nb_bytes: (10 * 1_024), k: 10, -- GitLab From c834af10e9d9698775dac4418d5e39e163636d2f Mon Sep 17 00:00:00 2001 From: "a.stevan" <antoine.stevan@isae-supaero.fr> Date: Wed, 29 May 2024 16:32:58 +0200 Subject: [PATCH 6/9] add missing dependency to `inbreeding` --- bins/inbreeding/Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/bins/inbreeding/Cargo.toml b/bins/inbreeding/Cargo.toml index c8982f38..5fbcc697 100644 --- a/bins/inbreeding/Cargo.toml +++ b/bins/inbreeding/Cargo.toml @@ -11,3 +11,4 @@ clap = { version = "4.5.4", features = ["derive"] } rand = "0.8.5" indicatif = "0.17.8" ark-ff = "0.4.2" +hex = "0.4.3" -- GitLab From b3cdb9c75c388eb0b0c1cb3cc404b94c8a10764a Mon Sep 17 00:00:00 2001 From: "a.stevan" <antoine.stevan@isae-supaero.fr> Date: Wed, 29 May 2024 16:35:54 +0200 Subject: [PATCH 7/9] compute the seeds directly by hashing --- bins/inbreeding/run.nu | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/bins/inbreeding/run.nu b/bins/inbreeding/run.nu index c9cfbd04..e27cdc85 100644 --- a/bins/inbreeding/run.nu +++ b/bins/inbreeding/run.nu @@ -1,5 +1,4 @@ use consts.nu -use ../../.nushell cargo "cargo bin" use ../../.nushell error "error throw" const VALID_HEX_CHARS = "abcdefABCDEF0123456789" @@ -81,19 +80,6 @@ export def main [ mkdir $output_dir print $"data will be dumped to `($output_dir)`" - # compute a unique seed for that strategy and global seed - let seed = $s + $"($prng_seed)" - | hash sha256 - | split chars - | last 2 - | str join - | $"0x($in)" - | into int - # compute all the seeds for that strategy, one per scenario - let seeds = cargo bin rng ...[ -n $options.nb_scenarii --prng-seed $prng_seed ] - | lines - | into int - for i in 1..$options.nb_scenarii { let output = [ $output_dir, $"($i)" ] | path join @@ -108,7 +94,7 @@ export def main [ --test-case recoding --strategy $s --environment $options.environment - --prng-seed ($seeds | get ($i - 1)) + --prng-seed ([$prng_seed, $s, $i] | str join | hash sha256) ] out> $output } -- GitLab From 29d2a3c13a2a9365c2fac9c2b260edff34907bfa Mon Sep 17 00:00:00 2001 From: "a.stevan" <antoine.stevan@isae-supaero.fr> Date: Wed, 29 May 2024 17:29:26 +0200 Subject: [PATCH 8/9] make Clippy happy --- bins/rng/src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bins/rng/src/main.rs b/bins/rng/src/main.rs index d1c15748..32223c9f 100644 --- a/bins/rng/src/main.rs +++ b/bins/rng/src/main.rs @@ -27,7 +27,7 @@ struct Cli { fn main() { let cli = Cli::parse(); - let mut rng = StdRng::from_seed(cli.prng_seed.into()); + let mut rng = StdRng::from_seed(cli.prng_seed); for _ in 0..cli.n { println!("{}", rng.gen::<u8>()); -- GitLab From 454b3a2a171ed199df1f9261443e1cb9000123b2 Mon Sep 17 00:00:00 2001 From: "a.stevan" <antoine.stevan@isae-supaero.fr> Date: Wed, 29 May 2024 17:34:28 +0200 Subject: [PATCH 9/9] allow `seed: string` in `inbreeding inspect` --- bins/inbreeding/inspect.nu | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bins/inbreeding/inspect.nu b/bins/inbreeding/inspect.nu index 0df2ea82..96a908a5 100644 --- a/bins/inbreeding/inspect.nu +++ b/bins/inbreeding/inspect.nu @@ -5,7 +5,7 @@ def get-seeds [] [ nothing -> list<string> ] { $consts.CACHE | path join '*' | into glob | ls $in | get name | each { path split | last } } -export def main [seed: int@get-seeds]: [ +export def main [seed: string@get-seeds]: [ nothing -> table< seed: string, timestamp: string, -- GitLab