Skip to content

Commit

Permalink
Engine builder
Browse files Browse the repository at this point in the history
  • Loading branch information
quackzar committed Aug 22, 2024
1 parent be182a3 commit 74d39ad
Show file tree
Hide file tree
Showing 4 changed files with 257 additions and 19 deletions.
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#![allow(dead_code)]
#![allow(clippy::cast_possible_truncation)]
#![feature(async_fn_traits)]
#![feature(async_closure)]

pub mod algebra;
pub mod net;
Expand Down
10 changes: 10 additions & 0 deletions src/vm/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
pub mod parsing;

use std::future::Future;

Check failure on line 3 in src/vm/mod.rs

View workflow job for this annotation

GitHub Actions / cargo test

unused import: `std::future::Future`

use ff::Field;
use itertools::Itertools;
use rand::RngCore;
Expand Down Expand Up @@ -269,6 +271,14 @@ where
}
Ok(())
}

pub async fn raw<Func, Out>(&mut self, routine: Func) -> Out
where
Func: async Fn(&mut Network<C>, &S::Context, &mut R) -> Out,
{
// TODO: Add other resources.
routine(&mut self.network, &mut self.context, &mut self.rng).await
}
}

#[cfg(test)]
Expand Down
1 change: 1 addition & 0 deletions wecare/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#![feature(async_closure)]
pub mod vm;

