Skip to content

Commit

Permalink
Temp checkout
Browse files Browse the repository at this point in the history
  • Loading branch information
benjaminsavage committed Oct 12, 2023
1 parent c75dfd7 commit 9d88ae0
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 25 deletions.
17 changes: 17 additions & 0 deletions src/bin/report_collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ enum ReportCollectorCommand {
},
/// Apply differential privacy noise to IPA inputs
ApplyDpNoise(ApplyDpArgs),
/// Execute OPRF IPA in a semi-honest majority setting
ExecuteOprfIpa(IpaQueryConfig),
}

#[derive(Debug, clap::Args)]
Expand Down Expand Up @@ -134,6 +136,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
IpaSecurityModel::SemiHonest,
config,
&clients,
false,
)
.await?
}
Expand All @@ -144,6 +147,7 @@ async fn main() -> Result<(), Box<dyn Error>> {
IpaSecurityModel::Malicious,
config,
&clients,
false,
)
.await?
}
Expand All @@ -153,6 +157,17 @@ async fn main() -> Result<(), Box<dyn Error>> {
gen_args,
} => gen_inputs(count, seed, args.output_file, gen_args)?,
ReportCollectorCommand::ApplyDpNoise(ref dp_args) => apply_dp_noise(&args, dp_args)?,
ReportCollectorCommand::ExecuteOprfIpa(config) => {
ipa(
&args,
&network,
IpaSecurityModel::SemiHonest,
config,
&clients,
true,
)
.await?
}
};

Ok(())
Expand Down Expand Up @@ -221,6 +236,7 @@ async fn ipa(
security_model: IpaSecurityModel,
ipa_query_config: IpaQueryConfig,
helper_clients: &[MpcHelperClient; 3],
oprf_algorithm: bool,
) -> Result<(), Box<dyn Error>> {
let input = InputSource::from(&args.input);
let query_type: QueryType;
Expand Down Expand Up @@ -265,6 +281,7 @@ async fn ipa(
query_id,
ipa_query_config,
key_registries.init_from(network),
oprf_algorithm,
)
.await;

Expand Down
46 changes: 28 additions & 18 deletions src/cli/playbook/ipa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ pub async fn playbook_ipa<F, MK, BK, KR>(
query_id: QueryId,
query_config: IpaQueryConfig,
encryption: Option<(KeyIdentifier, [&KR; 3])>,
oprf_algorithm: bool,
) -> IpaQueryResult
where
F: PrimeField + IntoShares<AdditiveShare<F>>,
Expand Down Expand Up @@ -77,24 +78,33 @@ where
buffer.resize(query_size * sz, 0u8);
}

let inputs = records.iter().map(|x| {
ipa_test_input!(
{
timestamp: x.timestamp,
match_key: x.user_id,
is_trigger_report: x.is_trigger_report,
breakdown_key: x.breakdown_key,
trigger_value: x.trigger_value,
};
(F, MatchKey, BreakdownKey)
)
});
let shares: [Vec<IPAInputRow<_, _, _>>; 3] = inputs.share();
zip(&mut buffers, shares).for_each(|(buf, shares)| {
for (share, chunk) in zip(shares, buf.chunks_mut(sz)) {
share.serialize(GenericArray::from_mut_slice(chunk));
}
});
if oprf_algorithm {
let shares: [Vec<IPAInputRowOprfVersion>; 3] = records.iter().share();
zip(&mut buffers, shares).for_each(|(buf, shares)| {
for (share, chunk) in zip(shares, buf.chunks_mut(sz)) {
share.serialize(GenericArray::from_mut_slice(chunk));
}
});
} else {
let inputs = records.iter().map(|x| {
ipa_test_input!(
{
timestamp: x.timestamp,
match_key: x.user_id,
is_trigger_report: x.is_trigger_report,
breakdown_key: x.breakdown_key,
trigger_value: x.trigger_value,
};
(F, MatchKey, BreakdownKey)
)
});
let shares: [Vec<IPAInputRow<_, _, _>>; 3] = inputs.share();
zip(&mut buffers, shares).for_each(|(buf, shares)| {
for (share, chunk) in zip(shares, buf.chunks_mut(sz)) {
share.serialize(GenericArray::from_mut_slice(chunk));
}
});
}
}

