Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
bd4f54b
feat: add share encryption (merge commits)
hmzakhalid Dec 16, 2025
16ef3d0
chore: formatting
hmzakhalid Dec 16, 2025
ef1b9b5
chore: trigger CI
hmzakhalid Dec 16, 2025
d4be5d3
chore: update max document payload size
hmzakhalid Dec 17, 2025
4c7a3c0
feat: add document chunking
hmzakhalid Dec 18, 2025
0b2de3e
feat: inject params during init
hmzakhalid Dec 18, 2025
96acb34
chore: formatting
hmzakhalid Dec 18, 2025
c61c80d
chore: remove duplicate comments
hmzakhalid Dec 18, 2025
7a6506c
chore: remove duplicate comments
hmzakhalid Dec 18, 2025
47ba25f
chore: add external marking and info comments
hmzakhalid Dec 18, 2025
4e70a98
Merge branch 'main' into feat/share-encryption
hmzakhalid Dec 18, 2025
de0d8c8
fix: extract shares
hmzakhalid Dec 18, 2025
c623ce0
chore: remove option
hmzakhalid Dec 19, 2025
30b8010
chore: revert chunking
hmzakhalid Dec 19, 2025
aa55989
Merge branch 'main' into feat/share-encryption
hmzakhalid Dec 19, 2025
0b84ea0
Update crates/events/src/enclave_event/threshold_share_created.rs
hmzakhalid Dec 22, 2025
0db7342
Merge branch 'main' into feat/share-encryption
hmzakhalid Dec 22, 2025
195d589
Merge branch 'main' into feat/share-encryption
hmzakhalid Dec 24, 2025
195a891
Merge branch 'main' into feat/share-encryption
hmzakhalid Dec 24, 2025
999d5ac
feat: move spliting to threshold keyshare
hmzakhalid Dec 24, 2025
9c5aea8
fix: make event buffer key a composite
hmzakhalid Dec 24, 2025
c3a4405
feat: add bookend events
hmzakhalid Dec 24, 2025
4aba96e
chore: formatting
hmzakhalid Dec 24, 2025
3349109
fix: add E3 Completed to Threshold keyshare
hmzakhalid Dec 24, 2025
File filter

Filter by extension

Filter by extension


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

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

1 change: 1 addition & 0 deletions crates/ciphernode-builder/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@ e3-keyshare.workspace = true
e3-multithread.workspace = true
e3-request.workspace = true
e3-sortition.workspace = true
e3-trbfv.workspace = true
e3-utils.workspace = true
tracing.workspace = true
2 changes: 2 additions & 0 deletions crates/ciphernode-builder/src/ciphernode_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -438,12 +438,14 @@ impl CiphernodeBuilder {

if let Some(KeyshareKind::Threshold) = self.keyshare {
let multithread = self.ensure_multithread();
let share_encryption_params = e3_trbfv::helpers::get_share_encryption_params();
info!("Setting up ThresholdKeyshareExtension");
e3_builder = e3_builder.with(ThresholdKeyshareExtension::create(
&bus,
&self.cipher,
&multithread,
&addr,
share_encryption_params,
))
}

Expand Down
1 change: 1 addition & 0 deletions crates/events/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ bs58 = { workspace = true }
chrono = { workspace = true }
derivative = { workspace = true }
futures-util = { workspace = true }
hex = { workspace = true }
once_cell = { workspace = true }
rand = { workspace = true }
serde = { workspace = true }
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: LGPL-3.0-only
//
// This file is provided WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.

use crate::E3id;
use actix::Message;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display};

#[derive(Message, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[rtype(result = "()")]
pub struct EncryptionKeyCollectionFailed {
pub e3_id: E3id,
pub reason: String,
pub missing_parties: Vec<u64>,
}

impl Display for EncryptionKeyCollectionFailed {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}
37 changes: 37 additions & 0 deletions crates/events/src/enclave_event/encryption_key_created.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: LGPL-3.0-only
//
// This file is provided WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.

use crate::E3id;
use actix::Message;
use derivative::Derivative;
use e3_utils::utility_types::ArcBytes;
use serde::{Deserialize, Serialize};
use std::{
fmt::{self, Display},
sync::Arc,
};

#[derive(Derivative, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[derivative(Debug)]
pub struct EncryptionKey {
pub party_id: u64,
#[derivative(Debug(format_with = "e3_utils::formatters::hexf"))]
pub pk_bfv: ArcBytes,
}

#[derive(Message, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[rtype(result = "()")]
pub struct EncryptionKeyCreated {
pub e3_id: E3id,
pub key: Arc<EncryptionKey>,
pub external: bool,
}

