Skip to content

Commit

Permalink
Eliminate async_trait for BooleanArrayMul
Browse files Browse the repository at this point in the history
  • Loading branch information
andyleiserson committed Feb 21, 2024
1 parent 5e23eb0 commit 38e2461
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 11 deletions.
9 changes: 7 additions & 2 deletions ipa-core/src/protocol/basics/if_else.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ use crate::{
error::Error,
ff::{boolean::Boolean, Field},
protocol::{
basics::{mul::BooleanArrayMul, SecureMul},
basics::{
mul::{boolean_array_multiply, BooleanArrayMul},
SecureMul,
},
context::Context,
RecordId,
},
Expand Down Expand Up @@ -84,7 +87,9 @@ where
// false_value + condition * (true_value - false_value)
// = false_value + 0
// = false_value
let product = B::multiply(ctx, record_id, &condition, &(true_value - &false_value)).await?;
let product =
boolean_array_multiply::<_, B>(ctx, record_id, &condition, &(true_value - &false_value))
.await?;

Ok((false_value + &product).into())
}
37 changes: 28 additions & 9 deletions ipa-core/src/protocol/basics/mul/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use std::ops::{Add, Sub};
use std::{
future::Future,
ops::{Add, Sub},
};

use async_trait::async_trait;

Expand Down Expand Up @@ -55,40 +58,56 @@ use semi_honest::multiply as semi_honest_mul;
// breakdown key type BK is BA8) can invoke vectorized multiply. Without this trait, those
// implementations would need to specify the `N` const parameter, which is tricky, because you
// can't supply an expression involving a type parameter (BK::BITS) as a const parameter.
#[async_trait]
pub trait BooleanArrayMul:
Expand<Input = Replicated<Boolean>> + From<Self::Vectorized> + Into<Self::Vectorized>
{
type Vectorized: Send
+ Sync
+ for<'a> Add<&'a Self::Vectorized, Output = Self::Vectorized>
+ for<'a> Sub<&'a Self::Vectorized, Output = Self::Vectorized>;
+ for<'a> Sub<&'a Self::Vectorized, Output = Self::Vectorized>
+ 'static;

async fn multiply<'fut, C>(
fn multiply<'fut, C>(
ctx: C,
record_id: RecordId,
a: &'fut Self::Vectorized,
b: &'fut Self::Vectorized,
) -> Result<Self::Vectorized, Error>
) -> impl Future<Output = Result<Self::Vectorized, Error>> + Send + 'fut
where
C: Context + 'fut;
}

// Workaround for https://github.com/rust-lang/rust/issues/100013. Calling this wrapper function
// instead of `<_ as BooleanArrayMul>::multiply` seems to hide the BooleanArrayMul `impl Future`
// GAT.
pub fn boolean_array_multiply<'fut, C, B>(
ctx: C,
record_id: RecordId,
a: &'fut B::Vectorized,
b: &'fut B::Vectorized,
) -> impl Future<Output = Result<B::Vectorized, Error>> + Send + 'fut
where
C: Context + 'fut,
B: BooleanArrayMul,
{
B::multiply(ctx, record_id, a, b)
}

macro_rules! boolean_array_mul {
($dim:expr, $vec:ty) => {
#[async_trait]
impl BooleanArrayMul for Replicated<$vec> {
type Vectorized = Replicated<Boolean, $dim>;

async fn multiply<'fut, C>(
fn multiply<'fut, C>(
ctx: C,
record_id: RecordId,
a: &'fut Self::Vectorized,
b: &'fut Self::Vectorized,
) -> Result<Self::Vectorized, Error>
) -> impl Future<Output = Result<Self::Vectorized, Error>> + Send + 'fut
where
C: Context + 'fut,
{
semi_honest_mul(ctx, record_id, a, b, ZeroPositions::NONE).await
semi_honest_mul(ctx, record_id, a, b, ZeroPositions::NONE)
}
}
};
Expand Down

0 comments on commit 38e2461

Please sign in to comment.