let inputs = buffers.map(BodyStream::from);
Expand Down
17 changes: 16 additions & 1 deletion src/ff/galois_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::{

use bitvec::prelude::{bitarr, BitArr, Lsb0};
use generic_array::GenericArray;
use typenum::{Unsigned, U1, U4, U5};
use typenum::{Unsigned, U1, U3, U4, U5};

use crate::{
ff::{Field, Serializable},
Expand All @@ -25,13 +25,18 @@ pub trait GaloisField:

// Bit store type definitions
type U8_1 = BitArr!(for 8, in u8, Lsb0);
type U8_3 = BitArr!(for 24, in u8, Lsb0);
type U8_4 = BitArr!(for 32, in u8, Lsb0);
type U8_5 = BitArr!(for 40, in u8, Lsb0);

impl Block for U8_1 {
type Size = U1;
}

impl Block for U8_3 {
type Size = U3;
}

impl Block for U8_4 {
type Size = U4;
}
Expand Down Expand Up @@ -550,6 +555,16 @@ bit_array_impl!(
0b1_0000_0000_0000_0000_0000_0000_1000_1101_u128
);

bit_array_impl!(
bit_array_20,
Gf20Bit,
U8_3,
20,
bitarr!(const u8, Lsb0; 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
// x^20 + x^17 + x^15 + x^14 + x^11 + x^10 + x^9 + x^7 + x^6 + x^5 + 1
0b1_0010_1100_1110_1110_0001_u128
);

bit_array_impl!(
bit_array_8,
Gf8Bit,
Expand Down
2 changes: 1 addition & 1 deletion src/ff/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ mod prime_field;
use std::ops::{Add, AddAssign, Sub, SubAssign};

pub use field::{Field, FieldType};
pub use galois_field::{GaloisField, Gf2, Gf32Bit, Gf3Bit, Gf40Bit, Gf5Bit, Gf8Bit};
pub use galois_field::{GaloisField, Gf2, Gf20Bit, Gf32Bit, Gf3Bit, Gf40Bit, Gf5Bit, Gf8Bit};
use generic_array::{ArrayLength, GenericArray};
#[cfg(any(test, feature = "weak-field"))]
pub use prime_field::Fp31;
Expand Down
4 changes: 3 additions & 1 deletion src/protocol/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ pub use basics::BasicProtocols;

use crate::{
error::Error,
ff::{Gf40Bit, Gf8Bit},
ff::{Gf20Bit, Gf3Bit, Gf40Bit, Gf8Bit},
};

pub type MatchKey = Gf40Bit;
pub type BreakdownKey = Gf8Bit;
pub type TriggerValue = Gf3Bit;
pub type Timestamp = Gf20Bit;

/// Unique identifier of the MPC query requested by report collectors
/// TODO(615): Generating this unique id may be tricky as it may involve communication between helpers and
Expand Down
18 changes: 17 additions & 1 deletion src/report.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use rand_core::{CryptoRng, RngCore};
use typenum::Unsigned;

use crate::{
ff::{GaloisField, Gf40Bit, Gf8Bit, PrimeField, Serializable},
ff::{GaloisField, Gf2, Gf3Bit, Gf40Bit, Gf8Bit, PrimeField, Serializable},
hpke::{
open_in_place, seal_in_place, CryptError, FieldShareCrypt, Info, KeyPair, KeyRegistry,
PublicKeyRegistry,
Expand Down Expand Up @@ -285,6 +285,22 @@ where
}
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct OprfReport<TS, BK, TV>
where
TS: GaloisField,
BK: GaloisField,
TV: GaloisField,
{
pub timestamp: Replicated<TS>,
pub mk_oprf: u64,
pub event_type: EventType,
pub breakdown_key: Replicated<BK>,
pub trigger_value: Replicated<TV>,
pub epoch: Epoch,
pub site_domain: String,
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Report<F, MK, BK>
where
Expand Down
38 changes: 35 additions & 3 deletions src/test_fixture/input/sharing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ use std::iter::zip;
use rand::{distributions::Standard, prelude::Distribution};

use crate::{
ff::{Field, GaloisField, PrimeField, Serializable},
ff::{Field, GaloisField, Gf2, Gf20Bit, PrimeField, Serializable},
protocol::{
attribution::input::{
AccumulateCreditInputRow, ApplyAttributionWindowInputRow, CreditCappingInputRow,
},
ipa::IPAInputRow,
BreakdownKey, MatchKey,
BreakdownKey, MatchKey, Timestamp, TriggerValue,
},
rand::Rng,
report::{EventType, Report},
report::{EventType, OprfReport, Report},
secret_sharing::{replicated::semi_honest::AdditiveShare as Replicated, IntoShares},
test_fixture::{
input::{GenericReportShare, GenericReportTestInput},
Expand Down Expand Up @@ -275,6 +275,38 @@ where
}
}

impl IntoShares<OprfReport<Timestamp, BreakdownKey, TriggerValue>> for TestRawDataRecord {
fn share_with<R: Rng>(
self,
rng: &mut R,
) -> [OprfReport<Timestamp, BreakdownKey, TriggerValue>; 3] {
let event_type = if self.is_trigger_report {
EventType::Trigger
} else {
EventType::Source
};
let timestamp = Timestamp::truncate_from(self.timestamp).share_with(rng);
let breakdown_key = BreakdownKey::truncate_from(self.breakdown_key).share_with(rng);
let trigger_value = TriggerValue::truncate_from(self.trigger_value).share_with(rng);
let epoch = 1;
let site_domain = DOMAINS[rng.gen_range(0..DOMAINS.len())].to_owned();

zip(zip(timestamp, breakdown_key), trigger_value)
.map(|((ts_share, bk_share), tv_share)| OprfReport {
timestamp: ts_share,
mk_oprf: self.user_id,
event_type,
breakdown_key: bk_share,
trigger_value: tv_share,
epoch,
site_domain: site_domain.clone(),
})
.collect::<Vec<_>>()
.try_into()
.unwrap()
}
}

impl<F> IntoShares<Report<F, MatchKey, BreakdownKey>>
for GenericReportTestInput<F, MatchKey, BreakdownKey>
where
Expand Down

0 comments on commit 9d88ae0

Please sign in to comment.