Skip to content

Commit

Permalink
Merge pull request #1283 from akoshelev/hybrid-query-type
Browse files Browse the repository at this point in the history
Hybrid and sharded suffle query types
  • Loading branch information
akoshelev committed Sep 19, 2024
2 parents f847d28 + 0aa1e50 commit 61788a5
Show file tree
Hide file tree
Showing 7 changed files with 131 additions and 1 deletion.
10 changes: 10 additions & 0 deletions ipa-core/src/bin/test_mpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ enum TestAction {
/// All helpers add their shares locally and set the resulting share to be the
/// sum. No communication is required to run the circuit.
AddInPrimeField,
/// A test protocol for sharded MPCs. The goal here is to use
/// both shard-to-shard and helper-to-helper communication channels.
/// This is exactly what shuffle does and that's why it is picked
/// for this purpose.
ShardedShuffle,
}

#[tokio::main]
Expand All @@ -102,6 +107,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
match args.action {
TestAction::Multiply => multiply(&args, &clients).await,
TestAction::AddInPrimeField => add(&args, &clients).await,
TestAction::ShardedShuffle => sharded_shuffle(&args, &clients).await,
};

Ok(())
Expand Down Expand Up @@ -159,3 +165,7 @@ async fn add(args: &Args, helper_clients: &[MpcHelperClient; 3]) {
FieldType::Fp32BitPrime => add_in_field::<Fp32BitPrime>(args, helper_clients).await,
};
}

async fn sharded_shuffle(_args: &Args, _helper_clients: &[MpcHelperClient; 3]) {
unimplemented!()
}
32 changes: 32 additions & 0 deletions ipa-core/src/helpers/transport/query/hybrid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use serde::{Deserialize, Serialize};

#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq)]
#[cfg_attr(feature = "clap", derive(clap::Args))]
pub struct HybridQueryParams {
#[cfg_attr(feature = "clap", arg(long, default_value = "8"))]
pub per_user_credit_cap: u32,
#[cfg_attr(feature = "clap", arg(long, default_value = "5"))]
pub max_breakdown_key: u32,
#[cfg_attr(feature = "clap", arg(short = 'd', long, default_value = "1"))]
pub with_dp: u32,
#[cfg_attr(feature = "clap", arg(short = 'e', long, default_value = "5.0"))]
pub epsilon: f64,
#[cfg_attr(feature = "clap", arg(long))]
#[serde(default)]
pub plaintext_match_keys: bool,
}

#[cfg(test)]
impl Eq for HybridQueryParams {}

impl Default for HybridQueryParams {
fn default() -> Self {
Self {
per_user_credit_cap: 8,
max_breakdown_key: 20,
with_dp: 1,
epsilon: 0.10,
plaintext_match_keys: false,
}
}
}
11 changes: 11 additions & 0 deletions ipa-core/src/helpers/transport/query/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
mod hybrid;

use std::{
fmt::{Debug, Display, Formatter},
num::NonZeroU32,
};

pub use hybrid::HybridQueryParams;
use serde::{Deserialize, Deserializer, Serialize};

