Skip to content

Rust API Reference

Accurate reference for the current Rust workspace API.

For Python bindings, see Python SDK.

For day-to-day usage, start with:

Use this page for complete type and function coverage.

Crate: openentropy-core
Path: crates/openentropy-core/

pub use conditioning::{
ConditioningMode, MinEntropyReport, QualityReport, condition, grade_min_entropy,
min_entropy_estimate, quick_autocorrelation_lag1, quick_min_entropy, quick_quality, quick_shannon,
};
pub use platform::{detect_available_sources, platform_info};
pub use pool::{EntropyPool, HealthReport, SourceHealth, SourceInfoSnapshot};
pub use source_resolution::{SourceMatchMode, SourceResolution, resolve_source_names};
pub use comparison::{
AggregateDelta, ComparisonResult, DigramAnalysis, MarkovAnalysis, MultiLagAnalysis,
RunLengthComparison, TemporalAnalysis, TwoSampleTests, WindowAnomaly, aggregate_delta,
cliffs_delta, compare, compare_with_analysis, digram_analysis, markov_analysis,
multi_lag_analysis, run_length_comparison, temporal_analysis, two_sample_tests,
};
pub use trials::{
CalibrationResult, StoufferResult, TrialAnalysis, TrialConfig, calibration_check,
stouffer_combine, trial_analysis,
};
pub use chaos::{
BiEntropyResult, BootstrapHurstResult, ChaosAnalysis, CorrelationDimResult, DfaResult,
EpiplexityResult, HurstResult, LyapunovResult, RollingHurstResult, RqaResult,
SampleEntropyResult, bientropy, bootstrap_hurst, bootstrap_hurst_default,
chaos_analysis, correlation_dimension, dfa, dfa_default, epiplexity,
hurst_exponent, lyapunov_exponent, rolling_hurst, rolling_hurst_default,
rqa, rqa_default, sample_entropy, sample_entropy_default,
};
pub use analysis::{
AndersonDarlingResult, ApproxEntropyResult, PermutationEntropyResult,
anderson_darling, approximate_entropy, approximate_entropy_default,
permutation_entropy, permutation_entropy_default,
};
pub use statistics::{
StatisticsAnalysis, CramerVonMisesResult, LjungBoxResult, GapTestResult,
AnovaResult, KruskalWallisResult, LeveneResult, PowerResult, MultipleCorrectionResult,
statistics_analysis, cramer_von_mises, ljung_box, gap_test,
anova, kruskal_wallis, levene_test, power_analysis,
bonferroni_correction, holm_bonferroni_correction,
};
pub use temporal::{
TemporalAnalysisSuite, ChangePointResult, AnomalyDetectionResult, BurstResult,
ShiftResult, DriftResult, StabilityResult,
temporal_analysis_suite, change_point_detection, anomaly_detection,
burst_detection, shift_detection, temporal_drift, inter_session_stability,
};
pub use synchrony::{
SynchronyAnalysis, MutualInfoResult, PhaseCoherenceResult, CrossSyncResult,
GlobalEventResult, synchrony_analysis, mutual_information, phase_coherence,
cross_sync, global_event_detection,
};
pub use dispatcher::{
AnalysisConfig, AnalysisProfile, AnalysisReport, SourceReport, VerdictSummary, analyze,
};
pub use session::{
MachineInfo, SessionConfig, SessionMeta, SessionSourceAnalysis, SessionWriter,
detect_machine_info,
};
pub use source::{EntropySource, Platform, Requirement, SourceCategory, SourceInfo};
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
use openentropy_core::{ConditioningMode, EntropyPool};
let pool = EntropyPool::auto();
let source = pool.source_names()[0].clone();
let raw = pool.get_source_raw_bytes(&source, 4096).unwrap();
let conditioned = pool
.get_source_bytes(&source, 256, ConditioningMode::Sha256)
.unwrap();
pub fn new(seed: Option<&[u8]>) -> Self
pub fn auto() -> Self
pub fn add_source(&mut self, source: Box<dyn EntropySource>)
pub fn source_count(&self) -> usize
pub fn collect_all(&self) -> usize
pub fn collect_all_parallel(&self, timeout_secs: f64) -> usize
pub fn collect_enabled(&self, enabled_names: &[String]) -> usize
pub fn collect_enabled_n(&self, enabled_names: &[String], n_samples: usize) -> usize
pub fn get_raw_bytes(&self, n_bytes: usize) -> Vec<u8>
pub fn get_random_bytes(&self, n_bytes: usize) -> Vec<u8>
pub fn get_bytes(&self, n_bytes: usize, mode: ConditioningMode) -> Vec<u8>
pub fn get_source_bytes(
&self,
source_name: &str,
n_bytes: usize,
mode: ConditioningMode,
) -> Option<Vec<u8>>
pub fn get_source_raw_bytes(&self, source_name: &str, n_samples: usize) -> Option<Vec<u8>>
pub fn health_report(&self) -> HealthReport
pub fn print_health(&self)
pub fn source_names(&self) -> Vec<String>
pub fn source_infos(&self) -> Vec<SourceInfoSnapshot>
pub struct HealthReport {
pub healthy: usize,
pub total: usize,
pub raw_bytes: u64,
pub output_bytes: u64,
pub buffer_size: usize,
pub sources: Vec<SourceHealth>,
}
pub struct SourceHealth {
pub name: String,
pub healthy: bool,
pub bytes: u64,
pub entropy: f64,
pub min_entropy: f64,
pub autocorrelation: f64,
pub time: f64,
pub failures: u64,
}
pub struct SourceInfoSnapshot {
pub name: String,
pub description: String,
pub physics: String,
pub category: String,
pub platform: String,
pub requirements: Vec<String>,
pub entropy_rate_estimate: f64,
pub composite: bool,
pub config: Vec<(&'static str, String)>,
}

EntropySource and metadata (openentropy_core::source)

Section titled “EntropySource and metadata (openentropy_core::source)”
pub trait EntropySource: Send + Sync {
fn info(&self) -> &SourceInfo;
fn is_available(&self) -> bool;
fn collect(&self, n_samples: usize) -> Vec<u8>;
fn name(&self) -> &'static str { self.info().name }
}
pub struct SourceInfo {
pub name: &'static str,
pub description: &'static str,
pub physics: &'static str,
pub category: SourceCategory,
pub platform: Platform,
pub requirements: &'static [Requirement],
pub entropy_rate_estimate: f64,
pub composite: bool,
pub is_fast: bool,
}
pub enum Platform { Any, MacOS, Linux }
pub enum Requirement {
Metal,
AudioUnit,
Wifi,
Usb,
Camera,
AppleSilicon,
Bluetooth,
IOKit,
IOSurface,
SecurityFramework,
RawBlockDevice,
}
pub enum SourceCategory {
Thermal,
Timing,
Scheduling,
IO,
IPC,
Microarch,
GPU,
Network,
System,
Quantum,
Signal,
Sensor,
}
pub fn detect_available_sources() -> Vec<Box<dyn EntropySource>>
pub fn platform_info() -> PlatformInfo
pub fn resolve_source_names(
available: &[String],
requested: &[String],
mode: SourceMatchMode,
) -> SourceResolution
pub fn all_sources() -> Vec<Box<dyn EntropySource>> // registry size varies by release

resolve_source_names() is the shared name-matching helper used across surfaces. Use SourceMatchMode::ExactOnly for strict SDK/API behavior and SourceMatchMode::ExactThenSubstringInsensitive for CLI-style exact-then-partial matching.

Crate: openentropy-tests
Path: crates/openentropy-tests/

pub struct TestResult {
pub name: String,
pub passed: bool,
pub p_value: Option<f64>,
pub statistic: f64,
pub details: String,
pub grade: char,
}
pub fn run_all_tests(data: &[u8]) -> Vec<TestResult>
pub fn calculate_quality_score(results: &[TestResult]) -> f64

Crate: openentropy-server
Path: crates/openentropy-server/

pub async fn run_server(pool: EntropyPool, host: &str, port: u16, allow_raw: bool) -> std::io::Result<()>

HTTP endpoints:

