diff --git a/pycare/Cargo.toml b/pycare/Cargo.toml index aec93a3..2da0a53 100644 --- a/pycare/Cargo.toml +++ b/pycare/Cargo.toml @@ -9,5 +9,5 @@ name = "caring" crate-type = ["cdylib"] [dependencies] -pyo3 = { version = "0.21", features = ["abi3-py37", "generate-import-lib"]} +pyo3 = { version = "0.21", features = ["abi3-py37", "generate-import-lib", "extension-module"]} wecare = { path = "../wecare" } diff --git a/src/marker/exptree.rs b/src/marker/exptree.rs index a2d6205..2c24084 100644 --- a/src/marker/exptree.rs +++ b/src/marker/exptree.rs @@ -88,4 +88,5 @@ impl ExpTree { Some(res) } + } diff --git a/src/marker/mod.rs b/src/marker/mod.rs index c189710..8ceef16 100644 --- a/src/marker/mod.rs +++ b/src/marker/mod.rs @@ -1,8 +1,9 @@ mod exptree; +use rand::RngCore; use serde::{de::DeserializeOwned, Deserialize, Serialize}; -use crate::{net::Communicate, schemes::{Shared, Verify}}; +use crate::{net::Communicate, schemes::{interactive::InteractiveShared, Shared, Verify}}; #[repr(transparent)] @@ -31,12 +32,39 @@ impl Unverified { None } } +} +impl Unverified { pub fn assume_verified(self) -> Verified { Verified(self.0) } } + +impl Verified { + pub async fn open(self, ctx: &S::Context, coms: impl Communicate) -> Result { + S::recombine(ctx, self.0, coms).await + } + + pub async fn share(val: S::Value, ctx: &S::Context, rng: impl RngCore + Send, coms: impl Communicate) -> Result { + let s = S::share(ctx, val, rng, coms).await?; + Ok(Self(s)) + } + +} + +impl Unverified { + pub async fn share_symmetric(val: S::Value, ctx: &S::Context, rng: impl RngCore + Send, coms: impl Communicate) -> Result, S::Error> { + let s = S::symmetric_share(ctx, val, rng, coms).await?; + Ok(s.into_iter().map(Self).collect()) + } + + pub async fn receive_share(ctx: &S::Context, coms: impl Communicate, from: usize) -> Result { + let s = S::receive_share(ctx, coms, from).await?; + Ok(Self(s)) + } +} + impl From>> for Vec> { fn from(value: Unverified>) -> Self { value.0.into_iter().map(|t| Unverified(t)).collect() @@ -58,18 +86,12 @@ impl Unverified> { }).collect(); Verified(res) } - - - pub fn assume_verified(self) -> Verified { - todo!() - } } // Pure boring manual operator implementations // Could be done with some macros instead. mod ops { - use std::ops::{Add, Sub}; - + use std::ops::{Add, Mul, Sub}; use crate::schemes::Shared; use super::*; @@ -121,8 +143,23 @@ mod ops { Self(self.0 - rhs.0) } } -} + impl Mul for Verified where S: Mul { + type Output = Self; + + fn mul(self, rhs: S::Value) -> Self::Output { + Self(self.0 * rhs) + } + } + + impl Mul for Unverified where S: Mul { + type Output = Self; + + fn mul(self, rhs: S::Value) -> Self::Output { + Self(self.0 * rhs) + } + } +} #[cfg(test)] mod test { @@ -142,7 +179,7 @@ mod test { me: 0, }; let mut rng = rngs::mock::StepRng::new(0, 0); - let s = mock::Share::share(&ctx, Mod11(3), &mut rng); + let s = as Shared>::share(&ctx, Mod11(3), &mut rng); let s = Verified(s[0]); let s0 = s.clone(); let s = s0 + s; diff --git a/src/schemes/mod.rs b/src/schemes/mod.rs index aca6f32..405fe00 100644 --- a/src/schemes/mod.rs +++ b/src/schemes/mod.rs @@ -32,13 +32,12 @@ use std::{ }; use rand::RngCore; -use serde::{de::DeserializeOwned, Deserialize, Serialize}; use crate::net::Communicate; /// Currently unused trait, but might be a better way to represent that a share /// can be multiplied by a const, however, it could also just be baked into 'Shared' directly. -trait MulByConst: +pub trait MulByConst: Shared + std::ops::Mul + std::ops::MulAssign { } @@ -143,12 +142,27 @@ pub trait InteractiveMult: Shared { ) -> impl Future>>; } -mod interactive { +pub mod interactive { + use thiserror::Error; + + use crate::net::Tuneable; + + + #[derive(Debug, Error)] + #[error("Communication failure: {0}")] + pub struct CommunicationError(Box); + impl CommunicationError { + fn new(e: impl Error + Send + 'static) -> Self { + Self(Box::new(e)) + } + + } + use super::*; impl InteractiveShared for S where S: Shared + Send, V: Send + Clone, C: Send + Sync + Clone { type Context = S::Context; type Value = V; - type Error = Box; + type Error = CommunicationError; async fn share( ctx: &Self::Context, @@ -158,11 +172,7 @@ mod interactive { ) -> Result { let shares = S::share(ctx, secret, rng); let my_share = shares[coms.id()].clone(); - coms.unicast(&shares).await.map_err(|e| { - let e : Box = Box::new(e); - e - } - )?; + coms.unicast(&shares).await.map_err(CommunicationError::new)?; Ok(my_share) } @@ -171,7 +181,7 @@ mod interactive { secret: Self, mut coms: impl Communicate, ) -> Result { - let shares = coms.symmetric_broadcast(secret).await.unwrap(); + let shares = coms.symmetric_broadcast(secret).await.map_err(CommunicationError::new)?; Ok(Shared::recombine(ctx, &shares).unwrap()) } @@ -182,9 +192,19 @@ mod interactive { mut coms: impl Communicate, ) -> Result, Self::Error> { let shares = S::share(ctx, secret, rng); - let shared = coms.symmetric_unicast(shares).await.unwrap(); + let shared = coms.symmetric_unicast(shares).await.map_err(CommunicationError::new)?; Ok(shared) } + + async fn receive_share( + _ctx: &Self::Context, + mut coms: impl Communicate, + from: usize, + ) -> Result { + let s = Tuneable::recv_from(&mut coms, from).await; + let s = s.map_err(CommunicationError::new)?; + Ok(s) + } } @@ -215,6 +235,12 @@ mod interactive { coms: impl Communicate, ) -> impl std::future::Future, Self::Error>>; + fn receive_share( + ctx: &Self::Context, + coms: impl Communicate, + from: usize, + ) -> impl std::future::Future>; + fn recombine( ctx: &Self::Context, secrets: Self,