Skip to content

feat: add share encryption [skip-line-limit]#1114

Merged
ryardley merged 24 commits into
mainfrom
feat/share-encryption
Dec 27, 2025
Merged

feat: add share encryption [skip-line-limit]#1114
ryardley merged 24 commits into
mainfrom
feat/share-encryption

Conversation

@hmzakhalid

@hmzakhalid hmzakhalid commented Dec 16, 2025

Copy link
Copy Markdown
Collaborator

closes #783

Overview

The flow consists of 5 phases:

  1. BFV Key Exchange - Parties exchange BFV public keys for encrypting shares
  2. Share Generation - Each party generates their TrBFV shares (pk_share, sk_sss, esi_sss)
  3. Share Distribution - Shares are BFV-encrypted and sent to target parties
  4. Key Aggregation - Each party decrypts received shares and computes decryption key
  5. Decryption - When ciphertext arrives, parties compute decryption shares

State Machine

Init
  │
  ▼ CiphernodeSelected
CollectingEncryptionKeys
  │
  ▼ AllEncryptionKeysCollected
GeneratingThresholdShare
  │
  ▼ SharesGenerated (both pk_share/sk_sss and esi_sss ready)
AggregatingDecryptionKey
  │
  ▼ AllThresholdSharesCollected + CalculateDecryptionKeyResponse
ReadyForDecryption
  │
  ▼ CiphertextOutputPublished
Decrypting
  │
  ▼ CalculateDecryptionShareResponse
Completed

Sequence Diagram

sequenceDiagram
    autonumber
    participant EVM as Blockchain/EVM
    participant Bus as Event Bus
    participant TK as ThresholdKeyshare
    participant EKC as EncryptionKeyCollector
    participant TSC as ThresholdShareCollector
    participant MT as Multithread (Compute)
    participant Net as Network/DHT

    Note over TK: State: Init

    %% Phase 1: BFV Key Generation & Exchange
    rect rgb(230, 245, 255)
        Note right of EVM: Phase 1: BFV Key Exchange
        EVM->>Bus: CiphernodeSelected
        Bus->>TK: CiphernodeSelected
        TK->>TK: Generate BFV keypair (sk_bfv, pk_bfv)
        Note over TK: State: CollectingEncryptionKeys
        TK->>Bus: EncryptionKeyCreated (party_id, pk_bfv)
        Bus->>Net: Publish to DHT (broadcast)
        Bus->>EKC: EncryptionKeyCreated (local)

        Note over Net: All N parties publish their BFV public keys

        Net-->>Bus: EncryptionKeyCreated (remote parties)
        Bus->>EKC: EncryptionKeyCreated (party 0..N-1)

        EKC->>EKC: Collect all N keys
        EKC->>TK: AllEncryptionKeysCollected (sorted by party_id)
    end

    %% Phase 2: TrBFV Share Generation
    rect rgb(255, 245, 230)
        Note right of TK: Phase 2: Share Generation
        Note over TK: State: GeneratingThresholdShare

        par Parallel computation
            TK->>MT: GenEsiSss
            MT-->>TK: GenEsiSssResponse (esi_sss)
        and 
            TK->>MT: GenPkShareAndSkSss
            MT-->>TK: GenPkShareAndSkSssResponse (pk_share, sk_sss)
        end

        Note over TK: State: AggregatingDecryptionKey
        TK->>TK: SharesGenerated: Encrypt shares with recipients' BFV public keys
    end

    %% Phase 3: Share Distribution (Domain-Level Splitting)
    rect rgb(245, 255, 230)
        Note right of TK: Phase 3: Share Distribution (N×N messages total)
        loop For each recipient party i (0..N)
            TK->>Bus: ThresholdShareCreated (target_party_id=i)
            Bus->>Net: Publish with Filter(party_id=i)
        end

        Note over Net: Each party receives only shares targeted to them

        Net-->>Bus: ThresholdShareCreated (filtered for this party)
        Bus->>TK: ThresholdShareCreated
        TK->>TK: Check: target_party_id == my_party_id?
        TK->>TSC: Forward if match

        TSC->>TSC: Collect N shares (one from each sender)
        TSC->>TK: AllThresholdSharesCollected
    end

    %% Phase 4: Decryption Key Aggregation
    rect rgb(255, 230, 245)
        Note right of TK: Phase 4: Key Aggregation
        TK->>TK: Decrypt received shares using own sk_bfv
        TK->>MT: CalculateDecryptionKey (sk_sss, esi_sss)
        MT-->>TK: CalculateDecryptionKeyResponse (sk_poly_sum, es_poly_sum)
        Note over TK: State: ReadyForDecryption
        TK->>Bus: KeyshareCreated (pk_share)
    end

    %% Phase 5: Decryption
    rect rgb(230, 230, 255)
        Note right of EVM: Phase 5: Decryption
        EVM->>Bus: CiphertextOutputPublished
        Bus->>TK: CiphertextOutputPublished
        Note over TK: State: Decrypting
        TK->>MT: CalculateDecryptionShare
        MT-->>TK: CalculateDecryptionShareResponse (d_share_poly)
        TK->>Bus: DecryptionshareCreated
        Note over TK: State: Completed
    end
Loading

Summary by CodeRabbit

  • New Features

    • BFV-based encryption key events and a deterministic key-collection workflow with failure reporting.
    • Per-recipient BFV-encrypted threshold shares plus BFV key serialization/deserialization and shared BFV parameters utilities.
    • Integrated key-collection into threshold keyshare, networking, and builder flows.
  • Public API

    • Keyshare extension and keyshare paths accept and propagate shared BFV encryption parameters.
  • Tests

    • Integration tests updated to wait for encryption-key exchange completion before processing threshold shares.

✏️ Tip: You can customize this high-level summary in your review settings.

@vercel

vercel Bot commented Dec 16, 2025

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
crisp Ready Ready Preview, Comment Dec 24, 2025 9:28pm
enclave-docs Ready Ready Preview, Comment Dec 24, 2025 9:28pm

@coderabbitai

coderabbitai Bot commented Dec 16, 2025

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

Adds BFV-based share encryption and BFV key-exchange: new EncryptionKey/EncryptionKeyCreated events and collectors, BFV-encrypted share types and helpers, ThresholdKeyshare integration and state transitions, network document routing for key exchange, test updates, and workspace dependency changes. (≤50 words)

Changes

Cohort / File(s) Summary
Encryption Key Event
crates/events/src/enclave_event/encryption_key_created.rs
New public EncryptionKey and EncryptionKeyCreated Actix message types (e3_id, Arc<EncryptionKey>, external) and Display impl.
Enclave Event Integration
crates/events/src/enclave_event/mod.rs
Register/re-export new modules; add EnclaveEventData variants EncryptionKeyCreated, EncryptionKeyCollectionFailed, ThresholdShareCollectionFailed; update get_e3_id and conversion macro support.
Threshold Share Structs
crates/events/src/enclave_event/threshold_share_created.rs
Replace PVW types with BfvEncryptedShares; remove PvwBytes; add extract_for_party and num_parties; ThresholdShareCreated adds target_party_id and Actix rtype attribute.
Encryption Key Collector
crates/keyshare/src/encryption_key_collector.rs, crates/keyshare/src/lib.rs
New EncryptionKeyCollector actor, CollectorState, AllEncryptionKeysCollected message, EncryptionKeyCollectionTimeout, deterministic sorting conversion from HashMap, setup constructor; module added and re-exported.
ThresholdKeyshare BFV flow
crates/keyshare/src/threshold_keyshare.rs, crates/keyshare/src/ext.rs
Add CollectingEncryptionKeys state/data, BFV key generation and publish of EncryptionKeyCreated, collector wiring and handlers (ensure_encryption_key_collector, handle_encryption_key_created, handle_all_encryption_keys_collected), propagate share_encryption_params.
BFV encrypted shares & helpers
crates/trbfv/src/shares/bfv_encrypted.rs, crates/trbfv/src/shares/mod.rs, crates/trbfv/src/shares/pvw.rs (removed)
Add BfvEncryptedShare / BfvEncryptedShares with encrypt/decrypt, accessors, defaults and tests; remove PVW wrapper and replace pvw module with bfv_encrypted.
BFV key serialization / params
crates/trbfv/src/helpers.rs
Add serialize_secret_key, deserialize_secret_key, get_share_encryption_params and internal SecretKeyData wrapper.
Test helpers & integration tests
crates/test-helpers/src/usecase_helpers.rs, crates/trbfv/tests/integration.rs, crates/tests/tests/integration.rs
Introduce GeneratedShares (shares + bfv_secret_keys); generate_shares_hash_mapGeneratedShares; tests updated to use BFV keys and wait for EncryptionKeyCreated events before share processing.
Network / Document publishing
crates/net/src/document_publisher.rs
Add ReceivableDocument::EncryptionKeyCreated, from_bytes/to_bytes support, EventConverter handler for EncryptionKeyCreated, per-E3id publish filtering, and include in is_document_publisher_event.
Threshold share collector timeout
crates/keyshare/src/threshold_share_collector.rs
Add collection timeout constant/timeout message, e3_id tracking, timeout scheduling/handler, emit ThresholdShareCollectionFailed on timeout.
Builder & workspace changes
crates/ciphernode-builder/src/ciphernode_builder.rs, crates/keyshare/Cargo.toml, crates/trbfv/Cargo.toml, crates/ciphernode-builder/Cargo.toml, crates/events/Cargo.toml
ciphernode_builder obtains share_encryption_params and passes into ThresholdKeyshareExtension::create; workspace deps updated (fhe, hex, rand relocation).
Minor exports & API surface
crates/events/src/enclave_event/publish_document/mod.rs, crates/keyshare/src/ext.rs
Filter re-export made public; ThresholdKeyshareExtension gains share_encryption_params field and create now accepts it.
Artifacts
packages/enclave-contracts/.../EnclaveTicketToken.json
Artifact immutable reference keys and buildInfoId updated (keys renamed only).

Sequence Diagram(s)

sequenceDiagram
    participant Party as Party / Ciphernode
    participant Net as Network / DocumentPublisher
    participant TKS as ThresholdKeyshare
    participant EKC as EncryptionKeyCollector

    rect rgb(230,240,255)
    Note over Party,TKS: Phase 1 — BFV key generation & publish
    Party->>TKS: ciphernode_selected (trigger)
    TKS->>TKS: generate BFV keys (sk_bfv, pk_bfv)
    TKS->>EKC: setup(parent=TKS, total)
    TKS->>Net: Publish EncryptionKeyCreated(e3_id, pk_bfv, party_id)
    Net->>Party: broadcast EncryptionKeyCreated
    end

    rect rgb(220,255,235)
    Note over Party,EKC: Phase 2 — Key collection
    Party->>EKC: EncryptionKeyCreated (per party)
    EKC->>EKC: validate & store by party_id
    EKC->>TKS: AllEncryptionKeysCollected(keys)
    end

    rect rgb(255,250,210)
    Note over TKS: Phase 3 — Share generation & BFV encryption
    TKS->>TKS: transition → GeneratingThresholdShare
    TKS->>TKS: generate Shamir shares
    TKS->>TKS: encrypt shares with collected pk_bfv
    TKS->>Net: Publish ThresholdShareCreated(BFV-encrypted)
    Net->>Party: deliver encrypted shares
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

ciphernode

Suggested reviewers

  • ryardley
  • 0xjei
  • cedoor

Poem

🐇 I hopped and hid a BFV key,
Collected pals from one to five,
Each share wrapped snug in ciphered night,
The collector chimed — all keys alive,
Now shares may travel safe and spry.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 69.64% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat: add share encryption' directly and concisely summarizes the main change: implementing encryption for Shamir shares.
Linked Issues check ✅ Passed The PR implements the core requirement from #783 to encrypt per-recipient Shamir shares, transitioning from PVW to BFV encryption while maintaining the overall objectives of secure share distribution.
Out of Scope Changes check ✅ Passed All changes are directly related to share encryption: BFV-based share encryption/decryption, encryption key collection, modified share structures, and integration into the distribution pipeline.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/share-encryption

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@hmzakhalid hmzakhalid changed the title feat: add share encryption feat: add share encryption [skip-line-limit] Dec 16, 2025

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
crates/trbfv/src/helpers.rs (1)

46-50: Consider making encryption parameters configurable to support different security levels.

The hardcoded parameter set (Set8192_144115188075855872_2) works for now, but as indicated by the TODO, configurability would enable flexibility for different security requirements or use cases. BFV parameters affect many aspects of the encryption scheme, such as operational performance, security level, multiplicative depth of the circuit, and space consumption.

crates/trbfv/src/shares/bfv_encrypted.rs (1)

97-124: Consider validating degree against decrypted vector length.

The decrypt method assumes the decrypted vector has at least degree elements. If the plaintext was encoded with a different degree, take(degree) silently truncates or the loop underfills data. Consider adding a validation check.

             let decrypted: Vec<u64> = Vec::<u64>::try_decode(&pt, Encoding::poly())
                 .context("Failed to decode plaintext")?;

+            if decrypted.len() < degree {
+                anyhow::bail!(
+                    "Decrypted vector has {} elements, expected at least {}",
+                    decrypted.len(),
+                    degree
+                );
+            }
+
             for (i, val) in decrypted.into_iter().take(degree).enumerate() {
                 data[[m, i]] = val;
             }
crates/keyshare/src/threshold_keyshare.rs (1)

909-910: Remove duplicate comment line.

Line 909 and 910 contain the same comment.