  • GET /api/v1/random?length=N&type=T[&raw=true|&conditioning=...] length is output bytes, not array-item count. Responses report length as returned bytes and value_count as the number of encoded items in data. type=hex16 and type=uint16 require an even length.
  • GET /health
  • GET /sources
  • GET /pool/status

Invalid query parameters return JSON 400 Bad Request responses. /health and /pool/status use sources_healthy for the aggregate healthy-source count; per-source entries use healthy as a boolean.

/sources and /pool/status source rows expose: name, healthy, bytes, entropy, min_entropy, autocorrelation, time, and failures.

Crate: openentropy-cli
Binary: openentropy
Path: crates/openentropy-cli/

Subcommands:

  • scan
  • bench
  • analyze
  • stream
  • server
  • monitor
  • record
  • sessions

Benchmark Module (openentropy_core::benchmark)

Section titled “Benchmark Module (openentropy_core::benchmark)”

benchmark_sources(pool: &EntropyPool, config: &BenchConfig) -> Result<BenchReport, BenchError>

Section titled “benchmark_sources(pool: &EntropyPool, config: &BenchConfig) -> Result<BenchReport, BenchError>”

Run a multi-round benchmark across all sources in a pool.

use openentropy_core::{EntropyPool, benchmark::{benchmark_sources, BenchConfig}};
let pool = EntropyPool::auto();
let config = BenchConfig::default();
let report = benchmark_sources(&pool, &config)?;
for src in &report.sources {
println!("{}: grade={} score={:.3}", src.name, src.grade, src.score);
}

BenchConfig fields (all public):

