Skip to main content

aura_core/effects/
random.rs

1//! Random effects trait definitions
2//!
3//! This module defines the trait interface for random number generation.
4//! Implementations are provided in aura-protocol handlers.
5//!
6//! # Effect Classification
7//!
8//! - **Category**: Infrastructure Effect
9//! - **Implementation**: `aura-effects` (Layer 3)
10//! - **Usage**: All crates needing cryptographically secure randomness
11//!
12//! This is an infrastructure effect that must be implemented in `aura-effects`
13//! with stateless handlers. Provides production (system RNG), testing (seeded),
14//! and simulation (controlled) implementations.
15
16use async_trait::async_trait;
17use uuid::Uuid;
18
19/// Core random effects for generating random values.
20///
21/// This trait provides cryptographically secure random number generation
22/// for the Aura effects system. Implementations in handlers provide:
23/// - Production: System cryptographic RNG
24/// - Testing: Deterministic seeded RNG for reproducible tests
25/// - Simulation: Controlled randomness for scenario testing
26#[async_trait]
27pub trait RandomCoreEffects: Send + Sync {
28    /// Generate random bytes of specified length
29    async fn random_bytes(&self, len: usize) -> Vec<u8>;
30
31    /// Generate 32 random bytes as array
32    async fn random_bytes_32(&self) -> [u8; 32];
33
34    /// Generate a random u64 value
35    async fn random_u64(&self) -> u64;
36}
37
38/// Optional random effects that build on the core RNG.
39#[async_trait]
40pub trait RandomExtendedEffects: RandomCoreEffects + Send + Sync {
41    /// Generate a random number in the specified range
42    async fn random_range(&self, min: u64, max: u64) -> u64 {
43        if max <= min {
44            return min;
45        }
46        let span = max - min;
47        min + (self.random_u64().await % span)
48    }
49
50    /// Generate a random UUID v4
51    async fn random_uuid(&self) -> Uuid {
52        let mut bytes = [0u8; 16];
53        let random = self.random_bytes(16).await;
54        bytes.copy_from_slice(&random[..16]);
55        // Set UUID v4 variant bits without using disallowed Builder APIs.
56        bytes[6] = (bytes[6] & 0x0f) | 0x40;
57        bytes[8] = (bytes[8] & 0x3f) | 0x80;
58        Uuid::from_bytes(bytes)
59    }
60}
61
62#[async_trait]
63impl<T: RandomCoreEffects + ?Sized> RandomExtendedEffects for T {}
64
65/// Combined random effects surface (core + extended).
66pub trait RandomEffects: RandomCoreEffects + RandomExtendedEffects {}
67
68impl<T: RandomCoreEffects + RandomExtendedEffects + ?Sized> RandomEffects for T {}
69
70/// Blanket implementation for Arc<T> where T: RandomCoreEffects
71#[async_trait]
72impl<T: RandomCoreEffects + ?Sized> RandomCoreEffects for std::sync::Arc<T> {
73    async fn random_bytes(&self, len: usize) -> Vec<u8> {
74        (**self).random_bytes(len).await
75    }
76
77    async fn random_bytes_32(&self) -> [u8; 32] {
78        (**self).random_bytes_32().await
79    }
80
81    async fn random_u64(&self) -> u64 {
82        (**self).random_u64().await
83    }
84}