# PVUGC-007 Crypto-Peer-Reviewer Assessment **Date:** 2025-10-28 23:25 **Expert:** Crypto-Peer-Reviewer **Issue:** PVUGC-007 (Timing Attacks & Race Conditions) **Consultation Request:** Standards compliance validation - side-channel security and liveness assessment --- **Vote:** **PARTIAL** --- ## Reasoning The v2.7 specification demonstrates **substantial progress** in addressing timing side-channel and liveness concerns identified in the v3.0 peer review, but falls short of providing **algorithmically enforceable constant-time guarantees** and **verifiable compliance criteria** that are essential for cryptographic protocols claiming zero-knowledge properties. While the normative language is present ("MUST be constant-time"), the specification lacks the **algorithmic precision** needed to make this requirement **testable and implementable** without ambiguity. ### Side-Channel Prevention Analysis **Assessment:** **Improvement but insufficient algorithmic enforcement** v2.7 contains **three explicit MUST requirements** for constant-time execution: 1. Line 377: "Decap, pairings, scalars, and DEM MUST be constant-time" 2. Line 374: "constant‑time decap (no early returns; verify all equations then branch on result)" 3. Line 306: "constant‑time pairings, constant‑time DEM decryption" **Strengths:** - **Normative language:** The use of MUST (RFC 2119) elevates constant-time from recommendation to requirement - **No early returns:** Line 374 explicitly forbids early abort patterns, addressing a common timing leak vector - **Cache-timing awareness:** Line 377 mentions "avoid cache-tunable table leakage" - rare to see in protocol specs - **Library guidance:** Line 390 recommends libraries with "constant-time pairings and explicit subgroup checks" **Critical Gap: Algorithmic Under-Specification** The phrase "constant-time decap" is **semantically ambiguous** without algorithmic specification: **Problem 1: Variable Loop Iteration Count** M2's v3.0 analysis quantified that decapsulation loops over `m₁ + m₂` pairings, where `m₁, m₂ ∈ [1, 96]` and `m₁ + m₂ ≤ 96`. If the implementation naively loops over the **actual** commitment count: ```rust // VULNERABLE: Loop count varies with m₁, m₂ for j in 0..m1 { product *= pairing(C1[j], D1[j]); // Constant-time per pairing } for k in 0..m2 { product *= pairing(D2[k], C2[k]); // Constant-time per pairing } ``` This leaks `m₁ + m₂` via **total execution time** even if each individual pairing is constant-time. With μs-level timing precision (achievable via `rdtsc` or network observation), an adversary distinguishes: - Min case: m₁=1, m₂=1 → 2 pairings → ~2.4ms - Max case: m₁=48, m₂=48 → 96 pairings → ~115.2ms - **Distinguishability:** 112.8ms difference is trivially observable M2's information-theoretic analysis showed this leaks **I(W; T_decap) ≈ 10-12 bits** on average, with **complete witness structure leakage** (H=0) for extreme small witnesses. **v2.7's "constant-time decap" does NOT prevent this** unless interpreted to mean "fixed iteration count", which requires **algorithmic specification**: ```rust // CORRECT: Fixed 96 iterations regardless of m₁, m₂ const MAX_PAIRINGS: usize = 96; for i in 0..MAX_PAIRINGS { if i < m1 { product *= pairing(C1[i], D1[i]); } else { product *= pairing(G1::identity(), G2::identity()); // Dummy pairing } } // Similar for m₂ commitments ``` M2's v3.0 recommendation explicitly specified: **"MUST perform fixed 96 pairing operations regardless of actual m₁, m₂"** with **"Pad with dummy pairings e(G₁_identity, G₂_identity)"**. This is **algorithmic enforcement**, not just normative guidance. **Problem 2: DEM Decryption Early Abort** Line 374 states "no early returns; verify all equations then branch on result" for decapsulation, but does NOT explicitly address DEM tag verification. A naive implementation might: ```rust // VULNERABLE: Early abort on tag mismatch let plaintext = poseidon2_decrypt(ct, K); if !verify_tag(tag, K, ct, AD) { return Err("Invalid tag"); // Timing leak: fail-fast path is faster } ``` The success path (tag valid) vs. failure path (tag invalid) have **measurably different timing** (typically 1-5μs difference for hash-based MACs). Over many observations, this leaks which armers provided valid vs. malformed ciphertexts. **Correct implementation** (implied by "verify all equations then branch on result"): ```rust // CORRECT: Constant-time tag verification let plaintext = poseidon2_decrypt(ct, K); let tag_valid = constant_time_eq(tag, compute_tag(K, ct, AD)); // Use constant-time select to return plaintext OR dummy constant_time_select(tag_valid, plaintext, DUMMY) ``` This is **implementation technique**, not **specification**. v2.7 hints at it ("no early returns") but doesn't mandate the constant-time selection pattern. **Cryptographic Verdict on Side-Channels:** The **zero-knowledge property** M2 identified as violated requires: ``` For all witnesses w, w' and all adversaries A with timing oracle: | Pr[A(w, Time(Decap(w))) = 1] - Pr[A(w', Time(Decap(w'))) = 1] | < negl(λ) ``` v2.7's text **implies** this via "MUST be constant-time", but does NOT **algorithmically enforce** it. Two independent implementers could both claim "constant-time" compliance while producing: - Implementation A: Fixed 96 pairings (M2 spec) → **ZK preserved** - Implementation B: Variable m₁+m₂ pairings with constant-time library → **ZK violated** Both satisfy v2.7's text ("constant-time pairings") but only A prevents the information leak. **Assessment:** v2.7 provides **normative intent** but lacks **algorithmic precision**. This is a **HIGH severity gap** because zero-knowledge is a **core security property**, not an optimization. --- ### Testing and Verification Analysis **Assessment:** **Critical verifiability gap** v2.7 specifies **MUST requirements** without **acceptance criteria**. How does an auditor verify that an implementation satisfies "MUST be constant-time"? **Standard Practice in Cryptographic Specifications:** Cryptographic standards typically provide **test vectors** and **validation methodology**: - **FIPS 140-3 (NIST):** Requires statistical randomness tests (ENT, Dieharder) with pass/fail thresholds - **RFC 9380 (Hash-to-Curve):** Provides 150+ test vectors covering edge cases - **BIP-340 (Schnorr):** Provides test vectors and reference implementation for interoperability For **constant-time requirements**, the state-of-the-art is: **1. TOST (Two One-Sided Tests) for Equivalence:** M2's v3.0 recommendation (correcting the statistically incorrect Welch's t-test in earlier drafts): ``` Test null hypothesis H₀: Timing distributions differ by more than ε Accept H₁ (constant-time) if BOTH one-sided tests reject at α=0.05 level Requires n ≥ 10⁶ samples per distribution ``` This is **standard methodology** in side-channel resistance validation (see: Bernstein's "Cache-timing attacks on AES", Langley's "ctgrind", Project Wycheproof). **2. Representative Test Cases:** M2 specified: ``` Test 1: (m₁=20, m₂=20) vs (m₁=48, m₂=48) - Min vs Max pairing counts Test 2: Valid DEM tag vs Invalid DEM tag - Success vs Failure paths Test 3: All k PoCE-B valid vs 1 invalid - Early-abort detection ``` These are **security-critical edge cases** where timing leaks are most likely. **v2.7's Position:** **Zero testing requirements specified.** Line 377 says "MUST be constant-time" but provides: - No test vectors - No statistical testing methodology - No acceptance thresholds (what is "constant-time"? ±1μs? ±1ms?) - No CI/CD integration guidance **Consequence:** Without test methodology, "MUST be constant-time" is **unverifiable**. Implementations can claim compliance with: - No statistical validation - No independent audit - No interoperability assurance This is **acceptable** for non-cryptographic requirements (e.g., "SHOULD log errors"), but **unacceptable** for a requirement protecting a **core cryptographic property** (zero-knowledge). **Comparison: Other Gaps in v2.7 with Testing** Interestingly, v2.7 DOES provide testing guidance for other requirements: - Line 191: GS size bound (m₁+m₂≤96) - **Algorithmically testable** (reject if sum exceeds 96) - Line 374: Subgroup checks - **Testable** (verify point is in prime-order subgroup) - Line 306: Canonical encodings - **Testable** (reject non-canonical representations) Why does **constant-time** lack similar precision? **Cryptographic Verdict on Testing:** The absence of **statistical testing requirements** and **test vectors** for constant-time compliance is a **CRITICAL gap** because: 1. **Unverifiable:** Auditors cannot assess compliance objectively 2. **Uninteroperable:** No ground truth for what "constant-time" means quantitatively 3. **Unreproducible:** Different implementations will have different (unstated) tolerance levels This is **specification immaturity**, not acceptable implementation discretion. --- ### Liveness and State Machine Analysis **Assessment:** **Acceptable timeout-based approach with minor gaps** **Strengths:** v2.7 provides **two layers** of liveness protection: **Layer 1: CSV Timeout Path (Line 315)** ``` Timeout/Abort path (MUST for production). CSV=Δ path (e.g., Δ=144 blocks ≈24h) sending funds to a neutral sink or alternate policy. Required to prevent indefinite liveness failure if any armer posts malformed masks/ciphertexts that pass PoK but fail PoCE-B at decap time. ``` This is **excellent**: - **MUST for production** (upgraded from v2.0's SHOULD) - **Rationale provided:** "prevent indefinite liveness failure" - **Concrete parameter:** Δ=144 blocks (industry-standard Bitcoin timeout) - **Operator-agnostic:** "This is operator-agnostic liveness protection, not optional" The phrase **"not optional"** is particularly strong - it signals that CSV path is **mandatory for production deployments**, even though the core WE innovation is path-agnostic. **Layer 2: Per-Phase Timeouts (Line 375)** ``` enforce per-phase timeouts (arming: 120s, presig: 180s); abort on timeout or mismatch ``` This prevents **intra-protocol deadlock** (armers waiting indefinitely for each other), while CSV handles **inter-protocol deadlock** (Bitcoin-level fund recovery). **Comparison to M2's State Machine:** M2 proposed a **formal state machine** with 8 states (IDLE, ARMING, PRE_SIGNING, AWAITING_PROOF, DECAP, BROADCAST, COMPLETED, ABORTED) and **transition invariants**: ``` Invariant I1: Once ARMING completes, pre-signature cannot be used for different (vk,x) Invariant I2: CSV timeout Δ_CSV > T_ARMING + T_PRESIG + T_PROVING Invariant I3: Timeout transitions are irreversible (ABORTED is terminal) Invariant I4: At most one adaptor (T, R, s') per context ``` **Trade-off Analysis:** | Approach | Precision | Implementability | Testability | |----------|-----------|------------------|-------------| | **M2 Formal State Machine** | High (8 states, 4 invariants, explicit transition logic) | Low (requires state tracking, event handlers) | High (can verify state transitions) | | **v2.7 Timeout-Based** | Medium (3 timeout values, CSV path) | High (simpler: just enforce timeouts) | Medium (can verify timeouts, but state implicit) | **Cryptographic Verdict on Liveness:** v2.7's **timeout-based approach is acceptable** for liveness protection: - **CSV path (MUST):** Prevents indefinite fund lockup ✅ - **Per-phase timeouts:** Prevents coordinator deadlock ✅ - **Missing formal states:** Not a security gap, just lower precision The **missing formal state machine** is a **MEDIUM severity gap**: - **Workaround exists:** Implementers can derive state machine from timeout logic - **Risk manageable:** Timeout values (120s, 180s, 144 blocks) are concrete enough - **Best practice missing:** Formal states improve auditability and testing **Minor Gap: State Transition Invariants** M2's invariants (I1-I4) enforce **cryptographic binding** between protocol phases: - **I1:** Prevents arming reuse across contexts (security-critical for ctx_hash binding) - **I4:** One adaptor per context (prevents nonce reuse in MuSig2) v2.7 **implies** these via ctx_hash binding and "fresh T, fresh R" (line 306), but does NOT state them as **explicit invariants**. This is a **LOW severity gap** (implied by other requirements). --- ### Cache-Timing and Library Validation **Assessment:** **Adequate awareness, weak validation** **Strengths:** Line 377 is **unusually sophisticated** for a protocol specification: ``` avoid cache-tunable table leakage across different `ctx_hash` values ``` This shows **awareness** of: - **Cache-timing attacks:** Flush+Reload, Prime+Probe, Evict+Time - **Data-dependent table lookups:** Pairing libraries use precomputed tables indexed by scalar bits - **Cross-context leakage:** Attackers observing cache state across multiple decapsulations with different ctx_hash This level of detail is **rare** in protocol specs (most just say "use constant-time crypto" with no cache awareness). **Library Guidance (Line 390):** ``` choose libraries with constant‑time pairings and explicit subgroup checks ``` This is **actionable guidance** but lacks **validation methodology**. **Gaps:** M2 recommended **cache-timing testing**: - Flush+Reload simulation (measure cache eviction patterns) - Prime+Probe simulation (measure cache set contention) - Performance counter monitoring (Intel PT, ARM PMU) v2.7 **mentions** cache-timing risks but provides **no testing methodology**. This is a **MEDIUM severity gap**: - **Workaround:** Rely on library documentation (e.g., blst's constant-time guarantees) - **Risk:** Implementers may choose libraries without validating cache resistance - **Best practice:** Provide recommended libraries with validation evidence **Recommended Library Validation (Not in v2.7):** M2 specified: ``` Recommended Libraries: - blst (Rust/C): Constant-time by default, battle-tested - arkworks (Rust): Enable `asm` and `constant_time` features - MCL (C++): Use `MCL_USE_CONSTANT_TIME` flag ``` v2.7 **lacks** this actionable guidance. Implementers may choose libraries like: - **PBC (Pairing-Based Cryptography):** Fast but NOT constant-time by default - **RELIC:** Configurable, but constant-time features are opt-in **Verdict:** Cache-timing awareness is present, but **validation gap** prevents verification. --- ### Production Readiness Determination **Overall Assessment:** **Conditionally acceptable with mandatory hardening** v2.7 represents **substantial improvement** from v2.0 (which had only generic "consider constant-time" language), but falls short of **cryptographic-grade specification** due to: **CRITICAL Gaps (Must Fix Before Production):** 1. **Algorithmic constant-time specification:** Add fixed 96 pairing loop with padding 2. **Statistical testing methodology:** Add TOST requirements with test vectors **HIGH Gaps (Should Fix, Workarounds Exist):** 3. **DEM constant-time tag verification:** Explicitly require constant-time MAC verification 4. **PoCE-B constant-time verification:** Require verifying all k shares without early abort **MEDIUM Gaps (Recommended Improvement):** 5. **Formal state machine:** Add explicit states and invariants (improves auditability) 6. **Cache-timing testing:** Add Flush+Reload, Prime+Probe test guidance 7. **Library validation:** Provide recommended libraries with validation evidence **LOW Gaps (Optional Enhancement):** 8. **Front-running mitigations:** Add §12.3 with encrypted mempool guidance **Security Posture:** Given M2's quantified **10-12 bit witness leakage per observation** (worst-case: complete leakage), v2.7's current text: - **Prevents exploitation IF** implementers interpret "constant-time decap" as "fixed 96 pairings" (optimistic interpretation) - **Permits exploitation IF** implementers interpret "constant-time decap" as "use constant-time pairing library" while keeping variable loop count (literal interpretation) The **ambiguity** is the problem. Cryptographic specifications must be **unambiguous** to prevent vulnerabilities. **Conditional Acceptance Criteria:** v2.7 is **production-ready IF AND ONLY IF** implementations adopt: 1. **Fixed 96 pairing loop** (algorithmic constant-time) 2. **TOST validation** with ≥10⁶ samples, ε < 2^-40 3. **Constant-time DEM tag verification** (no early abort) 4. **Cache-resistant pairing library** (blst, arkworks with constant_time feature) These are **not optional** - they are **mandatory to preserve zero-knowledge**. --- ## Evidence from PVUGC-2025-10-27.md **Supporting v2.7's Improvement:** 1. **Line 377 (MUST constant-time):** > "Decap, pairings, scalars, and DEM MUST be constant-time; no data-dependent branches; avoid cache-tunable table leakage across different `ctx_hash` values." **Assessment:** Strongest normative language for side-channel protection in any PVUGC version 2. **Line 374 (No early returns):** > "constant‑time decap (no early returns; verify all equations then branch on result)" **Assessment:** Prevents common timing leak pattern (fail-fast early abort) 3. **Line 315 (CSV MUST for production):** > "Timeout/Abort path (MUST for production). ... Required to prevent indefinite liveness failure ... This is operator-agnostic liveness protection, not optional." **Assessment:** Excellent - CSV upgraded from SHOULD to MUST, strong rationale 4. **Line 375 (Per-phase timeouts):** > "enforce per-phase timeouts (arming: 120s, presig: 180s); abort on timeout or mismatch" **Assessment:** Concrete timeout values prevent coordinator deadlock **Illustrating v2.7's Gaps:** 1. **No algorithmic specification for fixed pairing count** - Search: "96 pairing" → Found only in Line 191 (size bound), NOT in decapsulation algorithm - M2's "MUST perform fixed 96 pairing operations" → **Absent** 2. **No statistical testing requirements** - Search: "TOST", "statistical", "equivalence test", "timing test" → **No matches** - M2's TOST methodology, test vectors, CI/CD integration → **Absent** 3. **No formal state machine** - Search: "state machine", "IDLE", "ARMING", "PRE_SIGNING" → **No matches** (only timeout values) - M2's 8-state machine with invariants → **Absent** 4. **No front-running mitigation** - Search: "front-running", "encrypted mempool", "direct miner" → **No matches** - M2's §12.3 guidance → **Absent** --- ## Gap Classification | Gap | Severity | Rationale | |-----|----------|-----------| | **Fixed 96 pairing loop specification** | **CRITICAL** | Absence allows variable-time implementations that leak 10-12 bits per observation, **violating zero-knowledge property**. Two implementers can both claim "constant-time" compliance with different algorithms (fixed vs. variable count). **Algorithmic ambiguity** in cryptographic specifications is a **specification failure**. | | **Statistical testing methodology (TOST)** | **CRITICAL** | "MUST be constant-time" is **unverifiable** without test methodology. Implementations cannot prove compliance, auditors cannot validate claims. This is **specification immaturity** - cryptographic requirements need **acceptance criteria**. | | **DEM constant-time tag verification** | **HIGH** | v2.7 implies this ("no early returns") but does NOT explicitly require constant-time MAC verification. Fail-fast tag checks leak 1-5μs, revealing which armers provided malformed ciphertexts over many observations. **Workaround:** Implementers familiar with constant-time crypto will do this correctly, but spec should be explicit. | | **PoCE-B constant-time verification** | **HIGH** | No requirement to verify all k armer shares without early abort. Early abort on first invalid share leaks **which armer** is malicious via timing. For threshold settings with large k, this is **correlation attack** enabler. **Workaround:** Implementers can infer from general constant-time guidance. | | **Formal state machine** | **MEDIUM** | Timeout values (120s, 180s, CSV Δ) provide liveness protection, but lack **explicit state definitions and invariants** reduces auditability. Implementers can derive state machine from timeouts, but formal states improve testing. **Workaround:** Derive implicit state machine from timeout logic. | | **Cache-timing testing** | **MEDIUM** | v2.7 mentions "avoid cache-tunable table leakage" but provides no **validation methodology** (Flush+Reload, Prime+Probe tests). Implementers relying on library claims (e.g., "blst is constant-time") have no **independent validation**. **Workaround:** Trust library documentation. | | **Library validation guidance** | **MEDIUM** | No recommended libraries (blst, arkworks, MCL) with feature flags (constant_time, asm). Implementers may choose PBC or RELIC without enabling constant-time modes. **Workaround:** Cryptography-aware implementers will choose correct libraries. | | **Front-running mitigation** | **LOW** | No guidance on encrypted mempool or direct miner submission. Front-running window exists between proof submission and broadcast. **Workaround:** Operational countermeasures (submit to private mempool, use Flashbots-like services). Not a **protocol-level** issue. | --- ## Recommended Actions ### CRITICAL (MUST Fix Before Production) **1. Add Algorithmic Constant-Time Specification** Insert into Line 374 (KEM/DEM section): ```markdown **Constant-time decapsulation (MUST):** Implementations MUST execute a fixed number of pairing operations regardless of the actual GS attestation size (m₁, m₂): 1. Compute product initialization: product = 1_GT 2. FOR i = 0 TO 95: - IF i < m₁: product *= e(C¹ᵢ, D₁,ᵢ) - ELSE: product *= e(G₁_identity, D₁,₀) // Dummy pairing 3. FOR j = 0 TO 95: - IF j < m₂: product *= e(D₂,ⱼ, C²ⱼ) - ELSE: product *= e(G₁_identity, D₂,₀) // Dummy pairing 4. Compare product ?= R(vk,x)^ρ AFTER all 96 pairings complete This ensures total execution time is independent of witness structure, preserving the zero-knowledge property. Implementations MUST NOT use variable-length loops based on m₁, m₂ values, as this leaks approximately log₂(m₁·m₂/96) bits of witness structure information per decapsulation. ``` **Rationale:** Removes algorithmic ambiguity, makes zero-knowledge property **verifiable**. --- **2. Add Statistical Testing Requirements** Insert new subsection after Line 377: ```markdown **Constant-time validation (MUST for production deployments):** Implementations claiming constant-time compliance MUST provide statistical validation evidence using Two One-Sided Tests (TOST) for equivalence: **Test 1: Decapsulation Timing Uniformity** - Inputs: Attestations with (m₁=10, m₂=10), (m₁=48, m₂=48), (m₁=1, m₁=1) - Samples: n ≥ 10⁶ timing measurements per input - Method: TOST with equivalence bounds ε = 2^(-20) for CI/CD, ε = 2^(-40) for production - Pass criteria: Both one-sided tests reject at α=0.05 significance level **Test 2: DEM Decryption Tag Verification** - Inputs: Valid ciphertext (correct tag), Invalid ciphertext (incorrect tag) - Samples: n ≥ 10⁶ timing measurements per input - Method: TOST with equivalence bounds ε = 2^(-60) (cryptographic-grade) - Pass criteria: Both one-sided tests reject at α=0.05 significance level **Test 3: PoCE-B Verification** - Inputs: All k shares valid, One share invalid (rest valid) - Samples: n ≥ 10⁵ timing measurements per input - Method: TOST with equivalence bounds ε = 2^(-40) - Pass criteria: Both one-sided tests reject at α=0.05 significance level **CI/CD Integration:** Timing tests SHOULD be integrated into continuous integration pipelines and MUST fail builds if equivalence is rejected (timing leak detected). **Reference Implementation:** Provide reference implementation with TOST validation demonstrating compliant constant-time execution across all test cases. ``` **Rationale:** Makes "MUST be constant-time" **testable and verifiable**, aligns with FIPS 140-3 validation methodology. --- ### HIGH (SHOULD Fix, Workarounds Exist) **3. Explicitly Require Constant-Time DEM Tag Verification** Modify Line 374 to add: ```markdown DEM decryption MUST use constant-time tag verification: compute MAC for both success and failure cases, use constant-time comparison (e.g., `subtle::ConstantTimeEq` in Rust), and constant-time selection to return plaintext on success or dummy value on failure. Implementations MUST NOT use early-abort patterns (e.g., `if !verify_tag() { return Err }`). ``` **Rationale:** Eliminates 1-5μs timing difference between valid/invalid tag paths. --- **4. Explicitly Require Constant-Time PoCE-B Verification** Modify Line 375 to add: ```markdown PoCE-B verification MUST check all k armer shares in constant-time: verify each share's pairing equation Tᵢ ?= sᵢ·G regardless of earlier failures, accumulate results in a bitmask, and report validation outcome only after all k shares are checked. Implementations MUST NOT use early-abort on first invalid share. ``` **Rationale:** Prevents correlation attacks that identify malicious armers via timing. --- ### MEDIUM (Recommended Improvement) **5. Add Formal State Machine (Optional but Recommended)** Insert new section §12.2 State Machine: ```markdown ### 12.2 Protocol State Machine (Recommended) Implementations SHOULD maintain explicit protocol state to enforce phase transitions and timeout invariants: **States:** - IDLE: Pre-initialization - ARMING: Collecting armer shares (timeout: 120s from first share) - PRE_SIGNING: MuSig2 adaptor signature generation (timeout: 180s from arming complete) - AWAITING_PROOF: Waiting for valid GS attestation (timeout: CSV Δ blocks) - DECAP: Decapsulation in progress (atomic operation) - BROADCAST: Transaction broadcast to Bitcoin network - COMPLETED: Terminal success state - ABORTED: Terminal failure state (CSV recovery active) **Invariants:** - I1: ctx_hash is immutable after ARMING state entry - I2: Adaptor (T, R, s') cannot be reused across different ctx_hash - I3: CSV timeout Δ_CSV > T_ARMING + T_PRESIG (120s + 180s = 300s = 50 blocks minimum) - I4: ABORTED state is terminal (no transition back to active states) ``` **Rationale:** Improves auditability and testing, prevents state confusion bugs. --- **6. Add Cache-Timing Testing Guidance** Modify Line 377 to add: ```markdown **Cache-timing validation (SHOULD):** Implementations SHOULD validate cache resistance using: - Flush+Reload simulation (measure cache eviction patterns during decapsulation) - Prime+Probe simulation (measure cache set contention across different ctx_hash) - Performance counter monitoring (Intel PT, ARM PMU) to detect data-dependent cache access Recommended tool: ctgrind (constant-time validation tool by Adam Langley) ``` **Rationale:** Provides actionable validation methodology for cache-timing claims. --- **7. Add Library Validation Guidance** Modify Line 390 to add: ```markdown **Recommended pairing libraries with validated constant-time properties:** - blst (Rust/C): Constant-time by default, used by Ethereum, extensive audit history - arkworks (Rust): Enable `asm` and `constant_time` features for constant-time execution - MCL (C++): Use `MCL_USE_CONSTANT_TIME` compilation flag Implementations MUST document: 1. Which pairing library is used 2. Library version and commit hash 3. Feature flags enabled (if any) 4. Cache-timing validation evidence (if available) Avoid libraries without explicit constant-time guarantees (e.g., PBC without modifications, RELIC without CONSTTIME configuration). ``` **Rationale:** Prevents implementers from choosing libraries with unknown or poor constant-time properties. --- ### LOW (Optional Enhancement) **8. Add Front-Running Mitigation Guidance** Insert new section §12.3 Front-Running Mitigations (optional): ```markdown ### 12.3 Front-Running Mitigations (Optional) After decapsulation but before Bitcoin network broadcast, a front-running window exists where an observer with mempool access can extract (s, R) from the broadcast transaction and attempt to front-run with higher fees. **Mitigation strategies (SHOULD consider for high-value contracts):** - **Encrypted mempool:** Submit to services providing encrypted relay (e.g., Flashbots Protect) - **Direct miner submission:** Submit directly to mining pool APIs (bypasses public mempool) - **Commit-reveal:** Split transaction into commit (reveal s' in OP_RETURN) and reveal (publish s in second transaction) with time lock Note: This is an **operational concern**, not a protocol-level vulnerability. The Bitcoin network's first-seen policy and CPFP anchor provide baseline protection. ``` **Rationale:** Provides guidance on known attack vector without overspecifying operational details. --- ## Summary **Vote: PARTIAL** v2.7 demonstrates **substantial progress** in addressing M2's v3.0 timing and liveness concerns, with strong normative language ("MUST be constant-time") and upgraded liveness protection (CSV "MUST for production"). However, **critical specification gaps** remain: 1. **Algorithmic ambiguity:** "Constant-time decap" permits variable-loop implementations that leak 10-12 bits per observation 2. **Verifiability gap:** No statistical testing methodology makes "MUST" claims unverifiable These gaps are **CRITICAL** because they: - Undermine the **zero-knowledge property** (core security claim) - Prevent **independent validation** (no objective compliance assessment) - Allow **non-interoperable interpretations** (fixed vs. variable pairing counts) **Conditional Acceptance:** v2.7 is **production-ready IF** implementations adopt: 1. Fixed 96 pairing loop (algorithmic constant-time) 2. TOST validation with ε < 2^-40 3. Constant-time DEM/PoCE-B verification 4. Cache-resistant libraries (blst, arkworks with features) **Recommendation:** Adopt **Critical** and **High** recommended actions to upgrade v2.7 from **PARTIAL (conditionally acceptable)** to **RESOLVED (unconditionally production-ready)**. --- **Crypto-Peer-Reviewer:** Claude (Side-Channel Security Specialist) **Date:** 2025-10-28 23:25 **Consultation Duration:** 45 minutes (detailed cryptographic analysis)