Skip to content

Commit

Permalink
Merge pull request #6 from dfns/nostd
Browse files Browse the repository at this point in the history
no_std and wasm support
  • Loading branch information
survived authored May 16, 2024
2 parents d607fb7 + b1908cc commit fe42d6b
Show file tree
Hide file tree
Showing 19 changed files with 612 additions and 150 deletions.
44 changes: 35 additions & 9 deletions .github/workflows/rust.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,34 @@ env:
CARGO_NET_GIT_FETCH_WITH_CLI: true

jobs:
build-and-test:
check-no-features:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: "true"
- name: Build no features
run: cargo build -p round-based
- name: Build with tokio
run: cargo build -p round-based --features runtime-tokio
- name: Build with all features
run: cargo build -p round-based --all-features
- name: Run tests
run: cargo test --all-features
- name: cargo check
run: cargo check -p round-based --no-default-features
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: "true"
- name: cargo check
run: cargo check -p round-based
check-all-features:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: "true"
- name: cargo check
run: cargo check -p round-based --all-features

check-fmt:
runs-on: ubuntu-latest
steps:
Expand All @@ -48,3 +61,16 @@ jobs:
cache-on-failure: "true"
- name: Run clippy
run: cargo clippy --all --lib

build-wasm-nostd:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: "true"
- name: Install wasm32-unknown-unknown toolchain
run: rustup target add wasm32-unknown-unknown
- name: Build on wasm32-unknown-unknown (no_std)
run:
(cd wasm/no_std && cargo build --target wasm32-unknown-unknown)
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
/target
/wasm/no_std/target
.idea

.cargo/
Expand Down
56 changes: 27 additions & 29 deletions Cargo.lock

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

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ members = [
"round-based-derive",
"examples/random-generation-protocol",
]
exclude = [
"wasm/no_std",
]
22 changes: 14 additions & 8 deletions examples/random-generation-protocol/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,24 @@ publish = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
round-based = { path = "../../round-based", features = ["derive"] }
round-based = { path = "../../round-based", default-features = false, features = ["derive"] }

tokio = { version = "1.15", features = ["rt"] }
futures = "0.3"
rand = "0.8"
sha2 = "0.10"
serde = { version = "1", features = ["derive"] }
rand_core = { version = "0.6", default-features = false }
sha2 = { version = "0.10", default-features = false }
serde = { version = "1", default-features = false, features = ["derive"] }

displaydoc = { version = "0.2", default-features = false }
thiserror = { version = "1", optional = true }

# We don't use it directy, but we need to enable `serde` feature
generic-array = { version = "0.14", features = ["serde"] }
thiserror = "1"

[dev-dependencies]
round-based = { path = "../../round-based", features = ["derive", "dev"] }
tokio = { version = "1.15", features = ["macros", "rt"] }
futures = "0.3"
hex = "0.4"
rand_chacha = "0.3"
rand_dev = "0.1"

[features]
std = ["thiserror"]
84 changes: 62 additions & 22 deletions examples/random-generation-protocol/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,53 @@
use futures::SinkExt;
use rand::RngCore;
//! Simple protocol in which parties cooperate to generate randomness

#![no_std]
#![forbid(unused_crate_dependencies, missing_docs)]

#[cfg(feature = "std")]
extern crate std;

extern crate alloc;

mod _unused_deps {
// We don't use it directy, but we need to enable `serde` feature
use generic_array as _;
}

use alloc::{vec, vec::Vec};

use serde::{Deserialize, Serialize};
use sha2::{digest::Output, Digest, Sha256};
use thiserror::Error;

use round_based::rounds_router::{
simple_store::{RoundInput, RoundInputError},
CompleteRoundError, RoundsRouter,
};
use round_based::{Delivery, Mpc, MpcParty, MsgId, Outgoing, PartyIndex, ProtocolMessage};
use round_based::{Delivery, Mpc, MpcParty, MsgId, Outgoing, PartyIndex, ProtocolMessage, SinkExt};

/// Protocol message
#[derive(Clone, Debug, PartialEq, ProtocolMessage, Serialize, Deserialize)]
pub enum Msg {
/// Round 1
CommitMsg(CommitMsg),
/// Round 2
DecommitMsg(DecommitMsg),
}

