From 8433d08e1adb774e55ada3050d823f5d5f1d963a Mon Sep 17 00:00:00 2001 From: Andy Leiserson Date: Thu, 25 Jan 2024 11:21:10 -0800 Subject: [PATCH] Move u128 conversions out of Field trait --- ipa-core/benches/ct/arithmetic_circuit.rs | 4 +- ipa-core/src/bin/test_mpc.rs | 8 +-- ipa-core/src/cli/playbook/input.rs | 8 +-- ipa-core/src/ff/boolean.rs | 7 +-- ipa-core/src/ff/boolean_array.rs | 14 ++--- ipa-core/src/ff/ec_prime_field.rs | 8 +-- ipa-core/src/ff/field.rs | 9 ---- ipa-core/src/ff/galois_field.rs | 8 +-- ipa-core/src/ff/mod.rs | 12 ++++- ipa-core/src/ff/prime_field.rs | 11 ++-- .../src/helpers/buffers/ordering_sender.rs | 2 +- .../src/helpers/buffers/unordered_receiver.rs | 4 +- ipa-core/src/helpers/gateway/mod.rs | 8 +-- ipa-core/src/helpers/mod.rs | 2 +- ipa-core/src/protocol/basics/check_zero.rs | 2 +- .../src/protocol/basics/mul/semi_honest.rs | 4 +- .../basics/sum_of_product/semi_honest.rs | 2 +- ipa-core/src/protocol/boolean/comparison.rs | 2 +- .../protocol/boolean/random_bits_generator.rs | 2 +- ipa-core/src/protocol/boolean/solved_bits.rs | 2 +- ipa-core/src/protocol/boolean/xor.rs | 10 ++-- ipa-core/src/protocol/context/mod.rs | 4 +- .../boolean_ops/addition_sequential.rs | 2 +- .../comparison_and_subtraction_sequential.rs | 4 +- ipa-core/src/protocol/ipa_prf/mod.rs | 13 +++-- .../protocol/ipa_prf/prf_sharding/bucket.rs | 4 +- .../prf_sharding/feature_label_dot_product.rs | 5 +- .../src/protocol/ipa_prf/prf_sharding/mod.rs | 51 +++++++++---------- ipa-core/src/protocol/ipa_prf/quicksort.rs | 6 +-- ipa-core/src/protocol/ipa_prf/shuffle/base.rs | 2 +- ipa-core/src/protocol/ipa_prf/shuffle/mod.rs | 8 +-- .../modulus_conversion/convert_shares.rs | 6 +-- ipa-core/src/protocol/prss/mod.rs | 2 +- ipa-core/src/query/executor.rs | 2 +- ipa-core/src/query/processor.rs | 2 +- ipa-core/src/query/runner/oprf_ipa.rs | 4 +- ipa-core/src/query/runner/test_multiply.rs | 2 +- .../replicated/malicious/additive_share.rs | 7 +-- .../replicated/semi_honest/additive_share.rs | 2 +- ipa-core/src/test_fixture/circuit.rs | 4 +- ipa-core/src/test_fixture/input/sharing.rs | 18 +++---- ipa-core/src/test_fixture/mod.rs | 18 ++++--- ipa-core/src/test_fixture/sharing.rs | 26 +++++----- 43 files changed, 171 insertions(+), 150 deletions(-) diff --git a/ipa-core/benches/ct/arithmetic_circuit.rs b/ipa-core/benches/ct/arithmetic_circuit.rs index fac67dca9..ee7a3ae75 100644 --- a/ipa-core/benches/ct/arithmetic_circuit.rs +++ b/ipa-core/benches/ct/arithmetic_circuit.rs @@ -3,7 +3,7 @@ use criterion::{ BenchmarkId, Criterion, SamplingMode, Throughput, }; use ipa_core::{ - ff::{Field, Fp31, Fp32BitPrime}, + ff::{Field, Fp31, Fp32BitPrime, U128Conversions}, protocol::{basics::SecureMul, context::SemiHonestContext}, secret_sharing::{replicated::semi_honest::AdditiveShare as Replicated, FieldSimd, IntoShares}, test_fixture::circuit, @@ -18,7 +18,7 @@ fn do_benchmark( depth: u16, ) where M: Measurement, - F: Field + FieldSimd, + F: Field + FieldSimd + U128Conversions, for<'a> Replicated: SecureMul>, [F; N]: IntoShares>, Standard: Distribution, diff --git a/ipa-core/src/bin/test_mpc.rs b/ipa-core/src/bin/test_mpc.rs index 93f48d7b7..cd3b1c9d6 100644 --- a/ipa-core/src/bin/test_mpc.rs +++ b/ipa-core/src/bin/test_mpc.rs @@ -8,7 +8,7 @@ use ipa_core::{ playbook::{make_clients, secure_mul, validate, InputSource}, Verbosity, }, - ff::{Field, FieldType, Fp31, Fp32BitPrime, Serializable}, + ff::{Field, FieldType, Fp31, Fp32BitPrime, Serializable, U128Conversions}, helpers::query::{QueryConfig, QueryType::TestMultiply}, net::MpcHelperClient, secret_sharing::{replicated::semi_honest::AdditiveShare, IntoShares}, @@ -99,8 +99,10 @@ async fn main() -> Result<(), Box> { Ok(()) } -async fn multiply_in_field(args: &Args, helper_clients: &[MpcHelperClient; 3]) -where +async fn multiply_in_field( + args: &Args, + helper_clients: &[MpcHelperClient; 3], +) where F: Field + IntoShares>, ::Size: Add<::Size>, <::Size as Add<::Size>>::Output: ArrayLength, diff --git a/ipa-core/src/cli/playbook/input.rs b/ipa-core/src/cli/playbook/input.rs index b5f429a72..2405ee89f 100644 --- a/ipa-core/src/cli/playbook/input.rs +++ b/ipa-core/src/cli/playbook/input.rs @@ -6,16 +6,16 @@ use std::{ path::PathBuf, }; -use crate::{ff::Field, test_fixture::ipa::TestRawDataRecord}; +use crate::{ff::U128Conversions, test_fixture::ipa::TestRawDataRecord}; pub trait InputItem { fn from_str(s: &str) -> Self; } -impl InputItem for F { +impl InputItem for T { fn from_str(s: &str) -> Self { let int_v = s.parse::().unwrap(); - F::truncate_from(int_v) + T::truncate_from(int_v) } } @@ -170,7 +170,7 @@ mod tests { mod input_source { use super::*; - use crate::{cli::playbook::input::InputSource, ff::Field}; + use crate::{cli::playbook::input::InputSource, ff::U128Conversions}; #[test] fn multiline() { diff --git a/ipa-core/src/ff/boolean.rs b/ipa-core/src/ff/boolean.rs index fafd3bc2b..954d9806f 100644 --- a/ipa-core/src/ff/boolean.rs +++ b/ipa-core/src/ff/boolean.rs @@ -3,7 +3,7 @@ use typenum::U1; use super::Gf32Bit; use crate::{ - ff::{Field, Serializable}, + ff::{Field, Serializable, U128Conversions}, impl_shared_value_common, protocol::prss::FromRandomU128, secret_sharing::{ @@ -158,12 +158,13 @@ impl From for Boolean { } } -///implement Field because required by PRSS impl Field for Boolean { const NAME: &'static str = "Boolean"; const ONE: Boolean = Boolean(true); +} +impl U128Conversions for Boolean { fn as_u128(&self) -> u128 { Boolean::as_u128(self) } @@ -192,7 +193,7 @@ impl TryFrom for Boolean { impl FromRandomU128 for Boolean { fn from_random_u128(src: u128) -> Self { - Field::truncate_from(src) + Self::truncate_from(src) } } diff --git a/ipa-core/src/ff/boolean_array.rs b/ipa-core/src/ff/boolean_array.rs index ae34dc1e8..3078f5856 100644 --- a/ipa-core/src/ff/boolean_array.rs +++ b/ipa-core/src/ff/boolean_array.rs @@ -7,7 +7,7 @@ use typenum::{U14, U2, U32, U8}; use crate::{ error::LengthError, - ff::{boolean::Boolean, ArrayAccess, ArrayBuilder, Field, Serializable}, + ff::{boolean::Boolean, ArrayAccess, ArrayBuilder, Field, Serializable, U128Conversions}, protocol::prss::{FromRandom, FromRandomU128}, secret_sharing::{Block, FieldVectorizable, SharedValue, StdArray, Vectorizable}, }; @@ -134,11 +134,9 @@ macro_rules! boolean_array_impl_small { const NAME: &'static str = stringify!($name); const ONE: Self = Self(bitarr_one!($bits)); + } - fn as_u128(&self) -> u128 { - (*self).into() - } - + impl U128Conversions for $name { fn truncate_from>(v: T) -> Self { let v = v.into(); let mut val = ::ZERO; @@ -148,6 +146,10 @@ macro_rules! boolean_array_impl_small { val } + + fn as_u128(&self) -> u128 { + (*self).into() + } } impl TryFrom for $name { @@ -188,7 +190,7 @@ macro_rules! boolean_array_impl_small { impl FromRandomU128 for $name { fn from_random_u128(src: u128) -> Self { - Field::truncate_from(src) + Self::truncate_from(src) } } diff --git a/ipa-core/src/ff/ec_prime_field.rs b/ipa-core/src/ff/ec_prime_field.rs index c2478c8cf..147defaad 100644 --- a/ipa-core/src/ff/ec_prime_field.rs +++ b/ipa-core/src/ff/ec_prime_field.rs @@ -7,7 +7,7 @@ use sha2::Sha256; use typenum::U32; use crate::{ - ff::{boolean_array::BA256, Field, Serializable}, + ff::{boolean_array::BA256, Field, Serializable, U128Conversions}, impl_shared_value_common, protocol::prss::FromRandomU128, secret_sharing::{Block, FieldVectorizable, SharedValue, StdArray, Vectorizable}, @@ -187,12 +187,14 @@ impl FieldVectorizable<1> for Fp25519 { type ArrayAlias = StdArray; } -///implement Field because required by PRSS impl Field for Fp25519 { const NAME: &'static str = "Fp25519"; const ONE: Fp25519 = Fp25519::ONE; +} +// TODO(812): remove these impls +impl U128Conversions for Fp25519 { ///both following methods are based on hashing and do not allow to actually convert elements in Fp25519 /// from or into u128. However it is sufficient to generate random elements in Fp25519 fn as_u128(&self) -> u128 { @@ -205,7 +207,6 @@ impl Field for Fp25519 { } } -// TODO(812): remove this impl impl FromRandomU128 for Fp25519 { fn from_random_u128(v: u128) -> Self { let hk = Hkdf::::new(None, &v.to_le_bytes()); @@ -228,6 +229,7 @@ impl TryFrom for Fp25519 { Ok(f) } } +// TODO(812): end remove impls #[cfg(all(test, unit_test))] mod test { diff --git a/ipa-core/src/ff/field.rs b/ipa-core/src/ff/field.rs index 4e098cfda..88d41087b 100644 --- a/ipa-core/src/ff/field.rs +++ b/ipa-core/src/ff/field.rs @@ -37,15 +37,6 @@ pub trait Field: /// Multiplicative identity element const ONE: Self; - - /// Truncates the higher-order bits larger than `Self::BITS`, and converts - /// into this data type. This conversion is lossy. Callers are encouraged - /// to use `try_from` if the input is not known in advance. - fn truncate_from>(v: T) -> Self; - - /// Blanket implementation to represent the instance of this trait as 16 byte integer. - /// Uses the fact that such conversion already exists via `Self` -> `Self::Integer` -> `Into` - fn as_u128(&self) -> u128; } #[derive(Copy, Clone, Debug, Eq, PartialEq)] diff --git a/ipa-core/src/ff/galois_field.rs b/ipa-core/src/ff/galois_field.rs index 1b7d1f526..c1d7be389 100644 --- a/ipa-core/src/ff/galois_field.rs +++ b/ipa-core/src/ff/galois_field.rs @@ -12,7 +12,7 @@ use typenum::{Unsigned, U1, U2, U3, U4, U5}; use super::ArrayAccess; use crate::{ - ff::{boolean_array::NonZeroPadding, Field, Serializable}, + ff::{boolean_array::NonZeroPadding, Field, Serializable, U128Conversions}, impl_serializable_trait, impl_shared_value_common, protocol::prss::FromRandomU128, secret_sharing::{Block, FieldVectorizable, SharedValue, Vectorizable}, @@ -189,7 +189,9 @@ macro_rules! bit_array_impl { const NAME: &'static str = stringify!($field); const ONE: Self = Self($one); + } + impl U128Conversions for $name { fn as_u128(&self) -> u128 { (*self).into() } @@ -226,7 +228,7 @@ macro_rules! bit_array_impl { impl FromRandomU128 for $name { fn from_random_u128(src: u128) -> Self { - Field::truncate_from(src) + U128Conversions::truncate_from(src) } } @@ -503,7 +505,7 @@ macro_rules! bit_array_impl { type Strategy = prop::strategy::Map, fn(u128) -> Self>; fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy { - (0..=MASK).prop_map(Field::truncate_from as _) + (0..=MASK).prop_map(<$name as U128Conversions>::truncate_from as _) } } diff --git a/ipa-core/src/ff/mod.rs b/ipa-core/src/ff/mod.rs index 96bdbca60..dc72ba836 100644 --- a/ipa-core/src/ff/mod.rs +++ b/ipa-core/src/ff/mod.rs @@ -23,7 +23,7 @@ use generic_array::{ArrayLength, GenericArray}; pub use prime_field::Fp31; pub use prime_field::{Fp32BitPrime, PrimeField}; -use crate::error::UnwrapInfallible; +use crate::{error::UnwrapInfallible, protocol::prss::FromRandomU128}; #[derive(Debug, thiserror::Error, PartialEq, Eq)] pub enum Error { @@ -45,6 +45,16 @@ impl AddSub for T where pub trait AddSubAssign: AddAssign + SubAssign {} impl AddSubAssign for T where T: AddAssign + SubAssign {} +pub trait U128Conversions: FromRandomU128 + TryFrom { + /// Truncates higher-order bits and converts into this data type. This conversion is lossy if + /// the higher order bits are non-zero. Callers are encouraged to use `try_from` if the input may + /// not be convertible. + fn truncate_from>(v: T) -> Self; + + /// Blanket implementation to represent the instance of this trait as 16 byte integer. + fn as_u128(&self) -> u128; +} + /// Trait for items that have fixed-byte length representation. pub trait Serializable: Sized { /// Required number of bytes to store this message on disk/network diff --git a/ipa-core/src/ff/prime_field.rs b/ipa-core/src/ff/prime_field.rs index 27e22a74e..589f9b2c1 100644 --- a/ipa-core/src/ff/prime_field.rs +++ b/ipa-core/src/ff/prime_field.rs @@ -4,13 +4,13 @@ use generic_array::GenericArray; use super::Field; use crate::{ - ff::{FieldType, Serializable}, + ff::{FieldType, Serializable, U128Conversions}, impl_shared_value_common, protocol::prss::FromRandomU128, secret_sharing::{Block, FieldVectorizable, SharedValue, StdArray, Vectorizable}, }; -pub trait PrimeField: Field { +pub trait PrimeField: Field + U128Conversions { type PrimeInteger: Into; const PRIME: Self::PrimeInteger; @@ -47,10 +47,11 @@ macro_rules! field_impl { const NAME: &'static str = stringify!($field); const ONE: Self = $field(1); + } + impl U128Conversions for $field { fn as_u128(&self) -> u128 { - let int: Self::Storage = (*self).into(); - int.into() + u128::from(self.0) } /// An infallible conversion from `u128` to this type. This can be used to draw @@ -67,7 +68,7 @@ macro_rules! field_impl { impl FromRandomU128 for $field { fn from_random_u128(src: u128) -> Self { - Field::truncate_from(src) + U128Conversions::truncate_from(src) } } diff --git a/ipa-core/src/helpers/buffers/ordering_sender.rs b/ipa-core/src/helpers/buffers/ordering_sender.rs index 1e77a98a2..b2a9e9ec7 100644 --- a/ipa-core/src/helpers/buffers/ordering_sender.rs +++ b/ipa-core/src/helpers/buffers/ordering_sender.rs @@ -523,7 +523,7 @@ mod test { use super::OrderingSender; use crate::{ - ff::{Field, Fp31, Fp32BitPrime, Gf20Bit, Gf9Bit, Serializable}, + ff::{Fp31, Fp32BitPrime, Gf20Bit, Gf9Bit, Serializable, U128Conversions}, helpers::Message, rand::thread_rng, sync::Arc, diff --git a/ipa-core/src/helpers/buffers/unordered_receiver.rs b/ipa-core/src/helpers/buffers/unordered_receiver.rs index 080dadedb..4a236a59d 100644 --- a/ipa-core/src/helpers/buffers/unordered_receiver.rs +++ b/ipa-core/src/helpers/buffers/unordered_receiver.rs @@ -75,7 +75,7 @@ impl Spare { self.buf.extend_from_slice(v); } - /// Extend the buffer with new data. + /// Extend the buffer with new data. /// This returns a message if there is enough data. /// This returns a value because it can be more efficient in cases where /// received chunks don't align with messages. @@ -405,7 +405,7 @@ mod test { use typenum::Unsigned; use crate::{ - ff::{Field, Fp31, Fp32BitPrime, Serializable}, + ff::{Fp31, Fp32BitPrime, Serializable, U128Conversions}, helpers::buffers::unordered_receiver::UnorderedReceiver, }; diff --git a/ipa-core/src/helpers/gateway/mod.rs b/ipa-core/src/helpers/gateway/mod.rs index 4fd839ca5..018431d62 100644 --- a/ipa-core/src/helpers/gateway/mod.rs +++ b/ipa-core/src/helpers/gateway/mod.rs @@ -179,8 +179,8 @@ mod tests { use futures_util::future::{join, try_join, try_join_all}; use crate::{ - ff::{Field, Fp31, Fp32BitPrime, Gf2}, - helpers::{Direction, GatewayConfig, Role, SendingEnd}, + ff::{Fp31, Fp32BitPrime, Gf2, U128Conversions}, + helpers::{Direction, GatewayConfig, Message, Role, SendingEnd}, protocol::{context::Context, RecordId}, test_fixture::{Runner, TestWorld, TestWorldConfig}, }; @@ -192,9 +192,9 @@ mod tests { /// Gateway must be able to deal with it. #[tokio::test] async fn can_handle_heterogeneous_channels() { - async fn send(channel: &SendingEnd, i: usize) { + async fn send(channel: &SendingEnd, i: usize) { channel - .send(i.into(), F::truncate_from(u128::try_from(i).unwrap())) + .send(i.into(), V::truncate_from(u128::try_from(i).unwrap())) .await .unwrap(); } diff --git a/ipa-core/src/helpers/mod.rs b/ipa-core/src/helpers/mod.rs index ced453615..b2b15f305 100644 --- a/ipa-core/src/helpers/mod.rs +++ b/ipa-core/src/helpers/mod.rs @@ -660,7 +660,7 @@ mod concurrency_tests { use shuttle_crate::rand::thread_rng; use crate::{ - ff::{Field, FieldType, Fp31, Fp32BitPrime}, + ff::{FieldType, Fp31, Fp32BitPrime, U128Conversions}, helpers::{ query::{QueryConfig, QueryType::TestMultiply}, Direction, GatewayConfig, diff --git a/ipa-core/src/protocol/basics/check_zero.rs b/ipa-core/src/protocol/basics/check_zero.rs index d391ea7ce..192533d85 100644 --- a/ipa-core/src/protocol/basics/check_zero.rs +++ b/ipa-core/src/protocol/basics/check_zero.rs @@ -70,7 +70,7 @@ mod tests { use crate::{ error::Error, - ff::{Field, Fp31, PrimeField}, + ff::{Fp31, PrimeField, U128Conversions}, protocol::{basics::check_zero, context::Context, RecordId}, rand::thread_rng, secret_sharing::{IntoShares, SharedValue}, diff --git a/ipa-core/src/protocol/basics/mul/semi_honest.rs b/ipa-core/src/protocol/basics/mul/semi_honest.rs index 303027deb..0d1c1ad96 100644 --- a/ipa-core/src/protocol/basics/mul/semi_honest.rs +++ b/ipa-core/src/protocol/basics/mul/semi_honest.rs @@ -123,7 +123,7 @@ mod test { use super::multiply; use crate::{ - ff::{Field, Fp31, Fp32BitPrime}, + ff::{Field, Fp31, Fp32BitPrime, U128Conversions}, helpers::TotalRecords, protocol::{ basics::{SecureMul, ZeroPositions}, @@ -205,7 +205,7 @@ mod test { async fn multiply_sync(world: &TestWorld, a: u128, b: u128) -> u128 where - F: Field, + F: Field + U128Conversions, (F, F): Sized, Standard: Distribution, { diff --git a/ipa-core/src/protocol/basics/sum_of_product/semi_honest.rs b/ipa-core/src/protocol/basics/sum_of_product/semi_honest.rs index cee2f518a..bdbe06b09 100644 --- a/ipa-core/src/protocol/basics/sum_of_product/semi_honest.rs +++ b/ipa-core/src/protocol/basics/sum_of_product/semi_honest.rs @@ -87,7 +87,7 @@ impl super::SumOfProducts for Replicated { mod test { use super::sum_of_products; use crate::{ - ff::{Field, Fp31}, + ff::{Fp31, U128Conversions}, protocol::{context::Context, RecordId}, rand::{thread_rng, Rng}, secret_sharing::SharedValue, diff --git a/ipa-core/src/protocol/boolean/comparison.rs b/ipa-core/src/protocol/boolean/comparison.rs index b95f8cc94..81e1d05c0 100644 --- a/ipa-core/src/protocol/boolean/comparison.rs +++ b/ipa-core/src/protocol/boolean/comparison.rs @@ -308,7 +308,7 @@ mod tests { greater_than_constant, }; use crate::{ - ff::{Field, Fp31, Fp32BitPrime, PrimeField}, + ff::{Field, Fp31, Fp32BitPrime, PrimeField, U128Conversions}, protocol::{ boolean::random_bits_generator::RandomBitsGenerator, context::{Context, UpgradableContext, Validator}, diff --git a/ipa-core/src/protocol/boolean/random_bits_generator.rs b/ipa-core/src/protocol/boolean/random_bits_generator.rs index 520648dee..314a0ddd2 100644 --- a/ipa-core/src/protocol/boolean/random_bits_generator.rs +++ b/ipa-core/src/protocol/boolean/random_bits_generator.rs @@ -100,7 +100,7 @@ mod tests { use super::RandomBitsGenerator; use crate::{ - ff::{Field, Fp31}, + ff::{Fp31, U128Conversions}, protocol::{ context::{Context, UpgradableContext, Validator}, RecordId, diff --git a/ipa-core/src/protocol/boolean/solved_bits.rs b/ipa-core/src/protocol/boolean/solved_bits.rs index 2e3ef1b07..452383e24 100644 --- a/ipa-core/src/protocol/boolean/solved_bits.rs +++ b/ipa-core/src/protocol/boolean/solved_bits.rs @@ -153,7 +153,7 @@ mod tests { use rand::{distributions::Standard, prelude::Distribution}; use crate::{ - ff::{Field, Fp31, Fp32BitPrime, PrimeField}, + ff::{Field, Fp31, Fp32BitPrime, PrimeField, U128Conversions}, protocol::{ boolean::solved_bits::solved_bits, context::{Context, UpgradableContext, Validator}, diff --git a/ipa-core/src/protocol/boolean/xor.rs b/ipa-core/src/protocol/boolean/xor.rs index 95e20059a..ae1da2886 100644 --- a/ipa-core/src/protocol/boolean/xor.rs +++ b/ipa-core/src/protocol/boolean/xor.rs @@ -1,6 +1,6 @@ use crate::{ error::Error, - ff::Field, + ff::{Field, U128Conversions}, protocol::{ basics::{MultiplyZeroPositions, SecureMul, ZeroPositions}, context::Context, @@ -15,7 +15,7 @@ use crate::{ /// When communication fails. pub async fn xor(ctx: C, record_id: RecordId, a: &S, b: &S) -> Result where - F: Field, + F: Field + U128Conversions, C: Context, S: LinearSecretSharing + SecureMul, { @@ -33,7 +33,7 @@ pub async fn xor_sparse( zeros_at: MultiplyZeroPositions, ) -> Result where - F: Field, + F: Field + U128Conversions, C: Context, S: LinearSecretSharing + SecureMul, { @@ -47,7 +47,7 @@ mod tests { use super::xor; use crate::{ - ff::{Field, Fp31, Fp32BitPrime}, + ff::{Field, Fp31, Fp32BitPrime, U128Conversions}, protocol::{ basics::{mul::sparse::test::SparseField, MultiplyZeroPositions, ZeroPositions}, boolean::xor_sparse, @@ -60,7 +60,7 @@ mod tests { async fn run(world: &TestWorld, a: F, b: F) -> F where - F: ExtendableField, + F: ExtendableField + U128Conversions, Standard: Distribution, { let result = world diff --git a/ipa-core/src/protocol/context/mod.rs b/ipa-core/src/protocol/context/mod.rs index 69cd66934..ca1965135 100644 --- a/ipa-core/src/protocol/context/mod.rs +++ b/ipa-core/src/protocol/context/mod.rs @@ -281,7 +281,7 @@ mod tests { use typenum::Unsigned; use crate::{ - ff::{Field, Fp31, Serializable}, + ff::{Field, Fp31, Serializable, U128Conversions}, helpers::{Direction, Role}, protocol::{ context::{ @@ -326,7 +326,7 @@ mod tests { /// Toy protocol to execute PRSS generation and send/receive logic async fn toy_protocol(ctx: C, index: usize, share: &S) -> Replicated where - F: Field, + F: Field + U128Conversions, Standard: Distribution, C: Context, S: ReplicatedLeftValue, diff --git a/ipa-core/src/protocol/ipa_prf/boolean_ops/addition_sequential.rs b/ipa-core/src/protocol/ipa_prf/boolean_ops/addition_sequential.rs index a506f0753..e4b937790 100644 --- a/ipa-core/src/protocol/ipa_prf/boolean_ops/addition_sequential.rs +++ b/ipa-core/src/protocol/ipa_prf/boolean_ops/addition_sequential.rs @@ -172,7 +172,7 @@ mod test { use crate::{ ff::{ boolean_array::{BA32, BA64}, - Field, + U128Conversions, }, protocol, protocol::{ diff --git a/ipa-core/src/protocol/ipa_prf/boolean_ops/comparison_and_subtraction_sequential.rs b/ipa-core/src/protocol/ipa_prf/boolean_ops/comparison_and_subtraction_sequential.rs index 90f427d21..82b68e0e3 100644 --- a/ipa-core/src/protocol/ipa_prf/boolean_ops/comparison_and_subtraction_sequential.rs +++ b/ipa-core/src/protocol/ipa_prf/boolean_ops/comparison_and_subtraction_sequential.rs @@ -244,7 +244,7 @@ mod test { ff::{ boolean::Boolean, boolean_array::{BA3, BA32, BA5, BA64}, - Expand, Field, + Expand, Field, U128Conversions, }, protocol, protocol::{ @@ -406,7 +406,7 @@ mod test { let x = repeat_with(|| rng.gen()) .take(BENCH_COUNT) .collect::>(); - let x_int = x.iter().map(Field::as_u128).collect::>(); + let x_int = x.iter().map(U128Conversions::as_u128).collect::>(); let y: BA64 = rng.gen::(); let y_int = y.as_u128(); diff --git a/ipa-core/src/protocol/ipa_prf/mod.rs b/ipa-core/src/protocol/ipa_prf/mod.rs index e7dc68f52..8068a5684 100644 --- a/ipa-core/src/protocol/ipa_prf/mod.rs +++ b/ipa-core/src/protocol/ipa_prf/mod.rs @@ -7,7 +7,10 @@ use typenum::{Unsigned, U18}; use self::{quicksort::quicksort_ranges_by_key_insecure, shuffle::shuffle_inputs}; use crate::{ error::{Error, UnwrapInfallible}, - ff::{boolean::Boolean, boolean_array::BA64, CustomArray, Field, PrimeField, Serializable}, + ff::{ + boolean::Boolean, boolean_array::BA64, CustomArray, Field, PrimeField, Serializable, + U128Conversions, + }, protocol::{ context::{UpgradableContext, UpgradedContext}, ipa_prf::{ @@ -168,10 +171,10 @@ where C: UpgradableContext, C::UpgradedContext: UpgradedContext>, C::UpgradedContext: UpgradedContext>, - BK: SharedValue + CustomArray + Field, - TV: SharedValue + CustomArray + Field, - TS: SharedValue + CustomArray + Field, - SS: SharedValue + CustomArray + Field, + BK: SharedValue + U128Conversions + CustomArray + Field, + TV: SharedValue + U128Conversions + CustomArray + Field, + TS: SharedValue + U128Conversions + CustomArray + Field, + SS: SharedValue + U128Conversions + CustomArray + Field, F: PrimeField + ExtendableField, Replicated: Serializable, { diff --git a/ipa-core/src/protocol/ipa_prf/prf_sharding/bucket.rs b/ipa-core/src/protocol/ipa_prf/prf_sharding/bucket.rs index 94da6a674..12ae48bf3 100644 --- a/ipa-core/src/protocol/ipa_prf/prf_sharding/bucket.rs +++ b/ipa-core/src/protocol/ipa_prf/prf_sharding/bucket.rs @@ -66,7 +66,7 @@ impl From for Error { /// produce [`row_contribution`]_r,0 =[`value`]-[`bd_key`]_r.[`value`] and [`row_contribution`]_r,1=[`bd_key`]_r.[`value`]. /// This takes the most significant bit of `bd_key` and places value in one of the two child nodes of the binary tree. /// At each successive round, the next most significant bit is propagated from the leaf nodes of the tree into further leaf nodes: -/// [`row_contribution`]_r+1,q,0 =[`row_contribution`]_r,q - [`bd_key`]_r+1.[`row_contribution`]_r,q and [`row_contribution`]_r+1,q,1 =[`bd_key`]_r+1.[`row_contribution`]_r,q. +/// [`row_contribution`]_r+1,q,0 =[`row_contribution`]_r,q - [`bd_key`]_r+1.[`row_contribution`]_r,q and [`row_contribution`]_r+1,q,1 =[`bd_key`]_r+1.[`row_contribution`]_r,q. /// The work of each iteration therefore doubles relative to the one preceding. /// /// In case a malicious entity sends a out of range breakdown key (i.e. greater than the max count) to this function, we need to do some @@ -146,7 +146,7 @@ pub mod tests { use rand::thread_rng; use crate::{ - ff::{Field, Fp32BitPrime, Gf8Bit, Gf9Bit}, + ff::{Fp32BitPrime, Gf8Bit, Gf9Bit, U128Conversions}, protocol::{ context::{Context, UpgradableContext, Validator}, ipa_prf::prf_sharding::bucket::move_single_value_to_bucket, diff --git a/ipa-core/src/protocol/ipa_prf/prf_sharding/feature_label_dot_product.rs b/ipa-core/src/protocol/ipa_prf/prf_sharding/feature_label_dot_product.rs index 3206263c1..c706395c4 100644 --- a/ipa-core/src/protocol/ipa_prf/prf_sharding/feature_label_dot_product.rs +++ b/ipa-core/src/protocol/ipa_prf/prf_sharding/feature_label_dot_product.rs @@ -346,7 +346,10 @@ where #[cfg(all(test, unit_test))] pub mod tests { use crate::{ - ff::{boolean::Boolean, boolean_array::BA32, CustomArray, Field, Fp32BitPrime}, + ff::{ + boolean::Boolean, boolean_array::BA32, CustomArray, Field, Fp32BitPrime, + U128Conversions, + }, protocol::ipa_prf::prf_sharding::feature_label_dot_product::{ compute_feature_label_dot_product, PrfShardedIpaInputRow, }, diff --git a/ipa-core/src/protocol/ipa_prf/prf_sharding/mod.rs b/ipa-core/src/protocol/ipa_prf/prf_sharding/mod.rs index c1de99f66..52a50b4d1 100644 --- a/ipa-core/src/protocol/ipa_prf/prf_sharding/mod.rs +++ b/ipa-core/src/protocol/ipa_prf/prf_sharding/mod.rs @@ -16,7 +16,7 @@ use crate::{ ff::{ boolean::Boolean, boolean_array::{BA32, BA7}, - ArrayAccess, CustomArray, Expand, Field, PrimeField, Serializable, + ArrayAccess, CustomArray, Expand, Field, PrimeField, Serializable, U128Conversions, }, helpers::Role, protocol::{ @@ -100,12 +100,12 @@ struct InputsRequiredFromPrevRow, } -impl< - BK: SharedValue + CustomArray + Field, - TV: SharedValue + CustomArray + Field, - TS: SharedValue + CustomArray + Field, - SS: SharedValue + CustomArray + Field, - > InputsRequiredFromPrevRow +impl InputsRequiredFromPrevRow +where + BK: SharedValue + U128Conversions + CustomArray + Field, + TV: SharedValue + U128Conversions + CustomArray + Field, + TS: SharedValue + U128Conversions + CustomArray + Field, + SS: SharedValue + U128Conversions + CustomArray + Field, { /// /// This function contains the main logic for the per-user attribution circuit. @@ -466,10 +466,10 @@ where C::UpgradedContext: UpgradedContext>, C::UpgradedContext: UpgradedContext, S: LinearSecretSharing + Serializable + SecureMul>, - BK: SharedValue + CustomArray + Field, - TV: SharedValue + CustomArray + Field, - TS: SharedValue + CustomArray + Field, - SS: SharedValue + CustomArray + Field, + BK: SharedValue + U128Conversions + CustomArray + Field, + TV: SharedValue + U128Conversions + CustomArray + Field, + TS: SharedValue + U128Conversions + CustomArray + Field, + SS: SharedValue + U128Conversions + CustomArray + Field, F: PrimeField + ExtendableField, { // Get the validator and context to use for Boolean multiplication operations @@ -572,10 +572,10 @@ async fn evaluate_per_user_attribution_circuit( ) -> Result>, Error> where C: Context, - BK: SharedValue + CustomArray + Field, - TV: SharedValue + CustomArray + Field, - TS: SharedValue + CustomArray + Field, - SS: SharedValue + CustomArray + Field, + BK: SharedValue + U128Conversions + CustomArray + Field, + TV: SharedValue + U128Conversions + CustomArray + Field, + TS: SharedValue + U128Conversions + CustomArray + Field, + SS: SharedValue + U128Conversions + CustomArray + Field, { assert!(!rows_for_user.is_empty()); if rows_for_user.len() == 1 { @@ -670,7 +670,7 @@ async fn timestamp_of_most_recent_source_event( ) -> Result, Error> where C: Context, - TS: SharedValue + CustomArray + Field, + TS: SharedValue + U128Conversions + CustomArray + Field, { match attribution_window_seconds { None => Ok(prev_row_timestamp_bits.clone()), @@ -711,8 +711,8 @@ async fn zero_out_trigger_value_unless_attributed( ) -> Result, Error> where C: Context, - TV: SharedValue + CustomArray + Field, - TS: SharedValue + CustomArray + Field, + TV: SharedValue + U128Conversions + CustomArray + Field, + TS: SharedValue + U128Conversions + CustomArray + Field, { let (did_trigger_get_attributed, is_trigger_within_window) = try_join( is_trigger_bit.multiply( @@ -765,8 +765,7 @@ async fn is_trigger_event_within_attribution_window( ) -> Result, Error> where C: Context, - TS: SharedValue, - TS: SharedValue + CustomArray + Field, + TS: SharedValue + U128Conversions + CustomArray + Field, { if let Some(attribution_window_seconds) = attribution_window_seconds { let time_delta_bits = integer_sub( @@ -822,7 +821,7 @@ async fn compute_capped_trigger_value( ) -> Result, Error> where C: Context, - TV: SharedValue + CustomArray + Field, + TV: SharedValue + U128Conversions + CustomArray + Field, { let narrowed_ctx1 = ctx.narrow(&Step::ComputedCappedAttributedTriggerValueNotSaturatedCase); let narrowed_ctx2 = ctx.narrow(&Step::ComputedCappedAttributedTriggerValueJustSaturatedCase); @@ -860,7 +859,7 @@ pub mod tests { ff::{ boolean::Boolean, boolean_array::{BA20, BA3, BA5, BA8}, - CustomArray, Field, Fp32BitPrime, + CustomArray, Field, Fp32BitPrime, U128Conversions, }, protocol::ipa_prf::prf_sharding::attribute_cap_aggregate, rand::Rng, @@ -886,7 +885,7 @@ pub mod tests { trigger_value: u8, ) -> PreShardedAndSortedOPRFTestInput where - BK: SharedValue + Field, + BK: SharedValue + U128Conversions + Field, { oprf_test_input_with_timestamp( prf_of_match_key, @@ -905,7 +904,7 @@ pub mod tests { timestamp: u32, ) -> PreShardedAndSortedOPRFTestInput where - BK: SharedValue + Field, + BK: SharedValue + U128Conversions + Field, { let is_trigger_bit = if is_trigger { Boolean::ONE @@ -982,8 +981,8 @@ pub mod tests { impl Reconstruct for [&CappedAttributionOutputs; 3] where - BK: SharedValue + CustomArray + Field, - TV: SharedValue + CustomArray + Field, + BK: SharedValue + U128Conversions + CustomArray + Field, + TV: SharedValue + U128Conversions + CustomArray + Field, { fn reconstruct(&self) -> PreAggregationTestOutputInDecimal { let [s0, s1, s2] = self; diff --git a/ipa-core/src/protocol/ipa_prf/quicksort.rs b/ipa-core/src/protocol/ipa_prf/quicksort.rs index 0ac73a985..3c9caaf42 100644 --- a/ipa-core/src/protocol/ipa_prf/quicksort.rs +++ b/ipa-core/src/protocol/ipa_prf/quicksort.rs @@ -9,7 +9,7 @@ use ipa_macros::Step; use crate::{ error::Error, - ff::{boolean::Boolean, ArrayAccess, ArrayBuild, CustomArray, Field}, + ff::{boolean::Boolean, ArrayAccess, ArrayBuild, CustomArray}, protocol::{ basics::Reveal, context::Context, ipa_prf::boolean_ops::comparison_and_subtraction_sequential::compare_gt, RecordId, @@ -60,7 +60,7 @@ where C: Context, S: Send + Sync, F: Fn(&S) -> &AdditiveShare + Sync + Send + Copy, - K: SharedValue + Field + CustomArray, + K: SharedValue + CustomArray, AdditiveShare: ArrayAccess + ArrayBuild>, { assert!(!ranges_to_sort.iter().any(Range::is_empty)); @@ -163,7 +163,7 @@ pub mod tests { use crate::{ ff::{ boolean_array::{BA20, BA64}, - Field, + Field, U128Conversions, }, protocol::{context::Context, ipa_prf::quicksort::quicksort_ranges_by_key_insecure}, rand::thread_rng, diff --git a/ipa-core/src/protocol/ipa_prf/shuffle/base.rs b/ipa-core/src/protocol/ipa_prf/shuffle/base.rs index 970f79d14..7f0b92283 100644 --- a/ipa-core/src/protocol/ipa_prf/shuffle/base.rs +++ b/ipa-core/src/protocol/ipa_prf/shuffle/base.rs @@ -351,7 +351,7 @@ where pub mod tests { use super::shuffle; use crate::{ - ff::{Field, Gf40Bit}, + ff::{Gf40Bit, U128Conversions}, test_fixture::{Reconstruct, Runner, TestWorld, TestWorldConfig}, }; diff --git a/ipa-core/src/protocol/ipa_prf/shuffle/mod.rs b/ipa-core/src/protocol/ipa_prf/shuffle/mod.rs index 62a7ac5fc..5750f9c1d 100644 --- a/ipa-core/src/protocol/ipa_prf/shuffle/mod.rs +++ b/ipa-core/src/protocol/ipa_prf/shuffle/mod.rs @@ -5,7 +5,7 @@ use crate::{ ff::{ boolean::Boolean, boolean_array::{BA112, BA64}, - ArrayAccess, CustomArray, Expand, Field, + ArrayAccess, CustomArray, Expand, }, protocol::{ context::{UpgradableContext, UpgradedContext}, @@ -27,9 +27,9 @@ pub async fn shuffle_inputs( where C: UpgradableContext, C::UpgradedContext: UpgradedContext>, - BK: SharedValue + CustomArray + Field, - TV: SharedValue + CustomArray + Field, - TS: SharedValue + CustomArray + Field, + BK: SharedValue + CustomArray, + TV: SharedValue + CustomArray, + TS: SharedValue + CustomArray, { let shuffle_input: Vec> = input .into_iter() diff --git a/ipa-core/src/protocol/modulus_conversion/convert_shares.rs b/ipa-core/src/protocol/modulus_conversion/convert_shares.rs index ab3581e96..03d26543c 100644 --- a/ipa-core/src/protocol/modulus_conversion/convert_shares.rs +++ b/ipa-core/src/protocol/modulus_conversion/convert_shares.rs @@ -34,7 +34,7 @@ use pin_project::pin_project; use crate::{ error::Error, exact::ExactSizeStream, - ff::{ArrayAccess, Field, Gf2, PrimeField}, + ff::{ArrayAccess, Field, Gf2, PrimeField, U128Conversions}, helpers::Role, protocol::{ basics::{SecureMul, ZeroPositions}, @@ -266,7 +266,7 @@ async fn convert_bit( locally_converted_bits: &BitConversionTriple, ) -> Result where - F: Field, + F: Field + U128Conversions, C: Context, S: LinearSecretSharing + SecureMul, { @@ -398,7 +398,7 @@ mod tests { use crate::{ error::Error, - ff::{Field, Fp31, Fp32BitPrime, Gf2, PrimeField}, + ff::{Field, Fp31, Fp32BitPrime, Gf2, PrimeField, U128Conversions}, helpers::{Direction, Role}, protocol::{ context::{Context, UpgradableContext, UpgradedContext, Validator}, diff --git a/ipa-core/src/protocol/prss/mod.rs b/ipa-core/src/protocol/prss/mod.rs index 9ddf3a874..15690fd7e 100644 --- a/ipa-core/src/protocol/prss/mod.rs +++ b/ipa-core/src/protocol/prss/mod.rs @@ -350,7 +350,7 @@ pub mod test { use super::{Generator, KeyExchange, SequentialSharedRandomness}; use crate::{ - ff::{Field, Fp31}, + ff::{Field, Fp31, U128Conversions}, protocol::{ prss::{Endpoint, PrssIndex, SharedRandomness}, step::{Gate, StepNarrow}, diff --git a/ipa-core/src/query/executor.rs b/ipa-core/src/query/executor.rs index 75c6b2e1a..b2085980e 100644 --- a/ipa-core/src/query/executor.rs +++ b/ipa-core/src/query/executor.rs @@ -147,7 +147,7 @@ where #[cfg(all(test, unit_test))] mod tests { use crate::{ - ff::{Field, Fp31}, + ff::{Fp31, U128Conversions}, query::ProtocolResult, secret_sharing::{replicated::semi_honest::AdditiveShare, IntoShares}, }; diff --git a/ipa-core/src/query/processor.rs b/ipa-core/src/query/processor.rs index a18641661..5e96a0140 100644 --- a/ipa-core/src/query/processor.rs +++ b/ipa-core/src/query/processor.rs @@ -538,7 +538,7 @@ mod tests { error::BoxError, ff::{ boolean_array::{BA20, BA3, BA8}, - Field, Fp31, + Fp31, U128Conversions, }, helpers::query::{IpaQueryConfig, QueryType}, protocol::ipa_prf::OPRFIPAInputRow, diff --git a/ipa-core/src/query/runner/oprf_ipa.rs b/ipa-core/src/query/runner/oprf_ipa.rs index b1ab90495..2df91cb7a 100644 --- a/ipa-core/src/query/runner/oprf_ipa.rs +++ b/ipa-core/src/query/runner/oprf_ipa.rs @@ -136,7 +136,7 @@ mod tests { use crate::{ ff::{ boolean_array::{BA20, BA3, BA8}, - Field, Fp31, + Fp31, U128Conversions, }, helpers::{ query::{IpaQueryConfig, QuerySize}, @@ -235,7 +235,7 @@ mod tests { assert_eq!( results.reconstruct()[0..3] .iter() - .map(Field::as_u128) + .map(U128Conversions::as_u128) .collect::>(), EXPECTED ); diff --git a/ipa-core/src/query/runner/test_multiply.rs b/ipa-core/src/query/runner/test_multiply.rs index 02f6ece81..18fcc2c9c 100644 --- a/ipa-core/src/query/runner/test_multiply.rs +++ b/ipa-core/src/query/runner/test_multiply.rs @@ -73,7 +73,7 @@ mod tests { use super::*; use crate::{ - ff::{Field, Fp31}, + ff::{Fp31, U128Conversions}, secret_sharing::IntoShares, test_fixture::{join3v, Reconstruct, TestWorld}, }; diff --git a/ipa-core/src/secret_sharing/replicated/malicious/additive_share.rs b/ipa-core/src/secret_sharing/replicated/malicious/additive_share.rs index 8a74b9cae..6e8c84b80 100644 --- a/ipa-core/src/secret_sharing/replicated/malicious/additive_share.rs +++ b/ipa-core/src/secret_sharing/replicated/malicious/additive_share.rs @@ -13,7 +13,8 @@ use generic_array::{ArrayLength, GenericArray}; use typenum::Unsigned; use crate::{ - ff::{Field, Gf2, Gf32Bit, PrimeField, Serializable}, + ff::{Field, Gf2, Gf32Bit, PrimeField, Serializable, U128Conversions}, + protocol::prss::FromRandom, secret_sharing::{ replicated::semi_honest::AdditiveShare as SemiHonestAdditiveShare, BitDecomposed, Linear as LinearSecretSharing, SecretSharing, SharedValue, @@ -40,7 +41,7 @@ pub struct AdditiveShare { } pub trait ExtendableField: Field { - type ExtendedField: Field; + type ExtendedField: Field + FromRandom; fn to_extended(&self) -> Self::ExtendedField; } @@ -415,7 +416,7 @@ impl ThisCodeIsAuthorizedToDowngradeFromMalicious for UnauthorizedDowngrad mod tests { use super::{AdditiveShare, Downgrade, ThisCodeIsAuthorizedToDowngradeFromMalicious}; use crate::{ - ff::{Field, Fp31}, + ff::{Field, Fp31, U128Conversions}, helpers::Role, rand::{thread_rng, Rng}, secret_sharing::{ diff --git a/ipa-core/src/secret_sharing/replicated/semi_honest/additive_share.rs b/ipa-core/src/secret_sharing/replicated/semi_honest/additive_share.rs index 9310a0bf2..817c870cd 100644 --- a/ipa-core/src/secret_sharing/replicated/semi_honest/additive_share.rs +++ b/ipa-core/src/secret_sharing/replicated/semi_honest/additive_share.rs @@ -511,7 +511,7 @@ mod tests { }; use crate::{ - ff::{Field, Fp31, Fp32BitPrime}, + ff::{Fp31, Fp32BitPrime, U128Conversions}, secret_sharing::{ replicated::{semi_honest::AdditiveShare, ReplicatedSecretSharing}, SharedValue, StdArray, Vectorizable, diff --git a/ipa-core/src/test_fixture/circuit.rs b/ipa-core/src/test_fixture/circuit.rs index 1fce74ead..2f1f67cb0 100644 --- a/ipa-core/src/test_fixture/circuit.rs +++ b/ipa-core/src/test_fixture/circuit.rs @@ -3,7 +3,7 @@ use rand::distributions::{Distribution, Standard}; use super::join3v; use crate::{ - ff::Field, + ff::{Field, U128Conversions}, helpers::TotalRecords, protocol::{ basics::SecureMul, @@ -21,7 +21,7 @@ use crate::{ /// panics when circuits did not produce the expected value. pub async fn arithmetic(width: u32, depth: u16) where - F: Field + FieldSimd, + F: Field + FieldSimd + U128Conversions, for<'a> Replicated: SecureMul>, [F; N]: IntoShares>, Standard: Distribution, diff --git a/ipa-core/src/test_fixture/input/sharing.rs b/ipa-core/src/test_fixture/input/sharing.rs index 206c07958..1d674efff 100644 --- a/ipa-core/src/test_fixture/input/sharing.rs +++ b/ipa-core/src/test_fixture/input/sharing.rs @@ -1,7 +1,7 @@ use std::iter::{repeat, zip}; use crate::{ - ff::{boolean::Boolean, boolean_array::BA64, Field}, + ff::{boolean::Boolean, boolean_array::BA64, Field, U128Conversions}, protocol::ipa_prf::OPRFIPAInputRow, rand::Rng, report::{EventType, OprfReport}, @@ -22,9 +22,9 @@ const DOMAINS: &[&str] = &[ // TODO: this mostly duplicates the impl for GenericReportTestInput, can we avoid that? impl IntoShares> for TestRawDataRecord where - BK: SharedValue + Field + IntoShares>, - TV: SharedValue + Field + IntoShares>, - TS: SharedValue + Field + IntoShares>, + BK: SharedValue + U128Conversions + IntoShares>, + TV: SharedValue + U128Conversions + IntoShares>, + TS: SharedValue + U128Conversions + IntoShares>, { fn share_with(self, rng: &mut R) -> [OprfReport; 3] { let match_key = BA64::try_from(u128::from(self.user_id)) @@ -82,10 +82,10 @@ where let timestamp: [Replicated; 3] = TS::try_from(u128::from(self.timestamp)) .unwrap() .share_with(rng); - let breakdown_key = BK::try_from(self.breakdown_key.into()) + let breakdown_key = BK::try_from(u128::from(self.breakdown_key)) .unwrap() .share_with(rng); - let trigger_value = TV::try_from(self.trigger_value.into()) + let trigger_value = TV::try_from(u128::from(self.trigger_value)) .unwrap() .share_with(rng); @@ -112,9 +112,9 @@ where impl Reconstruct for [&OPRFIPAInputRow; 3] where - BK: SharedValue + Field, - TV: SharedValue + Field, - TS: SharedValue + Field, + BK: SharedValue + U128Conversions, + TV: SharedValue + U128Conversions, + TS: SharedValue + U128Conversions, { fn reconstruct(&self) -> TestRawDataRecord { let [s0, s1, s2] = self; diff --git a/ipa-core/src/test_fixture/mod.rs b/ipa-core/src/test_fixture/mod.rs index e383d4db0..0f96aee7b 100644 --- a/ipa-core/src/test_fixture/mod.rs +++ b/ipa-core/src/test_fixture/mod.rs @@ -28,13 +28,15 @@ pub use sharing::{get_bits, into_bits, Reconstruct, ReconstructArr}; pub use world::{Runner, TestWorld, TestWorldConfig}; use crate::{ - ff::Field, + ff::{Field, U128Conversions}, protocol::{ context::Context, prss::Endpoint as PrssEndpoint, step::{Gate, Step, StepNarrow}, }, - secret_sharing::{replicated::semi_honest::AdditiveShare as Replicated, IntoShares}, + secret_sharing::{ + replicated::semi_honest::AdditiveShare as Replicated, IntoShares, SharedValue, + }, }; /// Narrows a set of contexts all at once. @@ -80,11 +82,11 @@ pub type ReplicatedShares = [Vec>; 3]; /// Generate vector shares from vector of inputs for three participant /// /// # Panics -/// If the input cannot be converted into the given field `F` without truncation. +/// If the input cannot be converted into the given value type `V` without truncation. #[must_use] -pub fn generate_shares(input: &[u128]) -> ReplicatedShares +pub fn generate_shares(input: &[u128]) -> ReplicatedShares where - Standard: Distribution, + Standard: Distribution, { let mut rand = StepRng::new(100, 1); @@ -94,7 +96,7 @@ where let mut shares2 = Vec::with_capacity(len); for i in input { - let [s0, s1, s2] = F::try_from(*i).unwrap().share_with(&mut rand); + let [s0, s1, s2] = V::try_from(*i).unwrap().share_with(&mut rand); shares0.push(s0); shares1.push(s1); shares2.push(s2); @@ -156,7 +158,7 @@ where } /// Take a slice of bits in `{0,1} ⊆ F_p`, and reconstruct the integer in `Z` -pub fn bits_to_value(x: &[F]) -> u128 { +pub fn bits_to_value(x: &[F]) -> u128 { #[allow(clippy::cast_possible_truncation)] let v = x .iter() @@ -169,6 +171,6 @@ pub fn bits_to_value(x: &[F]) -> u128 { /// /// # Panics /// If the input cannot be converted into the given field `F` without truncation. -pub fn bits_to_field(x: &[F]) -> F { +pub fn bits_to_field(x: &[F]) -> F { F::try_from(bits_to_value(x)).unwrap() } diff --git a/ipa-core/src/test_fixture/sharing.rs b/ipa-core/src/test_fixture/sharing.rs index 32286a853..d120090d4 100644 --- a/ipa-core/src/test_fixture/sharing.rs +++ b/ipa-core/src/test_fixture/sharing.rs @@ -1,30 +1,32 @@ use std::{borrow::Borrow, iter::zip, ops::Deref}; use crate::{ - ff::{Field, PrimeField}, + ff::{Field, PrimeField, U128Conversions}, secret_sharing::{ replicated::{ malicious::{AdditiveShare as MaliciousReplicated, ExtendableField}, semi_honest::AdditiveShare as Replicated, ReplicatedSecretSharing, }, - BitDecomposed, FieldSimd, Vectorizable, + BitDecomposed, FieldSimd, SharedValue, Vectorizable, }, }; /// Deconstructs a field value into N values, one for each bit. -pub fn into_bits(v: F) -> BitDecomposed { +/// +/// The bit width is determined based on the field type. +pub fn into_bits(v: F) -> BitDecomposed { BitDecomposed::decompose(u128::BITS - F::PRIME.into().leading_zeros(), |i| { F::truncate_from((v.as_u128() >> i) & 1) }) } /// Deconstructs a value into N values, one for each bit. -/// # Panics -/// It won't +/// +/// The bit width is specified explicitly. #[must_use] -pub fn get_bits(x: u32, num_bits: u32) -> BitDecomposed { - BitDecomposed::decompose(num_bits, |i| F::truncate_from((x >> i) & 1)) +pub fn get_bits(x: u32, num_bits: u32) -> BitDecomposed { + BitDecomposed::decompose(num_bits, |i| V::truncate_from((x >> i) & 1)) } /// A trait that is helpful for reconstruction of values in tests. @@ -49,8 +51,8 @@ pub trait ReconstructArr { fn reconstruct_arr(&self) -> T; } -impl Reconstruct for [&Replicated; 3] { - fn reconstruct(&self) -> F { +impl Reconstruct for [&Replicated; 3] { + fn reconstruct(&self) -> V { let s0 = &self[0]; let s1 = &self[1]; let s2 = &self[2]; @@ -68,8 +70,8 @@ impl Reconstruct for [&Replicated; 3] { } } -impl Reconstruct for [Replicated; 3] { - fn reconstruct(&self) -> F { +impl Reconstruct for [Replicated; 3] { + fn reconstruct(&self) -> V { [&self[0], &self[1], &self[2]].reconstruct() } } @@ -153,7 +155,7 @@ where #[cfg(feature = "descriptive-gate")] impl Reconstruct for [crate::protocol::boolean::RandomBitsShare; 3] where - F: Field, + F: Field + U128Conversions, S: crate::secret_sharing::SecretSharing, for<'a> [&'a S; 3]: Reconstruct, {