use crate::{
Expand Down Expand Up @@ -198,16 +201,21 @@ pub enum QueryType {
TestMultiply,
#[cfg(any(test, feature = "test-fixture", feature = "cli"))]
TestAddInPrimeField,
#[cfg(any(test, feature = "test-fixture", feature = "cli"))]
TestShardedShuffle,
SemiHonestOprfIpa(IpaQueryConfig),
MaliciousOprfIpa(IpaQueryConfig),
SemiHonestHybrid(HybridQueryParams),
}

impl QueryType {
/// TODO: strum
pub const TEST_MULTIPLY_STR: &'static str = "test-multiply";
pub const TEST_ADD_STR: &'static str = "test-add";
pub const TEST_SHARDED_SHUFFLE_STR: &'static str = "test-sharded-shuffle";
pub const SEMI_HONEST_OPRF_IPA_STR: &'static str = "semi-honest-oprf-ipa";
pub const MALICIOUS_OPRF_IPA_STR: &'static str = "malicious-oprf-ipa";
pub const SEMI_HONEST_HYBRID_STR: &'static str = "semi-honest-hybrid";
}

/// TODO: should this `AsRef` impl (used for `Substep`) take into account config of IPA?
Expand All @@ -218,8 +226,11 @@ impl AsRef<str> for QueryType {
QueryType::TestMultiply => Self::TEST_MULTIPLY_STR,
#[cfg(any(test, feature = "cli", feature = "test-fixture"))]
QueryType::TestAddInPrimeField => Self::TEST_ADD_STR,
#[cfg(any(test, feature = "cli", feature = "test-fixture"))]
QueryType::TestShardedShuffle => Self::TEST_SHARDED_SHUFFLE_STR,
QueryType::SemiHonestOprfIpa(_) => Self::SEMI_HONEST_OPRF_IPA_STR,
QueryType::MaliciousOprfIpa(_) => Self::MALICIOUS_OPRF_IPA_STR,
QueryType::SemiHonestHybrid(_) => Self::SEMI_HONEST_HYBRID_STR,
}
}
}
Expand Down
18 changes: 18 additions & 0 deletions ipa-core/src/net/http_serde.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ pub mod query {
match self.query_type {
#[cfg(any(test, feature = "test-fixture", feature = "cli"))]
QueryType::TestMultiply | QueryType::TestAddInPrimeField => Ok(()),
#[cfg(any(test, feature = "test-fixture", feature = "cli"))]
QueryType::TestShardedShuffle => Ok(()),
QueryType::SemiHonestOprfIpa(config) | QueryType::MaliciousOprfIpa(config) => {
write!(
f,
Expand All @@ -170,6 +172,22 @@ pub mod query {
write!(f, "&attribution_window_seconds={}", window.get())?;
}

Ok(())
}
QueryType::SemiHonestHybrid(config) => {
write!(
f,
"&per_user_credit_cap={}&max_breakdown_key={}&with_dp={}&epsilon={}",
config.per_user_credit_cap,
config.max_breakdown_key,
config.with_dp,
config.epsilon,
)?;

if config.plaintext_match_keys {
write!(f, "&plaintext_match_keys=true")?;
}

Ok(())
}
}
Expand Down
22 changes: 21 additions & 1 deletion ipa-core/src/query/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ use crate::{
Gate,
},
query::{
runner::{OprfIpaQuery, QueryResult},
runner::{HybridQuery, OprfIpaQuery, QueryResult},
state::RunningQuery,
},
sync::Arc,
Expand Down Expand Up @@ -94,6 +94,13 @@ pub fn execute<R: PrivateKeyRegistry>(
Box::pin(execute_test_multiply::<Fp32BitPrime>(prss, gateway, input))
})
}
#[cfg(any(test, feature = "cli", feature = "test-fixture"))]
(QueryType::TestShardedShuffle, _) => do_query(
config,
gateway,
input,
|_prss, _gateway, _config, _input| unimplemented!(),
),
#[cfg(any(test, feature = "weak-field"))]
(QueryType::TestAddInPrimeField, FieldType::Fp31) => {
do_query(config, gateway, input, |prss, gateway, _config, input| {
Expand Down Expand Up @@ -138,6 +145,19 @@ pub fn execute<R: PrivateKeyRegistry>(
)
},
),
(QueryType::SemiHonestHybrid(query_params), _) => do_query(
config,
gateway,
input,
move |prss, gateway, config, input| {
let ctx = SemiHonestContext::new(prss, gateway);
Box::pin(
HybridQuery::<_, BA32, R>::new(query_params, key_registry)
.execute(ctx, config.size, input)
.then(|res| ready(res.map(|out| Box::new(out) as Box<dyn Result>))),
)
},
),
}
}

Expand Down
37 changes: 37 additions & 0 deletions ipa-core/src/query/runner/hybrid.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use std::{marker::PhantomData, sync::Arc};

use crate::{
error::Error,
helpers::{
query::{HybridQueryParams, QuerySize},
BodyStream,
},
hpke::PrivateKeyRegistry,
secret_sharing::{replicated::semi_honest::AdditiveShare as ReplicatedShare, SharedValue},
};

pub struct Query<C, HV, R: PrivateKeyRegistry> {
_config: HybridQueryParams,
_key_registry: Arc<R>,
phantom_data: PhantomData<(C, HV)>,
}

impl<C, HV: SharedValue, R: PrivateKeyRegistry> Query<C, HV, R> {
pub fn new(query_params: HybridQueryParams, key_registry: Arc<R>) -> Self {
Self {
_config: query_params,
_key_registry: key_registry,
phantom_data: PhantomData,
}
}

#[tracing::instrument("hybrid_query", skip_all, fields(sz=%query_size))]
pub async fn execute(
self,
_ctx: C,
query_size: QuerySize,
_input_stream: BodyStream,
) -> Result<Vec<ReplicatedShare<HV>>, Error> {
unimplemented!()
}
}
2 changes: 2 additions & 0 deletions ipa-core/src/query/runner/mod.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#[cfg(any(test, feature = "cli", feature = "test-fixture"))]
mod add_in_prime_field;
mod hybrid;
mod oprf_ipa;
#[cfg(any(test, feature = "cli", feature = "test-fixture"))]
mod test_multiply;

#[cfg(any(test, feature = "cli", feature = "test-fixture"))]
pub(super) use add_in_prime_field::execute as test_add_in_prime_field;
pub use hybrid::Query as HybridQuery;
#[cfg(any(test, feature = "cli", feature = "test-fixture"))]
pub(super) use test_multiply::execute_test_multiply;

Expand Down

0 comments on commit 61788a5

Please sign in to comment.