Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 6 additions & 5 deletions agent/flow-trace/00_INDEX.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,12 @@ _Found during source-code cross-referencing of these trace documents._

### Circuit Audit Remediations

| Finding | Status | Implemented behavior |
| ----------------------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **IF-001 — unconstrained U64 modular division** | Fixed | `ModU64::div_mod` verifies the hinted quotient satisfies `result * divisor == dividend (mod modulus)`; the Noir suite includes a non-invertible-divisor regression test. |
| **IF-002 — conditional C7 decoding equality** | Fixed | C7 compares every decoded coefficient with the claimed message, including zero coefficients; a focused regression test rejects a nonzero decoded value claimed as zero. |
| **IF-003 — decryption proof phase and party binding** | Fixed | `decryption_aggregator` requires 1-indexed, strictly increasing party IDs, while `BfvDecryptionVerifier` checks the surfaced SK/ESM commitments against the E3's registry-backed DKG anchors. |
| Finding | Status | Implemented behavior |
| ----------------------------------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **IF-001 — unconstrained U64 modular division** | Fixed | `ModU64::div_mod` verifies the hinted quotient satisfies `result * divisor == dividend (mod modulus)`; the Noir suite includes a non-invertible-divisor regression test. |
| **IF-002 — conditional C7 decoding equality** | Fixed | C7 compares every decoded coefficient with the claimed message, including zero coefficients; a focused regression test rejects a nonzero decoded value claimed as zero. |
| **IF-003 — decryption proof phase and party binding** | Fixed | `decryption_aggregator` requires 1-indexed, strictly increasing party IDs, while `BfvDecryptionVerifier` checks the surfaced SK/ESM commitments against the E3's registry-backed DKG anchors. |
| **IF-004 — ciphertext commitment binding** | Fixed | The off-chain SAFE commitment is stored at ciphertext publication, propagated as a final decryption-proof public input, and compared on-chain without attempting BFV decoding or Poseidon2 execution in Solidity. |

### Protocol Design Concerns

Expand Down
29 changes: 16 additions & 13 deletions agent/flow-trace/04_DKG_AND_COMPUTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -414,8 +414,9 @@ ShareVerificationActor receives ShareVerificationDispatched(kind=ShareProofs)
│ │ │ C4a→C6 (SameParty): C4a's commitment == C6's expected_sk_commitment
│ │ │ C4b→C6 (SameParty): C4b's commitment == C6's expected_e_sm_commitment
│ │ │ C6→C7 (CrossParty): C6's d_commitment matches C7's expected_d_commitment
│ │ │ (on-chain / E3 state) C3/C6 ciphertext commitments are checked against their ciphertext witnesses off-chain;
│ │ │ the final EVM proof does not yet expose a ciphertext commitment for comparison with `keccak256(e3.ciphertextOutput)`
│ │ │ (on-chain / E3 state) C3/C6 ciphertext commitments are checked against their ciphertext witnesses;
│ │ │ the final decryption proof exposes the SAFE commitment and the wrapper compares it with
│ │ │ the commitment stored at ciphertext publication. Keccak(raw output) remains separate.
│ │ │
│ │ ├─ On mismatch: publishes CommitmentConsistencyViolation
│ │ │ → AccusationManager initiates accusation quorum (see Part 5)
Expand Down Expand Up @@ -704,13 +705,14 @@ on-chain; the explicit test/CI skip mode works only with mock verifiers that tru
> additionally compares the immutable VK hashes with the version-controlled circuit artifacts.

The decryption wrapper exposes
`verify(e3Id, decryptionDomain, plaintextOutputHash, committeeHash, proof)`. `Interfold` recomputes
`decryptionDomain` over
`verify(e3Id, decryptionDomain, plaintextOutputHash, committeeHash, ciphertextCommitment, proof)`.
`Interfold` recomputes `decryptionDomain` over
`(chainId, Interfold address, e3Id, committeeHash, ciphertextOutputHash, committeePublicKey)`. The
wrapper checks the domain limbs in the final proof, then uses the separate `e3Id` to resolve the
registry's stored DKG anchors and compares every surfaced party ID, secret-key commitment, and
smudging-noise commitment. The party IDs are circuit-side 1-indexed Shamir coordinates and are
translated to the registry's 0-indexed committee slots for this comparison.
wrapper checks the domain limbs and SAFE ciphertext commitment in the final proof, then uses the
separate `e3Id` to resolve the registry's stored DKG anchors and compares every surfaced party ID,
secret-key commitment, and smudging-noise commitment. The party IDs are circuit-side 1-indexed
Shamir coordinates and are translated to the registry's 0-indexed committee slots for this
comparison.

---

Expand All @@ -732,24 +734,25 @@ Data providers submit encrypted inputs:
```
Compute provider runs computation on encrypted data:
└─ Interfold.publishCiphertextOutput(e3Id, ciphertextOutput, proof)
└─ Interfold.publishCiphertextOutput(e3Id, ciphertextOutput, ciphertextCommitment, proof)
│ ┌─── ON-CHAIN (Interfold.sol) ─────────────────────────────┐
│ │ │
│ │ publishCiphertextOutput(e3Id, output, proof) {
│ │ publishCiphertextOutput(e3Id, output, commitment, proof) { │
│ │ 1. require(stage == KeyPublished) │
│ │ 2. require(block.timestamp <= computeDeadline) │
│ │ 3. require(block.timestamp >= inputWindow[1]) │
│ │ → Input window must have closed │
│ │ 4. require(e3.ciphertextOutput == 0) │
│ │ → Can only publish once │
│ │ 5. e3.ciphertextOutput = keccak256(output) │
│ │ 6. e3Program.verify(e3Id, hash, proof) │
│ │ 5. e3.ciphertextOutput = keccak256(output) │
│ │ e3.ciphertextCommitment = commitment │
│ │ 6. e3Program.verify(e3Id, hash, proof) │
│ │ → Program verifies computation correctness │
│ │ → Must return true │
│ │ 7. stage = CiphertextReady │
│ │ 8. decryptionDeadline = now + decryptionWindow │
│ │ 9. Emit CiphertextOutputPublished(e3Id, output)
│ │ 9. Emit CiphertextOutputPublished(e3Id, output, commitment)
│ │ 10. Emit E3StageChanged(CiphertextReady) │
│ │ } │
│ └─────────────────────────────────────────────────────────┘
Expand Down
100 changes: 50 additions & 50 deletions circuits/benchmarks/results_insecure_minimum/crisp_verify_gas.json

Large diffs are not rendered by default.

132 changes: 66 additions & 66 deletions circuits/benchmarks/results_insecure_minimum/integration_summary.json

Large diffs are not rendered by default.

Loading
Loading