/// Message from round 1
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct CommitMsg {
/// Party commitment
pub commitment: Output<Sha256>,
}

/// Message from round 2
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct DecommitMsg {
/// Randomness generated by party
pub randomness: [u8; 32],
}

/// Carries out the randomness generation protocol
pub async fn protocol_of_random_generation<R, M>(
party: M,
i: PartyIndex,
Expand All @@ -34,7 +56,7 @@ pub async fn protocol_of_random_generation<R, M>(
) -> Result<[u8; 32], Error<M::ReceiveError, M::SendError>>
where
M: Mpc<ProtocolMessage = Msg>,
R: RngCore,
R: rand_core::RngCore,
{
let MpcParty { delivery, .. } = party.into_party();
let (incoming, mut outgoing) = delivery.split();
Expand Down Expand Up @@ -109,48 +131,66 @@ where
}
}

#[derive(Debug, Error)]
/// Protocol error
#[derive(Debug, displaydoc::Display)]
#[cfg_attr(feature = "std", derive(thiserror::Error))]
pub enum Error<RecvErr, SendErr> {
#[error("send a message at round 1")]
Round1Send(#[source] SendErr),
#[error("receive messages at round 1")]
Round1Receive(#[source] CompleteRoundError<RoundInputError, RecvErr>),
#[error("send a message at round 2")]
Round2Send(#[source] SendErr),
#[error("receive messages at round 2")]
Round2Receive(#[source] CompleteRoundError<RoundInputError, RecvErr>),

#[error("malicious parties: {guilty_parties:?}")]
PartiesOpenedRandomnessDoesntMatchCommitment { guilty_parties: Vec<Blame> },
/// Couldn't send a message in the first round
#[displaydoc("send a message at round 1")]
Round1Send(#[cfg_attr(feature = "std", source)] SendErr),
/// Couldn't receive a message in the first round
#[displaydoc("receive messages at round 1")]
Round1Receive(
#[cfg_attr(feature = "std", source)] CompleteRoundError<RoundInputError, RecvErr>,
),
/// Couldn't send a message in the second round
#[displaydoc("send a message at round 2")]
Round2Send(#[cfg_attr(feature = "std", source)] SendErr),
/// Couldn't receive a message in the second round
#[displaydoc("receive messages at round 2")]
Round2Receive(
#[cfg_attr(feature = "std", source)] CompleteRoundError<RoundInputError, RecvErr>,
),

/// Some of the parties cheated
#[displaydoc("malicious parties: {guilty_parties:?}")]
PartiesOpenedRandomnessDoesntMatchCommitment {
/// List of cheated parties
guilty_parties: Vec<Blame>,
},
}

/// Blames a party in cheating during the protocol
#[derive(Debug)]
pub struct Blame {
/// Index of the cheated party
pub guilty_party: PartyIndex,
/// ID of the message that party sent in the first round
pub commitment_msg: MsgId,
/// ID of the message that party sent in the second round
pub decommitment_msg: MsgId,
}

#[cfg(test)]
mod tests {
use rand::SeedableRng;
use rand_chacha::ChaCha20Rng;
use alloc::vec;

use round_based::simulation::Simulation;

use super::{protocol_of_random_generation, Msg};

#[tokio::test]
async fn main() {
let mut rng = rand_dev::DevRng::new();

let n: u16 = 5;

let mut simulation = Simulation::<Msg>::new();
let mut party_output = vec![];

for i in 0..n {
let party = simulation.add_party();
let rng = ChaCha20Rng::from_entropy();
let output = protocol_of_random_generation(party, i, n, rng);
let output = protocol_of_random_generation(party, i, n, rng.fork());
party_output.push(output);
}

Expand All @@ -161,6 +201,6 @@ mod tests {
assert_eq!(output[0], output[usize::from(i)]);
}

println!("Output randomness: {}", hex::encode(output[0]));
std::println!("Output randomness: {}", hex::encode(output[0]));
}
}
5 changes: 5 additions & 0 deletions round-based/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## v0.3.0
* Add no_std and wasm support [#6]

[#6]: https://github.com/dfns/round-based/pull/6

## v0.2.2

* fix: correct handling of stores that need no messages in RoundsRouter [#4]
Expand Down
Loading

0 comments on commit fe42d6b

Please sign in to comment.