Skip to content

Commit

Permalink
Progress
Browse files Browse the repository at this point in the history
  • Loading branch information
martinthomson committed Mar 28, 2024
1 parent b69d518 commit a085870
Show file tree
Hide file tree
Showing 13 changed files with 112 additions and 27 deletions.
29 changes: 25 additions & 4 deletions ipa-core/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,45 @@
#![allow(clippy::module_name_repetitions)]

use cfg_aliases::cfg_aliases;
// use ipa_step::build_gate;
use ipa_step::build_gate;
use ipa_step_derive::track_steps;

track_steps!(
setup_steps:
helpers::prss_protocol::prss_step @"src/helpers/prss_step.rs",
protocol::{basics::mul::step, boolean::step},
helpers::prss_protocol::prss_step @ "src/helpers/prss_step.rs",
protocol::{
basics::{
mul::step,
step,
sum_of_product::step,
},
boolean::{
comparison_step,
fallback_step,
step,
},
context::step,
ipa_prf::{
boolean_ops::step,
prf_sharding::step,
shuffle::step,
step,
},
modulus_conversion::step,
step,
},
);

fn main() {
setup_steps();
// build_gate();
build_gate::<protocol::step::ProtocolStep>();

// test is not supported because cfg_aliases is based on
// https://docs.rs/tectonic_cfg_support macro and that only supports features, target_os, family
// env, etc.
// https://docs.rs/tectonic_cfg_support/latest/tectonic_cfg_support/struct.TargetConfiguration.html
cfg_aliases! {
descriptive_gate: { not(all(feature = "compact-gate", not(test), not(unit_test))) },
unit_test: { all(not(feature = "shuttle"), feature = "in-memory-infra") },
web_test: { all(not(feature = "shuttle"), feature = "real-world-infra") },
}
Expand Down
17 changes: 5 additions & 12 deletions ipa-core/src/protocol/boolean/bitwise_less_than_prime.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
use std::cmp::Ordering;

use futures::future::try_join;
use ipa_step_derive::CompactStep;

use crate::{
error::Error,
ff::PrimeField,
protocol::{
boolean::{any_ones, multiply_all_shares, or::or, step::BitOpStep},
boolean::{
any_ones, multiply_all_shares,
or::or,
step::{BitOpStep, BitwiseLessThanStep as Step},
},
context::Context,
BasicProtocols, RecordId,
},
Expand Down Expand Up @@ -190,16 +193,6 @@ impl BitwiseLessThanPrime {
}
}

#[derive(CompactStep)]
pub(crate) enum Step {
CheckTrimmed,
CheckIfAnyOnes,
LeadingOnesOrRest,
CheckIfAllOnes,
CheckLeastSignificantBits,
AllOnesAndFinalBits,
}

#[cfg(all(test, unit_test))]
mod tests {
use rand::{distributions::Standard, prelude::Distribution};
Expand Down
10 changes: 10 additions & 0 deletions ipa-core/src/protocol/boolean/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,13 @@ pub(crate) enum ComparisonStep {
PrefixOr,
DotProduct,
}

#[derive(CompactStep)]
pub(crate) enum BitwiseLessThanStep {
CheckTrimmed,
CheckIfAnyOnes,
LeadingOnesOrRest,
CheckIfAllOnes,
CheckLeastSignificantBits,
AllOnesAndFinalBits,
}
1 change: 0 additions & 1 deletion ipa-core/src/protocol/context/upgrade_triple_step.rs

This file was deleted.

5 changes: 3 additions & 2 deletions ipa-core/src/protocol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub mod dp;
pub mod ipa_prf;
pub mod modulus_conversion;
pub mod prss;
pub mod step;

use std::{
fmt::{Debug, Display, Formatter},
Expand All @@ -24,9 +25,9 @@ pub type BreakdownKey = Gf8Bit;
pub type TriggerValue = Gf3Bit;
pub type Timestamp = Gf20Bit;

#[cfg(all(feature = "compact-gate", not(test), not(unit_test)))]
#[cfg(not(descriptive_gate))]
pub type Gate = ProtocolGate;
#[cfg(not(all(feature = "compact-gate", not(test), not(unit_test))))]
#[cfg(descriptive_gate)]
pub type Gate = ipa_step::descriptive::Descriptive;

/// Unique identifier of the MPC query requested by report collectors
Expand Down
5 changes: 1 addition & 4 deletions ipa-core/src/protocol/modulus_conversion/convert_shares.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use crate::{
basics::{SecureMul, ZeroPositions},
boolean::xor_sparse,
context::{Context, UpgradeContext, UpgradeToMalicious, UpgradedContext},
modulus_conversion::step::ConvertSharesStep,
RecordId,
},
secret_sharing::{
Expand All @@ -48,10 +49,6 @@ use crate::{
seq_join::seq_join,
};

#[path = "convert_step.rs"]
mod convert_step;
use convert_step::ConvertSharesStep;

#[derive(Clone)]
pub struct BitConversionTriple<S>(pub(crate) [S; 3]);

Expand Down
1 change: 1 addition & 0 deletions ipa-core/src/protocol/modulus_conversion/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod convert_shares;
pub mod step;

// TODO: wean usage off convert_some_bits.
pub(crate) use convert_shares::convert_some_bits;
Expand Down
8 changes: 8 additions & 0 deletions ipa-core/src/protocol/step.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
use ipa_step_derive::{CompactGate, CompactStep};

#[derive(CompactStep, CompactGate)]
pub enum ProtocolStep {
IpaPrf,
IpaClassic,
Multiply,
}
27 changes: 27 additions & 0 deletions ipa-step-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,39 @@ pub fn derive_step(input: TokenStreamBasic) -> TokenStreamBasic {

/// Generate a `Gate` implementation from an implementation of `CompactStep`.
/// The resulting object will be the top-level entry-point for a complete protocol.
///
/// For this macro to work, you need to use `track_steps!` and call
/// `ipa_step::build_gate::<path::to::your::Step>()` in your `build.rs` file.
#[proc_macro_derive(CompactGate)]
pub fn derive_gate(input: TokenStreamBasic) -> TokenStreamBasic {
TokenStreamBasic::from(derive_gate_impl(&parse_macro_input!(input as DeriveInput)))
}

/// Used to generate a map of steps for use in a build script.
///
/// ```ignore
/// track_steps! {
/// fn_name:
/// path::to::step,
/// path::to::other_step,
/// other::path::{a, b @ "src/other/path/b_step.rs"}
/// }
/// ```
///
/// The first thing that needs to be included is an identifier, followed by a colon.
/// The macro will generate a function by this name. Call this function from `main()`.
///
/// Next, there is a list of module paths. You can specify these in much the same
/// way you would a `use` statement. The macro will load files from your `src/`
/// directory by default, inferring the name of the file from the module name.
/// If you have a `mod.rs` or non-default filename (`#[path = "..."]`) then
/// you can supply the location of the code by following the module name with `@`
/// and the location of the file.
///
/// To keep things clean, you should put any `CompactStep` definitions in their own
/// file. Include as little additional code as possible, because that code will
/// be compiled twice. Any dependencies for that code will also need to be listed
/// in `Cargo.toml` under `[build-dependencies]`.
#[cfg(feature = "build")]
#[proc_macro]
pub fn track_steps(input: TokenStreamBasic) -> TokenStreamBasic {
Expand Down
19 changes: 16 additions & 3 deletions ipa-step-derive/src/track.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ use std::{
};

use proc_macro2::{
token_stream::IntoIter as TokenTreeIter, Delimiter, Punct, Spacing, TokenStream, TokenTree,
token_stream::IntoIter as TokenTreeIter, Delimiter, Punct, Spacing, Span, TokenStream,
TokenTree,
};
use quote::{quote, ToTokens, TokenStreamExt};
use syn::{parse::Parser, parse2, Ident, LitStr};
use syn::{parse::Parser, parse2, token::Pub, Ident, LitStr, Visibility};

use crate::IntoSpan;

Expand All @@ -28,6 +29,10 @@ impl ModulePath {
self.path.len()
}

fn is_empty(&self) -> bool {
self.path.is_empty()
}

/// Determine if this path is a prefix of the other.
fn is_prefix(&self, other: &Self) -> bool {
(self.len() < other.len()) && self.path.iter().eq(other.path.iter().take(self.len()))
Expand Down Expand Up @@ -238,8 +243,16 @@ impl<'p, 'm> ToTokens for ModuleTokens<'p, 'm> {
prefix: &prefix,
paths: self.paths,
};
let exposure = if self.prefix.is_empty() {
TokenStream::new()
} else {
Visibility::Public(Pub {
span: Span::call_site(),
})
.into_token_stream()
};
tokens.extend(quote! {
mod #label {
#exposure mod #label {
#inner_tokens
}
});
Expand Down
3 changes: 2 additions & 1 deletion ipa-step-test/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@ use ipa_step_derive::track_steps;
// otherwise you will make the build take longer than necessary.
// If they are not in the usual place, or if they are defined in "foo/mod.rs",
// then you will need to list the files too.
track_steps!(setup: basic_step, complex_step @ "src/complex_step.rs");
track_steps!(setup: basic_step, complex_step @ "src/complex_step.rs", module::{a, b});

fn main() {
setup();

// Now, for each step that is annotated with `#[derive(CompactGate)]`,
// invoke this script to build it.
build_gate::<complex_step::ComplexStep>();
build_gate::<module::a::Alpha>();
}
14 changes: 14 additions & 0 deletions ipa-step-test/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod basic_step;
mod complex_step;
mod module;

#[cfg(test)]
mod tests {
Expand All @@ -8,6 +9,10 @@ mod tests {
use crate::{
basic_step::BasicStep,
complex_step::{ComplexGate, ComplexStep},
module::{
a::{Alpha, AlphaGate},
b::Beta,
},
};

#[test]
Expand Down Expand Up @@ -49,4 +54,13 @@ mod tests {
fn bad_narrow() {
_ = ComplexGate::from("/two2/one").narrow(&BasicStep::Two);
}

/// Test that the alpha and beta gates work.
#[test]
fn alpha_and_beta() {
assert_eq!(
AlphaGate::default().narrow(&Alpha).narrow(&Beta::One),
AlphaGate::from("/alpha/one")
);
}
}

0 comments on commit a085870

Please sign in to comment.