Skip to content

Commit

Permalink
Merge pull request #22 from alexandrainst/typed-verification
Browse files Browse the repository at this point in the history
Typed Verification
  • Loading branch information
quackzar authored May 29, 2024
2 parents 2145b6d + 5a4cc28 commit 7091377
Show file tree
Hide file tree
Showing 15 changed files with 622 additions and 75 deletions.
2 changes: 1 addition & 1 deletion pycare/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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" }
2 changes: 1 addition & 1 deletion src/algebra/poly.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ impl<F: Field> Polynomial<F> {
///
/// * `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()
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#![deny(unsafe_code)]
#![allow(refining_impl_trait)]
#![allow(dead_code)]
#![feature(async_fn_traits)]

mod algebra;
pub mod net;
Expand All @@ -9,5 +10,6 @@ mod protocols;
pub mod schemes;

mod help;
pub mod marker;
#[cfg(test)]
mod testing;
109 changes: 109 additions & 0 deletions src/marker/exptree.rs
Original file line number Diff line number Diff line change
@@ -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<T> {
Verified,
Unverified {
parents: (u32, u32),
data: Option<T>,
},
Failure,
}

pub struct ExpTree<T> {
tree: Mutex<BTreeMap<u32, Status<T>>>,
issuer: AtomicU32,
}

impl<T: Clone> ExpTree<T> {
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<T> = 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<F, C>(&mut self, id: u32, verify_fn: F, coms: C) -> Option<bool>
where
F: AsyncFn(Vec<T>, C) -> Option<bool>,
C: Communicate,
{
let mut to_check = vec![];
let mut datas: Vec<T> = 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)
}
}
221 changes: 221 additions & 0 deletions src/marker/mod.rs
Original file line number Diff line number Diff line change
@@ -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>(S);

#[repr(transparent)]
#[derive(Serialize, Debug, Clone)]
pub struct Unverified<S>(S);

impl<'de, S: Shared + DeserializeOwned> Deserialize<'de> for Unverified<S> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
Deserialize::deserialize(deserializer).map(|s| Unverified(s))
}
}

impl<S: Verify> Unverified<S> {
pub async fn verify(self, coms: impl Communicate, args: S::Args) -> Option<Verified<S>> {
if self.0.verify(coms, args).await {
Some(Verified(self.0))
} else {
None
}
}
}

impl<S> Unverified<S> {
pub fn assume_verified(self) -> Verified<S> {
Verified(self.0)
}
}

impl<S: InteractiveShared> Verified<S> {
pub async fn open(
self,
ctx: &S::Context,
coms: impl Communicate,
) -> Result<S::Value, S::Error> {
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<Self, S::Error> {
let s = S::share(ctx, val, rng, coms).await?;
Ok(Self(s))
}
}

impl<S: InteractiveShared> Unverified<S> {
pub async fn share_symmetric(
val: S::Value,
ctx: &S::Context,
rng: impl RngCore + Send,
coms: impl Communicate,
) -> Result<Vec<Self>, 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<Self, S::Error> {
let s = S::receive_share(ctx, coms, from).await?;
Ok(Self(s))
}
}

impl<T> From<Unverified<Vec<T>>> for Vec<Unverified<T>> {
fn from(value: Unverified<Vec<T>>) -> Self {
value.0.into_iter().map(|t| Unverified(t)).collect()
}
}

impl<T> From<Verified<Vec<T>>> for Vec<Verified<T>> {
fn from(value: Verified<Vec<T>>) -> Self {
value.0.into_iter().map(|t| Verified(t)).collect()
}
}

impl<S: Verify> Unverified<Vec<S>> {
pub async fn verify_all(
self,
coms: impl Communicate,
args: S::Args,
) -> Verified<Vec<Option<S>>> {
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<S: Shared> Add for Verified<S> {
type Output = Self;

fn add(self, rhs: Self) -> Self::Output {
Self(self.0 + rhs.0)
}
}

impl<S: Shared> Sub for Verified<S> {
type Output = Self;

fn sub(self, rhs: Self) -> Self::Output {
Self(self.0 - rhs.0)
}
}

impl<S: Shared> Add<Unverified<S>> for Verified<S> {
type Output = Unverified<S>;

fn add(self, rhs: Unverified<S>) -> Self::Output {
Unverified(self.0 + rhs.0)
}
}

impl<S: Shared> Sub<Unverified<S>> for Verified<S> {
type Output = Unverified<S>;

fn sub(self, rhs: Unverified<S>) -> Self::Output {
Unverified(self.0 - rhs.0)
}
}

impl<S: Shared> Add for Unverified<S> {
type Output = Self;

fn add(self, rhs: Self) -> Self::Output {
Self(self.0 + rhs.0)
}
}

impl<S: Shared> Sub for Unverified<S> {
type Output = Self;

fn sub(self, rhs: Self) -> Self::Output {
Self(self.0 - rhs.0)
}
}

impl<S: Shared> Mul<S::Value> for Verified<S>
where
S: Mul<S::Value, Output = S>,
{
type Output = Self;

fn mul(self, rhs: S::Value) -> Self::Output {
Self(self.0 * rhs)
}
}

impl<S: Shared> Mul<S::Value> for Unverified<S>
where
S: Mul<S::Value, Output = S>,
{
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 = <mock::Share<Mod11> 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<Share<Mod11>> = bincode::deserialize(&to_send).unwrap();

println!("Hello again {back_again:?}");
}
}
Loading

0 comments on commit 7091377

Please sign in to comment.