parlov-analysis 0.2.0

Analysis engine trait and signal detection for parlov.
Documentation
  • Coverage
  • 100%
    10 out of 10 items documented0 out of 5 items with examples
  • Size
  • Source code size: 48.69 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 2.06 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 38s Average build duration of successful builds.
  • all releases: 37s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • gtfodev

parlov-analysis

Signal detection and oracle classification for parlov. Pure synchronous computation — no I/O, no async, no network stack.

trait

pub enum SampleDecision {
    Complete(OracleResult),
    NeedMore,
}

pub trait Analyzer: Send + Sync {
    fn evaluate(&self, data: &ProbeSet) -> SampleDecision;
    fn oracle_class(&self) -> OracleClass;
}

The caller drives an adaptive loop — collect pairs, call evaluate(), stop when Complete. All oracle semantics (how many samples, stability criteria, classification) live in the analyzer.

use it

use parlov_analysis::existence::ExistenceAnalyzer;
use parlov_analysis::{Analyzer, SampleDecision};

let analyzer = ExistenceAnalyzer;

// feed it a growing ProbeSet
match analyzer.evaluate(&probe_set) {
    SampleDecision::Complete(result) => {
        println!("{:?}{:?}", result.verdict, result.severity);
    }
    SampleDecision::NeedMore => {
        // collect another baseline + probe pair and call again
    }
}

existence oracle

ExistenceAnalyzer implements two detection layers:

  • Layer 1 (code-blind): same status on first sample → NotPresent immediately. Different status → collect up to 3 pairs and check stability.
  • Layer 2 (RFC-informed): classifies stable differentials against a 30-pattern table — 403/404Confirmed/High, 409/201Confirmed/High, 304/404Confirmed/High, etc. Each pattern carries a label, leaks description, and RFC section. Unrecognized stable differentials → Likely/Low.

adding an oracle

Implement Analyzer for a new oracle class:

pub struct TimingAnalyzer;

impl Analyzer for TimingAnalyzer {
    fn evaluate(&self, data: &ProbeSet) -> SampleDecision {
        if data.baseline.len() < 30 {
            return SampleDecision::NeedMore;
        }
        // Mann-Whitney U test on timing_ns...
        SampleDecision::Complete(result)
    }

    fn oracle_class(&self) -> OracleClass {
        OracleClass::Timing // once the variant exists
    }
}

The binary's adaptive loop works unchanged — it just calls evaluate() until Complete, regardless of how many samples the analyzer needs.

license

MIT OR Apache-2.0