diff --git a/iroh-willow/src/net.rs b/iroh-willow/src/net.rs index 17b6f792fb..1d6420a137 100644 --- a/iroh-willow/src/net.rs +++ b/iroh-willow/src/net.rs @@ -174,6 +174,7 @@ async fn open_logical_channels( .ok_or(MissingChannel(channel)) }; + let pai = take_and_spawn_channel(LogicalChannel::Intersection)?; let rec = take_and_spawn_channel(LogicalChannel::Reconciliation)?; let stt = take_and_spawn_channel(LogicalChannel::StaticToken)?; let aoi = take_and_spawn_channel(LogicalChannel::AreaOfInterest)?; @@ -182,6 +183,7 @@ async fn open_logical_channels( Ok(( LogicalChannelSenders { + intersection: pai.0, reconciliation: rec.0, static_tokens: stt.0, aoi: aoi.0, @@ -189,6 +191,7 @@ async fn open_logical_channels( data: dat.0, }, LogicalChannelReceivers { + intersection_recv: pai.1.into(), reconciliation_recv: rec.1.into(), static_tokens_recv: stt.1.into(), aoi_recv: aoi.1.into(), diff --git a/iroh-willow/src/proto/sync.rs b/iroh-willow/src/proto/sync.rs index 62b53e9c3b..06418ad5eb 100644 --- a/iroh-willow/src/proto/sync.rs +++ b/iroh-willow/src/proto/sync.rs @@ -147,6 +147,8 @@ impl Channel { strum::EnumCount, )] pub enum LogicalChannel { + /// Logical channel for controlling the binding of new IntersectionHandles. + Intersection, /// Logical channel for performing 3d range-based set reconciliation. Reconciliation, // TODO: use all the channels @@ -183,6 +185,7 @@ impl LogicalChannel { } pub fn fmt_short(&self) -> &'static str { match self { + LogicalChannel::Intersection => "Pai", LogicalChannel::Reconciliation => "Rec", LogicalChannel::StaticToken => "StT", LogicalChannel::Capability => "Cap", @@ -193,22 +196,24 @@ impl LogicalChannel { pub fn from_id(id: u8) -> Result { match id { - 2 => Ok(Self::AreaOfInterest), - 3 => Ok(Self::Capability), - 4 => Ok(Self::StaticToken), - 5 => Ok(Self::Reconciliation), - 6 => Ok(Self::Data), + 2 => Ok(Self::Intersection), + 3 => Ok(Self::AreaOfInterest), + 4 => Ok(Self::Capability), + 5 => Ok(Self::StaticToken), + 6 => Ok(Self::Reconciliation), + 7 => Ok(Self::Data), _ => Err(InvalidChannelId), } } pub fn id(&self) -> u8 { match self { - LogicalChannel::AreaOfInterest => 2, - LogicalChannel::Capability => 3, - LogicalChannel::StaticToken => 4, - LogicalChannel::Reconciliation => 5, - LogicalChannel::Data => 6, + LogicalChannel::Intersection => 2, + LogicalChannel::AreaOfInterest => 3, + LogicalChannel::Capability => 4, + LogicalChannel::StaticToken => 5, + LogicalChannel::Reconciliation => 6, + LogicalChannel::Data => 7, } } } @@ -292,10 +297,14 @@ pub struct CommitmentReveal { pub enum Message { #[debug("{:?}", _0)] CommitmentReveal(CommitmentReveal), - // PaiReplyFragment - // PaiBindFragment - // PaiRequestSubspaceCapability - // PaiReplySubspaceCapability + #[debug("{:?}", _0)] + PaiReplyFragment(PaiReplyFragment), + #[debug("{:?}", _0)] + PaiBindFragment(PaiBindFragment), + #[debug("{:?}", _0)] + PaiRequestSubspaceCapability(PaiRequestSubspaceCapability), + #[debug("{:?}", _0)] + PaiReplySubspaceCapability(PaiReplySubspaceCapability), #[debug("{:?}", _0)] SetupBindStaticToken(SetupBindStaticToken), #[debug("{:?}", _0)] @@ -395,6 +404,10 @@ impl Decoder for Message { impl Message { pub fn channel(&self) -> Channel { match self { + Message::PaiBindFragment(_) | Message::PaiReplyFragment(_) => { + Channel::Logical(LogicalChannel::Intersection) + } + Message::SetupBindReadCapability(_) => Channel::Logical(LogicalChannel::Capability), Message::SetupBindAreaOfInterest(_) => Channel::Logical(LogicalChannel::AreaOfInterest), Message::SetupBindStaticToken(_) => Channel::Logical(LogicalChannel::StaticToken), @@ -412,6 +425,8 @@ impl Message { | Message::DataSetMetadata(_) => Channel::Logical(LogicalChannel::Data), Message::CommitmentReveal(_) + | Message::PaiRequestSubspaceCapability(_) + | Message::PaiReplySubspaceCapability(_) | Message::ControlIssueGuarantee(_) | Message::ControlAbsolve(_) | Message::ControlPlead(_) @@ -456,7 +471,7 @@ impl Message { // } // } // } -// + #[derive(Debug, derive_more::From, strum::Display)] pub enum ReconciliationMessage { SendFingerprint(ReconciliationSendFingerprint), @@ -465,6 +480,7 @@ pub enum ReconciliationMessage { SendPayload(ReconciliationSendPayload), TerminatePayload(ReconciliationTerminatePayload), } + impl TryFrom for ReconciliationMessage { type Error = (); fn try_from(message: Message) -> Result { @@ -478,6 +494,7 @@ impl TryFrom for ReconciliationMessage { } } } + impl From for Message { fn from(message: ReconciliationMessage) -> Self { match message { @@ -496,6 +513,7 @@ pub enum DataMessage { SendPayload(DataSendPayload), SetMetadata(DataSetMetadata), } + impl TryFrom for DataMessage { type Error = (); fn try_from(message: Message) -> Result { @@ -507,6 +525,7 @@ impl TryFrom for DataMessage { } } } + impl From for Message { fn from(message: DataMessage) -> Self { match message { @@ -516,7 +535,33 @@ impl From for Message { } } } -// + +#[derive(Debug, derive_more::From, strum::Display)] +pub enum IntersectionMessage { + BindFragment(PaiBindFragment), + ReplyFragment(PaiReplyFragment), +} + +impl TryFrom for IntersectionMessage { + type Error = (); + fn try_from(message: Message) -> Result { + match message { + Message::PaiBindFragment(msg) => Ok(msg.into()), + Message::PaiReplyFragment(msg) => Ok(msg.into()), + _ => Err(()), + } + } +} + +impl From for Message { + fn from(message: IntersectionMessage) -> Self { + match message { + IntersectionMessage::BindFragment(msg) => msg.into(), + IntersectionMessage::ReplyFragment(msg) => msg.into(), + } + } +} + // impl Encoder for ReconciliationMessage { // fn encoded_len(&self) -> usize { // Message::from(se) @@ -827,3 +872,40 @@ pub struct ControlFreeHandle { mine: bool, handle_type: HandleType, } + +type PsiGroup = (); +/// Bind data to an IntersectionHandle for performing private area intersection. +#[derive(Debug, Serialize, Deserialize)] +pub struct PaiBindFragment { + /// The result of first applying hash_into_group to some fragment for private area intersection and then performing scalar multiplication with scalar. + group_member: PsiGroup, + /// Set to true if the private set intersection item is a secondary fragment. + is_secondary: bool, +} + +/// Finalise private set intersection for a single item. +#[derive(Debug, Serialize, Deserialize)] +pub struct PaiReplyFragment { + /// The IntersectionHandle of the PaiBindFragment message which this finalises. + handle: IntersectionHandle, + /// The result of performing scalar multiplication between the group_member of the message that this is replying to and scalar. + group_member: PsiGroup, +} + +/// Ask the receiver to send a SubspaceCapability. +#[derive(Debug, Serialize, Deserialize)] +pub struct PaiRequestSubspaceCapability { + /// The IntersectionHandle bound by the sender for the least-specific secondary fragment for whose NamespaceId to request the SubspaceCapability. + handle: IntersectionHandle, +} + +/// Send a previously requested SubspaceCapability. +#[derive(Debug, Serialize, Deserialize)] +pub struct PaiReplySubspaceCapability { + /// The handle of the PaiRequestSubspaceCapability message that this answers (hence, an IntersectionHandle bound by the receiver of this message). + handle: IntersectionHandle, + /// A SubspaceCapability whose granted namespace corresponds to the request this answers. + capability: SubspaceCapability, + /// The SyncSubspaceSignature issued by the receiver of the capability over the sender’s challenge. + signature: SyncSignature, +} diff --git a/iroh-willow/src/session/channels.rs b/iroh-willow/src/session/channels.rs index eaada31164..85531288bd 100644 --- a/iroh-willow/src/session/channels.rs +++ b/iroh-willow/src/session/channels.rs @@ -10,7 +10,7 @@ use tracing::trace; use crate::{ proto::sync::{ - Channel, DataMessage, LogicalChannel, Message, ReconciliationMessage, + Channel, DataMessage, IntersectionMessage, LogicalChannel, Message, ReconciliationMessage, SetupBindAreaOfInterest, SetupBindReadCapability, SetupBindStaticToken, }, util::channel::{Receiver, Sender, WriteError}, @@ -66,6 +66,7 @@ impl> From> for MessageReceiver { #[derive(Debug)] pub struct LogicalChannelReceivers { + pub intersection_recv: MessageReceiver, pub reconciliation_recv: MessageReceiver, pub static_tokens_recv: MessageReceiver, pub capability_recv: MessageReceiver, @@ -75,6 +76,7 @@ pub struct LogicalChannelReceivers { impl LogicalChannelReceivers { pub fn close(&self) { + self.intersection_recv.close(); self.reconciliation_recv.close(); self.static_tokens_recv.close(); self.capability_recv.close(); @@ -85,6 +87,7 @@ impl LogicalChannelReceivers { #[derive(Debug, Clone)] pub struct LogicalChannelSenders { + pub intersection: Sender, pub reconciliation: Sender, pub static_tokens: Sender, pub aoi: Sender, @@ -93,6 +96,7 @@ pub struct LogicalChannelSenders { } impl LogicalChannelSenders { pub fn close(&self) { + self.intersection.close(); self.reconciliation.close(); self.static_tokens.close(); self.aoi.close(); @@ -102,6 +106,7 @@ impl LogicalChannelSenders { pub fn get(&self, channel: LogicalChannel) -> &Sender { match channel { + LogicalChannel::Intersection => &self.intersection, LogicalChannel::Reconciliation => &self.reconciliation, LogicalChannel::StaticToken => &self.static_tokens, LogicalChannel::Capability => &self.capability, diff --git a/iroh-willow/src/session/run.rs b/iroh-willow/src/session/run.rs index 57b56c05bb..3f2dad41ca 100644 --- a/iroh-willow/src/session/run.rs +++ b/iroh-willow/src/session/run.rs @@ -36,6 +36,7 @@ impl Session { capability_recv, aoi_recv, data_recv, + intersection_recv, }, } = recv;