  • samples_per_round: usize — default 2048
  • rounds: usize — default 3
  • warmup_rounds: usize — default 1
  • timeout_sec: f64 — default 2.0
  • rank_by: RankByBalanced | MinEntropy | Throughput, default Balanced
  • include_pool_quality: bool — default true
  • pool_quality_bytes: usize — default 65536
  • conditioning: ConditioningMode — default Sha256

BenchReport fields: generated_unix, config, sources: Vec<BenchSourceReport>, pool: Option<PoolQualityReport>

BenchSourceReport fields: name, composite, healthy, success_rounds, failures, avg_shannon, avg_min_entropy, avg_throughput_bps, avg_autocorrelation, p99_latency_ms, stability, grade: char, score: f64

Session Utilities (openentropy_core::session)

Section titled “Session Utilities (openentropy_core::session)”

SessionWriter session configs must declare a non-empty, duplicate-free source list. write_sample() only accepts source names declared in that session config.

list_sessions(dir: &Path) -> Result<Vec<(PathBuf, SessionMeta)>, std::io::Error>

Section titled “list_sessions(dir: &Path) -> Result<Vec<(PathBuf, SessionMeta)>, std::io::Error>”

List all recorded sessions in a directory, sorted newest-first. Returns empty Vec for nonexistent directory.

load_session_raw_data(session_dir: &Path) -> Result<HashMap<String, Vec<u8>>, std::io::Error>

Section titled “load_session_raw_data(session_dir: &Path) -> Result<HashMap<String, Vec<u8>>, std::io::Error>”

Load raw entropy data from a session directory. Returns a map of source name → raw bytes.

use openentropy_core::{list_sessions, load_session_raw_data, full_analysis};
use std::path::Path;
let sessions = list_sessions(Path::new("sessions"))?;
for (path, meta) in &sessions {
println!("{}: {} samples", meta.id, meta.total_samples);
let raw = load_session_raw_data(path)?;
for (source, data) in &raw {
let analysis = full_analysis(source, data);
println!(" {}: H∞={:.4}", source, analysis.min_entropy);
}
}

Forensic Analysis (openentropy_core::analysis)

Section titled “Forensic Analysis (openentropy_core::analysis)”

Core statistical analysis battery for evaluating entropy quality. Six tests that assess the fundamental properties expected of random data. See Choose an Analysis Path for interpretation guides and verdict thresholds.

full_analysis(source_name: &str, data: &[u8]) -> SourceAnalysis

Section titled “full_analysis(source_name: &str, data: &[u8]) -> SourceAnalysis”

Run all six forensic tests in one call. Returns a SourceAnalysis containing autocorrelation, spectral, bit bias, distribution, stationarity, and runs results, plus Shannon and min-entropy estimates.

use openentropy_core::full_analysis;
let analysis = full_analysis("clock_jitter", &data);
println!("Shannon: {:.4} bits/byte", analysis.shannon_entropy);
println!("Min-entropy: {:.4}", analysis.min_entropy);
println!("Spectral flatness: {:.4}", analysis.spectral.flatness);
println!("Stationary: {}", analysis.stationarity.is_stationary);
FunctionReturnsDescription
autocorrelation_profile(data, max_lag)AutocorrResultSerial dependence at multiple lags
spectral_analysis(data)SpectralResultFFT-based power spectral density
bit_bias(data)BitBiasResultPer-bit deviation from 50/50
distribution_stats(data)DistributionResultByte-value distribution vs uniform
stationarity_test(data)StationarityResultANOVA stability over 10 windows
runs_analysis(data)RunsResultConsecutive identical value patterns
cross_correlation_matrix(sources)CrossCorrMatrixPairwise Pearson correlation, flags |r| > 0.3
pearson_correlation(a, b)f64Pearson correlation coefficient

Chaos Theory Analysis (openentropy_core::chaos)

Section titled “Chaos Theory Analysis (openentropy_core::chaos)”

Distinguish true randomness from deterministic chaos with core and extended metrics. See Chaos Theory Analysis for interpretation guides and verdict thresholds.

chaos_analysis(data: &[u8]) -> ChaosAnalysis

Section titled “chaos_analysis(data: &[u8]) -> ChaosAnalysis”

Run the core chaos battery on a byte stream. Returns a ChaosAnalysis containing Hurst exponent, Lyapunov exponent, correlation dimension, BiEntropy, and epiplexity.

use openentropy_core::chaos::chaos_analysis;
let result = chaos_analysis(&data);
println!("Hurst H={:.4} (valid={})", result.hurst.hurst_exponent, result.hurst.is_valid);
println!("Lyapunov λ={:.4}", result.lyapunov.lyapunov_exponent);
println!("Correlation dim D₂={:.4}", result.correlation_dimension.dimension);
println!("BiEntropy={:.4}, TBiEn={:.4}", result.bientropy.bien, result.bientropy.tbien);
println!("Compression ratio={:.4}", result.epiplexity.compression_ratio);
FunctionReturnsDescription
hurst_exponent(data)HurstResultRescaled range (R/S) analysis — H≈0.5 = random
lyapunov_exponent(data)LyapunovResultLargest Lyapunov exponent — λ>0 = chaotic
correlation_dimension(data)CorrelationDimensionResultGrassberger–Procaccia D₂ estimate
bientropy(data)BiEntropyResultBinary entropy derivative (BiEn, TBiEn)
epiplexity(data)EpiplexityResultCompression-ratio complexity metric

Extended chaos functions:

FunctionReturnsDescription
sample_entropy(data, m, r)SampleEntropyResultSample entropy
dfa(data, order)DfaResultDetrended fluctuation analysis
rqa(data, dim, delay, threshold)RqaResultRecurrence quantification
rolling_hurst(data, window, step)RollingHurstResultSliding Hurst estimate
bootstrap_hurst(data, n_bootstrap)BootstrapHurstResultHurst uncertainty/p-value

For true random data, expect: Hurst H ≈ 0.5, Lyapunov λ > 0 (sensitive dependence), high correlation dimension, BiEntropy near maximum, compression ratio near 1.0. See the Verdict System for automated pass/fail classification of each metric.

Statistics Analysis (openentropy_core::statistics)

Section titled “Statistics Analysis (openentropy_core::statistics)”

Core one-call entry:

use openentropy_core::statistics_analysis;
let stats = statistics_analysis(&data);
println!("CvM p={:.4}, Ljung-Box p={:.4}", stats.cramer_von_mises.p_value, stats.ljung_box.p_value);

Additional group-level helpers are exported: anova, kruskal_wallis, levene_test, power_analysis, bonferroni_correction, holm_bonferroni_correction.

Temporal Analysis (openentropy_core::temporal)

Section titled “Temporal Analysis (openentropy_core::temporal)”

Core one-call entry:

use openentropy_core::temporal_analysis_suite;
let temporal = temporal_analysis_suite(&data);
println!("drift slope={:.4}", temporal.drift.drift_slope);

Individual functions include change_point_detection, anomaly_detection, burst_detection, shift_detection, temporal_drift, and inter_session_stability.

Synchrony Analysis (openentropy_core::synchrony)

Section titled “Synchrony Analysis (openentropy_core::synchrony)”

Pairwise and multi-stream entries:

use openentropy_core::{synchrony_analysis, global_event_detection};
let pair = synchrony_analysis(&data_a, &data_b);
let events = global_event_detection(&[&data_a, &data_b, &data_c]);
println!("NMI={:.4}", pair.mutual_info.normalized_mi);

Unified Analysis Dispatcher (openentropy_core::dispatcher)

Section titled “Unified Analysis Dispatcher (openentropy_core::dispatcher)”

Run multiple analysis modules through a single entry point with configurable profiles.

analyze(sources: &[(&str, &[u8])], config: &AnalysisConfig) -> AnalysisReport

Section titled “analyze(sources: &[(&str, &[u8])], config: &AnalysisConfig) -> AnalysisReport”

Dispatch analysis across one or more labeled byte streams. The config controls which modules run.

use openentropy_core::dispatcher::{analyze, AnalysisConfig, AnalysisProfile};
// Use a preset profile
let config = AnalysisProfile::Deep.to_config();
let report = analyze(&[("clock_jitter", &data)], &config);
for source in &report.sources {
println!("{}: forensic={} chaos={} trials={}",
source.label,
source.forensic.is_some(),
source.chaos.is_some(),
source.trials.is_some(),
);
println!(
" Verdicts: bias={:?} hurst={:?}",
source.verdicts.bias,
source.verdicts.hurst
);
}
FieldTypeDescription
forensicboolRun full_analysis (autocorrelation, spectral, bias, distribution, stationarity, runs)
entropyboolRun min_entropy_estimate (detailed entropy breakdown)
chaosboolRun chaos_analysis (Hurst, Lyapunov, correlation dimension, BiEntropy, epiplexity)
chaos_extendedboolRun extended chaos metrics (SampEn/ApEn/DFA/RQA/Hurst variants/PermEn/AD)
temporalboolRun temporal suite (change-point/anomaly/burst/shift/drift)
statisticsboolRun statistics suite (CvM/Ljung-Box/gap)
synchronyboolRun synchrony suite (pairwise + global-event checks)
trialsOption<TrialConfig>Run trial_analysis with given config; None = skip
cross_correlationboolRun cross_correlation_matrix when 2+ sources present
ProfileForensicEntropyChaosChaos ExtendedTemporalStatisticsSynchronyTrialsCross-Correlation
Quick
Standard
Deep—*
Security

* Synchrony is explicit in CLI because it requires 2+ streams.

use openentropy_core::dispatcher::{analyze, AnalysisConfig};
use openentropy_core::trials::TrialConfig;
let config = AnalysisConfig {
forensic: true,
entropy: false,
chaos: true,
chaos_extended: false,
temporal: false,
statistics: false,
synchrony: false,
trials: Some(TrialConfig::default()),
cross_correlation: false,
};
let report = analyze(&[
("source_a", &data_a),
("source_b", &data_b),
], &config);

Verdict System (openentropy_core::verdict)

Section titled “Verdict System (openentropy_core::verdict)”

Automated pass/fail classification for every forensic and chaos metric. Each source report includes a VerdictSummary with up to 11 verdict fields. See Verdict System for all thresholds and interpretation guidance.

use openentropy_core::dispatcher::{analyze, AnalysisProfile, VerdictSummary};
let config = AnalysisProfile::Deep.to_config();
let report = analyze(&[("src", &data)], &config);
for source in &report.sources {
let v = &source.verdicts;
println!("Autocorrelation: {:?}", v.autocorrelation);
println!("Spectral: {:?}", v.spectral);
println!("Bias: {:?}", v.bias);
println!("Distribution: {:?}", v.distribution);
println!("Stationarity: {:?}", v.stationarity);
println!("Runs: {:?}", v.runs);
println!("Hurst: {:?}", v.hurst);
println!("Lyapunov: {:?}", v.lyapunov);
println!("Correlation dim: {:?}", v.correlation_dimension);
println!("BiEntropy: {:?}", v.bientropy);
println!("Compression: {:?}", v.compression);
}

Verdict values: Pass, Warn, Fail, Na. Serializes as "PASS", "WARN", "FAIL", "N/A".

PEAR-style 200-bit trial analysis. Slices byte data into fixed-length trials and computes Z-scores, cumulative deviation, and effect sizes. See Trial Analysis Methodology for the statistical model.

trial_analysis(data: &[u8], config: &TrialConfig) -> TrialAnalysis

Section titled “trial_analysis(data: &[u8], config: &TrialConfig) -> TrialAnalysis”
use openentropy_core::trials::{trial_analysis, TrialConfig};
let config = TrialConfig::default(); // 200 bits per trial
let result = trial_analysis(&data, &config);
println!("Trials: {}, Terminal Z: {:.4}, Effect: {:.6}, p={:.4}",
result.num_trials, result.terminal_z,
result.effect_size, result.terminal_p_value);

stouffer_combine(analyses: &[&TrialAnalysis]) -> StoufferResult

Section titled “stouffer_combine(analyses: &[&TrialAnalysis]) -> StoufferResult”

Weighted Stouffer composition across multiple sessions (weights = √num_trials).

use openentropy_core::trials::{trial_analysis, stouffer_combine, TrialConfig};
let config = TrialConfig::default();
let t1 = trial_analysis(&data_a, &config);
let t2 = trial_analysis(&data_b, &config);
let combined = stouffer_combine(&[&t1, &t2]);
println!("Combined Z: {:.4}, p={:.4}", combined.stouffer_z, combined.p_value);

calibration_check(data: &[u8], config: &TrialConfig) -> CalibrationResult

Section titled “calibration_check(data: &[u8], config: &TrialConfig) -> CalibrationResult”

Pre-recording suitability check. Thresholds: |Z| < 2.0, bit bias < 0.005, Shannon > 7.9, Z-score std in [0.85, 1.15].

use openentropy_core::trials::{calibration_check, TrialConfig};
let result = calibration_check(&data, &TrialConfig::default());
println!("Suitable: {}, Warnings: {:?}", result.is_suitable, result.warnings);

Differential statistical analysis between two byte streams. See Choose an Analysis Path for context on how comparison fits into the analysis pipeline.

compare(label_a, data_a, label_b, data_b) -> ComparisonResult

Section titled “compare(label_a, data_a, label_b, data_b) -> ComparisonResult”

Full differential report including aggregate deltas, two-sample tests, temporal analysis, digram analysis, Markov transitions, multi-lag autocorrelation, and run-length distributions.

use openentropy_core::compare;
let result = compare("session_a", &data_a, "session_b", &data_b);
println!("KS p-value: {:.4}", result.two_sample.ks_p_value);
println!("Cliff's d: {:.4}", result.two_sample.cliffs_delta);
FunctionReturnsDescription
aggregate_delta(a, b)AggregateDeltaShannon/min-entropy/mean/variance deltas, Cohen’s d
two_sample_tests(a, b)TwoSampleTestsKS, chi-squared, Mann-Whitney, Cliff’s delta
cliffs_delta(a, b)f64Non-parametric effect size [-1, 1]
temporal_analysis(a, b, window, z)TemporalAnalysisSliding-window anomaly detection
digram_analysis(a, b)DigramAnalysisDigram chi-squared uniformity
markov_analysis(a, b)MarkovAnalysisPer-bit transition probabilities
multi_lag_analysis(a, b)MultiLagAnalysisAutocorrelation at multiple lags
run_length_comparison(a, b)RunLengthComparisonByte run-length distributions