diff --git a/ipa-core/src/protocol/basics/mod.rs b/ipa-core/src/protocol/basics/mod.rs index ebe34cb34..ab22efbcf 100644 --- a/ipa-core/src/protocol/basics/mod.rs +++ b/ipa-core/src/protocol/basics/mod.rs @@ -23,7 +23,7 @@ use crate::{ protocol::{ context::{ Context, DZKPUpgradedMaliciousContext, DZKPUpgradedSemiHonestContext, - UpgradedMaliciousContext, UpgradedSemiHonestContext, + ShardedUpgradedMaliciousContext, UpgradedMaliciousContext, UpgradedSemiHonestContext, }, ipa_prf::{AGG_CHUNK, PRF_CHUNK}, prss::FromPrss, @@ -66,6 +66,14 @@ where { } +impl<'a, const N: usize> BasicProtocols, Fp25519, N> + for malicious::AdditiveShare +where + Fp25519: FieldSimd, + AdditiveShare: FromPrss, +{ +} + /// Basic suite of MPC protocols for (possibly vectorized) boolean shares. /// /// Adds the requirement that the type implements `Not`. diff --git a/ipa-core/src/protocol/basics/reveal.rs b/ipa-core/src/protocol/basics/reveal.rs index 0e4f08378..e38d31500 100644 --- a/ipa-core/src/protocol/basics/reveal.rs +++ b/ipa-core/src/protocol/basics/reveal.rs @@ -37,7 +37,7 @@ use crate::{ boolean::step::TwoHundredFiftySixBitOpStep, context::{ Context, DZKPContext, DZKPUpgradedMaliciousContext, DZKPUpgradedSemiHonestContext, - UpgradedMaliciousContext, UpgradedSemiHonestContext, + ShardedUpgradedMaliciousContext, UpgradedMaliciousContext, UpgradedSemiHonestContext, }, RecordId, }, @@ -333,6 +333,50 @@ where } } +impl<'a, V, const N: usize, CtxF> Reveal> + for Replicated +where + CtxF: ExtendableField, + V: SharedValue + Vectorizable, +{ + type Output = >::Array; + + async fn generic_reveal<'fut>( + &'fut self, + ctx: ShardedUpgradedMaliciousContext<'a, CtxF>, + record_id: RecordId, + excluded: Option, + ) -> Result>::Array>, Error> + where + ShardedUpgradedMaliciousContext<'a, CtxF>: 'fut, + { + malicious_reveal(ctx, record_id, excluded, self).await + } +} + +impl<'a, F, const N: usize> Reveal> + for MaliciousReplicated +where + F: ExtendableFieldSimd, +{ + type Output = >::Array; + + async fn generic_reveal<'fut>( + &'fut self, + ctx: ShardedUpgradedMaliciousContext<'a, F>, + record_id: RecordId, + excluded: Option, + ) -> Result>::Array>, Error> + where + ShardedUpgradedMaliciousContext<'a, F>: 'fut, + { + use crate::secret_sharing::replicated::malicious::ThisCodeIsAuthorizedToDowngradeFromMalicious; + + let x_share = self.x().access_without_downgrade(); + malicious_reveal(ctx, record_id, excluded, x_share).await + } +} + impl<'a, V, B, const N: usize> Reveal> for Replicated where B: ShardBinding, diff --git a/ipa-core/src/protocol/context/mod.rs b/ipa-core/src/protocol/context/mod.rs index 205e022d6..d21896190 100644 --- a/ipa-core/src/protocol/context/mod.rs +++ b/ipa-core/src/protocol/context/mod.rs @@ -28,6 +28,7 @@ pub type ShardedSemiHonestContext<'a> = semi_honest::Context<'a, Sharded>; pub type MaliciousContext<'a, B = NotSharded> = malicious::Context<'a, B>; pub type ShardedMaliciousContext<'a> = malicious::Context<'a, Sharded>; pub type UpgradedMaliciousContext<'a, F, B = NotSharded> = malicious::Upgraded<'a, F, B>; +pub type ShardedUpgradedMaliciousContext<'a, F, B = Sharded> = malicious::Upgraded<'a, F, B>; #[cfg(all(feature = "in-memory-infra", any(test, feature = "test-fixture")))] pub(crate) use malicious::TEST_DZKP_STEPS; diff --git a/ipa-core/src/protocol/hybrid/oprf.rs b/ipa-core/src/protocol/hybrid/oprf.rs index bf1a14f3b..da2bf903f 100644 --- a/ipa-core/src/protocol/hybrid/oprf.rs +++ b/ipa-core/src/protocol/hybrid/oprf.rs @@ -21,7 +21,8 @@ use crate::{ context::{ dzkp_validator::{DZKPValidator, TARGET_PROOF_SIZE}, reshard_try_stream, DZKPUpgraded, MacUpgraded, MaliciousProtocolSteps, ShardedContext, - UpgradableContext, Validator, + ShardedUpgradedMaliciousContext, UpgradableContext, UpgradedMaliciousContext, + Validator, }, hybrid::step::HybridStep, ipa_prf::{ @@ -29,12 +30,12 @@ use crate::{ prf_eval::{eval_dy_prf, PrfSharing}, }, prss::{FromPrss, SharedRandomness}, - RecordId, + BasicProtocols, RecordId, }, report::hybrid::{IndistinguishableHybridReport, PrfHybridReport}, secret_sharing::{ - replicated::semi_honest::AdditiveShare as Replicated, BitDecomposed, TransposeFrom, - Vectorizable, + replicated::{malicious, semi_honest::AdditiveShare as Replicated}, + BitDecomposed, FieldSimd, TransposeFrom, Vectorizable, }, seq_join::seq_join, utils::non_zero_prev_power_of_two, @@ -81,6 +82,20 @@ fn conv_proof_chunk() -> usize { non_zero_prev_power_of_two(max(2, TARGET_PROOF_SIZE / CONV_CHUNK / 512)) } +/// Allow MAC-malicious shares to be used for PRF generation with shards +impl<'a, const N: usize> PrfSharing, N> + for Replicated +where + Fp25519: FieldSimd, + RP25519: Vectorizable, + malicious::AdditiveShare: + BasicProtocols, Fp25519, N>, + Replicated: FromPrss, +{ + type Field = Fp25519; + type UpgradedSharing = malicious::AdditiveShare; +} + /// This computes the Dodis-Yampolsky PRF value on every match key from input, /// and reshards the reports according to the computed PRF. At the end, reports with the /// same value end up on the same shard. @@ -233,9 +248,8 @@ mod test { }, ]; - // TODO: we need to use malicious circuits here let reports_per_shard = world - .semi_honest(records.clone().into_iter(), |ctx, reports| async move { + .malicious(records.clone().into_iter(), |ctx, reports| async move { let ind_reports = reports .into_iter() .map(IndistinguishableHybridReport::from) diff --git a/ipa-core/src/query/runner/hybrid.rs b/ipa-core/src/query/runner/hybrid.rs index 8a9f375be..09bef945c 100644 --- a/ipa-core/src/query/runner/hybrid.rs +++ b/ipa-core/src/query/runner/hybrid.rs @@ -276,7 +276,7 @@ mod tests { #[should_panic( expected = "not implemented: protocol::hybrid::hybrid_protocol is not fully implemented" )] - fn encrypted_hybrid_reports() { + fn encrypted_hybrid_reports_happy() { // While this test currently checks for an unimplemented panic it is // designed to test for a correct result for a complete implementation. run(|| async { @@ -293,7 +293,7 @@ mod tests { } = build_buffers_from_records(&records, SHARDS, &hybrid_info); let world = TestWorld::>::with_shards(TestWorldConfig::default()); - let contexts = world.contexts(); + let contexts = world.malicious_contexts(); #[allow(clippy::large_futures)] let results = flatten3v(buffers.into_iter().zip(contexts).map( @@ -384,7 +384,7 @@ mod tests { let world: TestWorld> = TestWorld::with_shards(TestWorldConfig::default()); - let contexts = world.contexts(); + let contexts = world.malicious_contexts(); #[allow(clippy::large_futures)] let results = flatten3v(buffers.into_iter().zip(contexts).map( @@ -437,7 +437,7 @@ mod tests { let world: TestWorld> = TestWorld::with_shards(TestWorldConfig::default()); - let contexts = world.contexts(); + let contexts = world.malicious_contexts(); #[allow(clippy::large_futures)] let results = flatten3v(buffers.into_iter().zip(contexts).map( diff --git a/ipa-core/src/query/runner/reshard_tag.rs b/ipa-core/src/query/runner/reshard_tag.rs index 5d1c3b8f5..9b535fc11 100644 --- a/ipa-core/src/query/runner/reshard_tag.rs +++ b/ipa-core/src/query/runner/reshard_tag.rs @@ -100,7 +100,7 @@ mod tests { let world: TestWorld> = TestWorld::with_shards(TestWorldConfig::default()); world - .semi_honest( + .malicious( vec![BA8::truncate_from(1u128), BA8::truncate_from(2u128)].into_iter(), |ctx, input| async move { let shard_id = ctx.shard_id(); @@ -130,7 +130,7 @@ mod tests { let world: TestWorld> = TestWorld::with_shards(TestWorldConfig::default()); world - .semi_honest( + .malicious( vec![BA8::truncate_from(1u128), BA8::truncate_from(2u128)].into_iter(), |ctx, input| async move { reshard_aad( diff --git a/ipa-core/src/test_fixture/world.rs b/ipa-core/src/test_fixture/world.rs index 8c2db9a4e..91cfc87ea 100644 --- a/ipa-core/src/test_fixture/world.rs +++ b/ipa-core/src/test_fixture/world.rs @@ -240,9 +240,10 @@ impl TestWorld> { /// Panics if world has more or less than 3 gateways/participants #[must_use] pub fn malicious_contexts(&self) -> [Vec>; 3] { + let gate = &self.next_gate(); self.shards() .iter() - .map(|shard| shard.malicious_contexts(&self.next_gate())) + .map(|shard| shard.malicious_contexts(gate)) .fold([Vec::new(), Vec::new(), Vec::new()], |mut acc, contexts| { // Distribute contexts into the respective vectors. for (vec, context) in acc.iter_mut().zip(contexts.iter()) {