use caring::{
Expand Down
264 changes: 245 additions & 19 deletions wecare/src/vm.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
use curve25519_dalek::Scalar;
use fixed::{FixedI128, FixedI32};
use rand::rngs::StdRng;
use std::{fs::File, net::SocketAddr, path::Path};

use curve25519_dalek::{RistrettoPoint, Scalar};
use fixed::{FixedI128, FixedI32};
use rand::{rngs::StdRng, SeedableRng};

use caring::{
algebra::element::Element32,
net::connection::TcpConnection,
schemes::{feldman, shamir, spdz},
algebra::{element::Element32, math::Vector},
net::{agency::Broadcast, connection::TcpConnection, network::TcpNetwork},
schemes::{
feldman,
interactive::{InteractiveShared, InteractiveSharedMany},
shamir, spdz,
},
vm::{self, parsing::Exp},
};

use crate::Mapping;

pub enum Number {
Float(f64),
Integer(u64),
Expand Down Expand Up @@ -71,20 +78,18 @@ impl TryFrom<Number> for Scalar {
}

#[derive(Clone, Copy)]
pub enum UnknownNumber{
pub enum UnknownNumber {
U32(u32),
U64(u64),
U128(u128),
}


impl UnknownNumber {

pub fn to_u64(self) -> u64 {
match self {
UnknownNumber::U32(a) => a.into(),
UnknownNumber::U64(a) => a,
UnknownNumber::U128(a) => a as u64
UnknownNumber::U128(a) => a as u64,
}
}

Expand All @@ -102,7 +107,7 @@ impl UnknownNumber {
UnknownNumber::U128(val) => {
let num = FixedI128::<64>::from_bits(val as i128);
num.to_num()
},
}
}
}
}
Expand Down Expand Up @@ -130,27 +135,248 @@ type ShamirElement32Engine = ShamirEngine<caring::algebra::element::Element32>;
type SpdzCurve25519Engine = SpdzEngine<curve25519_dalek::Scalar>;
type SpdzElement32Engine = SpdzEngine<caring::algebra::element::Element32>;


pub type Expr = Exp<Number>;

pub enum Engine {
Spdz(SpdzCurve25519Engine),
Shamir(ShamirElement32Engine),
Spdz25519(SpdzCurve25519Engine),
Spdz32(SpdzElement32Engine),
Shamir25519(ShamirCurve25519Engine),
Shamir32(ShamirElement32Engine),
Feldman25519(FeldmanEngine<Scalar, RistrettoPoint>),
}

impl Engine {
pub fn builder<'a>() -> EngineBuilder<'a> {
EngineBuilder::default()
}

pub async fn execute(&mut self, expr: Expr) -> UnknownNumber {
let res: UnknownNumber = match self {
Engine::Spdz(engine) => {
Engine::Spdz25519(engine) => {
let res = engine.execute(&expr.open().try_finalize().unwrap()).await;
res.into()
}
Engine::Shamir(engine) => {
engine.execute(&expr.open().try_finalize().unwrap()).await.into()
Engine::Shamir32(engine) => engine
.execute(&expr.open().try_finalize().unwrap())
.await
.into(),
Engine::Spdz32(engine) => {
let res = engine.execute(&expr.open().try_finalize().unwrap()).await;
res.into()
}
Engine::Shamir25519(engine) => {
let res = engine.execute(&expr.open().try_finalize().unwrap()).await;
res.into()
}
Engine::Feldman25519(engine) => {
let res = engine.execute(&expr.open().try_finalize().unwrap()).await;
res.into()
}
_ => panic!("unsupported!"),
};

res
}

// pub async fn raw<S, Func, O>(&mut self, routine: Func) -> O
// where S: InteractiveShared,
// Func: async Fn(&mut TcpNetwork, &mut S::Context, &mut StdRng) -> O
// {
// match self {
// Engine::Spdz25519(e) => { e.raw(routine).await },
// Engine::Spdz32(e) => e.raw(routine).await,
// Engine::Shamir25519(_) => todo!(),
// Engine::Shamir32(_) => todo!(),
// Engine::Feldman25519(_) => todo!(),
// }
// }

// compatilbity.
// pub async fn mpc_sum<F: Mapping, S: InteractiveSharedMany<Value = F>>(&mut self, nums: &[f64]) -> Option<Vec<f64>>
// where
// <S as InteractiveSharedMany>::VectorShare: std::iter::Sum,
// {
// self.raw(async |net, ctx, rng| {
// let nums: Vec<_> = nums.iter().map(|&num| F::from_f64(num)).collect();
// let shares: Vec<S::VectorShare> =
// S::symmetric_share_many(ctx, &nums, rng, net) .await .unwrap();
// let sum: S::VectorShare = shares.into_iter().sum();
// let res: Vector<F> = S::recombine_many(ctx, sum, net).await.unwrap();
//
// let res = res.into_iter().map(|x| F::into_f64(x)).collect();
// Some(res)
// }).await
// }
}

pub enum FieldKind {
Curve25519,
Element32,
}

pub enum SchemeKind {
Shamir,
Spdz,
Feldman,
}

#[derive(Default)]
pub struct EngineBuilder<'a> {
own: Option<SocketAddr>,
peers: Vec<SocketAddr>,
network: Option<TcpNetwork>,
threshold: Option<u64>,
preprocesing: Option<&'a Path>,
field: Option<FieldKind>,
scheme: Option<SchemeKind>,
}

impl<'a> EngineBuilder<'a> {
pub fn address(mut self, addr: impl Into<SocketAddr>) -> Self {
self.own.replace(addr.into());
self
}

pub fn participant(mut self, addr: impl Into<SocketAddr>) -> Self {
self.peers.push(addr.into());
self
}

pub fn participants<I, T>(mut self, addrs: I) -> Self
where
I: IntoIterator<Item = T>,
T: Into<SocketAddr>,
{
let addrs = addrs.into_iter().map(|s| s.into());
self.peers.extend(addrs);
self
}

pub fn threshold(mut self, t: u64) -> Self {
self.threshold = Some(t);
self
}

pub fn preprocessed(mut self, path: &'a Path) -> Self {
self.preprocesing = Some(path);
self
}

pub fn scheme(mut self, scheme: SchemeKind) -> Self {
self.scheme = Some(scheme);
self
}

pub fn field(mut self, field: FieldKind) -> Self {
self.field = Some(field);
self
}

pub async fn connect(mut self) -> Result<Self, &'static str> {
let network = TcpNetwork::connect(self.own.unwrap(), &self.peers)
.await
.map_err(|e| "Bad thing happened")?;

self.network = Some(network);
Ok(self)
}

pub fn build(self) -> Engine {
let network = self.network.expect("No network installed!");
let party_count = network.size();
let scheme = self.scheme.unwrap_or(SchemeKind::Shamir);
let threshold = self.threshold.unwrap_or(party_count as u64);
let field = self.field.unwrap_or(FieldKind::Curve25519);
let rng = rand::rngs::StdRng::from_entropy();

match (scheme, field) {
(SchemeKind::Shamir, FieldKind::Curve25519) => {
let ids = network
.participants()
.map(|id| (id + 1u32).into())
.collect();
let context = shamir::ShamirParams { threshold, ids };
Engine::Shamir25519(vm::Engine::new(context, network, rng))
}
(SchemeKind::Shamir, FieldKind::Element32) => {
let ids = network
.participants()
.map(|id| (id + 1u32).into())
.collect();
let context = shamir::ShamirParams { threshold, ids };
Engine::Shamir32(vm::Engine::new(context, network, rng))
}
(SchemeKind::Spdz, FieldKind::Curve25519) => {
let path = self.preprocesing.expect("Missing preproc!");
let mut file = File::open(path).unwrap();
let context = spdz::preprocessing::load_context(&mut file);
Engine::Spdz25519(vm::Engine::new(context, network, rng))
}
(SchemeKind::Spdz, FieldKind::Element32) => {
let path = self.preprocesing.expect("Missing preproc!");
let mut file = File::open(path).unwrap();
let context = spdz::preprocessing::load_context(&mut file);
Engine::Spdz32(vm::Engine::new(context, network, rng))
}
(SchemeKind::Feldman, FieldKind::Curve25519) => {
let ids = network
.participants()
.map(|id| (id + 1u32).into())
.collect();
let context = shamir::ShamirParams { threshold, ids };
Engine::Feldman25519(vm::Engine::new(context, network, rng))
}
(SchemeKind::Feldman, FieldKind::Element32) => {
panic!("Can't construct feldman from this field element. Missing group!")
}
}
}
}

pub mod blocking {
use crate::vm::{Expr, UnknownNumber};

pub struct Engine {
parent: super::Engine,
runtime: tokio::runtime::Runtime,
}

pub struct EngineBuilder<'a> {
parent: super::EngineBuilder<'a>,
runtime: tokio::runtime::Runtime,
}

impl<'a> super::EngineBuilder<'a> {
pub fn single_threaded_runtime(self) -> EngineBuilder<'a> {
let runtime = tokio::runtime::Builder::new_current_thread()
.build()
.unwrap();
EngineBuilder {
parent: self,
runtime,
}
}
pub fn multi_threaded_runtime(self) -> EngineBuilder<'a> {
let runtime = tokio::runtime::Builder::new_multi_thread().build().unwrap();
EngineBuilder {
parent: self,
runtime,
}
}
}

impl<'a> EngineBuilder<'a> {
pub fn connect_blocking(mut self) -> Result<Self, &'static str> {
let runtime = &mut self.runtime;
let mut parent = self.parent;
parent = runtime.block_on(async move { parent.connect().await })?;
self.parent = parent;
Ok(self)
}
}

impl Engine {
pub fn execute(&mut self, expr: Expr) -> UnknownNumber {
self.runtime
.block_on(async { self.parent.execute(expr).await })
}
}
}

0 comments on commit 74d39ad

Please sign in to comment.