Skip to content

Add runnable Exp3 timing-leak simulation harness with CLI and tests#70

Open
jverdicc wants to merge 1 commit intomainfrom
codex/add-runnable-harness-for-experiment-3
Open

Add runnable Exp3 timing-leak simulation harness with CLI and tests#70
jverdicc wants to merge 1 commit intomainfrom
codex/add-runnable-harness-for-experiment-3

Conversation

@jverdicc
Copy link
Owner

Motivation

  • Provide a deterministic, runnable Experiment 3 timing-leak simulation so results can be reproduced and included in paper-style artifacts.
  • Expose the experiment via the CLI so artifacts (JSON/MD) can be generated programmatically for analysis and CI.

Description

  • Added a new simulation module crates/discos-core/src/experiments/exp3.rs implementing Exp3Config and Exp3Result and the runner run_exp3 using a seeded ChaCha20Rng, Gaussian noise sampling, a train/eval single-threshold attacker, and equal-frequency binning mutual information estimator.
  • Exported exp3 in crates/discos-core/src/experiments/mod.rs so the experiment is available under the sim feature.
  • Added unit and property tests in crates/discos-core/tests/exp3_tests.rs covering ordering (acc_standard > acc_dlc > acc_pln), PLN near-chance, MI monotonicity, deterministic golden-values for a fixed seed, and proptest properties (intensity=0 and residual-frac bounds).
  • Added a feature-gated CLI command discos sim run exp3 in crates/discos-cli/src/main.rs which accepts experiment parameters and writes exp3_results.json and exp3_results.md to the specified output directory.

Testing

  • Ran formatting and lint checks with cargo fmt --check and cargo clippy --workspace --all-targets -- -D warnings and they passed.
  • Ran unit and integration tests with cargo test --workspace and cargo test -p discos-core --features sim --test exp3_tests, and all Exp3 tests (unit + proptest cases) passed.
  • Exercised the CLI with cargo run -p discos-cli --features sim -- sim run exp3 --out artifacts/exp3/default which produced artifacts/exp3/default/exp3_results.json and exp3_results.md successfully.

Codex Task

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b476885b18

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

fn accuracy_with_threshold(bits: &[u8], times: &[f64], threshold: f64) -> f64 {
let mut correct = 0usize;
for (b, t) in bits.iter().zip(times) {
let pred = if *t >= threshold { 1u8 } else { 0u8 };

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Learn threshold polarity before reporting attack accuracy

The attacker model only searches for a threshold and hard-codes t >= threshold as predicting bit 1, so an inverted leak direction (e.g. CLI input --intensity=-10, which is currently accepted) yields near-chance acc_* despite high mutual information. That produces misleading experiment conclusions for valid parameterizations; either reject negative intensity up front or evaluate both comparator polarities and keep the better one.

Useful? React with 👍 / 👎.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a deterministic, runnable Experiment 3 (timing-leak simulation) to DiscOS’ sim surface area, making it easy to reproduce results via both library APIs and the CLI, and to persist outputs as artifacts.

Changes:

  • Introduces crates/discos-core/src/experiments/exp3.rs with Exp3Config, Exp3Result, and run_exp3 (seeded RNG, threshold attacker, MI estimator).
  • Exports exp3 from the experiments module and adds integration/unit/property tests for expected trends and determinism.
  • Adds a feature-gated CLI entrypoint (discos sim run exp3) that writes JSON/MD result artifacts, plus commits a default artifact pair under artifacts/.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.

Show a summary per file
File Description
crates/discos-core/src/experiments/exp3.rs Implements the Exp3 simulation runner and statistics (accuracy + MI).
crates/discos-core/src/experiments/mod.rs Exposes exp3 in the experiments module.
crates/discos-core/tests/exp3_tests.rs Adds async unit tests and proptests for ordering, chance behavior, MI monotonicity, and fixed-seed “golden” checks.
crates/discos-cli/src/main.rs Adds discos sim run exp3 command to run the simulation and write JSON/MD outputs.
artifacts/exp3/default/exp3_results.json Adds a committed default JSON output example for Exp3.
artifacts/exp3/default/exp3_results.md Adds a committed default Markdown output example for Exp3.
Comments suppressed due to low confidence (4)

crates/discos-core/src/experiments/exp3.rs:4

  • exp3.rs is missing the repository’s standard Apache-2.0 copyright/license header that appears at the top of the other experiment modules (e.g. exp0.rs, exp1.rs, exp2.rs). Please add the same header here for consistency and licensing clarity.
use rand::{Rng, SeedableRng};
use rand_chacha::ChaCha20Rng;
use serde::{Deserialize, Serialize};

crates/discos-core/src/experiments/exp3.rs:45

  • run_exp3 validates that intensity is finite, but it allows negative values. With the current fixed-direction threshold attacker (pred = 1 when t >= threshold), a negative intensity flips the separation and can force accuracy down to ~chance even when the signal is perfectly separable. Consider enforcing intensity >= 0.0 (and/or learning the direction during training) so the simulation behaves consistently with the intended “signal intensity” parameter.
    anyhow::ensure!(cfg.intensity.is_finite(), "intensity must be finite");
    anyhow::ensure!(cfg.noise_sigma.is_finite(), "noise_sigma must be finite");

crates/discos-core/src/experiments/exp3.rs:54

  • residual_frac_dlc / residual_frac_pln are only checked for finiteness and non-negativity, but as “residual fractions” they likely should be constrained to [0.0, 1.0] (and typically residual_frac_pln <= residual_frac_dlc <= 1.0). Allowing values > 1 can make the defended channels leak more than the standard channel, which can break assumptions/tests about ordering and makes CLI inputs easy to misuse.
    anyhow::ensure!(
        cfg.residual_frac_dlc.is_finite() && cfg.residual_frac_dlc >= 0.0,
        "residual_frac_dlc must be finite and non-negative"
    );
    anyhow::ensure!(
        cfg.residual_frac_pln.is_finite() && cfg.residual_frac_pln >= 0.0,
        "residual_frac_pln must be finite and non-negative"
    );

crates/discos-core/tests/exp3_tests.rs:58

  • The fixed-seed “golden value” assertions use a very tight absolute tolerance (1e-12) on floating-point outputs derived from transcendentals (ln, sqrt, cos, log2). This can be brittle across different libm implementations / architectures and may cause flaky failures. Consider loosening the tolerance (e.g. 1e-8/1e-6) or asserting on rounded/serialized values instead of exact f64s.
    assert!((result.acc_standard - 1.0).abs() <= 1e-12);
    assert!((result.acc_dlc - 0.6136666666666667).abs() <= 1e-12);
    assert!((result.acc_pln - 0.5076666666666667).abs() <= 1e-12);
    assert!((result.mi_standard_bits - 0.9785881470241701).abs() <= 1e-12);
    assert!((result.mi_dlc_bits - 0.05021746994008992).abs() <= 1e-12);

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants