Skip to content

Commit be6473a

Browse files
committed
feat: lazy ot
1 parent 65994b0 commit be6473a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+4303
-6975
lines changed

Diff for: Cargo.toml

+4-2
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ mpz-ole-core = { path = "crates/mpz-ole-core" }
4444
clmul = { path = "crates/clmul" }
4545
matrix-transpose = { path = "crates/matrix-transpose" }
4646

47-
tlsn-utils = { git = "https://github.com/tlsnotary/tlsn-utils", rev = "6e0be94" }
48-
tlsn-utils-aio = { git = "https://github.com/tlsnotary/tlsn-utils", rev = "6e0be94" }
47+
tlsn-utils = { git = "https://github.com/tlsnotary/tlsn-utils", rev = "5899190" }
48+
tlsn-utils-aio = { git = "https://github.com/tlsnotary/tlsn-utils", rev = "5899190" }
4949

5050
# rand
5151
rand_chacha = "0.3"
@@ -124,3 +124,5 @@ typenum = "1"
124124
generic-array = "0.14"
125125
itybity = "0.2"
126126
enum-try-as-inner = "0.1.0"
127+
bitvec = "1.0"
128+
hashbrown = "0.14.5"

Diff for: crates/mpz-cointoss/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ edition = "2021"
55

66
[dependencies]
77
mpz-core.workspace = true
8-
mpz-common.workspace = true
8+
mpz-common = { workspace = true, features = ["ctx"] }
99
mpz-cointoss-core.workspace = true
1010

1111
futures.workspace = true

Diff for: crates/mpz-common/Cargo.toml

+9-5
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@ version = "0.1.0"
44
edition = "2021"
55

66
[features]
7-
default = ["sync"]
8-
sync = ["tokio/sync"]
9-
test-utils = ["uid-mux/test-utils"]
10-
ideal = []
7+
default = []
8+
ctx = []
9+
cpu = ["rayon"]
10+
executor = ["ctx", "cpu"]
11+
sync = ["tokio/sync", "ctx"]
12+
future = []
13+
test-utils = ["dep:uid-mux", "uid-mux/test-utils"]
14+
ideal = ["ctx"]
1115
rayon = ["dep:rayon"]
1216
force-st = []
1317

@@ -20,7 +24,7 @@ pin-project-lite.workspace = true
2024
scoped-futures.workspace = true
2125
thiserror.workspace = true
2226
serio.workspace = true
23-
uid-mux.workspace = true
27+
uid-mux = { workspace = true, optional = true }
2428
serde = { workspace = true, features = ["derive"] }
2529
pollster.workspace = true
2630
rayon = { workspace = true, optional = true }

Diff for: crates/mpz-common/src/future.rs

+193
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
//! Future types.
2+
3+
use std::{
4+
future::Future,
5+
mem,
6+
pin::Pin,
7+
task::{ready, Context, Poll},
8+
};
9+
10+
use futures::{channel::oneshot, FutureExt};
11+
use pin_project_lite::pin_project;
12+
13+
/// Creates a new output future.
14+
pub fn new_output<T>() -> (Sender<T>, MaybeDone<T>) {
15+
let (send, recv) = oneshot::channel();
16+
(Sender { send }, MaybeDone { recv })
17+
}
18+
19+
/// A future output value.
20+
///
21+
/// This trait extends [`std::future::Future`] for values which can be received
22+
/// outside of a task context.
23+
pub trait Output: Future<Output = Result<Self::Ok, Canceled>> {
24+
/// Success type.
25+
type Ok;
26+
27+
/// Attempts to receive the output outside of a task context, returning
28+
/// `None` if it is not ready.
29+
fn try_recv(&mut self) -> Result<Option<Self::Ok>, Canceled>;
30+
}
31+
32+
/// An extension trait for [`Output`].
33+
pub trait OutputExt: Output {
34+
/// Maps the output value to a different type.
35+
fn map<F, O>(self, f: F) -> Map<Self, F>
36+
where
37+
Self: Sized,
38+
F: FnOnce(Self::Ok) -> O,
39+
{
40+
Map::new(self, f)
41+
}
42+
}
43+
44+
impl<T> OutputExt for T where T: Output {}
45+
46+
/// Output canceled error.
47+
#[derive(Debug, thiserror::Error)]
48+
#[error("output canceled")]
49+
pub struct Canceled {
50+
_private: (),
51+
}
52+
53+
/// Sender of an output value.
54+
#[derive(Debug)]
55+
pub struct Sender<T> {
56+
send: oneshot::Sender<T>,
57+
}
58+
59+
impl<T> Sender<T> {
60+
/// Sends an output value.
61+
pub fn send(self, value: T) {
62+
let _ = self.send.send(value);
63+
}
64+
}
65+
66+
/// An output value that may be ready.
67+
#[derive(Debug)]
68+
#[must_use = "futures do nothing unless you `.await` or poll them"]
69+
pub struct MaybeDone<T> {
70+
recv: oneshot::Receiver<T>,
71+
}
72+
73+
impl<T> Output for MaybeDone<T> {
74+
type Ok = T;
75+
76+
fn try_recv(&mut self) -> Result<Option<Self::Ok>, Canceled> {
77+
match self.recv.try_recv() {
78+
Ok(Some(value)) => Ok(Some(value)),
79+
Ok(None) => Ok(None),
80+
Err(oneshot::Canceled) => Err(Canceled { _private: () }),
81+
}
82+
}
83+
}
84+
85+
impl<T> Future for MaybeDone<T> {
86+
type Output = Result<T, Canceled>;
87+
88+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
89+
self.recv
90+
.poll_unpin(cx)
91+
.map_err(|_| Canceled { _private: () })
92+
}
93+
}
94+
95+
pin_project! {
96+
/// Maps an output value to a different type.
97+
///
98+
/// Returned by [`OutputExt::map`].
99+
#[derive(Debug)]
100+
pub struct Map<I, F> {
101+
#[pin]
102+
inner: MapInner<I, F>,
103+
}
104+
}
105+
106+
impl<I, F> Map<I, F> {
107+
fn new(inner: I, f: F) -> Self {
108+
Self {
109+
inner: MapInner::Incomplete { inner, f },
110+
}
111+
}
112+
}
113+
114+
impl<I, F, O> Output for Map<I, F>
115+
where
116+
I: Output,
117+
F: FnOnce(I::Ok) -> O,
118+
{
119+
type Ok = O;
120+
121+
fn try_recv(&mut self) -> Result<Option<Self::Ok>, Canceled> {
122+
self.inner.try_recv()
123+
}
124+
}
125+
126+
impl<I, F, O> Future for Map<I, F>
127+
where
128+
I: Output,
129+
F: FnOnce(I::Ok) -> O,
130+
{
131+
type Output = Result<O, Canceled>;
132+
133+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
134+
self.project().inner.poll(cx)
135+
}
136+
}
137+
138+
pin_project! {
139+
/// Maps an output value to a different type.
140+
///
141+
/// Returned by [`OutputExt::map`].
142+
#[derive(Debug)]
143+
#[project = MapProj]
144+
#[project_replace = MapProjReplace]
145+
#[must_use = "futures do nothing unless you `.await` or poll them"]
146+
enum MapInner<I, F> {
147+
Incomplete {
148+
#[pin]
149+
inner: I,
150+
f: F,
151+
},
152+
Done,
153+
}
154+
}
155+
156+
impl<I, F, O> Output for MapInner<I, F>
157+
where
158+
I: Output,
159+
F: FnOnce(I::Ok) -> O,
160+
{
161+
type Ok = O;
162+
163+
fn try_recv(&mut self) -> Result<Option<Self::Ok>, Canceled> {
164+
let this = mem::replace(self, MapInner::Done);
165+
match this {
166+
MapInner::Incomplete { mut inner, f } => inner.try_recv().map(|res| res.map(f)),
167+
MapInner::Done => Err(Canceled { _private: () }),
168+
}
169+
}
170+
}
171+
172+
impl<I, F, O> Future for MapInner<I, F>
173+
where
174+
I: Output,
175+
F: FnOnce(I::Ok) -> O,
176+
{
177+
type Output = Result<O, Canceled>;
178+
179+
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
180+
match self.as_mut().project() {
181+
MapProj::Incomplete { inner, .. } => {
182+
let output = ready!(inner.poll(cx));
183+
match self.project_replace(Self::Done) {
184+
MapProjReplace::Incomplete { f, .. } => Poll::Ready(output.map(f)),
185+
MapProjReplace::Done => unreachable!(),
186+
}
187+
}
188+
MapProj::Done => {
189+
panic!("Map must not be polled after it returned `Poll::Ready`")
190+
}
191+
}
192+
}
193+
}