impl Display for EncryptionKeyCreated {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}
15 changes: 14 additions & 1 deletion crates/events/src/enclave_event/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ mod die;
mod e3_request_complete;
mod e3_requested;
mod enclave_error;
mod encryption_key_collection_failed;
mod encryption_key_created;
mod keyshare_created;
mod operator_activation_changed;
mod plaintext_aggregated;
Expand All @@ -27,6 +29,7 @@ mod publickey_aggregated;
mod publish_document;
mod shutdown;
mod test_event;
mod threshold_share_collection_failed;
mod threshold_share_created;
mod ticket_balance_updated;
mod ticket_generated;
Expand All @@ -47,6 +50,8 @@ pub use die::*;
pub use e3_request_complete::*;
pub use e3_requested::*;
pub use enclave_error::*;
pub use encryption_key_collection_failed::*;
pub use encryption_key_created::*;
pub use keyshare_created::*;
pub use operator_activation_changed::*;
pub use plaintext_aggregated::*;
Expand All @@ -56,6 +61,7 @@ pub use publish_document::*;
pub use shutdown::*;
use strum::IntoStaticStr;
pub use test_event::*;
pub use threshold_share_collection_failed::*;
pub use threshold_share_created::*;
pub use ticket_balance_updated::*;
pub use ticket_generated::*;
Expand Down Expand Up @@ -112,6 +118,9 @@ pub enum EnclaveEventData {
Shutdown(Shutdown),
DocumentReceived(DocumentReceived),
ThresholdShareCreated(ThresholdShareCreated),
EncryptionKeyCreated(EncryptionKeyCreated),
EncryptionKeyCollectionFailed(EncryptionKeyCollectionFailed),
ThresholdShareCollectionFailed(ThresholdShareCollectionFailed),
/// This is a test event to use in testing
TestEvent(TestEvent),
}
Expand Down Expand Up @@ -291,6 +300,7 @@ impl<S: SeqState> EnclaveEvent<S> {
EnclaveEventData::CommitteeFinalized(ref data) => Some(data.e3_id.clone()),
EnclaveEventData::TicketGenerated(ref data) => Some(data.e3_id.clone()),
EnclaveEventData::TicketSubmitted(ref data) => Some(data.e3_id.clone()),
EnclaveEventData::EncryptionKeyCreated(ref data) => Some(data.e3_id.clone()),
_ => None,
}
}
Expand Down Expand Up @@ -322,7 +332,10 @@ impl_into_event_data!(
Shutdown,
TestEvent,
DocumentReceived,
ThresholdShareCreated
ThresholdShareCreated,
EncryptionKeyCreated,
EncryptionKeyCollectionFailed,
ThresholdShareCollectionFailed
);

impl TryFrom<&EnclaveEvent<Sequenced>> for EnclaveError {
Expand Down
2 changes: 1 addition & 1 deletion crates/events/src/enclave_event/publish_document/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use std::fmt::{self, Display};
use actix::Message;
use chrono::{serde::ts_seconds, DateTime, Duration, Utc};
use e3_utils::ArcBytes;
use filter::Filter;
pub use filter::Filter;
use serde::{Deserialize, Serialize};
use tracing::warn;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: LGPL-3.0-only
//
// This file is provided WITHOUT ANY WARRANTY;
// without even the implied warranty of MERCHANTABILITY
// or FITNESS FOR A PARTICULAR PURPOSE.

use crate::E3id;
use actix::Message;
use serde::{Deserialize, Serialize};
use std::fmt::{self, Display};

#[derive(Message, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[rtype(result = "()")]
pub struct ThresholdShareCollectionFailed {
pub e3_id: E3id,
pub reason: String,
pub missing_parties: Vec<u64>,
}

impl Display for ThresholdShareCollectionFailed {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{:?}", self)
}
}
47 changes: 36 additions & 11 deletions crates/events/src/enclave_event/threshold_share_created.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,37 +7,62 @@
use crate::E3id;
use actix::Message;
use derivative::Derivative;
use e3_trbfv::shares::{PvwEncrypted, SharedSecret};
use e3_trbfv::shares::BfvEncryptedShares;
use e3_utils::utility_types::ArcBytes;
use serde::{Deserialize, Serialize};
use std::{
fmt::{self, Display},
sync::Arc,
};

/// Type Representing Pvw encrypted bytes
pub type PvwBytes = Vec<u8>;

/// PVW encrypted shares list for a party in the DKG
/// BFV-encrypted shares list for a party in the DKG.
///
/// Each party broadcasts their encrypted shares to all other parties.
/// Each recipient can only decrypt the share meant for them using their
/// BFV secret key.
#[derive(Derivative, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[derivative(Debug)]
pub struct ThresholdShare {
/// The publishers party_id
/// The publisher's party_id
pub party_id: u64,
/// The publishers public key share
/// The publisher's TrBFV public key share
#[derivative(Debug(format_with = "e3_utils::formatters::hexf"))]
pub pk_share: ArcBytes,
/// PVW encrypted sk_sss list with index determining party_id
pub sk_sss: PvwEncrypted<SharedSecret>,
/// PVW encrypted esi_sss list with index determining party_id
pub esi_sss: Vec<PvwEncrypted<SharedSecret>>,
/// BFV-encrypted sk_sss - each recipient can decrypt their share
pub sk_sss: BfvEncryptedShares,
/// BFV-encrypted esi_sss - one per secret key (sk), each recipient can decrypt their share
pub esi_sss: Vec<BfvEncryptedShares>,
}

impl ThresholdShare {
/// Extract only the shares meant for a specific party.
pub fn extract_for_party(&self, recipient_party_id: usize) -> Option<Self> {
let sk_sss = self.sk_sss.extract_for_party(recipient_party_id)?;
let esi_sss: Option<Vec<_>> = self
.esi_sss
.iter()
.map(|shares| shares.extract_for_party(recipient_party_id))
.collect();

esi_sss.map(|esi_sss| Self {
party_id: self.party_id,
pk_share: self.pk_share.clone(),
sk_sss,
esi_sss,
})
}
Comment thread
hmzakhalid marked this conversation as resolved.

pub fn num_parties(&self) -> usize {
self.sk_sss.len()
}
}

#[derive(Message, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[rtype(result = "()")]
pub struct ThresholdShareCreated {
pub e3_id: E3id,
pub share: Arc<ThresholdShare>,
pub target_party_id: u64,
pub external: bool,
}

Expand Down
1 change: 1 addition & 0 deletions crates/keyshare/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ e3-multithread = { workspace = true }
e3-request = { workspace = true }
e3-trbfv = { workspace = true }
e3-utils = { workspace = true }
fhe = { workspace = true }
fhe-traits = { workspace = true }
rand = { workspace = true }
rand_chacha = { workspace = true }
Expand Down
Loading
Loading