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/algebra/poly.rs b/src/algebra/poly.rs index 89cdd11..48bdf8c 100644 --- a/src/algebra/poly.rs +++ b/src/algebra/poly.rs @@ -62,7 +62,7 @@ impl Polynomial { /// /// * `degree`: the degree of the polynomial /// * `rng`: random number generator to use - pub fn random(degree: usize, mut rng: &mut impl RngCore) -> Self { + pub fn random(degree: usize, mut rng: impl RngCore) -> Self { (0..=degree).map(|_| F::random(&mut rng)).collect() } } diff --git a/src/lib.rs b/src/lib.rs index 33e5583..0e6fffa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,7 @@ #![deny(unsafe_code)] #![allow(refining_impl_trait)] #![allow(dead_code)] +#![feature(async_fn_traits)] mod algebra; pub mod net; @@ -9,5 +10,6 @@ mod protocols; pub mod schemes; mod help; +pub mod marker; #[cfg(test)] mod testing; diff --git a/src/marker/exptree.rs b/src/marker/exptree.rs new file mode 100644 index 0000000..047c52a --- /dev/null +++ b/src/marker/exptree.rs @@ -0,0 +1,109 @@ +use crate::net::Communicate; +use std::{ + collections::BTreeMap, + ops::AsyncFn, + sync::{ + atomic::{AtomicU32, Ordering::SeqCst}, + Mutex, + }, +}; +#[derive(Clone)] +pub enum Status { + Verified, + Unverified { + parents: (u32, u32), + data: Option, + }, + Failure, +} + +pub struct ExpTree { + tree: Mutex>>, + issuer: AtomicU32, +} + +impl ExpTree { + fn issue(&self) -> u32 { + let curr = self.issuer.fetch_update(SeqCst, SeqCst, |n| Some(n + 1)); + curr.expect("Never fails since lambda always returns Some") + } + + pub fn add_dependent(&self, a: u32, b: u32) -> u32 { + let new = self.issue(); + let status: Status = Status::Unverified { + parents: (a, b), + data: None, + }; + { + let mut tree = self.tree.lock().unwrap(); + tree.insert(new, status); + } + new + } + + pub fn add_dependent_with(&self, a: u32, b: u32, data: T) -> u32 { + let new = self.issue(); + let data = Some(data); + let status = Status::Unverified { + parents: (a, b), + data, + }; + { + let mut tree = self.tree.lock().unwrap(); + tree.insert(new, status); + } + new + } + + pub fn add_root(&self) -> u32 { + let new = self.issue(); + let status = Status::Verified; + { + let mut tree = self.tree.lock().unwrap(); + tree.insert(new, status); + } + new + } + + pub async fn verify(&mut self, id: u32, verify_fn: F, coms: C) -> Option + where + F: AsyncFn(Vec, C) -> Option, + C: Communicate, + { + let mut to_check = vec![]; + let mut datas: Vec = vec![]; + let mut checking = vec![]; + checking.push(id); + + let tree = self.tree.get_mut().unwrap(); + + while let Some(id) = checking.pop() { + let t = tree.get(&id)?; + match t { + Status::Failure => todo!("Taint dependent values -or- crash and burn"), + Status::Verified => (), + Status::Unverified { parents, data } => { + checking.push(parents.0); + checking.push(parents.1); + if let Some(data) = data { + datas.push(data.clone()); + } + to_check.push(id); + } + } + } + + let res = verify_fn.async_call((datas, coms)).await?; + let status = if res { + Status::Verified + } else { + Status::Failure + }; + + for id in to_check { + tree.insert(id, status.clone()); + } + + Some(res) + } +} diff --git a/src/marker/mod.rs b/src/marker/mod.rs new file mode 100644 index 0000000..ba7bea3 --- /dev/null +++ b/src/marker/mod.rs @@ -0,0 +1,221 @@ +mod exptree; + +use rand::RngCore; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; + +use crate::{ + net::Communicate, + schemes::{interactive::InteractiveShared, Shared, Verify}, +}; + +#[repr(transparent)] +#[derive(Serialize, Debug, Clone)] +pub struct Verified(S); + +#[repr(transparent)] +#[derive(Serialize, Debug, Clone)] +pub struct Unverified(S); + +impl<'de, S: Shared + DeserializeOwned> Deserialize<'de> for Unverified { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + Deserialize::deserialize(deserializer).map(|s| Unverified(s)) + } +} + +impl Unverified { + pub async fn verify(self, coms: impl Communicate, args: S::Args) -> Option> { + if self.0.verify(coms, args).await { + Some(Verified(self.0)) + } else { + 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() + } +} + +impl From>> for Vec> { + fn from(value: Verified>) -> Self { + value.0.into_iter().map(|t| Verified(t)).collect() + } +} + +impl Unverified> { + pub async fn verify_all( + self, + coms: impl Communicate, + args: S::Args, + ) -> Verified>> { + let res = S::verify_many(&self.0, coms, args).await; + let res = res + .into_iter() + .zip(self.0) + .map(|(verified, t)| verified.then_some(t)) + .collect(); + Verified(res) + } +} + +// Pure boring manual operator implementations +// Could be done with some macros instead. +mod ops { + use crate::schemes::Shared; + use std::ops::{Add, Mul, Sub}; + + use super::*; + + impl Add for Verified { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) + } + } + + impl Sub for Verified { + type Output = Self; + + fn sub(self, rhs: Self) -> Self::Output { + Self(self.0 - rhs.0) + } + } + + impl Add> for Verified { + type Output = Unverified; + + fn add(self, rhs: Unverified) -> Self::Output { + Unverified(self.0 + rhs.0) + } + } + + impl Sub> for Verified { + type Output = Unverified; + + fn sub(self, rhs: Unverified) -> Self::Output { + Unverified(self.0 - rhs.0) + } + } + + impl Add for Unverified { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + Self(self.0 + rhs.0) + } + } + + impl Sub for Unverified { + type Output = Self; + + fn sub(self, rhs: Self) -> Self::Output { + 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 { + use super::*; + + use rand::rngs; + + use crate::{ + algebra::element::Mod11, + testing::mock::{self, Share}, + }; + + #[test] + fn serdede() { + let ctx = mock::Context { + all_parties: 1, + me: 0, + }; + let mut rng = rngs::mock::StepRng::new(0, 0); + let s = as Shared>::share(&ctx, Mod11(3), &mut rng); + let s = Verified(s[0]); + let s0 = s.clone(); + let s = s0 + s; + + let to_send = bincode::serialize(&s).unwrap(); + // sending... + let back_again: Unverified> = bincode::deserialize(&to_send).unwrap(); + + println!("Hello again {back_again:?}"); + } +} diff --git a/src/net/agency.rs b/src/net/agency.rs index 0ed3e13..a6936ed 100644 --- a/src/net/agency.rs +++ b/src/net/agency.rs @@ -28,7 +28,7 @@ use futures::Future; use itertools::Itertools; pub trait Broadcast { - type Error: Error + 'static; + type Error: Error + Send + 'static; // type Error: Error + 'static; /// Broadcast a message to all other parties. @@ -67,9 +67,41 @@ pub trait Broadcast { fn size(&self) -> usize; } +impl<'a, B: Broadcast> Broadcast for &'a mut B { + type Error = B::Error; + + fn broadcast( + &mut self, + msg: &(impl serde::Serialize + Sync), + ) -> impl std::future::Future> { + (**self).broadcast(msg) + } + + fn symmetric_broadcast( + &mut self, + msg: T, + ) -> impl Future, Self::Error>> + where + T: serde::Serialize + serde::de::DeserializeOwned + Sync, + { + (**self).symmetric_broadcast(msg) + } + + fn recv_from( + &mut self, + idx: usize, + ) -> impl Future> { + (**self).recv_from(idx) + } + + fn size(&self) -> usize { + (**self).size() + } +} + // TODO: Possible rename this trait as it's name is confusing. pub trait Unicast { - type Error: Error + 'static; + type Error: Error + Send + 'static; /// Unicast messages to each party /// @@ -110,6 +142,37 @@ pub trait Unicast { fn size(&self) -> usize; } +impl<'a, U: Unicast> Unicast for &'a mut U { + type Error = U::Error; + + fn size(&self) -> usize { + (**self).size() + } + + fn receive_all( + &mut self, + ) -> impl Future, Self::Error>> { + (**self).receive_all() + } + + fn unicast( + &mut self, + msgs: &[impl serde::Serialize + Sync], + ) -> impl std::future::Future> { + (**self).unicast(msgs) + } + + fn symmetric_unicast( + &mut self, + msgs: Vec, + ) -> impl Future, Self::Error>> + where + T: serde::Serialize + serde::de::DeserializeOwned + Sync, + { + (**self).symmetric_unicast(msgs) + } +} + use digest::Digest; use tracing::{event, Level}; diff --git a/src/net/mod.rs b/src/net/mod.rs index 826de45..0f5d3d1 100644 --- a/src/net/mod.rs +++ b/src/net/mod.rs @@ -2,10 +2,7 @@ use std::error::Error; use futures::Future; -use crate::net::{ - connection::{Connection, ConnectionError, RecvBytes, SendBytes}, - network::Network, -}; +use crate::net::connection::{Connection, ConnectionError, RecvBytes, SendBytes}; pub mod agency; pub mod connection; @@ -56,9 +53,26 @@ pub trait SplitChannel: Channel { fn split(&mut self) -> (&mut Self::Sender, &mut Self::Receiver); } +impl<'a, C: Channel> Channel for &'a mut C { + type Error = C::Error; + + fn send( + &mut self, + msg: &T, + ) -> impl Future> + Send { + (**self).send(msg) + } + + fn recv( + &mut self, + ) -> impl Future> + Send { + (**self).recv() + } +} + /// Tune to a specific channel pub trait Tuneable { - type Error: Error + 'static; + type Error: Error + Send + 'static; fn id(&self) -> usize; @@ -74,27 +88,29 @@ pub trait Tuneable { ) -> impl std::future::Future>; } -impl Tuneable for Network { - type Error = C::Error; +impl<'a, R: Tuneable + ?Sized> Tuneable for &'a mut R { + type Error = R::Error; fn id(&self) -> usize { - self.index + (**self).id() } - async fn recv_from( + fn recv_from( &mut self, idx: usize, - ) -> Result { - let idx = self.id_to_index(idx); - self.connections[idx].recv().await + ) -> impl Future> { + (**self).recv_from(idx) } - async fn send_to( + fn send_to( &mut self, idx: usize, msg: &T, - ) -> Result<(), Self::Error> { - let idx = self.id_to_index(idx); - self.connections[idx].send(msg).await + ) -> impl std::future::Future> { + (**self).send_to(idx, msg) } } + +/// General communication with support for most network functionality. +pub trait Communicate: agency::Broadcast + agency::Unicast + Tuneable + Send {} +impl<'a, C: Communicate> Communicate for &'a mut C {} diff --git a/src/net/network.rs b/src/net/network.rs index 2b10136..cafca33 100644 --- a/src/net/network.rs +++ b/src/net/network.rs @@ -357,6 +357,31 @@ impl Broadcast for Network { } } +impl Tuneable for Network { + type Error = C::Error; + + fn id(&self) -> usize { + self.index + } + + async fn recv_from( + &mut self, + idx: usize, + ) -> Result { + let idx = self.id_to_index(idx); + self.connections[idx].recv().await + } + + async fn send_to( + &mut self, + idx: usize, + msg: &T, + ) -> Result<(), Self::Error> { + let idx = self.id_to_index(idx); + self.connections[idx].send(msg).await + } +} + /// Network containing only duplex connections. /// Used for local testing. pub type InMemoryNetwork = Network; diff --git a/src/protocols/beaver.rs b/src/protocols/beaver.rs index 2bf566d..c50ec5d 100644 --- a/src/protocols/beaver.rs +++ b/src/protocols/beaver.rs @@ -31,15 +31,15 @@ impl> BeaverTriple { let b = F::random(&mut rng); let c: F = a * b; // Share (preproccess) - let a = S::share(ctx, a, rng); - let b = S::share(ctx, b, rng); - let c = S::share(ctx, c, rng); + let a = S::share(ctx, a, &mut rng); + let b = S::share(ctx, b, &mut rng); + let c = S::share(ctx, c, &mut rng); itertools::izip!(a, b, c) .map(|(a, b, c)| Self { shares: (a, b, c) }) .collect() } - pub fn fake_many(ctx: &C, mut rng: &mut impl RngCore, count: usize) -> Vec> { + pub fn fake_many(ctx: &C, mut rng: impl RngCore, count: usize) -> Vec> { let zipped = iter::from_fn(|| { let a = F::random(&mut rng); let b = F::random(&mut rng); @@ -49,9 +49,9 @@ impl> BeaverTriple { .take(count); let (a, b, c): (Vec<_>, Vec<_>, Vec<_>) = multiunzip(zipped); // Share (preproccess) - let a = S::share_many(ctx, &a, rng); - let b = S::share_many(ctx, &b, rng); - let c = S::share_many(ctx, &c, rng); + let a = S::share_many(ctx, &a, &mut rng); + let b = S::share_many(ctx, &b, &mut rng); + let c = S::share_many(ctx, &c, &mut rng); itertools::izip!(a, b, c) .map(|(a, b, c)| { @@ -164,12 +164,12 @@ pub struct BeaverSquare { } impl> BeaverSquare { - pub fn fake(ctx: &C, mut rng: &mut impl RngCore) -> Vec { + pub fn fake(ctx: &C, mut rng: impl RngCore) -> Vec { let a = F::random(&mut rng); let c: F = a * a; // Share (preproccess) - let a = S::share(ctx, a, rng); - let c = S::share(ctx, c, rng); + let a = S::share(ctx, a, &mut rng); + let c = S::share(ctx, c, &mut rng); itertools::izip!(a, c) .map(|(a, c)| Self { val: a, diff --git a/src/schemes/feldman.rs b/src/schemes/feldman.rs index 7feb1a8..3b09775 100644 --- a/src/schemes/feldman.rs +++ b/src/schemes/feldman.rs @@ -38,7 +38,7 @@ pub fn share( val: F, ids: &[F], threshold: u64, - rng: &mut impl RngCore, + mut rng: impl RngCore, ) -> Vec> where G: std::ops::Mul, @@ -55,7 +55,7 @@ where // Sample random t-degree polynomial let n = ids.len(); - let poly = (1..threshold).map(|_| F::random(&mut *rng)); + let poly = (1..threshold).map(|_| F::random(&mut rng)); // I want to avoid this allocation :( let poly: Box<[F]> = iter::once(val).chain(poly).collect(); let mac_poly: Vector<_> = poly.iter().map(|a| G::generator() * *a).collect(); @@ -144,7 +144,7 @@ impl< type Context = ShamirParams; type Value = F; - fn share(ctx: &Self::Context, secret: F, rng: &mut impl RngCore) -> Vec { + fn share(ctx: &Self::Context, secret: F, rng: impl RngCore) -> Vec { share::(secret, &ctx.ids, ctx.threshold, rng) } @@ -267,7 +267,7 @@ pub fn share_many( vals: &[F], ids: &[F], threshold: u64, - rng: &mut impl RngCore, + mut rng: impl RngCore, ) -> Vec> // FIX: This `where` clause is a bit much, it does however work. where @@ -289,7 +289,7 @@ where let polys: Vec<_> = vals .iter() .map(|v| { - let mut p = Polynomial::::random(threshold as usize - 1, rng); + let mut p = Polynomial::::random(threshold as usize - 1, &mut rng); p.0[0] = *v; p }) diff --git a/src/schemes/mod.rs b/src/schemes/mod.rs index 867ae82..b529273 100644 --- a/src/schemes/mod.rs +++ b/src/schemes/mod.rs @@ -27,21 +27,17 @@ pub mod spdz; use std::{ error::Error, + future::Future, ops::{Add, Sub}, }; -use futures::Future; - use rand::RngCore; -use crate::net::{ - agency::{Broadcast, Unicast}, - Tuneable, -}; +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 { } @@ -73,7 +69,7 @@ pub trait Shared: /// * `secret`: secret value to share /// * `rng`: cryptographic secure random number generator /// - fn share(ctx: &Self::Context, secret: Self::Value, rng: &mut impl RngCore) -> Vec; + fn share(ctx: &Self::Context, secret: Self::Value, rng: impl RngCore) -> Vec; /// Recombine the shares back into a secret, /// returning an value if successfull. @@ -87,11 +83,11 @@ pub trait Shared: fn share_many( ctx: &Self::Context, secrets: &[Self::Value], - rng: &mut impl RngCore, + mut rng: impl RngCore, ) -> Vec> { let shares: Vec<_> = secrets .iter() - .map(|secret| Self::share(ctx, secret.clone(), rng)) + .map(|secret| Self::share(ctx, secret.clone(), &mut rng)) .collect(); crate::help::transpose(shares) } @@ -121,21 +117,6 @@ pub trait Shared: } } -pub trait SharedVec: - Sized - + Add - + Sub - + serde::Serialize - + serde::de::DeserializeOwned - + Clone -{ - type Value; - type Context: Send + Clone; - - fn share(ctx: &Self::Context, secrets: &[Self::Value], rng: &mut impl RngCore) -> Self; - fn recombine(ctx: &Self::Context, shares: &[Self], rng: &mut impl RngCore) -> Vec; -} - /// Support for multiplication of two shares for producing a share. /// /// Note, that this is different to beaver multiplication as it does not require @@ -151,10 +132,140 @@ pub trait InteractiveMult: Shared { /// /// Returns a result which contains the shared value corresponding /// to the multiplication of `a` and `b`. - fn interactive_mult( + fn interactive_mult( ctx: &Self::Context, net: &mut U, a: Self, b: Self, ) -> impl Future>>; } + +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 = CommunicationError; + + async fn share( + ctx: &Self::Context, + secret: Self::Value, + rng: impl RngCore + Send, + mut coms: impl Communicate, + ) -> Result { + let shares = S::share(ctx, secret, rng); + let my_share = shares[coms.id()].clone(); + coms.unicast(&shares) + .await + .map_err(CommunicationError::new)?; + Ok(my_share) + } + + async fn recombine( + ctx: &Self::Context, + secret: Self, + mut coms: impl Communicate, + ) -> Result { + let shares = coms + .symmetric_broadcast(secret) + .await + .map_err(CommunicationError::new)?; + Ok(Shared::recombine(ctx, &shares).unwrap()) + } + + async fn symmetric_share( + ctx: &Self::Context, + secret: Self::Value, + rng: impl RngCore + Send, + mut coms: impl Communicate, + ) -> Result, Self::Error> { + let shares = S::share(ctx, secret, rng); + 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) + } + } + + pub trait InteractiveShared: + Sized + + Add + + Sub + + serde::Serialize + + serde::de::DeserializeOwned + + Clone + + Sync + { + type Context: Sync + Send + Clone; + type Value: Clone + Send; + type Error: Send + Sized + 'static; + + fn share( + ctx: &Self::Context, + secret: Self::Value, + rng: impl RngCore + Send, + coms: impl Communicate, + ) -> impl std::future::Future>; + + fn symmetric_share( + ctx: &Self::Context, + secret: Self::Value, + rng: impl RngCore + Send, + 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, + coms: impl Communicate, + ) -> impl std::future::Future>; + } +} + +pub trait Verify: Sized { + type Args: Send; + + fn verify(&self, coms: impl Communicate, args: Self::Args) + -> impl Future + Send; + + fn verify_many( + batch: &[Self], + coms: impl Communicate, + args: Self::Args, + ) -> impl Future> + Send; +} diff --git a/src/schemes/pedersen.rs b/src/schemes/pedersen.rs index fa07a25..9275a4f 100644 --- a/src/schemes/pedersen.rs +++ b/src/schemes/pedersen.rs @@ -37,7 +37,7 @@ pub fn share( secret: F, ids: &[F], threshold: usize, - rng: &mut impl RngCore, + mut rng: impl RngCore, PedersenGenParams(g, h): &PedersenGenParams, ) -> Vec> where @@ -45,8 +45,8 @@ where F: Field, G: Group, { - let mut p1: Polynomial = Polynomial::random(threshold, rng); - let p2: Polynomial = Polynomial::random(threshold, rng); + let mut p1: Polynomial = Polynomial::random(threshold, &mut rng); + let p2: Polynomial = Polynomial::random(threshold, &mut rng); // secret `s` p1.0[0] = secret; // random secret `t` (left random) @@ -112,7 +112,7 @@ where type Value = F; - fn share(ctx: &Self::Context, secret: Self::Value, rng: &mut impl RngCore) -> Vec { + fn share(ctx: &Self::Context, secret: Self::Value, rng: impl RngCore) -> Vec { share(secret, &ctx.ids, ctx.threshold, rng, &ctx.pedersen_params) } diff --git a/src/schemes/rep3.rs b/src/schemes/rep3.rs index 56b394b..00a17d4 100644 --- a/src/schemes/rep3.rs +++ b/src/schemes/rep3.rs @@ -15,7 +15,7 @@ use crate::{net::Tuneable, schemes::InteractiveMult}; #[derive(Debug, Clone, Copy, Add, Sub, Serialize, Deserialize)] pub struct Share(F, F); -pub fn share(secret: F, mut rng: &mut impl RngCore) -> [Share; 3] { +pub fn share(secret: F, mut rng: impl RngCore) -> [Share; 3] { let mut shares = [0; 3].map(|_| F::random(&mut rng)); let sum = shares[0] + shares[1] + shares[2]; shares[0] += secret - sum; @@ -31,8 +31,8 @@ impl super::Shared for Share { type Context = (); type Value = F; - fn share(_ctx: &Self::Context, secret: F, rng: &mut impl RngCore) -> Vec { - share(secret, rng).to_vec() + fn share(_ctx: &Self::Context, secret: F, mut rng: impl RngCore) -> Vec { + share(secret, &mut rng).to_vec() } fn recombine(_ctx: &Self::Context, shares: &[Self]) -> Option { diff --git a/src/schemes/shamir.rs b/src/schemes/shamir.rs index c107e0a..36522b7 100644 --- a/src/schemes/shamir.rs +++ b/src/schemes/shamir.rs @@ -39,8 +39,8 @@ impl super::Shared fo type Context = ShamirParams; type Value = F; - fn share(ctx: &Self::Context, secret: F, rng: &mut impl RngCore) -> Vec { - share(secret, &ctx.ids, ctx.threshold, rng) + fn share(ctx: &Self::Context, secret: F, mut rng: impl RngCore) -> Vec { + share(secret, &ctx.ids, ctx.threshold, &mut rng) } fn recombine(ctx: &Self::Context, shares: &[Self]) -> Option { @@ -343,8 +343,8 @@ impl super::Shared for VecSh type Value = Vec; - fn share(ctx: &Self::Context, secret: Self::Value, rng: &mut impl RngCore) -> Vec { - share_many(&secret, &ctx.ids, ctx.threshold, rng) + fn share(ctx: &Self::Context, secret: Self::Value, mut rng: impl RngCore) -> Vec { + share_many(&secret, &ctx.ids, ctx.threshold, &mut rng) } fn recombine(ctx: &Self::Context, shares: &[Self]) -> Option { @@ -447,7 +447,7 @@ pub fn share_many( vs: &[F], ids: &[F], threshold: u64, - rng: &mut impl RngCore, + mut rng: impl RngCore, ) -> Vec> { // FIX: Code duplication with 'share' let n = ids.len(); @@ -461,7 +461,7 @@ pub fn share_many( let polynomials: Vec<_> = vs .iter() .map(|v| { - let mut p = Polynomial::random(threshold as usize - 1, rng); + let mut p = Polynomial::random(threshold as usize - 1, &mut rng); p.0[0] = *v; p }) diff --git a/src/testing/mock.rs b/src/testing/mock.rs index 4137a92..f250328 100644 --- a/src/testing/mock.rs +++ b/src/testing/mock.rs @@ -83,7 +83,7 @@ impl Shared for Shar fn share( ctx: &Self::Context, secret: Self::Value, - _rng: &mut impl rand::prelude::RngCore, + _rng: impl rand::prelude::RngCore, ) -> Vec { (0..ctx.all_parties) .map(|i| Share {