Diff for: crates/mpz-common/src/lib.rs

+23-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
//! Common functionality for `mpz`.
22
//!
3-
//! This crate provides various common functionalities needed for modeling protocol execution, I/O,
4-
//! and multi-threading.
3+
//! This crate provides various common functionalities needed for modeling
4+
//! protocol execution, I/O, and multi-threading.
55
//!
6-
//! This crate does not provide any cryptographic primitives, see `mpz-core` for that.
6+
//! This crate does not provide any cryptographic primitives, see `mpz-core` for
7+
//! that.
78
89
#![deny(
910
unsafe_code,
@@ -14,16 +15,22 @@
1415
clippy::all
1516
)]
1617

18+
#[cfg(any(test, feature = "ctx"))]
1719
mod context;
20+
#[cfg(any(test, feature = "cpu"))]
1821
pub mod cpu;
22+
#[cfg(any(test, feature = "executor"))]
1923
pub mod executor;
24+
#[cfg(any(test, feature = "future"))]
25+
pub mod future;
2026
mod id;
2127
#[cfg(any(test, feature = "ideal"))]
2228
pub mod ideal;
2329
#[cfg(feature = "sync")]
2430
pub mod sync;
2531

2632
use async_trait::async_trait;
33+
#[cfg(any(test, feature = "ctx"))]
2734
pub use context::{Context, ContextError};
2835
pub use id::{Counter, ThreadId};
2936

@@ -46,6 +53,19 @@ pub trait Preprocess<Ctx>: Allocate {
4653
async fn preprocess(&mut self, ctx: &mut Ctx) -> Result<(), Self::Error>;
4754
}
4855

56+
/// A functionality that can be flushed.
57+
#[async_trait]
58+
pub trait Flush<Ctx> {
59+
/// Error type.
60+
type Error: std::error::Error + Send + Sync + 'static;
61+
62+
/// Returns `true` if the functionality wants to be flushed.
63+
fn wants_flush(&self) -> bool;
64+
65+
/// Flushes the functionality.
66+
async fn flush(&mut self, ctx: &mut Ctx) -> Result<(), Self::Error>;
67+
}
68+
4969
/// A convenience macro for creating a closure which returns a scoped future.
5070
///
5171
/// # Example

Diff for: crates/mpz-core/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ bytemuck = { workspace = true, features = ["derive"] }
3232
generic-array.workspace = true
3333
rayon = { workspace = true, optional = true }
3434
cfg-if.workspace = true
35+
bitvec = { workspace = true, features = ["serde"] }
3536

3637
[dev-dependencies]
3738
rstest.workspace = true

Diff for: crates/mpz-core/src/bitvec.rs

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//! Bit vectors.
2+
3+
/// Bit vector.
4+
pub type BitVec<T = u32> = bitvec::vec::BitVec<T, bitvec::order::Lsb0>;
5+
/// Bit slice.
6+
pub type BitSlice<T = u32> = bitvec::slice::BitSlice<T, bitvec::order::Lsb0>;

Diff for: crates/mpz-core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#![deny(clippy::all)]
44

55
pub mod aes;
6+
pub mod bitvec;
67
pub mod block;
78
pub mod commit;
89
pub mod ggm_tree;

Diff for: crates/mpz-core/src/prg.rs

+5
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,11 @@ impl Prg {
118118
Prg::from_seed(rand::random::<Block>())
119119
}
120120

121+
/// Create a new PRG from a seed.
122+
pub fn new_with_seed(seed: [u8; 16]) -> Self {
123+
Prg::from_seed(Block::from(seed))
124+
}
125+
121126
/// Returns the current counter.
122127
pub fn counter(&self) -> u64 {
123128
self.0.core.counter

Diff for: crates/mpz-ot-core/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ test-utils = []
1616

1717
[dependencies]
1818
mpz-core.workspace = true
19+
mpz-common = { workspace = true, features = ["future"] }
1920
clmul.workspace = true
2021
matrix-transpose.workspace = true
2122

@@ -38,6 +39,7 @@ opaque-debug.workspace = true
3839
cfg-if.workspace = true
3940
bytemuck = { workspace = true, features = ["derive"] }
4041
enum-try-as-inner.workspace = true
42+
futures = { workspace = true }
4143

4244
[dev-dependencies]
4345
rstest.workspace = true

0 commit comments

Comments
 (0)