-// Will only receive events that are for this specific e3_id
 // Will only receive events that are for this specific e3_id
 impl Handler<EnclaveEvent> for ThresholdKeyshare {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4d85bab and 02c65c2.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (16)
  • crates/events/src/enclave_event/encryption_key_created.rs (1 hunks)
  • crates/events/src/enclave_event/mod.rs (5 hunks)
  • crates/events/src/enclave_event/threshold_share_created.rs (1 hunks)
  • crates/keyshare/Cargo.toml (1 hunks)
  • crates/keyshare/src/encryption_key_collector.rs (1 hunks)
  • crates/keyshare/src/lib.rs (1 hunks)
  • crates/keyshare/src/threshold_keyshare.rs (22 hunks)
  • crates/net/src/document_publisher.rs (7 hunks)
  • crates/test-helpers/src/usecase_helpers.rs (3 hunks)
  • crates/tests/tests/integration.rs (1 hunks)
  • crates/trbfv/Cargo.toml (1 hunks)
  • crates/trbfv/src/helpers.rs (1 hunks)
  • crates/trbfv/src/shares/bfv_encrypted.rs (1 hunks)
  • crates/trbfv/src/shares/mod.rs (1 hunks)
  • crates/trbfv/src/shares/pvw.rs (0 hunks)
  • crates/trbfv/tests/integration.rs (2 hunks)
💤 Files with no reviewable changes (1)
  • crates/trbfv/src/shares/pvw.rs
🧰 Additional context used
🧠 Learnings (16)
📓 Common learnings
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 660
File: crates/events/src/enclave_event/decryptionshare_created.rs:23-26
Timestamp: 2025-10-04T14:00:17.916Z
Learning: In the enclave codebase using threshold BFV cryptography, decryption shares (as in DecryptionshareCreated events) are not sensitive data and can be safely logged or displayed, as individual shares reveal nothing without reaching the threshold number of shares.
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 969
File: packages/enclave-sdk/src/enclave-sdk.ts:101-103
Timestamp: 2025-11-08T01:31:47.505Z
Learning: In packages/enclave-sdk/src/enclave-sdk.ts, the TRBFV protocol parameter setup is intentionally incomplete as of PR #969. The constructor sets BFV_THRESHOLD parameters for TRBFV, but the encryption methods (encryptNumber, encryptVector, encryptNumberAndGenInputs, encryptVectorAndGenInputs) intentionally only support BFV and will throw "Protocol not supported" for TRBFV until future implementation is completed.
📚 Learning: 2025-08-25T10:28:56.174Z
Learnt from: ctrlc03
Repo: gnosisguild/enclave PR: 657
File: Cargo.toml:32-34
Timestamp: 2025-08-25T10:28:56.174Z
Learning: The examples/CRISP directory has its own Cargo.toml workspace configuration with members like "server", "wasm-crypto", "program/core", "program/client", etc. The root workspace intentionally excludes "examples/CRISP/server", "examples/CRISP/program", and "examples/CRISP/wasm-crypto" to prevent double workspace membership, which is the correct approach for self-contained example workspaces.

Applied to files:

  • crates/trbfv/Cargo.toml
  • crates/keyshare/Cargo.toml
📚 Learning: 2024-10-22T02:36:01.448Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/data/Cargo.toml:0-0
Timestamp: 2024-10-22T02:36:01.448Z
Learning: In `packages/ciphernode/data/Cargo.toml`, `actix-rt` is only used in tests and should remain in `[dev-dependencies]`.

Applied to files:

  • crates/trbfv/Cargo.toml
📚 Learning: 2024-10-29T01:04:19.137Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/keyshare.rs:53-70
Timestamp: 2024-10-29T01:04:19.137Z
Learning: In the `Keyshare` struct within `packages/ciphernode/keyshare/src/keyshare.rs`, the `self.secret` field is stored in encrypted form and is not considered sensitive.

Applied to files:

  • crates/keyshare/src/lib.rs
  • crates/events/src/enclave_event/mod.rs
  • crates/events/src/enclave_event/encryption_key_created.rs
  • crates/test-helpers/src/usecase_helpers.rs
  • crates/trbfv/src/helpers.rs
  • crates/trbfv/src/shares/mod.rs
  • crates/trbfv/src/shares/bfv_encrypted.rs
  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/keyshare/src/threshold_keyshare.rs
  • crates/trbfv/tests/integration.rs
📚 Learning: 2024-10-23T02:03:02.008Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/encryption.rs:45-45
Timestamp: 2024-10-23T02:03:02.008Z
Learning: In the `packages/ciphernode/keyshare/src/encryption.rs` file, the environment variable `CIPHERNODE_SECRET` is used for the encryption password. A secure secret management solution is not currently available, but may be considered in future iterations.

Applied to files:

  • crates/keyshare/src/lib.rs
  • crates/events/src/enclave_event/mod.rs
  • crates/events/src/enclave_event/encryption_key_created.rs
  • crates/test-helpers/src/usecase_helpers.rs
  • crates/trbfv/src/helpers.rs
  • crates/trbfv/src/shares/mod.rs
  • crates/trbfv/src/shares/bfv_encrypted.rs
  • crates/keyshare/src/threshold_keyshare.rs
  • crates/trbfv/tests/integration.rs
📚 Learning: 2024-09-26T03:11:29.311Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 107
File: packages/ciphernode/sortition/src/distance.rs:1-1
Timestamp: 2024-09-26T03:11:29.311Z
Learning: In `packages/ciphernode/core/src/events.rs`, the import statements use the correct and updated `alloy::primitives` module.

Applied to files:

  • crates/keyshare/src/lib.rs
  • crates/events/src/enclave_event/mod.rs
  • crates/tests/tests/integration.rs
  • crates/events/src/enclave_event/encryption_key_created.rs
  • crates/net/src/document_publisher.rs
  • crates/trbfv/src/shares/mod.rs
  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-23T02:35:07.689Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/keyshare.rs:58-65
Timestamp: 2024-10-23T02:35:07.689Z
Learning: In `packages/ciphernode/keyshare/src/keyshare.rs`, the data being decrypted in the `get_secret` method of the `Keyshare` struct is not sensitive, so wrapping it with `Zeroizing` is unnecessary.

Applied to files:

  • crates/keyshare/src/lib.rs
  • crates/test-helpers/src/usecase_helpers.rs
  • crates/trbfv/src/helpers.rs
  • crates/trbfv/src/shares/bfv_encrypted.rs
  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/keyshare/src/threshold_keyshare.rs
  • crates/trbfv/tests/integration.rs
📚 Learning: 2024-10-08T19:45:18.209Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 133
File: packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs:137-139
Timestamp: 2024-10-08T19:45:18.209Z
Learning: In `packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs`, using the same RNG instance `rng_test` for generating multiple key shares without advancing its state is acceptable.

Applied to files:

  • crates/keyshare/src/lib.rs
  • crates/tests/tests/integration.rs
  • crates/test-helpers/src/usecase_helpers.rs
  • crates/trbfv/src/shares/bfv_encrypted.rs
  • crates/keyshare/src/threshold_keyshare.rs
  • crates/trbfv/tests/integration.rs
📚 Learning: 2024-10-22T02:10:34.864Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs:82-83
Timestamp: 2024-10-22T02:10:34.864Z
Learning: In the file `packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs`, when reviewing test functions like `generate_pk_share`, minor performance optimizations (e.g., minimizing mutex locks) are not a priority.

Applied to files:

  • crates/keyshare/src/lib.rs
  • crates/events/src/enclave_event/mod.rs
  • crates/tests/tests/integration.rs
  • crates/test-helpers/src/usecase_helpers.rs
  • crates/trbfv/src/helpers.rs
  • crates/trbfv/src/shares/mod.rs
  • crates/trbfv/src/shares/bfv_encrypted.rs
  • crates/keyshare/src/threshold_keyshare.rs
  • crates/trbfv/tests/integration.rs
📚 Learning: 2025-04-30T06:25:14.721Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 372
File: packages/ciphernode/events/src/eventbus.rs:15-15
Timestamp: 2025-04-30T06:25:14.721Z
Learning: EnclaveEvent implements Display in packages/ciphernode/events/src/enclave_event/mod.rs, which satisfies the Event trait requirement. Static analysis tools may incorrectly flag implementations as missing when they do exist.

Applied to files:

  • crates/events/src/enclave_event/mod.rs
  • crates/events/src/enclave_event/encryption_key_created.rs
  • crates/net/src/document_publisher.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-10-04T14:00:17.916Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 660
File: crates/events/src/enclave_event/decryptionshare_created.rs:23-26
Timestamp: 2025-10-04T14:00:17.916Z
Learning: In the enclave codebase using threshold BFV cryptography, decryption shares (as in DecryptionshareCreated events) are not sensitive data and can be safely logged or displayed, as individual shares reveal nothing without reaching the threshold number of shares.

Applied to files:

  • crates/tests/tests/integration.rs
  • crates/test-helpers/src/usecase_helpers.rs
  • crates/trbfv/src/helpers.rs
  • crates/trbfv/src/shares/bfv_encrypted.rs
  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/keyshare/src/threshold_keyshare.rs
  • crates/trbfv/tests/integration.rs
📚 Learning: 2024-10-10T23:24:43.341Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 143
File: packages/ciphernode/sortition/src/sortition.rs:4-9
Timestamp: 2024-10-10T23:24:43.341Z
Learning: In the `Sortition` module (`packages/ciphernode/sortition/src/sortition.rs`), errors are sent to the event bus using `self.bus.err`, which handles logging and printing. Therefore, explicit use of the `tracing` crate for logging errors may not be necessary in this context.

Applied to files:

  • crates/net/src/document_publisher.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-11-05T03:56:22.254Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 170
File: packages/ciphernode/evm/tests/evm_reader.rs:63-63
Timestamp: 2024-11-05T03:56:22.254Z
Learning: In the Rust test function `test_logs` in `packages/ciphernode/evm/tests/evm_reader.rs`, a sleep duration of 1 millisecond is sufficient for reliable event processing, even in CI environments.

Applied to files:

  • crates/net/src/document_publisher.rs
📚 Learning: 2025-05-07T15:18:20.056Z
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 388
File: packages/commons/src/bfv/mod.rs:38-48
Timestamp: 2025-05-07T15:18:20.056Z
Learning: The `build_bfv_params` and related functions in the commons BFV utilities intentionally use panic for error handling as a temporary solution. The team plans to refactor these to use proper Result-based error handling in the future.

Applied to files:

  • crates/trbfv/src/shares/mod.rs
📚 Learning: 2025-11-08T01:31:47.505Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 969
File: packages/enclave-sdk/src/enclave-sdk.ts:101-103
Timestamp: 2025-11-08T01:31:47.505Z
Learning: In packages/enclave-sdk/src/enclave-sdk.ts, the TRBFV protocol parameter setup is intentionally incomplete as of PR #969. The constructor sets BFV_THRESHOLD parameters for TRBFV, but the encryption methods (encryptNumber, encryptVector, encryptNumberAndGenInputs, encryptVectorAndGenInputs) intentionally only support BFV and will throw "Protocol not supported" for TRBFV until future implementation is completed.

Applied to files:

  • crates/trbfv/src/shares/bfv_encrypted.rs
  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-11-05T06:51:46.701Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 173
File: packages/ciphernode/evm/src/event_reader.rs:270-286
Timestamp: 2024-11-05T06:51:46.701Z
Learning: In `packages/ciphernode/evm/src/event_reader.rs`, the `state.ids` HashSet is intended to grow indefinitely to store all processed event IDs for deduplication purposes until an alternative like a bloom filter is implemented.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
🧬 Code graph analysis (7)
crates/tests/tests/integration.rs (1)
crates/net/src/bin/p2p_test.rs (1)
  • report (111-114)
crates/events/src/enclave_event/encryption_key_created.rs (2)
crates/events/src/enclave_event/mod.rs (1)
  • fmt (352-354)
crates/events/src/enclave_event/threshold_share_created.rs (1)
  • fmt (46-48)
crates/test-helpers/src/usecase_helpers.rs (2)
crates/trbfv/src/helpers.rs (1)
  • get_share_encryption_params (47-50)
crates/trbfv/src/shares/bfv_encrypted.rs (1)
  • encrypt_all (154-175)
crates/net/src/document_publisher.rs (3)
crates/events/src/enclave_event/mod.rs (1)
  • get_e3_id (280-300)
crates/keyshare/src/threshold_keyshare.rs (11)
  • get_e3_id (218-220)
  • handle_encryption_key_created (381-390)
  • msg (716-726)
  • msg (729-743)
  • handle (913-925)
  • handle (930-935)
  • handle (940-945)
  • handle (950-955)
  • handle (960-965)
  • handle (970-975)
  • handle (980-985)
crates/keyshare/src/encryption_key_collector.rs (1)
  • handle (93-130)
crates/keyshare/src/encryption_key_collector.rs (1)
crates/keyshare/src/threshold_keyshare.rs (1)
  • from (67-71)
crates/events/src/enclave_event/threshold_share_created.rs (2)
crates/test-helpers/src/usecase_helpers.rs (2)
  • shares (156-165)
  • shares (168-181)
crates/utils/src/utility_types.rs (1)
  • fmt (47-49)
crates/trbfv/tests/integration.rs (2)
crates/test-helpers/src/usecase_helpers.rs (5)
  • generate_shares_hash_map (40-120)
  • get_public_key (122-138)
  • shares (156-165)
  • shares (168-181)
  • get_decryption_keys (140-200)
crates/utils/src/helpers.rs (1)
  • to_ordered_vec (8-20)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: build_enclave_cli
  • GitHub Check: build_e3_support_dev
  • GitHub Check: crisp_unit
  • GitHub Check: build_sdk
  • GitHub Check: build_ciphernode_image
  • GitHub Check: test_net
  • GitHub Check: rust_integration
  • GitHub Check: integration_prebuild
  • GitHub Check: rust_unit
🔇 Additional comments (46)
crates/keyshare/src/lib.rs (1)

7-7: LGTM!

The new encryption_key_collector module declaration and public re-export follow the established pattern in this crate.

Also applies to: 13-13

crates/tests/tests/integration.rs (1)

290-305: LGTM!

The new synchronization point for EncryptionKeyCreated events correctly integrates the BFV key exchange phase into the test flow. The event count (5) matches threshold_n, and the pattern is consistent with other event waits in this test.

crates/trbfv/src/shares/mod.rs (1)

6-6: LGTM!

The module structure change correctly introduces bfv_encrypted to replace the PVW-based approach, aligning with the PR objective to encrypt Shamir shares using BFV.

Also applies to: 9-9

crates/events/src/enclave_event/mod.rs (3)

22-22: LGTM!

The EncryptionKeyCreated event is properly integrated with module declaration, re-export, and enum variant addition.

Also applies to: 51-51, 117-117


297-297: LGTM!

E3 ID extraction correctly handles the new EncryptionKeyCreated variant, maintaining consistency with other E3-scoped events.


329-330: LGTM!

The impl_into_event_data! macro invocation now includes both ThresholdShareCreated and EncryptionKeyCreated, enabling the From trait conversions.

crates/trbfv/src/helpers.rs (1)

26-44: LGTM!

The SecretKeyData wrapper and serialization/deserialization functions provide a clean approach for persisting BFV secret keys via bincode. The pattern of cloning coefficients and reconstructing with parameters is appropriate since SecretKey doesn't natively implement Serialize.

crates/trbfv/tests/integration.rs (1)

86-103: LGTM!

The test correctly adapts to the new GeneratedShares return type from generate_shares_hash_map, properly accessing generated.shares and passing generated.bfv_secret_keys to get_decryption_keys. This aligns with the BFV-based share encryption introduced in this PR.

crates/events/src/enclave_event/encryption_key_created.rs (1)

17-37: LGTM!

The new EncryptionKey and EncryptionKeyCreated types follow the established patterns in the codebase. The Display implementation using Debug format is consistent with other event types (e.g., ThresholdShareCreated), and the hex formatter for pk_bfv is appropriate for binary key data.

crates/events/src/enclave_event/threshold_share_created.rs (1)

18-35: LGTM!

The migration from PVW-based types to BFV-based BfvEncryptedShares aligns with the PR objective. The updated documentation accurately describes the BFV encryption semantics where each recipient decrypts only their intended share using their BFV secret key.

crates/test-helpers/src/usecase_helpers.rs (4)

33-38: LGTM!

The GeneratedShares struct cleanly bundles the threshold shares with the BFV secret keys needed for decryption in tests. This separation keeps the test infrastructure organized while providing necessary key material.


50-61: LGTM!

BFV keypair generation using OsRng is appropriate for cryptographic key material. The loop generates a keypair per party, storing secret keys for later decryption and public keys for share encryption.


84-119: LGTM!

The workflow correctly decrypts the locally stored secrets, then re-encrypts them using BFV for distribution to all recipients. Each party's share is encrypted with the corresponding recipient's BFV public key, enabling secure share distribution.


140-199: LGTM!

The decryption flow correctly has each party use their BFV secret key to decrypt shares addressed to them. The clone_share(party_id) method extracts the encrypted share for the specific recipient, and decrypt() uses the corresponding secret key. This aligns with the BFV-encrypted share structure.

crates/keyshare/src/encryption_key_collector.rs (3)

45-52: LGTM!

The From implementation correctly sorts keys by party_id for deterministic ordering, which is essential for consistent cryptographic operations across all parties. This matches the pattern used in AllThresholdSharesCollected.


69-85: LGTM!

The setup function correctly initializes the collector with all expected party IDs (0 to total-1) in the todo set. The actor starts immediately and returns its address for message routing.


91-130: LGTM!

The handler correctly uses HashSet::take() to atomically remove party IDs, naturally preventing duplicate key processing. The state machine transitions appropriately, and do_send is suitable for notifying the parent actor.

crates/net/src/document_publisher.rs (7)

18-19: LGTM!

The import additions for EncryptionKeyCreated are correctly placed alongside related event types.


73-81: LGTM!

The EncryptionKeyCreated event is correctly added to is_document_publisher_event following the same pattern as ThresholdShareCreated. This ensures the event is properly routed through the document publishing system.


381-402: LGTM!

The ReceivableDocument enum extension is well-structured. The get_e3_id accessor and serialization methods properly handle the new variant.


408-414: LGTM!

Subscription to EncryptionKeyCreated events is correctly added alongside the existing subscriptions.


433-450: LGTM!

The handle_encryption_key_created method correctly mirrors handle_threshold_share_created:

  • Guards against external events to prevent republishing
  • Wraps the message in ReceivableDocument
  • Creates appropriate DocumentMeta with DocumentKind::TrBFV
  • Publishes via PublishDocumentRequested

451-472: LGTM!

The handle_document_received extension correctly handles the EncryptionKeyCreated variant, republishing it with external: true to indicate it was received from the network.


479-509: LGTM!

The Handler implementations for EnclaveEvent and EncryptionKeyCreated correctly route events using the established patterns:

  • EnclaveEvent handler extracts and forwards EncryptionKeyCreated data
  • Dedicated handler invokes handle_encryption_key_created with proper error logging
crates/trbfv/src/shares/bfv_encrypted.rs (6)

1-26: LGTM!

Clean module structure with appropriate license header, imports, and re-exports of helper functions from the parent module.


27-48: LGTM!

Well-documented struct with clear purpose. The custom debug formatter for ciphertexts is a nice touch that avoids logging potentially large byte arrays while still providing useful summary information.


49-86: LGTM!

The encrypt method correctly:

  • Iterates over each modulus row of the Shamir share
  • Encodes as polynomial plaintext
  • Encrypts with the recipient's BFV public key
  • Serializes ciphertexts for transmission

Error handling with context provides clear diagnostics.


126-132: LGTM!

Default implementation is appropriate for the type.


134-202: LGTM!

BfvEncryptedShares provides a clean API for managing encrypted shares:

  • encrypt_all properly iterates parties and extracts per-party shares
  • Accessor methods (get_share, clone_share, len, is_empty) follow Rust conventions
  • Default implementation is appropriate

204-258: LGTM!

Tests provide good coverage of core functionality:

  • test_encrypt_decrypt_share validates the roundtrip for encryption/decryption
  • test_secret_key_serialization validates key serialization helpers

These tests ensure the fundamental cryptographic operations work correctly.

crates/keyshare/src/threshold_keyshare.rs (14)

74-79: LGTM!

The CollectingEncryptionKeysData struct correctly captures the BFV key pair and the original CiphernodeSelected event needed for the next phase.


81-96: LGTM!

Adding sk_bfv and pk_bfv fields to GeneratingThresholdShareData and AggregatingDecryptionKey properly carries the BFV key material through the state machine. Using SensitiveBytes for the secret key is appropriate.


112-128: LGTM!

The state machine extension is well-designed:

  • New CollectingEncryptionKeys variant inserted between Init and GeneratingThresholdShare
  • State transitions properly validated: Init → CollectingEncryptionKeys → GeneratingThresholdShare
  • variant_name updated for debugging/logging

Also applies to: 130-172


247-255: LGTM!

TryInto<CollectingEncryptionKeysData> implementation follows the established pattern for state extraction.


304-325: LGTM!

New fields encryption_key_collector and collected_encryption_keys properly initialized to None in the constructor.


351-390: LGTM!

The ensure_encryption_key_collector method correctly follows the pattern of ensure_collector, lazily initializing the collector when needed. The handle_encryption_key_created method properly forwards events to the collector.


392-431: LGTM!

The handle_ciphernode_selected method correctly:

  1. Initializes both collectors
  2. Generates a fresh BFV keypair using OsRng
  3. Encrypts the secret key for secure storage via SensitiveBytes
  4. Transitions state to CollectingEncryptionKeys
  5. Publishes EncryptionKeyCreated with external: false

433-464: LGTM!

The handle_all_encryption_keys_collected method properly:

  1. Stores collected keys for later use during encryption
  2. Extracts BFV keys from the current state
  3. Transitions to GeneratingThresholdShare with BFV key material
  4. Triggers both ESI and PK share generation

498-546: LGTM!

The handle_gen_esi_sss_response method is correctly updated to carry sk_bfv and pk_bfv through state transitions, with proper validation that sk_bfv is present before transitioning to AggregatingDecryptionKey.


577-626: LGTM!

The handle_gen_pk_share_and_sk_sss_response method correctly handles the new BFV key requirements:

  • Validates that sk_bfv is present when esi_sss is available
  • Properly propagates BFV keys through state transitions
  • Includes explicit error case for inconsistent state (esi_sss present without sk_bfv)

628-691: LGTM!

The handle_shares_generated method implements the core BFV encryption flow:

  1. Retrieves collected BFV public keys
  2. Deserializes public keys from bytes
  3. Decrypts local shares from encrypted storage
  4. Encrypts shares for all recipients using BFV
  5. Publishes ThresholdShareCreated with BFV-encrypted shares

This fulfills the PR objective of encrypting Shamir shares with BFV.


693-757: LGTM!

The handle_all_threshold_shares_collected method correctly:

  1. Retrieves and decrypts the local BFV secret key
  2. Extracts the share meant for this party from each sender's encrypted shares
  3. Decrypts using BFV
  4. Re-encrypts for storage using the local cipher
  5. Builds the CalculateDecryptionKeyRequest

The flow ensures each party can only decrypt shares intended for them.


911-926: LGTM!

The Handler<EnclaveEvent> correctly routes EncryptionKeyCreated events to the encryption key handler.


958-966: LGTM!

The Handler<AllEncryptionKeysCollected> implementation follows the established pattern for handling collected events, with proper error logging.

crates/keyshare/Cargo.toml (1)

23-23: Confirm the workspace Cargo.toml defines the fhe dependency.

The fhe = { workspace = true } syntax is correct, but verify that the workspace root Cargo.toml includes fhe in its [workspace.dependencies] section with an appropriate version before merging.

crates/trbfv/Cargo.toml (1)

27-27: Verify rand usage in production code and ensure secure RNG for cryptographic operations.

Moving rand from dev-dependencies to dependencies aligns with implementing BFV-based share encryption. However, please confirm:

  1. That rand is actually used in production code (not just tests)
  2. That cryptographic operations use secure RNGs (OsRng, ChaChaRng) rather than potentially insecure defaults like thread_rng()

@vercel vercel Bot temporarily deployed to Preview – crisp December 16, 2025 15:24 Inactive
@vercel vercel Bot temporarily deployed to Preview – enclave-docs December 16, 2025 15:24 Inactive
@0xjei 0xjei self-requested a review December 16, 2025 17:13

@0xjei 0xjei left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

just gave a quick look - seems you are going in the right direction - lmk when ready for a proper review!

@ryardley ryardley left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good. A couple of minor things I can see.

Comment thread crates/trbfv/src/shares/bfv_encrypted.rs Outdated
Comment thread crates/keyshare/src/threshold_keyshare.rs Outdated
Comment thread crates/trbfv/src/helpers.rs
Comment thread crates/keyshare/src/threshold_keyshare.rs Outdated
Comment thread crates/keyshare/src/threshold_keyshare.rs Outdated
Comment thread crates/keyshare/src/threshold_keyshare.rs Outdated
Comment thread crates/keyshare/src/threshold_keyshare.rs Outdated
Comment thread crates/net/src/document_publisher.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 4

♻️ Duplicate comments (5)
crates/ciphernode-builder/src/ciphernode_builder.rs (1)

439-450: Consider injecting BFV parameters as configuration.

The get_share_encryption_params() helper is called directly here and in other locations across the codebase. As noted in a previous review, centralizing parameter configuration would improve testability and flexibility.

crates/trbfv/src/helpers.rs (1)

46-50: Make BFV parameters configurable.

As noted in the TODO comment and previous review feedback, this hardcoded parameter set should be configurable to support different security levels and testing scenarios.

crates/trbfv/src/shares/bfv_encrypted.rs (1)

32-38: Addressed: Using Vec<ArcBytes> for debuggability and cloning.

This addresses the past review comment about using Vec<ArcBytes> for the ciphertexts field.

crates/keyshare/src/threshold_keyshare.rs (2)

82-99: Fields changed from direct values to Option types.

This addresses the past review comment about why fields are Option. The Option wrapping allows these fields to be populated incrementally as the state machine progresses through different phases.


448-467: State extraction pattern matches past review suggestion.

This addresses the past comment about using let current: CollectingEncryptionKeysData = self.state.try_get()?.try_into()?;

🧹 Nitpick comments (4)
crates/events/src/chunk.rs (1)

53-60: Consider adding validation for chunk parameters.

The new constructor doesn't validate that:

  • chunk_index < total_chunks
  • total_chunks > 0

Invalid chunk metadata could cause issues during reassembly.

🔎 Apply this diff to add validation:
 pub fn new(chunk_id: ChunkSetId, chunk_index: u32, total_chunks: u32, data: Vec<u8>) -> Self {
+    assert!(total_chunks > 0, "total_chunks must be greater than 0");
+    assert!(chunk_index < total_chunks, "chunk_index must be less than total_chunks");
     Self {
         chunk_id,
         chunk_index,
         total_chunks,
         data,
     }
 }
crates/keyshare/src/encryption_key_collector.rs (1)

105-111: Consider more idiomatic pattern for validation.

The pattern let Some(_) = self.todo.take(&pid) works but mixing pattern matching with side effects is less clear than alternatives.

🔎 View suggested refactor:
-let Some(_) = self.todo.take(&pid) else {
+if !self.todo.remove(&pid) {
     info!(
         "Error: {} was not in encryption key collector's ID list",
         pid
     );
     return;
 };
crates/net/src/chunking/collector.rs (1)

109-136: Consider logging the number of timed-out chunk sets for observability.

The timeout cleanup logic is correct. However, if multiple chunk sets time out simultaneously, a single aggregate log message might be more useful for monitoring.

🔎 Optional improvement:
     fn check_timeouts(&mut self) {
         let now = Instant::now();
         let timed_out: Vec<_> = self
             .start_times
             .iter()
             .filter(|(_, start)| now.duration_since(**start) > self.timeout)
             .map(|(id, _)| id.clone())
             .collect();

+        if !timed_out.is_empty() {
+            info!("Cleaning up {} timed-out chunk sets", timed_out.len());
+        }
+
         for chunk_id in timed_out {
crates/trbfv/src/shares/bfv_encrypted.rs (1)

188-193: Consider documenting the semantic change when using extract_for_party.

The extract_for_party method creates a new BfvEncryptedShares with only one share, but the resulting object will have shares[0] contain the extracted share rather than shares[party_id]. This could be confusing if the caller later uses get_share(party_id) on the extracted result.

🔎 Suggested documentation:
     /// Extract only the share for a specific party (for bandwidth optimization)
+    /// 
+    /// Note: The returned `BfvEncryptedShares` contains only one share at index 0,
+    /// regardless of the original party_id. Use `get_share(0)` to access it.
     pub fn extract_for_party(&self, party_id: usize) -> Option<Self> {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 77a8d84 and 96acb34.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (28)
  • crates/ciphernode-builder/Cargo.toml (1 hunks)
  • crates/ciphernode-builder/src/ciphernode_builder.rs (1 hunks)
  • crates/events/Cargo.toml (1 hunks)
  • crates/events/src/chunk.rs (1 hunks)
  • crates/events/src/enclave_event/encryption_key_created.rs (1 hunks)
  • crates/events/src/enclave_event/mod.rs (5 hunks)
  • crates/events/src/enclave_event/publish_document/mod.rs (1 hunks)
  • crates/events/src/enclave_event/threshold_share_created.rs (1 hunks)
  • crates/events/src/lib.rs (2 hunks)
  • crates/keyshare/Cargo.toml (1 hunks)
  • crates/keyshare/src/encryption_key_collector.rs (1 hunks)
  • crates/keyshare/src/ext.rs (4 hunks)
  • crates/keyshare/src/lib.rs (1 hunks)
  • crates/keyshare/src/threshold_keyshare.rs (24 hunks)
  • crates/net/src/chunking/chunkable.rs (1 hunks)
  • crates/net/src/chunking/collector.rs (1 hunks)
  • crates/net/src/chunking/mod.rs (1 hunks)
  • crates/net/src/document_publisher.rs (8 hunks)
  • crates/net/src/lib.rs (1 hunks)
  • crates/test-helpers/src/usecase_helpers.rs (3 hunks)
  • crates/tests/tests/integration.rs (1 hunks)
  • crates/trbfv/Cargo.toml (1 hunks)
  • crates/trbfv/src/helpers.rs (1 hunks)
  • crates/trbfv/src/shares/bfv_encrypted.rs (1 hunks)
  • crates/trbfv/src/shares/mod.rs (1 hunks)
  • crates/trbfv/src/shares/pvw.rs (0 hunks)
  • crates/trbfv/tests/integration.rs (2 hunks)
  • packages/enclave-contracts/artifacts/contracts/token/EnclaveTicketToken.sol/EnclaveTicketToken.json (2 hunks)
💤 Files with no reviewable changes (1)
  • crates/trbfv/src/shares/pvw.rs
✅ Files skipped from review due to trivial changes (1)
  • packages/enclave-contracts/artifacts/contracts/token/EnclaveTicketToken.sol/EnclaveTicketToken.json
🚧 Files skipped from review as they are similar to previous changes (4)
  • crates/trbfv/Cargo.toml
  • crates/keyshare/src/lib.rs
  • crates/keyshare/Cargo.toml
  • crates/events/src/enclave_event/encryption_key_created.rs
🧰 Additional context used
🧠 Learnings (21)
📓 Common learnings
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 660
File: crates/events/src/enclave_event/decryptionshare_created.rs:23-26
Timestamp: 2025-10-04T14:00:17.916Z
Learning: In the enclave codebase using threshold BFV cryptography, decryption shares (as in DecryptionshareCreated events) are not sensitive data and can be safely logged or displayed, as individual shares reveal nothing without reaching the threshold number of shares.
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 969
File: packages/enclave-sdk/src/enclave-sdk.ts:101-103
Timestamp: 2025-11-08T01:31:47.505Z
Learning: In packages/enclave-sdk/src/enclave-sdk.ts, the TRBFV protocol parameter setup is intentionally incomplete as of PR #969. The constructor sets BFV_THRESHOLD parameters for TRBFV, but the encryption methods (encryptNumber, encryptVector, encryptNumberAndGenInputs, encryptVectorAndGenInputs) intentionally only support BFV and will throw "Protocol not supported" for TRBFV until future implementation is completed.
📚 Learning: 2024-09-26T03:11:29.311Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 107
File: packages/ciphernode/sortition/src/distance.rs:1-1
Timestamp: 2024-09-26T03:11:29.311Z
Learning: In `packages/ciphernode/core/src/events.rs`, the import statements use the correct and updated `alloy::primitives` module.

Applied to files:

  • crates/net/src/lib.rs
  • crates/events/src/enclave_event/publish_document/mod.rs
  • crates/events/src/lib.rs
  • crates/ciphernode-builder/Cargo.toml
  • crates/events/Cargo.toml
  • crates/events/src/enclave_event/mod.rs
  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/net/src/document_publisher.rs
  • crates/keyshare/src/threshold_keyshare.rs
  • crates/events/src/chunk.rs
📚 Learning: 2024-10-10T11:26:47.259Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 143
File: packages/ciphernode/p2p/src/libp2p_router.rs:154-154
Timestamp: 2024-10-10T11:26:47.259Z
Learning: In `packages/ciphernode/p2p/src/libp2p_router.rs`, logging the entire message data using `trace!("{:?}", message);` is acceptable at this point.

Applied to files:

  • crates/events/src/enclave_event/publish_document/mod.rs
📚 Learning: 2024-10-29T01:04:19.137Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/keyshare.rs:53-70
Timestamp: 2024-10-29T01:04:19.137Z
Learning: In the `Keyshare` struct within `packages/ciphernode/keyshare/src/keyshare.rs`, the `self.secret` field is stored in encrypted form and is not considered sensitive.

Applied to files:

  • crates/trbfv/src/helpers.rs
  • crates/ciphernode-builder/src/ciphernode_builder.rs
  • crates/trbfv/tests/integration.rs
  • crates/test-helpers/src/usecase_helpers.rs
  • crates/events/src/enclave_event/mod.rs
  • crates/trbfv/src/shares/mod.rs
  • crates/keyshare/src/ext.rs
  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/trbfv/src/shares/bfv_encrypted.rs
  • crates/keyshare/src/threshold_keyshare.rs
  • crates/keyshare/src/encryption_key_collector.rs
📚 Learning: 2024-10-23T02:35:07.689Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/keyshare.rs:58-65
Timestamp: 2024-10-23T02:35:07.689Z
Learning: In `packages/ciphernode/keyshare/src/keyshare.rs`, the data being decrypted in the `get_secret` method of the `Keyshare` struct is not sensitive, so wrapping it with `Zeroizing` is unnecessary.

Applied to files:

  • crates/trbfv/src/helpers.rs
  • crates/ciphernode-builder/src/ciphernode_builder.rs
  • crates/trbfv/tests/integration.rs
  • crates/test-helpers/src/usecase_helpers.rs
  • crates/keyshare/src/ext.rs
  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/trbfv/src/shares/bfv_encrypted.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-23T02:03:02.008Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/encryption.rs:45-45
Timestamp: 2024-10-23T02:03:02.008Z
Learning: In the `packages/ciphernode/keyshare/src/encryption.rs` file, the environment variable `CIPHERNODE_SECRET` is used for the encryption password. A secure secret management solution is not currently available, but may be considered in future iterations.

Applied to files:

  • crates/trbfv/src/helpers.rs
  • crates/ciphernode-builder/src/ciphernode_builder.rs
  • crates/trbfv/tests/integration.rs
  • crates/test-helpers/src/usecase_helpers.rs
  • crates/events/src/enclave_event/mod.rs
  • crates/trbfv/src/shares/mod.rs
  • crates/keyshare/src/ext.rs
  • crates/trbfv/src/shares/bfv_encrypted.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-10-04T14:00:17.916Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 660
File: crates/events/src/enclave_event/decryptionshare_created.rs:23-26
Timestamp: 2025-10-04T14:00:17.916Z
Learning: In the enclave codebase using threshold BFV cryptography, decryption shares (as in DecryptionshareCreated events) are not sensitive data and can be safely logged or displayed, as individual shares reveal nothing without reaching the threshold number of shares.

Applied to files:

  • crates/trbfv/src/helpers.rs
  • crates/trbfv/tests/integration.rs
  • crates/test-helpers/src/usecase_helpers.rs
  • crates/keyshare/src/ext.rs
  • crates/tests/tests/integration.rs
  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/trbfv/src/shares/bfv_encrypted.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-10T23:24:43.341Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 143
File: packages/ciphernode/sortition/src/sortition.rs:4-9
Timestamp: 2024-10-10T23:24:43.341Z
Learning: In the `Sortition` module (`packages/ciphernode/sortition/src/sortition.rs`), errors are sent to the event bus using `self.bus.err`, which handles logging and printing. Therefore, explicit use of the `tracing` crate for logging errors may not be necessary in this context.

Applied to files:

  • crates/events/src/lib.rs
  • crates/net/src/document_publisher.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-04-30T06:25:14.721Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 372
File: packages/ciphernode/events/src/eventbus.rs:15-15
Timestamp: 2025-04-30T06:25:14.721Z
Learning: EnclaveEvent implements Display in packages/ciphernode/events/src/enclave_event/mod.rs, which satisfies the Event trait requirement. Static analysis tools may incorrectly flag implementations as missing when they do exist.

Applied to files:

  • crates/events/src/lib.rs
  • crates/events/src/enclave_event/mod.rs
  • crates/net/src/document_publisher.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-08-25T10:28:56.174Z
Learnt from: ctrlc03
Repo: gnosisguild/enclave PR: 657
File: Cargo.toml:32-34
Timestamp: 2025-08-25T10:28:56.174Z
Learning: The examples/CRISP directory has its own Cargo.toml workspace configuration with members like "server", "wasm-crypto", "program/core", "program/client", etc. The root workspace intentionally excludes "examples/CRISP/server", "examples/CRISP/program", and "examples/CRISP/wasm-crypto" to prevent double workspace membership, which is the correct approach for self-contained example workspaces.

Applied to files:

  • crates/ciphernode-builder/Cargo.toml
  • crates/events/Cargo.toml
📚 Learning: 2024-10-22T02:36:01.448Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/data/Cargo.toml:0-0
Timestamp: 2024-10-22T02:36:01.448Z
Learning: In `packages/ciphernode/data/Cargo.toml`, `actix-rt` is only used in tests and should remain in `[dev-dependencies]`.

Applied to files:

  • crates/ciphernode-builder/Cargo.toml
📚 Learning: 2024-10-22T02:10:34.864Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs:82-83
Timestamp: 2024-10-22T02:10:34.864Z
Learning: In the file `packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs`, when reviewing test functions like `generate_pk_share`, minor performance optimizations (e.g., minimizing mutex locks) are not a priority.

Applied to files:

  • crates/ciphernode-builder/src/ciphernode_builder.rs
  • crates/trbfv/tests/integration.rs
  • crates/test-helpers/src/usecase_helpers.rs
  • crates/events/src/enclave_event/mod.rs
  • crates/trbfv/src/shares/mod.rs
  • crates/tests/tests/integration.rs
  • crates/trbfv/src/shares/bfv_encrypted.rs
  • crates/keyshare/src/threshold_keyshare.rs
  • crates/keyshare/src/encryption_key_collector.rs
📚 Learning: 2024-10-08T01:48:49.778Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 139
File: packages/ciphernode/aggregator/src/publickey_aggregator.rs:46-46
Timestamp: 2024-10-08T01:48:49.778Z
Learning: In `packages/ciphernode/router/src/hooks.rs`, the `src_chain_id` parameter in `PublicKeyAggregator::new` is correctly handled, even if not explicitly provided during instantiation.

Applied to files:

  • crates/ciphernode-builder/src/ciphernode_builder.rs
  • crates/net/src/document_publisher.rs
📚 Learning: 2024-10-08T19:45:18.209Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 133
File: packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs:137-139
Timestamp: 2024-10-08T19:45:18.209Z
Learning: In `packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs`, using the same RNG instance `rng_test` for generating multiple key shares without advancing its state is acceptable.

Applied to files:

  • crates/trbfv/tests/integration.rs
  • crates/test-helpers/src/usecase_helpers.rs
  • crates/tests/tests/integration.rs
  • crates/trbfv/src/shares/bfv_encrypted.rs
  • crates/keyshare/src/threshold_keyshare.rs
  • crates/keyshare/src/encryption_key_collector.rs
📚 Learning: 2025-05-07T15:18:20.056Z
Learnt from: 0xjei
Repo: gnosisguild/enclave PR: 388
File: packages/commons/src/bfv/mod.rs:38-48
Timestamp: 2025-05-07T15:18:20.056Z
Learning: The `build_bfv_params` and related functions in the commons BFV utilities intentionally use panic for error handling as a temporary solution. The team plans to refactor these to use proper Result-based error handling in the future.

Applied to files:

  • crates/trbfv/src/shares/mod.rs
📚 Learning: 2025-11-08T01:31:47.505Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 969
File: packages/enclave-sdk/src/enclave-sdk.ts:101-103
Timestamp: 2025-11-08T01:31:47.505Z
Learning: In packages/enclave-sdk/src/enclave-sdk.ts, the TRBFV protocol parameter setup is intentionally incomplete as of PR #969. The constructor sets BFV_THRESHOLD parameters for TRBFV, but the encryption methods (encryptNumber, encryptVector, encryptNumberAndGenInputs, encryptVectorAndGenInputs) intentionally only support BFV and will throw "Protocol not supported" for TRBFV until future implementation is completed.

Applied to files:

  • crates/tests/tests/integration.rs
  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/trbfv/src/shares/bfv_encrypted.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-10-27T15:37:59.138Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 904
File: crates/net/src/bin/p2p_test.rs:22-45
Timestamp: 2025-10-27T15:37:59.138Z
Learning: In test files (especially integration test binaries like p2p_test.rs), suggesting correlation ID filtering for DHT events may be unnecessarily complex since test environments are typically more controlled and false positives are less of a concern.

Applied to files:

  • crates/tests/tests/integration.rs
  • crates/net/src/document_publisher.rs
📚 Learning: 2024-10-16T09:51:10.038Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/router/src/committee_meta.rs:43-43
Timestamp: 2024-10-16T09:51:10.038Z
Learning: In `packages/ciphernode/router/src/committee_meta.rs`, avoid suggesting making the `on_event` method in `CommitteMetaFeature` asynchronous or adding error handling for the `write` operation to the data store.

Applied to files:

  • crates/tests/tests/integration.rs
📚 Learning: 2024-11-05T03:56:22.254Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 170
File: packages/ciphernode/evm/tests/evm_reader.rs:63-63
Timestamp: 2024-11-05T03:56:22.254Z
Learning: In the Rust test function `test_logs` in `packages/ciphernode/evm/tests/evm_reader.rs`, a sleep duration of 1 millisecond is sufficient for reliable event processing, even in CI environments.

Applied to files:

  • crates/net/src/document_publisher.rs
📚 Learning: 2025-05-12T21:12:33.453Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 376
File: packages/ciphernode/sortition/src/sortition.rs:155-164
Timestamp: 2025-05-12T21:12:33.453Z
Learning: When refactoring Rust code to work with collections like HashMaps and moving values into closures, the compiler can sometimes determine that a value won't be used again and allow moving fields out of a borrowed value without requiring an explicit `move` keyword.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-11-05T06:51:46.701Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 173
File: packages/ciphernode/evm/src/event_reader.rs:270-286
Timestamp: 2024-11-05T06:51:46.701Z
Learning: In `packages/ciphernode/evm/src/event_reader.rs`, the `state.ids` HashSet is intended to grow indefinitely to store all processed event IDs for deduplication purposes until an alternative like a bloom filter is implemented.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
🧬 Code graph analysis (10)
crates/ciphernode-builder/src/ciphernode_builder.rs (2)
crates/trbfv/src/helpers.rs (1)
  • get_share_encryption_params (47-50)
crates/keyshare/src/ext.rs (2)
  • create (29-35)
  • create (124-138)
crates/trbfv/tests/integration.rs (2)
crates/test-helpers/src/usecase_helpers.rs (5)
  • generate_shares_hash_map (40-120)
  • get_public_key (122-138)
  • shares (156-165)
  • shares (168-181)
  • get_decryption_keys (140-200)
crates/utils/src/helpers.rs (1)
  • to_ordered_vec (8-20)
crates/test-helpers/src/usecase_helpers.rs (3)
crates/trbfv/src/helpers.rs (1)
  • get_share_encryption_params (47-50)
crates/fhe/src/fhe.rs (1)
  • new (49-51)
crates/trbfv/src/shares/bfv_encrypted.rs (1)
  • encrypt_all (155-176)
crates/keyshare/src/ext.rs (1)
crates/keyshare/src/threshold_keyshare.rs (2)
  • new (189-207)
  • new (319-329)
crates/tests/tests/integration.rs (1)
crates/net/src/bin/p2p_test.rs (1)
  • report (111-114)
crates/events/src/enclave_event/threshold_share_created.rs (2)
crates/test-helpers/src/usecase_helpers.rs (3)
  • shares (156-165)
  • shares (168-181)
  • esi_sss (86-89)
crates/trbfv/src/shares/bfv_encrypted.rs (1)
  • extract_for_party (189-193)
crates/net/src/chunking/collector.rs (2)
crates/events/src/chunk.rs (1)
  • new (53-60)
crates/net/src/chunking/chunkable.rs (1)
  • from_chunks (58-101)
crates/trbfv/src/shares/bfv_encrypted.rs (1)
crates/trbfv/src/helpers.rs (3)
  • deserialize_secret_key (41-44)
  • get_share_encryption_params (47-50)
  • serialize_secret_key (33-38)
crates/keyshare/src/threshold_keyshare.rs (4)
crates/trbfv/src/helpers.rs (2)
  • deserialize_secret_key (41-44)
  • serialize_secret_key (33-38)
crates/keyshare/src/encryption_key_collector.rs (1)
  • setup (75-84)
crates/utils/src/utility_types.rs (1)
  • from_bytes (25-27)
crates/trbfv/src/shares/bfv_encrypted.rs (2)
  • len (196-198)
  • encrypt_all (155-176)
crates/keyshare/src/encryption_key_collector.rs (1)
crates/keyshare/src/threshold_keyshare.rs (1)
  • from (68-72)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: build_sdk
  • GitHub Check: integration_prebuild
  • GitHub Check: rust_unit
  • GitHub Check: rust_integration
  • GitHub Check: build_enclave_cli
  • GitHub Check: build_ciphernode_image
  • GitHub Check: build_crisp_sdk
  • GitHub Check: test_net
🔇 Additional comments (36)
crates/ciphernode-builder/Cargo.toml (1)

25-25: LGTM!

The e3-trbfv workspace dependency is correctly added in alphabetical order and follows the established pattern. This addition aligns with the PR's objective to implement BFV-based share encryption.

crates/events/Cargo.toml (1)

21-21: The hex dependency addition is correct and necessary.

The hex crate is already in use in the events crate source code (crates/events/src/chunk.rs:34 and crates/events/src/seed.rs:36 call hex::encode()), and the dependency is properly configured with hex = "=0.4.3" in the root workspace Cargo.toml. The hex = { workspace = true } declaration in crates/events/Cargo.toml follows the correct pattern for workspace dependencies.

crates/events/src/enclave_event/publish_document/mod.rs (1)

14-14: LGTM! Public re-export enables external Filter usage.

The visibility change from private to public re-export allows external crates to construct DocumentMeta with filters, which is necessary for the chunking and document publishing infrastructure introduced in this PR.

crates/keyshare/src/encryption_key_collector.rs (1)

75-84: LGTM! Clean actor setup with proper initialization.

The setup method correctly initializes the collector with party IDs 0..total, sets up the parent reference, and starts the actor. The design properly separates collection state from the parent ThresholdKeyshare actor.

crates/net/src/lib.rs (1)

7-7: LGTM! Public chunking module export.

The new chunking module is properly exposed, enabling external crates to use the chunking infrastructure for large document transmission.

crates/events/src/lib.rs (1)

8-8: LGTM! Chunk types properly exposed.

The new chunk module and its public re-export make ChunkSetId and ChunkedDocument available at the crate root, following the existing pattern for other event types.

Also applies to: 23-23

crates/tests/tests/integration.rs (1)

290-305: LGTM! Correct synchronization for BFV key exchange phase.

The test now properly waits for all EncryptionKeyCreated events before proceeding to ThresholdShareCreated events, which correctly reflects the new BFV key exchange requirement. The timing instrumentation will help track the performance impact of this additional phase.

crates/net/src/chunking/mod.rs (1)

1-12: LGTM! Clean module organization.

The module properly aggregates chunking functionality, re-exporting the Chunkable trait, ChunkCollector actor, and chunk types from both internal submodules and e3_events. This provides a clean public API surface for the chunking infrastructure.

crates/trbfv/src/shares/mod.rs (1)

6-11: PVW module successfully removed; BFV encryption implementation complete.

The replacement of pvw with bfv_encrypted is clean—no remaining PVW references or artifacts detected in the codebase. The architectural shift from PVW to BFV, which is based on the Learning with Errors (LWE) problem and was proposed by Fan and Vercauteren, aligns with the PR's stated objective to implement BFV-based share encryption.

crates/trbfv/src/helpers.rs (1)

26-44: LGTM!

The SecretKey serialization utilities are well-structured. The use of a simple wrapper struct and bincode for serialization is appropriate.

crates/net/src/chunking/chunkable.rs (2)

12-55: LGTM!

The Chunkable trait and into_chunks implementation are well-designed. The content-based chunk ID generation ensures consistency, and the single-chunk optimization is a nice touch.


57-102: LGTM!

The reassembly logic is robust with comprehensive validation:

  • Empty chunk detection
  • Chunk set consistency checks
  • Duplicate index detection
  • Proper ordering before concatenation
crates/keyshare/src/ext.rs (1)

115-220: LGTM!

The share_encryption_params field is properly integrated throughout the extension lifecycle (create, on_event, hydrate). Using Arc for the parameters is efficient for sharing.

crates/events/src/enclave_event/mod.rs (1)

22-22: LGTM!

The EncryptionKeyCreated event is properly integrated with all necessary wiring points: module declaration, public export, enum variant, get_e3_id matching, and conversion macro.

Also applies to: 51-51, 117-117, 297-297, 329-330

crates/trbfv/tests/integration.rs (1)

86-103: LGTM!

The test correctly adapts to the new GeneratedShares structure, properly accessing both shares and bfv_secret_keys fields.

crates/events/src/enclave_event/threshold_share_created.rs (2)

10-35: LGTM!

The migration from PVW to BFV-encrypted shares is consistent and well-documented. Field types are updated appropriately.


37-58: LGTM!

The helper methods are well-implemented:

  • extract_for_party correctly handles the case where shares might be missing
  • num_parties provides a convenient accessor
crates/test-helpers/src/usecase_helpers.rs (4)

33-38: LGTM!

The GeneratedShares struct cleanly separates the shares from the BFV secret keys, making it clear that the keys are provided for test decryption purposes.


47-62: LGTM!

BFV key generation is properly implemented using OsRng for cryptographic randomness. Each party receives a unique key pair.


64-120: LGTM!

The share generation and BFV encryption flow is correct:

  1. Generate shares with local encryption
  2. Decrypt locally to get plaintext shares
  3. Re-encrypt for all recipients using BFV public keys

This properly separates storage encryption from transport encryption.


140-199: LGTM!

The decryption flow correctly uses party-specific BFV secret keys to decrypt shares. Error handling for missing shares is appropriate.

crates/net/src/chunking/collector.rs (3)

16-32: LGTM - Well-structured actor for chunk collection.

The ChunkCollector struct is cleanly designed with appropriate state tracking for chunk reassembly. The use of PhantomData<T> for the generic type parameter is correct.


51-107: LGTM - Solid chunk handling logic with proper duplicate detection.

The handle_chunk_internal method correctly:

  • Tracks expected totals and start times lazily
  • Detects and ignores duplicate chunks by index
  • Reassembles complete sets using T::from_chunks
  • Cleans up state after successful reassembly

173-197: LGTM - Handler correctly delegates to internal logic and publishes results.

The trait bounds on the Handler impl properly constrain T to be publishable via the event bus.

crates/trbfv/src/shares/bfv_encrypted.rs (3)

61-87: LGTM - Encryption logic correctly iterates over moduli rows.

The encryption method properly:

  • Iterates over each modulus row of the Shamir share
  • Encodes as plaintext with poly encoding
  • Encrypts with the recipient's BFV public key
  • Wraps ciphertext bytes in ArcBytes

98-124: LGTM - Decryption correctly reconstructs the share matrix.

The decryption logic properly reverses the encryption process, reconstructing the 2D array from decrypted plaintexts.


217-246: LGTM - Comprehensive round-trip test for encryption/decryption.

The test correctly validates that a share can be encrypted and decrypted back to its original value.

crates/net/src/document_publisher.rs (5)

34-38: LGTM - Reasonable chunk size for threshold shares.

10MB max chunk size is appropriate for network transmission of large threshold shares.


391-437: LGTM - Clean integration of chunk collector with lazy initialization.

The ensure_chunk_collector method properly creates the collector on-demand when the first chunk is received.


458-498: LGTM - Well-structured party-filtered chunk publishing.

The publish_party_chunks method correctly handles both single-chunk (complete) documents and multi-chunk scenarios with appropriate logging.


500-534: LGTM - Threshold share publishing correctly extracts per-party shares.

The logic properly:

  • Skips external events to avoid re-publishing received shares
  • Extracts shares for each party using extract_for_party
  • Chunks large shares and publishes with party filtering

617-625: LGTM - Handler for EncryptionKeyCreated follows established pattern.

Consistent with other handlers in the file.

crates/keyshare/src/threshold_keyshare.rs (4)

75-80: LGTM - Clean state struct for BFV key collection phase.

The CollectingEncryptionKeysData properly captures the BFV key pair and original event for continuation after collection completes.


396-435: LGTM - BFV key generation and state transition are correct.

The handler properly:

  • Generates BFV keypair using OsRng
  • Encrypts the secret key with the node's cipher for secure storage
  • Transitions to CollectingEncryptionKeys state
  • Publishes EncryptionKeyCreated event for distribution

641-702: LGTM - BFV encryption of shares for all recipients.

The handle_shares_generated method correctly:

  • Retrieves collected BFV public keys from state
  • Deserializes public keys from bytes
  • Decrypts local shares using the node's cipher
  • Encrypts shares for each recipient using their BFV public key
  • Publishes the encrypted shares

706-768: LGTM - BFV decryption of received shares.

The handle_all_threshold_shares_collected method correctly:

  • Retrieves the node's BFV secret key from encrypted storage
  • For each received share, extracts the portion encrypted for this party
  • Decrypts using the node's BFV secret key
  • Passes decrypted shares for aggregation

Comment thread crates/keyshare/src/encryption_key_collector.rs
Comment thread crates/keyshare/src/threshold_keyshare.rs Outdated
Comment thread crates/keyshare/src/threshold_keyshare.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
crates/keyshare/src/threshold_keyshare.rs (2)

518-539: Consider more defensive pattern matching for BFV key presence.

While the current logic is correct (BFV keys are guaranteed to be Some when entering GeneratingThresholdShare), the pattern at line 530 uses wildcards (None, None, _, _) which would silently accept a corrupted state where sk_bfv or collected_encryption_keys is None. For defensive programming, consider checking these explicitly.

🔎 Apply this diff for more defensive pattern matching:
-            let next = match (pk_share, sk_sss, &sk_bfv, &collected_encryption_keys) {
+            let next = match (pk_share, sk_sss, &sk_bfv, &pk_bfv, &collected_encryption_keys) {
                 // If the other shares are here then transition to aggregation
-                (Some(pk_share), Some(sk_sss), Some(sk_bfv_ref), Some(keys)) => {
+                (Some(pk_share), Some(sk_sss), Some(sk_bfv_ref), Some(_), Some(keys)) => {
                     K::AggregatingDecryptionKey(AggregatingDecryptionKey {
                         esi_sss,
                         pk_share,
                         sk_sss,
                         sk_bfv: sk_bfv_ref.clone(),
                         collected_encryption_keys: keys.clone(),
                     })
                 }
                 // If the other shares are not here yet then dont transition
-                (None, None, _, _) => K::GeneratingThresholdShare(GeneratingThresholdShareData {
+                (None, None, Some(sk_bfv), Some(pk_bfv), Some(keys)) => K::GeneratingThresholdShare(GeneratingThresholdShareData {
                     esi_sss: Some(esi_sss),
                     pk_share: None,
                     sk_sss: None,
-                    sk_bfv,
-                    pk_bfv,
-                    collected_encryption_keys,
+                    sk_bfv: Some(sk_bfv.clone()),
+                    pk_bfv: Some(pk_bfv.clone()),
+                    collected_encryption_keys: Some(keys.clone()),
                 }),
                 _ => bail!("Inconsistent state!"),
             };

598-626: Consider more defensive pattern matching for BFV key presence.

Similar to the handle_gen_esi_sss_response logic, the pattern at line 610 uses (None, sk_bfv, _) which accepts any value for sk_bfv and collected_encryption_keys. While the subsequent error cases (lines 621-625) catch some inconsistencies, it would be more defensive to explicitly validate that BFV keys are present when in GeneratingThresholdShare state.

🔎 Apply this diff for more defensive pattern matching:
-            let next = match (esi_sss, sk_bfv, &collected_encryption_keys) {
-                // If the esi shares and BFV key are here then transition to aggregation
-                (Some(esi_sss), Some(sk_bfv), Some(keys)) => {
+            let next = match (esi_sss, sk_bfv, &pk_bfv, &collected_encryption_keys) {
+                // If esi shares and BFV keys are here then transition to aggregation
+                (Some(esi_sss), Some(sk_bfv), Some(_), Some(keys)) => {
                     KeyshareState::AggregatingDecryptionKey(AggregatingDecryptionKey {
                         esi_sss,
                         pk_share,
                         sk_sss,
                         sk_bfv,
                         collected_encryption_keys: keys.clone(),
                     })
                 }
-                // If esi shares are not here yet then don't transition
-                (None, sk_bfv, _) => {
+                // If esi shares are not here yet but BFV keys are present, don't transition
+                (None, Some(sk_bfv), Some(pk_bfv), Some(keys)) => {
                     KeyshareState::GeneratingThresholdShare(GeneratingThresholdShareData {
                         esi_sss: None,
                         pk_share: Some(pk_share),
                         sk_sss: Some(sk_sss),
-                        sk_bfv,
-                        pk_bfv,
-                        collected_encryption_keys,
+                        sk_bfv: Some(sk_bfv),
+                        pk_bfv: Some(pk_bfv.clone()),
+                        collected_encryption_keys: Some(keys.clone()),
                     })
                 }
                 // If we have esi_sss but no sk_bfv, that's an error
-                (Some(_), None, _) => bail!("Have esi_sss but no sk_bfv - inconsistent state!"),
+                (Some(_), None, _, _) => bail!("Have esi_sss but no sk_bfv - inconsistent state!"),
+                // If we don't have esi_sss and missing BFV keys, that's an error too
+                (None, None, _, _) | (None, _, None, _) | (None, _, _, None) => {
+                    bail!("Missing BFV keys in GeneratingThresholdShare state!")
+                }
                 // If we have shares ready but no encryption keys, that's an error
-                (Some(_), Some(_), None) => {
+                (Some(_), Some(_), _, None) => {
                     bail!("Have shares but no collected encryption keys - inconsistent state!")
                 }
             };
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 96acb34 and c61c80d.

📒 Files selected for processing (2)
  • crates/keyshare/src/threshold_keyshare.rs (23 hunks)
  • crates/net/src/document_publisher.rs (8 hunks)
🧰 Additional context used
🧠 Learnings (18)
📓 Common learnings
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 660
File: crates/events/src/enclave_event/decryptionshare_created.rs:23-26
Timestamp: 2025-10-04T14:00:17.916Z
Learning: In the enclave codebase using threshold BFV cryptography, decryption shares (as in DecryptionshareCreated events) are not sensitive data and can be safely logged or displayed, as individual shares reveal nothing without reaching the threshold number of shares.
📚 Learning: 2024-09-26T03:11:29.311Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 107
File: packages/ciphernode/sortition/src/distance.rs:1-1
Timestamp: 2024-09-26T03:11:29.311Z
Learning: In `packages/ciphernode/core/src/events.rs`, the import statements use the correct and updated `alloy::primitives` module.

Applied to files:

  • crates/net/src/document_publisher.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-10-27T15:37:59.138Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 904
File: crates/net/src/bin/p2p_test.rs:22-45
Timestamp: 2025-10-27T15:37:59.138Z
Learning: In test files (especially integration test binaries like p2p_test.rs), suggesting correlation ID filtering for DHT events may be unnecessarily complex since test environments are typically more controlled and false positives are less of a concern.

Applied to files:

  • crates/net/src/document_publisher.rs
📚 Learning: 2025-04-30T06:25:14.721Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 372
File: packages/ciphernode/events/src/eventbus.rs:15-15
Timestamp: 2025-04-30T06:25:14.721Z
Learning: EnclaveEvent implements Display in packages/ciphernode/events/src/enclave_event/mod.rs, which satisfies the Event trait requirement. Static analysis tools may incorrectly flag implementations as missing when they do exist.

Applied to files:

  • crates/net/src/document_publisher.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-10T23:24:43.341Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 143
File: packages/ciphernode/sortition/src/sortition.rs:4-9
Timestamp: 2024-10-10T23:24:43.341Z
Learning: In the `Sortition` module (`packages/ciphernode/sortition/src/sortition.rs`), errors are sent to the event bus using `self.bus.err`, which handles logging and printing. Therefore, explicit use of the `tracing` crate for logging errors may not be necessary in this context.

Applied to files:

  • crates/net/src/document_publisher.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-11-05T03:56:22.254Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 170
File: packages/ciphernode/evm/tests/evm_reader.rs:63-63
Timestamp: 2024-11-05T03:56:22.254Z
Learning: In the Rust test function `test_logs` in `packages/ciphernode/evm/tests/evm_reader.rs`, a sleep duration of 1 millisecond is sufficient for reliable event processing, even in CI environments.

Applied to files:

  • crates/net/src/document_publisher.rs
📚 Learning: 2025-10-04T14:00:17.916Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 660
File: crates/events/src/enclave_event/decryptionshare_created.rs:23-26
Timestamp: 2025-10-04T14:00:17.916Z
Learning: In the enclave codebase using threshold BFV cryptography, decryption shares (as in DecryptionshareCreated events) are not sensitive data and can be safely logged or displayed, as individual shares reveal nothing without reaching the threshold number of shares.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-11-08T01:31:47.505Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 969
File: packages/enclave-sdk/src/enclave-sdk.ts:101-103
Timestamp: 2025-11-08T01:31:47.505Z
Learning: In packages/enclave-sdk/src/enclave-sdk.ts, the TRBFV protocol parameter setup is intentionally incomplete as of PR #969. The constructor sets BFV_THRESHOLD parameters for TRBFV, but the encryption methods (encryptNumber, encryptVector, encryptNumberAndGenInputs, encryptVectorAndGenInputs) intentionally only support BFV and will throw "Protocol not supported" for TRBFV until future implementation is completed.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-22T02:10:34.864Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs:82-83
Timestamp: 2024-10-22T02:10:34.864Z
Learning: In the file `packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs`, when reviewing test functions like `generate_pk_share`, minor performance optimizations (e.g., minimizing mutex locks) are not a priority.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-23T02:35:07.689Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/keyshare.rs:58-65
Timestamp: 2024-10-23T02:35:07.689Z
Learning: In `packages/ciphernode/keyshare/src/keyshare.rs`, the data being decrypted in the `get_secret` method of the `Keyshare` struct is not sensitive, so wrapping it with `Zeroizing` is unnecessary.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-29T01:04:19.137Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/keyshare.rs:53-70
Timestamp: 2024-10-29T01:04:19.137Z
Learning: In the `Keyshare` struct within `packages/ciphernode/keyshare/src/keyshare.rs`, the `self.secret` field is stored in encrypted form and is not considered sensitive.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-05-12T21:12:33.453Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 376
File: packages/ciphernode/sortition/src/sortition.rs:155-164
Timestamp: 2025-05-12T21:12:33.453Z
Learning: When refactoring Rust code to work with collections like HashMaps and moving values into closures, the compiler can sometimes determine that a value won't be used again and allow moving fields out of a borrowed value without requiring an explicit `move` keyword.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-22T03:39:29.448Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/evm/src/enclave_sol_reader.rs:87-89
Timestamp: 2024-10-22T03:39:29.448Z
Learning: In the `ciphernode` project, specifically in `packages/ciphernode/evm/src/enclave_sol_reader.rs`, the method `EnclaveSolReader::attach` should be retained even if it directly calls `EvmEventReader::attach` without additional processing. Avoid suggesting its removal in future reviews.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-11-05T06:49:46.285Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 173
File: packages/ciphernode/enclave_node/src/datastore.rs:14-16
Timestamp: 2024-11-05T06:49:46.285Z
Learning: In `packages/ciphernode/enclave_node/src/datastore.rs`, for internal functions like `get_in_mem_store`, adding extensive documentation and error handling may not be necessary if they are not client-facing.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-16T09:51:10.038Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/router/src/committee_meta.rs:43-43
Timestamp: 2024-10-16T09:51:10.038Z
Learning: In `packages/ciphernode/router/src/committee_meta.rs`, avoid suggesting making the `on_event` method in `CommitteMetaFeature` asynchronous or adding error handling for the `write` operation to the data store.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-11-05T06:51:46.701Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 173
File: packages/ciphernode/evm/src/event_reader.rs:270-286
Timestamp: 2024-11-05T06:51:46.701Z
Learning: In `packages/ciphernode/evm/src/event_reader.rs`, the `state.ids` HashSet is intended to grow indefinitely to store all processed event IDs for deduplication purposes until an alternative like a bloom filter is implemented.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-08T19:45:18.209Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 133
File: packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs:137-139
Timestamp: 2024-10-08T19:45:18.209Z
Learning: In `packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs`, using the same RNG instance `rng_test` for generating multiple key shares without advancing its state is acceptable.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-23T02:03:02.008Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/encryption.rs:45-45
Timestamp: 2024-10-23T02:03:02.008Z
Learning: In the `packages/ciphernode/keyshare/src/encryption.rs` file, the environment variable `CIPHERNODE_SECRET` is used for the encryption password. A secure secret management solution is not currently available, but may be considered in future iterations.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
🧬 Code graph analysis (2)
crates/net/src/document_publisher.rs (5)
crates/net/src/chunking/chunkable.rs (2)
  • max_chunk_size (14-16)
  • max_chunk_size (115-117)
crates/events/src/enclave_event/publish_document/mod.rs (2)
  • new (45-59)
  • new (84-87)
crates/net/src/chunking/collector.rs (1)
  • setup (47-49)
crates/events/src/enclave_event/mod.rs (1)
  • from_bytes (173-175)
crates/events/src/enclave_event/threshold_share_created.rs (1)
  • num_parties (55-57)
crates/keyshare/src/threshold_keyshare.rs (4)
crates/trbfv/src/helpers.rs (2)
  • deserialize_secret_key (41-44)
  • serialize_secret_key (33-38)
crates/keyshare/src/encryption_key_collector.rs (1)
  • setup (75-84)
crates/utils/src/utility_types.rs (1)
  • from_bytes (25-27)
crates/trbfv/src/shares/bfv_encrypted.rs (2)
  • len (196-198)
  • encrypt_all (155-176)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: build_ciphernode_image
  • GitHub Check: build_e3_support_dev
  • GitHub Check: build_sdk
  • GitHub Check: integration_prebuild
  • GitHub Check: test_enclave_circuits
  • GitHub Check: build_enclave_cli
  • GitHub Check: build_crisp_sdk
  • GitHub Check: test_net
🔇 Additional comments (8)
crates/keyshare/src/threshold_keyshare.rs (2)

640-701: LGTM! Secure share encryption implementation.

The BFV encryption flow is correctly implemented:

  • Public keys are deserialized with proper error handling
  • Local shares are decrypted, encrypted for each recipient using their BFV public key, and then the plaintext is discarded
  • Each party receives only their share, encrypted with their own public key
  • Cryptographically secure RNG (OsRng) is used for encryption

706-767: LGTM! Correct BFV share decryption and aggregation.

The decryption flow correctly:

  • Retrieves and decrypts the BFV secret key from encrypted storage
  • Extracts each party's share from the received encrypted collections
  • Decrypts shares using the BFV secret key
  • Re-encrypts for local compute operations
  • Handles missing shares with appropriate error messages

Based on learnings, individual Shamir shares are not considered sensitive enough to require explicit zeroization in this codebase.

crates/net/src/document_publisher.rs (6)

34-38: LGTM! Appropriate chunk size for encrypted shares.

Setting a 10 MB chunk size for ThresholdShareCreated is reasonable given that BFV-encrypted shares can be quite large, especially with multiple parties.


393-393: Excellent! Critical fix for per-E3ID chunk collection.

This implementation correctly addresses the critical issue flagged in a previous review where chunks from different E3 IDs would be incorrectly routed to a single global collector. Now each E3 ID maintains its own ChunkCollector, ensuring correct reassembly of multi-chunk documents.

Also applies to: 429-434


436-495: LGTM! Well-structured party-filtered publishing with chunking support.

The helper methods correctly:

  • Apply party filtering to ensure each party only receives their specific shares
  • Optimize single-chunk messages by publishing directly as ThresholdShareCreated
  • Handle multi-chunk messages by publishing individual chunks for reassembly
  • Include helpful logging for debugging

499-531: LGTM! Efficient party-filtered threshold share distribution.

The implementation correctly:

  • Prevents re-publishing of external shares
  • Extracts per-party shares from the full threshold share
  • Creates party-specific messages with appropriate chunking
  • Distributes shares such that each party only receives their encrypted shares

This is more efficient than broadcasting all shares to all parties.


532-542: LGTM! Correct broadcast of encryption keys to all parties.

BFV public keys are correctly broadcast to all parties (empty filter) since each party needs all other parties' public keys to encrypt shares for them. This is the expected behavior for the key exchange phase.


546-583: LGTM! Correct document-to-event conversion with chunk reassembly.

The implementation correctly:

  • Deserializes received documents to the appropriate event types
  • Marks network-received events with external: true to prevent re-publishing
  • Routes chunks to the per-E3ID collector for reassembly
  • Relies on upstream filtering (already done in DocumentPublisher) to ensure only relevant documents are processed

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
crates/net/src/document_publisher.rs (1)

34-38: Consider using the trait default instead of duplicating the value.

The Chunkable trait already provides a default max_chunk_size() of 10MB (per the relevant code snippet in chunking/chunkable.rs). This implementation duplicates that value.

Suggested simplification:
-impl Chunkable for ThresholdShareCreated {
-    fn max_chunk_size() -> usize {
-        10 * 1024 * 1024
-    }
-}
+impl Chunkable for ThresholdShareCreated {}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c61c80d and 7a6506c.

📒 Files selected for processing (1)
  • crates/net/src/document_publisher.rs (8 hunks)
🧰 Additional context used
🧠 Learnings (6)
📓 Common learnings
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 660
File: crates/events/src/enclave_event/decryptionshare_created.rs:23-26
Timestamp: 2025-10-04T14:00:17.916Z
Learning: In the enclave codebase using threshold BFV cryptography, decryption shares (as in DecryptionshareCreated events) are not sensitive data and can be safely logged or displayed, as individual shares reveal nothing without reaching the threshold number of shares.
📚 Learning: 2024-09-26T03:11:29.311Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 107
File: packages/ciphernode/sortition/src/distance.rs:1-1
Timestamp: 2024-09-26T03:11:29.311Z
Learning: In `packages/ciphernode/core/src/events.rs`, the import statements use the correct and updated `alloy::primitives` module.

Applied to files:

  • crates/net/src/document_publisher.rs
📚 Learning: 2025-10-27T15:37:59.138Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 904
File: crates/net/src/bin/p2p_test.rs:22-45
Timestamp: 2025-10-27T15:37:59.138Z
Learning: In test files (especially integration test binaries like p2p_test.rs), suggesting correlation ID filtering for DHT events may be unnecessarily complex since test environments are typically more controlled and false positives are less of a concern.

Applied to files:

  • crates/net/src/document_publisher.rs
📚 Learning: 2025-04-30T06:25:14.721Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 372
File: packages/ciphernode/events/src/eventbus.rs:15-15
Timestamp: 2025-04-30T06:25:14.721Z
Learning: EnclaveEvent implements Display in packages/ciphernode/events/src/enclave_event/mod.rs, which satisfies the Event trait requirement. Static analysis tools may incorrectly flag implementations as missing when they do exist.

Applied to files:

  • crates/net/src/document_publisher.rs
📚 Learning: 2024-10-10T23:24:43.341Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 143
File: packages/ciphernode/sortition/src/sortition.rs:4-9
Timestamp: 2024-10-10T23:24:43.341Z
Learning: In the `Sortition` module (`packages/ciphernode/sortition/src/sortition.rs`), errors are sent to the event bus using `self.bus.err`, which handles logging and printing. Therefore, explicit use of the `tracing` crate for logging errors may not be necessary in this context.

Applied to files:

  • crates/net/src/document_publisher.rs
📚 Learning: 2024-11-05T03:56:22.254Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 170
File: packages/ciphernode/evm/tests/evm_reader.rs:63-63
Timestamp: 2024-11-05T03:56:22.254Z
Learning: In the Rust test function `test_logs` in `packages/ciphernode/evm/tests/evm_reader.rs`, a sleep duration of 1 millisecond is sufficient for reliable event processing, even in CI environments.

Applied to files:

  • crates/net/src/document_publisher.rs
🧬 Code graph analysis (1)
crates/net/src/document_publisher.rs (3)
crates/net/src/chunking/chunkable.rs (2)
  • max_chunk_size (14-16)
  • max_chunk_size (115-117)
crates/net/src/chunking/collector.rs (1)
  • setup (47-49)
crates/events/src/enclave_event/threshold_share_created.rs (1)
  • num_parties (55-57)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: build_sdk
  • GitHub Check: test_net
  • GitHub Check: build_crisp_sdk
  • GitHub Check: build_ciphernode_image
  • GitHub Check: rust_unit
  • GitHub Check: build_e3_support_dev
  • GitHub Check: rust_integration
  • GitHub Check: integration_prebuild
  • GitHub Check: build_enclave_cli
🔇 Additional comments (7)
crates/net/src/document_publisher.rs (7)

80-88: LGTM!

Correctly extended to recognize EncryptionKeyCreated events for document publishing.


391-394: Good fix for the chunk routing issue.

The per-E3ID collector mapping correctly addresses the previous critical issue where chunks from different E3 IDs were routed to a single collector.


460-500: LGTM!

The branching logic correctly handles both single complete chunks (direct publish) and multi-chunk cases (per-chunk publish). This optimization avoids chunk collection overhead for small documents.


502-536: LGTM!

The party-filtered distribution logic correctly extracts per-party shares and publishes them with appropriate filters. Error handling for failed extractions is properly implemented.


537-547: LGTM!

The empty filter vec![] correctly broadcasts the encryption key to all interested parties, as opposed to the party-specific filtering used for threshold shares.


396-411: LGTM!

The ReceivableDocument enum correctly extends to support the new EncryptionKeyCreated and Chunk variants with appropriate serialization.


617-625: LGTM!

Handler follows the established pattern used by other message handlers in this file.

Comment thread crates/net/src/document_publisher.rs Outdated
Comment thread crates/net/src/document_publisher.rs Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
crates/events/src/enclave_event/threshold_share_created.rs (1)

55-57: Consider defensive validation for consistency.

The method assumes all share collections have the same length, which is reasonable for well-formed instances. However, adding an assertion or debug check could catch malformed data during development.

🔎 Optional: Add debug assertion for consistency
 pub fn num_parties(&self) -> usize {
+    debug_assert!(
+        self.esi_sss.iter().all(|shares| shares.len() == self.sk_sss.len()),
+        "All share collections should have the same length"
+    );
     self.sk_sss.len()
 }
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aa55989 and 0db7342.

📒 Files selected for processing (1)
  • crates/events/src/enclave_event/threshold_share_created.rs
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 660
File: crates/events/src/enclave_event/decryptionshare_created.rs:23-26
Timestamp: 2025-10-04T14:00:17.916Z
Learning: In the enclave codebase using threshold BFV cryptography, decryption shares (as in DecryptionshareCreated events) are not sensitive data and can be safely logged or displayed, as individual shares reveal nothing without reaching the threshold number of shares.
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 969
File: packages/enclave-sdk/src/enclave-sdk.ts:101-103
Timestamp: 2025-11-08T01:31:47.505Z
Learning: In packages/enclave-sdk/src/enclave-sdk.ts, the TRBFV protocol parameter setup is intentionally incomplete as of PR #969. The constructor sets BFV_THRESHOLD parameters for TRBFV, but the encryption methods (encryptNumber, encryptVector, encryptNumberAndGenInputs, encryptVectorAndGenInputs) intentionally only support BFV and will throw "Protocol not supported" for TRBFV until future implementation is completed.
📚 Learning: 2025-10-04T14:00:17.916Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 660
File: crates/events/src/enclave_event/decryptionshare_created.rs:23-26
Timestamp: 2025-10-04T14:00:17.916Z
Learning: In the enclave codebase using threshold BFV cryptography, decryption shares (as in DecryptionshareCreated events) are not sensitive data and can be safely logged or displayed, as individual shares reveal nothing without reaching the threshold number of shares.

Applied to files:

  • crates/events/src/enclave_event/threshold_share_created.rs
📚 Learning: 2025-11-08T01:31:47.505Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 969
File: packages/enclave-sdk/src/enclave-sdk.ts:101-103
Timestamp: 2025-11-08T01:31:47.505Z
Learning: In packages/enclave-sdk/src/enclave-sdk.ts, the TRBFV protocol parameter setup is intentionally incomplete as of PR #969. The constructor sets BFV_THRESHOLD parameters for TRBFV, but the encryption methods (encryptNumber, encryptVector, encryptNumberAndGenInputs, encryptVectorAndGenInputs) intentionally only support BFV and will throw "Protocol not supported" for TRBFV until future implementation is completed.

Applied to files:

  • crates/events/src/enclave_event/threshold_share_created.rs
📚 Learning: 2024-10-29T01:04:19.137Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/keyshare.rs:53-70
Timestamp: 2024-10-29T01:04:19.137Z
Learning: In the `Keyshare` struct within `packages/ciphernode/keyshare/src/keyshare.rs`, the `self.secret` field is stored in encrypted form and is not considered sensitive.

Applied to files:

  • crates/events/src/enclave_event/threshold_share_created.rs
📚 Learning: 2024-10-23T02:35:07.689Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/keyshare.rs:58-65
Timestamp: 2024-10-23T02:35:07.689Z
Learning: In `packages/ciphernode/keyshare/src/keyshare.rs`, the data being decrypted in the `get_secret` method of the `Keyshare` struct is not sensitive, so wrapping it with `Zeroizing` is unnecessary.

Applied to files:

  • crates/events/src/enclave_event/threshold_share_created.rs
📚 Learning: 2024-09-26T03:11:29.311Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 107
File: packages/ciphernode/sortition/src/distance.rs:1-1
Timestamp: 2024-09-26T03:11:29.311Z
Learning: In `packages/ciphernode/core/src/events.rs`, the import statements use the correct and updated `alloy::primitives` module.

Applied to files:

  • crates/events/src/enclave_event/threshold_share_created.rs
📚 Learning: 2024-10-23T02:03:02.008Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/encryption.rs:45-45
Timestamp: 2024-10-23T02:03:02.008Z
Learning: In the `packages/ciphernode/keyshare/src/encryption.rs` file, the environment variable `CIPHERNODE_SECRET` is used for the encryption password. A secure secret management solution is not currently available, but may be considered in future iterations.

Applied to files:

  • crates/events/src/enclave_event/threshold_share_created.rs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: crisp_unit
  • GitHub Check: build_enclave_cli
  • GitHub Check: rust_integration
  • GitHub Check: test_net
  • GitHub Check: integration_prebuild
  • GitHub Check: build_ciphernode_image
  • GitHub Check: rust_unit
🔇 Additional comments (2)
crates/events/src/enclave_event/threshold_share_created.rs (2)

10-11: LGTM! Imports updated for BFV migration.

The imports correctly bring in BfvEncryptedShares to replace the previous PVW-based types.


18-35: LGTM! ThresholdShare struct updated for BFV encryption.

The struct definition correctly uses BfvEncryptedShares types and the documentation clearly describes the BFV-based per-recipient encryption semantics.

Comment thread crates/events/src/enclave_event/threshold_share_created.rs
@vercel vercel Bot temporarily deployed to Preview – crisp December 24, 2025 18:25 Inactive
@vercel vercel Bot temporarily deployed to Preview – enclave-docs December 24, 2025 18:25 Inactive

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0db7342 and 999d5ac.

📒 Files selected for processing (4)
  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/keyshare/src/threshold_keyshare.rs
  • crates/net/src/document_publisher.rs
  • crates/tests/tests/integration.rs
🧰 Additional context used
🧠 Learnings (18)
📓 Common learnings
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 660
File: crates/events/src/enclave_event/decryptionshare_created.rs:23-26
Timestamp: 2025-10-04T14:00:17.916Z
Learning: In the enclave codebase using threshold BFV cryptography, decryption shares (as in DecryptionshareCreated events) are not sensitive data and can be safely logged or displayed, as individual shares reveal nothing without reaching the threshold number of shares.
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 969
File: packages/enclave-sdk/src/enclave-sdk.ts:101-103
Timestamp: 2025-11-08T01:31:47.505Z
Learning: In packages/enclave-sdk/src/enclave-sdk.ts, the TRBFV protocol parameter setup is intentionally incomplete as of PR #969. The constructor sets BFV_THRESHOLD parameters for TRBFV, but the encryption methods (encryptNumber, encryptVector, encryptNumberAndGenInputs, encryptVectorAndGenInputs) intentionally only support BFV and will throw "Protocol not supported" for TRBFV until future implementation is completed.
📚 Learning: 2024-10-22T02:10:34.864Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs:82-83
Timestamp: 2024-10-22T02:10:34.864Z
Learning: In the file `packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs`, when reviewing test functions like `generate_pk_share`, minor performance optimizations (e.g., minimizing mutex locks) are not a priority.

Applied to files:

  • crates/tests/tests/integration.rs
  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-08T19:45:18.209Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 133
File: packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs:137-139
Timestamp: 2024-10-08T19:45:18.209Z
Learning: In `packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs`, using the same RNG instance `rng_test` for generating multiple key shares without advancing its state is acceptable.

Applied to files:

  • crates/tests/tests/integration.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-11-08T01:31:47.505Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 969
File: packages/enclave-sdk/src/enclave-sdk.ts:101-103
Timestamp: 2025-11-08T01:31:47.505Z
Learning: In packages/enclave-sdk/src/enclave-sdk.ts, the TRBFV protocol parameter setup is intentionally incomplete as of PR #969. The constructor sets BFV_THRESHOLD parameters for TRBFV, but the encryption methods (encryptNumber, encryptVector, encryptNumberAndGenInputs, encryptVectorAndGenInputs) intentionally only support BFV and will throw "Protocol not supported" for TRBFV until future implementation is completed.

Applied to files:

  • crates/tests/tests/integration.rs
  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-10-04T14:00:17.916Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 660
File: crates/events/src/enclave_event/decryptionshare_created.rs:23-26
Timestamp: 2025-10-04T14:00:17.916Z
Learning: In the enclave codebase using threshold BFV cryptography, decryption shares (as in DecryptionshareCreated events) are not sensitive data and can be safely logged or displayed, as individual shares reveal nothing without reaching the threshold number of shares.

Applied to files:

  • crates/tests/tests/integration.rs
  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/keyshare/src/threshold_keyshare.rs
  • crates/net/src/document_publisher.rs
📚 Learning: 2024-10-08T19:45:18.209Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 107
File: packages/ciphernode/sortition/src/distance.rs:1-1
Timestamp: 2024-10-08T19:45:18.209Z
Learning: In `packages/ciphernode/core/src/events.rs`, the import statements use the correct and updated `alloy::primitives` module.

Applied to files:

  • crates/tests/tests/integration.rs
  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/keyshare/src/threshold_keyshare.rs
  • crates/net/src/document_publisher.rs
📚 Learning: 2024-11-05T03:56:22.254Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 170
File: packages/ciphernode/evm/tests/evm_reader.rs:63-63
Timestamp: 2024-11-05T03:56:22.254Z
Learning: In the Rust test function `test_logs` in `packages/ciphernode/evm/tests/evm_reader.rs`, a sleep duration of 1 millisecond is sufficient for reliable event processing, even in CI environments.

Applied to files:

  • crates/tests/tests/integration.rs
  • crates/net/src/document_publisher.rs
📚 Learning: 2024-10-29T01:04:19.137Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/keyshare.rs:53-70
Timestamp: 2024-10-29T01:04:19.137Z
Learning: In the `Keyshare` struct within `packages/ciphernode/keyshare/src/keyshare.rs`, the `self.secret` field is stored in encrypted form and is not considered sensitive.

Applied to files:

  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-23T02:35:07.689Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/keyshare.rs:58-65
Timestamp: 2024-10-23T02:35:07.689Z
Learning: In `packages/ciphernode/keyshare/src/keyshare.rs`, the data being decrypted in the `get_secret` method of the `Keyshare` struct is not sensitive, so wrapping it with `Zeroizing` is unnecessary.

Applied to files:

  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-23T02:03:02.008Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/encryption.rs:45-45
Timestamp: 2024-10-23T02:03:02.008Z
Learning: In the `packages/ciphernode/keyshare/src/encryption.rs` file, the environment variable `CIPHERNODE_SECRET` is used for the encryption password. A secure secret management solution is not currently available, but may be considered in future iterations.

Applied to files:

  • crates/events/src/enclave_event/threshold_share_created.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-05-12T21:12:33.453Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 376
File: packages/ciphernode/sortition/src/sortition.rs:155-164
Timestamp: 2025-05-12T21:12:33.453Z
Learning: When refactoring Rust code to work with collections like HashMaps and moving values into closures, the compiler can sometimes determine that a value won't be used again and allow moving fields out of a borrowed value without requiring an explicit `move` keyword.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-22T03:39:29.448Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/evm/src/enclave_sol_reader.rs:87-89
Timestamp: 2024-10-22T03:39:29.448Z
Learning: In the `ciphernode` project, specifically in `packages/ciphernode/evm/src/enclave_sol_reader.rs`, the method `EnclaveSolReader::attach` should be retained even if it directly calls `EvmEventReader::attach` without additional processing. Avoid suggesting its removal in future reviews.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
  • crates/net/src/document_publisher.rs
📚 Learning: 2024-10-16T09:51:10.038Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/router/src/committee_meta.rs:43-43
Timestamp: 2024-10-16T09:51:10.038Z
Learning: In `packages/ciphernode/router/src/committee_meta.rs`, avoid suggesting making the `on_event` method in `CommitteMetaFeature` asynchronous or adding error handling for the `write` operation to the data store.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-04-30T06:25:14.721Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 372
File: packages/ciphernode/events/src/eventbus.rs:15-15
Timestamp: 2025-04-30T06:25:14.721Z
Learning: EnclaveEvent implements Display in packages/ciphernode/events/src/enclave_event/mod.rs, which satisfies the Event trait requirement. Static analysis tools may incorrectly flag implementations as missing when they do exist.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
  • crates/net/src/document_publisher.rs
📚 Learning: 2024-11-05T06:49:46.285Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 173
File: packages/ciphernode/enclave_node/src/datastore.rs:14-16
Timestamp: 2024-11-05T06:49:46.285Z
Learning: In `packages/ciphernode/enclave_node/src/datastore.rs`, for internal functions like `get_in_mem_store`, adding extensive documentation and error handling may not be necessary if they are not client-facing.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-11-05T06:51:46.701Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 173
File: packages/ciphernode/evm/src/event_reader.rs:270-286
Timestamp: 2024-11-05T06:51:46.701Z
Learning: In `packages/ciphernode/evm/src/event_reader.rs`, the `state.ids` HashSet is intended to grow indefinitely to store all processed event IDs for deduplication purposes until an alternative like a bloom filter is implemented.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
  • crates/net/src/document_publisher.rs
📚 Learning: 2025-10-27T15:37:59.138Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 904
File: crates/net/src/bin/p2p_test.rs:22-45
Timestamp: 2025-10-27T15:37:59.138Z
Learning: In test files (especially integration test binaries like p2p_test.rs), suggesting correlation ID filtering for DHT events may be unnecessarily complex since test environments are typically more controlled and false positives are less of a concern.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
  • crates/net/src/document_publisher.rs
📚 Learning: 2024-10-10T23:24:43.341Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 143
File: packages/ciphernode/sortition/src/sortition.rs:4-9
Timestamp: 2024-10-10T23:24:43.341Z
Learning: In the `Sortition` module (`packages/ciphernode/sortition/src/sortition.rs`), errors are sent to the event bus using `self.bus.err`, which handles logging and printing. Therefore, explicit use of the `tracing` crate for logging errors may not be necessary in this context.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
  • crates/net/src/document_publisher.rs
🧬 Code graph analysis (2)
crates/events/src/enclave_event/threshold_share_created.rs (1)
crates/trbfv/src/shares/bfv_encrypted.rs (1)
  • extract_for_party (189-193)
crates/keyshare/src/threshold_keyshare.rs (6)
crates/trbfv/src/helpers.rs (2)
  • deserialize_secret_key (41-44)
  • serialize_secret_key (33-38)
crates/keyshare/src/encryption_key_collector.rs (1)
  • setup (75-84)
crates/events/src/enclave_event/mod.rs (1)
  • from_bytes (173-175)
crates/utils/src/utility_types.rs (1)
  • from_bytes (25-27)
crates/trbfv/src/shares/bfv_encrypted.rs (2)
  • len (196-198)
  • encrypt_all (155-176)
crates/events/src/enclave_event/threshold_share_created.rs (1)
  • num_parties (55-57)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: integration_prebuild
  • GitHub Check: build_e3_support_dev
  • GitHub Check: build_sdk
  • GitHub Check: build_enclave_cli
  • GitHub Check: test_net
  • GitHub Check: build_crisp_sdk
  • GitHub Check: build_ciphernode_image
  • GitHub Check: rust_unit
  • GitHub Check: rust_integration
🔇 Additional comments (11)
crates/tests/tests/integration.rs (1)

290-315: LGTM! Test flow correctly implements BFV key exchange sequence.

The test now properly waits for the two-phase protocol:

  1. BFV key collection: 5 EncryptionKeyCreated events (one per party)
  2. Share distribution: 25 ThresholdShareCreated events (5 parties × 5 targets)

This aligns with the per-recipient BFV encryption flow described in the PR objectives.

crates/events/src/enclave_event/threshold_share_created.rs (2)

37-58: LGTM! Per-party extraction logic is correct.

The extract_for_party method correctly:

  • Extracts the recipient's share from both sk_sss and esi_sss
  • Propagates None if any extraction fails (using collect::<Option<Vec<_>>>)
  • Preserves party_id and pk_share from the original share

The usize parameter type is consistent with BfvEncryptedShares::extract_for_party API (see crates/trbfv/src/shares/bfv_encrypted.rs:188).


65-65: LGTM! Field addition enables per-party filtering.

The target_party_id field correctly identifies the intended recipient of each share, enabling the per-party document filtering described in the PR objectives.

crates/net/src/document_publisher.rs (4)

416-433: LGTM! Helper method correctly implements per-party filtering.

The publish_filtered method appropriately:

  • Serializes the receivable document
  • Creates metadata with Filter::Item(party_id) for per-party routing
  • Publishes the filtered document request

This aligns with the per-recipient filtering objective described in the PR.


437-455: LGTM! Threshold share publishing correctly implements party filtering.

The method properly:

  • Skips external (already received) shares to prevent loops
  • Publishes using target_party_id for per-recipient filtering
  • Logs the publishing action at info level

This implements the domain-level per-party splitting described in the PR objectives.


456-466: LGTM! Encryption key publishing correctly broadcasts to all parties.

The method appropriately:

  • Skips external events to prevent loops
  • Uses an empty filter vec![] to broadcast BFV public keys to all parties

Broadcasting is correct here because each party needs all other parties' BFV public keys to encrypt shares for them.


470-498: LGTM! Document reception correctly marks events as external.

The method properly:

  • Deserializes received documents
  • Sets external: true when publishing to the local bus
  • Handles both ThresholdShareCreated and EncryptionKeyCreated variants

The external: true flag prevents re-publishing loops (as noted in past review comments, addressed in commit 47ba25f).

crates/keyshare/src/threshold_keyshare.rs (4)

407-446: LGTM! BFV key generation follows secure practices.

The method correctly:

  • Uses OsRng for cryptographically secure key generation
  • Encrypts the BFV secret key with SensitiveBytes before persisting
  • Stores the public key as ArcBytes (not sensitive)
  • Transitions to CollectingEncryptionKeys state
  • Publishes EncryptionKeyCreated with external: false (locally generated)

Based on learnings, encrypted secrets are appropriately handled in this codebase.


448-478: LGTM! Encryption key collection transition is correct.

The method properly:

  • Extracts CollectingEncryptionKeysData from current state
  • Transitions to GeneratingThresholdShare with BFV keys and collected encryption keys
  • Preserves sk_bfv, pk_bfv, and stores collected_encryption_keys
  • Triggers both share generation tasks (GenEsiSss and GenPkShareAndSkSss)

Past reviews confirmed that collected_encryption_keys are already sorted by party_id in the collector.


634-714: LGTM! BFV encryption and per-party publishing is correct.

The method properly:

  • Deserializes collected BFV public keys (already sorted by party_id per past reviews)
  • Decrypts local shares from encrypted storage
  • Encrypts shares for all recipients using BfvEncryptedShares::encrypt_all with OsRng
  • Implements domain-level splitting by publishing one ThresholdShareCreated event per recipient
  • Each event contains only the share data for that specific party (extract_for_party)

This correctly implements the per-recipient BFV encryption flow described in the PR objectives.


737-768: LGTM! BFV decryption logic correctly handles local and network shares.

The method properly:

  • Retrieves and deserializes the BFV secret key from encrypted storage
  • Decrypts received shares using BFV with correct parameters
  • Uses conditional indexing: if len == 1 { 0 } else { party_id }
    • Local shares (from self) contain all parties' data → use party_id index
    • Network shares (received via DHT) are pre-filtered → use index 0

Past reviews confirmed this approach is correct with party-filtered distribution.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
crates/keyshare/src/encryption_key_collector.rs (1)

18-50: LGTM - Timeout mechanism now implemented!

This addresses the previous review feedback about missing timeout protection. The AllEncryptionKeysCollected correctly sorts keys by party_id for deterministic ordering, which is essential for correct BFV encryption/decryption indexing.

🧹 Nitpick comments (1)
crates/events/src/enclave_event/mod.rs (1)

303-306: Consider adding get_e3_id handling for failure events.

EncryptionKeyCollectionFailed and ThresholdShareCollectionFailed both have e3_id fields but are not handled in get_e3_id(), causing it to return None for these events. If E3-scoped routing or filtering is needed for failure events, consider adding them:

🔎 Proposed diff
             EnclaveEventData::TicketSubmitted(ref data) => Some(data.e3_id.clone()),
             EnclaveEventData::EncryptionKeyCreated(ref data) => Some(data.e3_id.clone()),
+            EnclaveEventData::EncryptionKeyCollectionFailed(ref data) => Some(data.e3_id.clone()),
+            EnclaveEventData::ThresholdShareCollectionFailed(ref data) => Some(data.e3_id.clone()),
             _ => None,
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9c5aea8 and 4aba96e.

📒 Files selected for processing (7)
  • crates/events/src/enclave_event/encryption_key_collection_failed.rs
  • crates/events/src/enclave_event/mod.rs
  • crates/events/src/enclave_event/threshold_share_collection_failed.rs
  • crates/keyshare/src/encryption_key_collector.rs
  • crates/keyshare/src/lib.rs
  • crates/keyshare/src/threshold_keyshare.rs
  • crates/keyshare/src/threshold_share_collector.rs
🧰 Additional context used
🧠 Learnings (18)
📓 Common learnings
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 660
File: crates/events/src/enclave_event/decryptionshare_created.rs:23-26
Timestamp: 2025-10-04T14:00:17.916Z
Learning: In the enclave codebase using threshold BFV cryptography, decryption shares (as in DecryptionshareCreated events) are not sensitive data and can be safely logged or displayed, as individual shares reveal nothing without reaching the threshold number of shares.
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 969
File: packages/enclave-sdk/src/enclave-sdk.ts:101-103
Timestamp: 2025-11-08T01:31:47.505Z
Learning: In packages/enclave-sdk/src/enclave-sdk.ts, the TRBFV protocol parameter setup is intentionally incomplete as of PR #969. The constructor sets BFV_THRESHOLD parameters for TRBFV, but the encryption methods (encryptNumber, encryptVector, encryptNumberAndGenInputs, encryptVectorAndGenInputs) intentionally only support BFV and will throw "Protocol not supported" for TRBFV until future implementation is completed.
📚 Learning: 2025-04-30T06:25:14.721Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 372
File: packages/ciphernode/events/src/eventbus.rs:15-15
Timestamp: 2025-04-30T06:25:14.721Z
Learning: EnclaveEvent implements Display in packages/ciphernode/events/src/enclave_event/mod.rs, which satisfies the Event trait requirement. Static analysis tools may incorrectly flag implementations as missing when they do exist.

Applied to files:

  • crates/events/src/enclave_event/encryption_key_collection_failed.rs
  • crates/events/src/enclave_event/mod.rs
  • crates/events/src/enclave_event/threshold_share_collection_failed.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-08T19:45:18.209Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 107
File: packages/ciphernode/sortition/src/distance.rs:1-1
Timestamp: 2024-10-08T19:45:18.209Z
Learning: In `packages/ciphernode/core/src/events.rs`, the import statements use the correct and updated `alloy::primitives` module.

Applied to files:

  • crates/events/src/enclave_event/encryption_key_collection_failed.rs
  • crates/events/src/enclave_event/mod.rs
  • crates/keyshare/src/lib.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-23T02:03:02.008Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/encryption.rs:45-45
Timestamp: 2024-10-23T02:03:02.008Z
Learning: In the `packages/ciphernode/keyshare/src/encryption.rs` file, the environment variable `CIPHERNODE_SECRET` is used for the encryption password. A secure secret management solution is not currently available, but may be considered in future iterations.

Applied to files:

  • crates/events/src/enclave_event/mod.rs
  • crates/keyshare/src/lib.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-22T02:10:34.864Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs:82-83
Timestamp: 2024-10-22T02:10:34.864Z
Learning: In the file `packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs`, when reviewing test functions like `generate_pk_share`, minor performance optimizations (e.g., minimizing mutex locks) are not a priority.

Applied to files:

  • crates/events/src/enclave_event/mod.rs
  • crates/keyshare/src/lib.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-29T01:04:19.137Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/keyshare.rs:53-70
Timestamp: 2024-10-29T01:04:19.137Z
Learning: In the `Keyshare` struct within `packages/ciphernode/keyshare/src/keyshare.rs`, the `self.secret` field is stored in encrypted form and is not considered sensitive.

Applied to files:

  • crates/events/src/enclave_event/mod.rs
  • crates/keyshare/src/lib.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-10T23:24:43.341Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 143
File: packages/ciphernode/sortition/src/sortition.rs:4-9
Timestamp: 2024-10-10T23:24:43.341Z
Learning: In the `Sortition` module (`packages/ciphernode/sortition/src/sortition.rs`), errors are sent to the event bus using `self.bus.err`, which handles logging and printing. Therefore, explicit use of the `tracing` crate for logging errors may not be necessary in this context.

Applied to files:

  • crates/events/src/enclave_event/mod.rs
  • crates/events/src/enclave_event/threshold_share_collection_failed.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-08-02T15:41:12.872Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 609
File: crates/crypto/src/secret_holder.rs:110-112
Timestamp: 2025-08-02T15:41:12.872Z
Learning: In `crates/crypto/src/secret_holder.rs`, the `TimedSecretHolder` uses `try_lock()` instead of `lock()` in the purge callback intentionally. This creates graceful behavior where purging only happens when the secret is idle (lock available) and skips purging when the secret is actively being used (lock held), preventing blocking and deadlocks while maintaining security.

Applied to files:

  • crates/keyshare/src/encryption_key_collector.rs
📚 Learning: 2024-10-23T02:35:07.689Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/keyshare.rs:58-65
Timestamp: 2024-10-23T02:35:07.689Z
Learning: In `packages/ciphernode/keyshare/src/keyshare.rs`, the data being decrypted in the `get_secret` method of the `Keyshare` struct is not sensitive, so wrapping it with `Zeroizing` is unnecessary.

Applied to files:

  • crates/keyshare/src/lib.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-08T19:45:18.209Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 133
File: packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs:137-139
Timestamp: 2024-10-08T19:45:18.209Z
Learning: In `packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs`, using the same RNG instance `rng_test` for generating multiple key shares without advancing its state is acceptable.

Applied to files:

  • crates/keyshare/src/lib.rs
  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-10-04T14:00:17.916Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 660
File: crates/events/src/enclave_event/decryptionshare_created.rs:23-26
Timestamp: 2025-10-04T14:00:17.916Z
Learning: In the enclave codebase using threshold BFV cryptography, decryption shares (as in DecryptionshareCreated events) are not sensitive data and can be safely logged or displayed, as individual shares reveal nothing without reaching the threshold number of shares.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-11-08T01:31:47.505Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 969
File: packages/enclave-sdk/src/enclave-sdk.ts:101-103
Timestamp: 2025-11-08T01:31:47.505Z
Learning: In packages/enclave-sdk/src/enclave-sdk.ts, the TRBFV protocol parameter setup is intentionally incomplete as of PR #969. The constructor sets BFV_THRESHOLD parameters for TRBFV, but the encryption methods (encryptNumber, encryptVector, encryptNumberAndGenInputs, encryptVectorAndGenInputs) intentionally only support BFV and will throw "Protocol not supported" for TRBFV until future implementation is completed.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-05-12T21:12:33.453Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 376
File: packages/ciphernode/sortition/src/sortition.rs:155-164
Timestamp: 2025-05-12T21:12:33.453Z
Learning: When refactoring Rust code to work with collections like HashMaps and moving values into closures, the compiler can sometimes determine that a value won't be used again and allow moving fields out of a borrowed value without requiring an explicit `move` keyword.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-22T03:39:29.448Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/evm/src/enclave_sol_reader.rs:87-89
Timestamp: 2024-10-22T03:39:29.448Z
Learning: In the `ciphernode` project, specifically in `packages/ciphernode/evm/src/enclave_sol_reader.rs`, the method `EnclaveSolReader::attach` should be retained even if it directly calls `EvmEventReader::attach` without additional processing. Avoid suggesting its removal in future reviews.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-16T09:51:10.038Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/router/src/committee_meta.rs:43-43
Timestamp: 2024-10-16T09:51:10.038Z
Learning: In `packages/ciphernode/router/src/committee_meta.rs`, avoid suggesting making the `on_event` method in `CommitteMetaFeature` asynchronous or adding error handling for the `write` operation to the data store.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-11-05T06:49:46.285Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 173
File: packages/ciphernode/enclave_node/src/datastore.rs:14-16
Timestamp: 2024-11-05T06:49:46.285Z
Learning: In `packages/ciphernode/enclave_node/src/datastore.rs`, for internal functions like `get_in_mem_store`, adding extensive documentation and error handling may not be necessary if they are not client-facing.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-11-05T06:51:46.701Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 173
File: packages/ciphernode/evm/src/event_reader.rs:270-286
Timestamp: 2024-11-05T06:51:46.701Z
Learning: In `packages/ciphernode/evm/src/event_reader.rs`, the `state.ids` HashSet is intended to grow indefinitely to store all processed event IDs for deduplication purposes until an alternative like a bloom filter is implemented.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-10-27T15:37:59.138Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 904
File: crates/net/src/bin/p2p_test.rs:22-45
Timestamp: 2025-10-27T15:37:59.138Z
Learning: In test files (especially integration test binaries like p2p_test.rs), suggesting correlation ID filtering for DHT events may be unnecessarily complex since test environments are typically more controlled and false positives are less of a concern.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
🧬 Code graph analysis (3)
crates/events/src/enclave_event/threshold_share_collection_failed.rs (2)
crates/events/src/enclave_event/encryption_key_collection_failed.rs (1)
  • fmt (21-23)
crates/events/src/enclave_event/mod.rs (1)
  • fmt (360-362)
crates/keyshare/src/threshold_share_collector.rs (1)
crates/keyshare/src/encryption_key_collector.rs (4)
  • setup (71-81)
  • started (87-96)
  • handle (101-152)
  • handle (157-189)
crates/keyshare/src/encryption_key_collector.rs (2)
crates/keyshare/src/threshold_keyshare.rs (10)
  • from (69-73)
  • new (190-208)
  • new (320-330)
  • handle (942-954)
  • handle (959-964)
  • handle (969-974)
  • handle (979-984)
  • handle (989-994)
  • handle (999-1004)
  • handle (1009-1014)
crates/keyshare/src/threshold_share_collector.rs (2)
  • setup (43-53)
  • started (59-68)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (9)
  • GitHub Check: build_e3_support_dev
  • GitHub Check: test_net
  • GitHub Check: build_crisp_sdk
  • GitHub Check: build_enclave_cli
  • GitHub Check: integration_prebuild
  • GitHub Check: build_sdk
  • GitHub Check: rust_unit
  • GitHub Check: rust_integration
  • GitHub Check: build_ciphernode_image
🔇 Additional comments (17)
crates/events/src/enclave_event/threshold_share_collection_failed.rs (1)

1-24: LGTM!

The ThresholdShareCollectionFailed message struct is well-defined and follows the same patterns as EncryptionKeyCollectionFailed in this PR. The Display implementation using Debug formatting is consistent with other event types in the codebase (per the relevant code snippets from mod.rs).

crates/keyshare/src/lib.rs (1)

7-13: LGTM!

The new encryption_key_collector module is properly added and only the necessary types (AllEncryptionKeysCollected, EncryptionKeyCollector) are re-exported, following the existing patterns in this crate.

crates/events/src/enclave_event/encryption_key_collection_failed.rs (1)

1-24: LGTM!

The EncryptionKeyCollectionFailed message is well-structured and consistent with ThresholdShareCollectionFailed. Both share the same pattern for failure events with e3_id, reason, and missing_parties fields.

crates/events/src/enclave_event/mod.rs (2)

121-123: LGTM!

The new EnclaveEventData variants are correctly added, maintaining consistency with the existing enum structure.


335-339: LGTM!

The impl_into_event_data! macro invocation correctly includes all new event types, enabling automatic From implementations.

crates/keyshare/src/threshold_share_collector.rs (4)

20-31: LGTM!

The timeout mechanism is well-structured with a clear 120-second default, a dedicated ThresholdShareCollectionTimeout message, and the TimedOut state variant. This follows the same pattern as EncryptionKeyCollector (60s timeout), providing consistent timeout handling across collectors.


43-68: LGTM!

The setup() method correctly initializes with e3_id for traceability, and the started() hook properly schedules the timeout and stores the handle for later cancellation.


73-118: LGTM!

The ThresholdShareCreated handler correctly:

  1. Guards against processing in non-Collecting states
  2. Validates party_id against expected set
  3. Cancels timeout upon completion
  4. Sends AllThresholdSharesCollected to parent

121-156: LGTM!

The timeout handler correctly guards against duplicate handling, logs missing parties with structured fields, transitions to TimedOut, notifies the parent with ThresholdShareCollectionFailed, and stops the actor. This addresses the previous review feedback about adding timeout mechanisms.

crates/keyshare/src/encryption_key_collector.rs (3)

70-96: LGTM!

The setup() and started() implementations follow the same pattern as ThresholdShareCollector, ensuring consistent behavior across collectors.


99-152: LGTM!

The EncryptionKeyCreated handler correctly:

  1. Guards against non-Collecting states
  2. Validates party_id against expected set
  3. Cancels timeout upon completion
  4. Converts to sorted AllEncryptionKeysCollected and sends to parent

155-189: LGTM!

The timeout handler is consistent with ThresholdShareCollector, properly logging, transitioning state, notifying parent, and stopping the actor.

crates/keyshare/src/threshold_keyshare.rs (5)

76-100: LGTM!

The new CollectingEncryptionKeysData state and extensions to GeneratingThresholdShareData and AggregatingDecryptionKey properly carry the BFV key material (sk_bfv, pk_bfv, collected_encryption_keys) through the state machine.


412-451: LGTM!

The BFV key generation is secure:

  • Uses OsRng for cryptographically secure randomness
  • Serializes and encrypts the secret key (sk_bfv) with the cipher before storage
  • Properly transitions state and publishes the encryption key event

658-717: LGTM!

The BFV-based share encryption flow is well-implemented:

  1. Collected keys are already sorted by party_id (from AllEncryptionKeysCollected)
  2. Shares are encrypted for all recipients using BFV
  3. Per-party extraction (extract_for_party) ensures each party only receives their share
  4. target_party_id enables correct routing/filtering

744-773: LGTM - Dynamic index selection correctly handles both local and network shares.

The logic at lines 748 and 765 correctly differentiates:

  • Network shares (pre-extracted, len == 1): use index 0
  • Local shares (full, len > 1): use party_id index

This addresses the previous review concern about clone_share(0) being incorrect for all cases.


1017-1068: LGTM!

Both failure handlers properly:

  1. Log structured warnings with e3_id and missing_parties
  2. Clear collector references
  3. Publish failure events to the bus for sync tracking (as noted by ryardley in past comments)
  4. Stop the actor to prevent proceeding in an inconsistent state

Comment thread crates/keyshare/src/threshold_keyshare.rs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (1)
crates/keyshare/src/threshold_keyshare.rs (1)

744-756: Clarify comment about share lengths.

The comment states "Local share (from self) has all parties' shares, network shares are pre-extracted," but lines 705-718 show all shares (including local) go through extract_for_party before publishing. This means all received shares should have len() == 1 in practice. The conditional at line 749 (and 766) appears to be defensive programming rather than handling an expected case.

Consider updating the comment to clarify when len() != 1 would actually occur, or note that the conditional is defensive code to handle unexpected cases.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4aba96e and 3349109.

📒 Files selected for processing (1)
  • crates/keyshare/src/threshold_keyshare.rs
🧰 Additional context used
🧠 Learnings (18)
📓 Common learnings
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 660
File: crates/events/src/enclave_event/decryptionshare_created.rs:23-26
Timestamp: 2025-10-04T14:00:17.916Z
Learning: In the enclave codebase using threshold BFV cryptography, decryption shares (as in DecryptionshareCreated events) are not sensitive data and can be safely logged or displayed, as individual shares reveal nothing without reaching the threshold number of shares.
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 969
File: packages/enclave-sdk/src/enclave-sdk.ts:101-103
Timestamp: 2025-11-08T01:31:47.505Z
Learning: In packages/enclave-sdk/src/enclave-sdk.ts, the TRBFV protocol parameter setup is intentionally incomplete as of PR #969. The constructor sets BFV_THRESHOLD parameters for TRBFV, but the encryption methods (encryptNumber, encryptVector, encryptNumberAndGenInputs, encryptVectorAndGenInputs) intentionally only support BFV and will throw "Protocol not supported" for TRBFV until future implementation is completed.
📚 Learning: 2025-10-04T14:00:17.916Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 660
File: crates/events/src/enclave_event/decryptionshare_created.rs:23-26
Timestamp: 2025-10-04T14:00:17.916Z
Learning: In the enclave codebase using threshold BFV cryptography, decryption shares (as in DecryptionshareCreated events) are not sensitive data and can be safely logged or displayed, as individual shares reveal nothing without reaching the threshold number of shares.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-29T01:04:19.137Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/keyshare.rs:53-70
Timestamp: 2024-10-29T01:04:19.137Z
Learning: In the `Keyshare` struct within `packages/ciphernode/keyshare/src/keyshare.rs`, the `self.secret` field is stored in encrypted form and is not considered sensitive.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-11-08T01:31:47.505Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 969
File: packages/enclave-sdk/src/enclave-sdk.ts:101-103
Timestamp: 2025-11-08T01:31:47.505Z
Learning: In packages/enclave-sdk/src/enclave-sdk.ts, the TRBFV protocol parameter setup is intentionally incomplete as of PR #969. The constructor sets BFV_THRESHOLD parameters for TRBFV, but the encryption methods (encryptNumber, encryptVector, encryptNumberAndGenInputs, encryptVectorAndGenInputs) intentionally only support BFV and will throw "Protocol not supported" for TRBFV until future implementation is completed.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-23T02:35:07.689Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/keyshare.rs:58-65
Timestamp: 2024-10-23T02:35:07.689Z
Learning: In `packages/ciphernode/keyshare/src/keyshare.rs`, the data being decrypted in the `get_secret` method of the `Keyshare` struct is not sensitive, so wrapping it with `Zeroizing` is unnecessary.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-22T02:10:34.864Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs:82-83
Timestamp: 2024-10-22T02:10:34.864Z
Learning: In the file `packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs`, when reviewing test functions like `generate_pk_share`, minor performance optimizations (e.g., minimizing mutex locks) are not a priority.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-05-12T21:12:33.453Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 376
File: packages/ciphernode/sortition/src/sortition.rs:155-164
Timestamp: 2025-05-12T21:12:33.453Z
Learning: When refactoring Rust code to work with collections like HashMaps and moving values into closures, the compiler can sometimes determine that a value won't be used again and allow moving fields out of a borrowed value without requiring an explicit `move` keyword.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-22T03:39:29.448Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/evm/src/enclave_sol_reader.rs:87-89
Timestamp: 2024-10-22T03:39:29.448Z
Learning: In the `ciphernode` project, specifically in `packages/ciphernode/evm/src/enclave_sol_reader.rs`, the method `EnclaveSolReader::attach` should be retained even if it directly calls `EvmEventReader::attach` without additional processing. Avoid suggesting its removal in future reviews.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-16T09:51:10.038Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 145
File: packages/ciphernode/router/src/committee_meta.rs:43-43
Timestamp: 2024-10-16T09:51:10.038Z
Learning: In `packages/ciphernode/router/src/committee_meta.rs`, avoid suggesting making the `on_event` method in `CommitteMetaFeature` asynchronous or adding error handling for the `write` operation to the data store.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-04-30T06:25:14.721Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 372
File: packages/ciphernode/events/src/eventbus.rs:15-15
Timestamp: 2025-04-30T06:25:14.721Z
Learning: EnclaveEvent implements Display in packages/ciphernode/events/src/enclave_event/mod.rs, which satisfies the Event trait requirement. Static analysis tools may incorrectly flag implementations as missing when they do exist.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-11-05T06:49:46.285Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 173
File: packages/ciphernode/enclave_node/src/datastore.rs:14-16
Timestamp: 2024-11-05T06:49:46.285Z
Learning: In `packages/ciphernode/enclave_node/src/datastore.rs`, for internal functions like `get_in_mem_store`, adding extensive documentation and error handling may not be necessary if they are not client-facing.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-08T19:45:18.209Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 133
File: packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs:137-139
Timestamp: 2024-10-08T19:45:18.209Z
Learning: In `packages/ciphernode/tests/tests/test_aggregation_and_decryption.rs`, using the same RNG instance `rng_test` for generating multiple key shares without advancing its state is acceptable.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-11-05T06:51:46.701Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 173
File: packages/ciphernode/evm/src/event_reader.rs:270-286
Timestamp: 2024-11-05T06:51:46.701Z
Learning: In `packages/ciphernode/evm/src/event_reader.rs`, the `state.ids` HashSet is intended to grow indefinitely to store all processed event IDs for deduplication purposes until an alternative like a bloom filter is implemented.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2025-10-27T15:37:59.138Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 904
File: crates/net/src/bin/p2p_test.rs:22-45
Timestamp: 2025-10-27T15:37:59.138Z
Learning: In test files (especially integration test binaries like p2p_test.rs), suggesting correlation ID filtering for DHT events may be unnecessarily complex since test environments are typically more controlled and false positives are less of a concern.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-08T01:50:45.185Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 139
File: packages/ciphernode/core/src/events.rs:323-323
Timestamp: 2024-10-08T01:50:45.185Z
Learning: When suggesting that instances of `E3Requested` should include `src_chain_id`, double-check to ensure that the field is actually missing before making the suggestion.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-08T19:45:18.209Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 107
File: packages/ciphernode/sortition/src/distance.rs:1-1
Timestamp: 2024-10-08T19:45:18.209Z
Learning: In `packages/ciphernode/core/src/events.rs`, the import statements use the correct and updated `alloy::primitives` module.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-10T23:24:43.341Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 143
File: packages/ciphernode/sortition/src/sortition.rs:4-9
Timestamp: 2024-10-10T23:24:43.341Z
Learning: In the `Sortition` module (`packages/ciphernode/sortition/src/sortition.rs`), errors are sent to the event bus using `self.bus.err`, which handles logging and printing. Therefore, explicit use of the `tracing` crate for logging errors may not be necessary in this context.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
📚 Learning: 2024-10-23T02:03:02.008Z
Learnt from: ryardley
Repo: gnosisguild/enclave PR: 156
File: packages/ciphernode/keyshare/src/encryption.rs:45-45
Timestamp: 2024-10-23T02:03:02.008Z
Learning: In the `packages/ciphernode/keyshare/src/encryption.rs` file, the environment variable `CIPHERNODE_SECRET` is used for the encryption password. A secure secret management solution is not currently available, but may be considered in future iterations.

Applied to files:

  • crates/keyshare/src/threshold_keyshare.rs
🧬 Code graph analysis (1)
crates/keyshare/src/threshold_keyshare.rs (4)
crates/trbfv/src/helpers.rs (2)
  • deserialize_secret_key (41-44)
  • serialize_secret_key (33-38)
crates/keyshare/src/threshold_share_collector.rs (3)
  • setup (43-53)
  • handle (73-118)
  • handle (123-155)
crates/keyshare/src/encryption_key_collector.rs (3)
  • setup (71-81)
  • handle (101-152)
  • handle (157-189)
crates/trbfv/src/shares/bfv_encrypted.rs (2)
  • len (196-198)
  • encrypt_all (155-176)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: build_crisp_sdk
  • GitHub Check: build_enclave_cli
  • GitHub Check: build_sdk
  • GitHub Check: integration_prebuild
  • GitHub Check: build_ciphernode_image
  • GitHub Check: rust_integration
  • GitHub Check: rust_unit
  • GitHub Check: test_net
🔇 Additional comments (2)
crates/keyshare/src/threshold_keyshare.rs (2)

1072-1087: LGTM—E3RequestComplete handler implemented correctly.

The handler properly clears both collector references and triggers actor shutdown via the Die message. This addresses the cleanup concern raised in previous review comments and follows the expected pattern for request completion.


413-452: LGTM—BFV encryption integration is well-implemented.

The BFV key generation, share encryption, and decryption flow demonstrates solid cryptographic practices:

  • OsRng used for key generation
  • Secret keys protected with SensitiveBytes
  • Per-party filtering ensures shares are only processed by intended recipients
  • State transitions maintain consistency
  • Comprehensive error handling with failure events

The integration successfully implements the per-recipient share encryption objectives from the PR.

Also applies to: 640-721, 726-788

Comment thread crates/keyshare/src/threshold_share_collector.rs

@ryardley ryardley left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good! 🚀

@ryardley ryardley merged commit 6b576ea into main Dec 27, 2025
27 checks passed
@0xjei

0xjei commented Dec 29, 2025

Copy link
Copy Markdown
Contributor

amazing work @hmzakhalid @ryardley

@github-actions github-actions Bot deleted the feat/share-encryption branch January 4, 2026 03:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement Share Encryption

3 participants