Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Protocol combinators #60

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `SessionId::new()` renamed to `from_seed()`. ([#41])
- `FirstRound::new()` takes a `&[u8]` instead of a `SessionId` object. ([#41])
- The signatures of `Round::make_echo_broadcast()`, `Round::make_direct_message()`, and `Round::receive_message()`, take messages without `Option`s. ([#46])
- `Round::make_direct_message_with_artifact()` is the method returning an artifact now; `Round::make_direct_message()` is a shortcut for cases where no artifact is returned. ([#46])
- `Artifact::empty()` removed, the user should return `None` instead. ([#46])
- `EchoBroadcast` and `DirectMessage` now use `ProtocolMessagePart` trait for their methods. ([#47])
- Added normal broadcasts support in addition to echo ones; signatures of `Round` methods changed accordingly; added `Round::make_normal_broadcast()`. ([#47])
Expand Down
1 change: 1 addition & 0 deletions examples/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
extern crate alloc;

pub mod simple;
mod simple_chain;

#[cfg(test)]
mod simple_malicious;
10 changes: 6 additions & 4 deletions examples/src/simple.rs
Original file line number Diff line number Diff line change
Expand Up @@ -228,14 +228,15 @@ impl<Id: PartyId> Round<Id> for Round1<Id> {
_rng: &mut impl CryptoRngCore,
serializer: &Serializer,
destination: &Id,
) -> Result<DirectMessage, LocalError> {
) -> Result<(DirectMessage, Option<Artifact>), LocalError> {
debug!("{:?}: making direct message for {:?}", self.context.id, destination);

let message = Round1Message {
my_position: self.context.ids_to_positions[&self.context.id],
your_position: self.context.ids_to_positions[destination],
};
DirectMessage::new(serializer, message)
let dm = DirectMessage::new(serializer, message)?;
Ok((dm, None))
}

fn receive_message(
Expand Down Expand Up @@ -325,14 +326,15 @@ impl<Id: PartyId> Round<Id> for Round2<Id> {
_rng: &mut impl CryptoRngCore,
serializer: &Serializer,
destination: &Id,
) -> Result<DirectMessage, LocalError> {
) -> Result<(DirectMessage, Option<Artifact>), LocalError> {
debug!("{:?}: making direct message for {:?}", self.context.id, destination);

let message = Round2Message {
my_position: self.context.ids_to_positions[&self.context.id],
your_position: self.context.ids_to_positions[destination],
};
DirectMessage::new(serializer, message)
let dm = DirectMessage::new(serializer, message)?;
Ok((dm, None))
}

fn receive_message(
Expand Down
86 changes: 86 additions & 0 deletions examples/src/simple_chain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
use core::fmt::Debug;
use core::marker::PhantomData;

use manul::{combinators::*, protocol::PartyId};

use super::simple::{Inputs, Round1, SimpleProtocol};

pub struct ChainedSimple<Id>(PhantomData<Id>);

#[derive(Debug)]
pub struct NewInputs<Id>(Inputs<Id>);

impl<'a, Id: PartyId> From<&'a NewInputs<Id>> for Inputs<Id> {
fn from(source: &'a NewInputs<Id>) -> Self {
source.0.clone()
}
}

impl<Id: PartyId> From<(NewInputs<Id>, u8)> for Inputs<Id> {
fn from(source: (NewInputs<Id>, u8)) -> Self {
source.0 .0
}
}

impl<Id: PartyId> Chained<Id> for ChainedSimple<Id> {
type Protocol1 = SimpleProtocol;
type Protocol2 = SimpleProtocol;
type CorrectnessProof = ();
type Inputs = NewInputs<Id>;
type EntryPoint1 = Round1<Id>;
type EntryPoint2 = Round1<Id>;
}

#[cfg(test)]
mod tests {
use alloc::collections::BTreeSet;

use manul::{
combinators::Chain,
session::{signature::Keypair, SessionOutcome},
testing::{run_sync, BinaryFormat, TestSessionParams, TestSigner, TestVerifier},
};
use rand_core::OsRng;
use tracing_subscriber::EnvFilter;

use super::{ChainedSimple, NewInputs};
use crate::simple::Inputs;

#[test]
fn round() {
let signers = (0..3).map(TestSigner::new).collect::<Vec<_>>();
let all_ids = signers
.iter()
.map(|signer| signer.verifying_key())
.collect::<BTreeSet<_>>();
let inputs = signers
.into_iter()
.map(|signer| {
(
signer,
NewInputs(Inputs {
all_ids: all_ids.clone(),
}),
)
})
.collect::<Vec<_>>();

let my_subscriber = tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.finish();
let reports = tracing::subscriber::with_default(my_subscriber, || {
run_sync::<Chain<TestVerifier, ChainedSimple<TestVerifier>>, TestSessionParams<BinaryFormat>>(
&mut OsRng, inputs,
)
.unwrap()
});

for (_id, report) in reports {
if let SessionOutcome::Result(result) = report.outcome {
assert_eq!(result, 3); // 0 + 1 + 2
} else {
panic!("Session did not finish successfully");
}
}
}
}
Loading
Loading