Skip to content

Instantly share code, notes, and snippets.

@RandyMcMillan
Forked from rust-play/playground.rs
Created March 1, 2026 15:07
Show Gist options
  • Select an option

  • Save RandyMcMillan/8169c2f7ca3430b3cbcaa567750df79f to your computer and use it in GitHub Desktop.

Select an option

Save RandyMcMillan/8169c2f7ca3430b3cbcaa567750df79f to your computer and use it in GitHub Desktop.
det_rng_macro.rs
//! # Cryptographic Playground V2 - Seeded Edition
//! Demonstrates using recursive macros to generate entropy seeds for
//! deterministic RNG initialization while handling complex token trees.
#![allow(deprecated)]
#![allow(unused_attributes)]
#![allow(dead_code)]
use rand_0_8_5::{SeedableRng as SeedableLegacy, Rng as RngLegacy};
use rand_0_9_2::{SeedableRng as SeedableLatest, Rng as RngLatest};
// Note: These must be available in the playground environment
use rand_chacha_0_3_1::ChaCha8Rng as ChaChaLegacy;
use rand_chacha_0_9_0::ChaCha8Rng as ChaChaLatest;
use num_bigint::BigUint;
/// # The `compute!` Macro
/// Performs recursive expansion to evaluate expressions or reduce them into a 64-bit seed.
macro_rules! compute {
// --- Evaluation Patterns ---
(eval $e:expr) => {
{
let res = $e;
println!("Result of [{}]: {}", stringify!($e), res);
res
}
};
(eval $e:expr, $($rest:tt)+) => {
{
compute!(eval $e);
compute!($($rest)+)
}
};
// --- Seed Generation Patterns (Fixed) ---
// Base case: a single seed value
(seed $e:expr) => { ($e as u64) };
// Recursive case: Peels the first 'seed expr', then recursively calls
// compute! on the rest of the tokens to handle subsequent 'seed' keywords.
(seed $e:expr, $($rest:tt)+) => {
($e as u64) ^ compute!($($rest)+)
};
}
/// # The `create_vault!` Macro
/// Generates crypto-structures seeded by the provided entropy.
macro_rules! create_vault {
($name:ident { $($field:ident: $size:expr),* }) => {
struct $name {
$( $field: Vec<u8> ),*
}
impl $name {
/// Generates entropy using a seeded ChaCha8Rng for determinism.
fn generate_seeded(seed_val: u64) -> Self {
let mut v9 = ChaChaLatest::seed_from_u64(seed_val);
Self {
$( $field: (0..$size).map(|_| v9.r#gen()).collect() ),*
}
}
}
};
}
create_vault!(SecretData {
key: 32,
salt: 16
});
fn main() {
println!("--- Macro-Driven Seed Generation ---");
// This now expands correctly by recursively peeling 'seed' tokens
let derived_seed = compute!(
seed 0xDEADBEEF,
seed 12345,
seed 42 * 1337
);
println!("Derived Seed from Macro: {}\n", derived_seed);
// Initialize Seeded RNGs from both versions
let mut v8 = ChaChaLegacy::seed_from_u64(derived_seed);
let mut v9 = ChaChaLatest::seed_from_u64(derived_seed);
// Instantiate vault using the derived seed
let vault = SecretData::generate_seeded(derived_seed);
let p_factor = BigUint::from_bytes_be(&vault.salt);
// Comparison of cross-version output from the same seed
let legacy_val: u32 = RngLegacy::r#gen(&mut v8);
let latest_val: u32 = RngLatest::r#gen(&mut v9);
println!("--- Seeded Entropy Report ---");
println!("Salt length: {} bytes", vault.salt.len());
println!("Legacy Seeded (v0.8.5): {}", legacy_val);
println!("Latest Seeded (v0.9.2): {}", latest_val);
println!("BigInt Factor: {}", p_factor);
}
@RandyMcMillan
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment