Skip to content

Commit

Permalink
Move u128 conversions out of Field trait
Browse files Browse the repository at this point in the history
  • Loading branch information
andyleiserson committed Feb 14, 2024
1 parent 030cfc7 commit a1d91e8
Show file tree
Hide file tree
Showing 59 changed files with 237 additions and 201 deletions.
4 changes: 2 additions & 2 deletions ipa-core/benches/ct/arithmetic_circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -18,7 +18,7 @@ fn do_benchmark<M, F, const N: usize>(
depth: u16,
) where
M: Measurement,
F: Field + FieldSimd<N>,
F: Field + FieldSimd<N> + U128Conversions,
for<'a> Replicated<F, N>: SecureMul<SemiHonestContext<'a>>,
[F; N]: IntoShares<Replicated<F, N>>,
Standard: Distribution<F>,
Expand Down
2 changes: 1 addition & 1 deletion ipa-core/benches/oneshot/sort.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::time::Instant;
use futures::stream::iter as stream_iter;
use ipa_core::{
error::Error,
ff::{Field, Fp32BitPrime, GaloisField},
ff::{Fp32BitPrime, GaloisField, U128Conversions},
helpers::GatewayConfig,
protocol::{
context::{validator::SemiHonest as SemiHonestValidator, Validator},
Expand Down
8 changes: 5 additions & 3 deletions ipa-core/src/bin/test_mpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -99,8 +99,10 @@ async fn main() -> Result<(), Box<dyn Error>> {
Ok(())
}

async fn multiply_in_field<F: Field>(args: &Args, helper_clients: &[MpcHelperClient; 3])
where
async fn multiply_in_field<F: Field + U128Conversions>(
args: &Args,
helper_clients: &[MpcHelperClient; 3],
) where
F: Field + IntoShares<AdditiveShare<F>>,
<F as Serializable>::Size: Add<<F as Serializable>::Size>,
<<F as Serializable>::Size as Add<<F as Serializable>::Size>>::Output: ArrayLength,
Expand Down
15 changes: 10 additions & 5 deletions ipa-core/src/cli/playbook/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{
};

use crate::{
ff::{Field, GaloisField},
ff::{Field, GaloisField, U128Conversions},
ipa_test_input,
test_fixture::{input::GenericReportTestInput, ipa::TestRawDataRecord},
};
Expand All @@ -16,10 +16,10 @@ pub trait InputItem {
fn from_str(s: &str) -> Self;
}

impl<F: Field> InputItem for F {
impl<T: U128Conversions> InputItem for T {
fn from_str(s: &str) -> Self {
let int_v = s.parse::<u128>().unwrap();
F::truncate_from(int_v)
T::truncate_from(int_v)
}
}

Expand All @@ -29,7 +29,12 @@ impl InputItem for u64 {
}
}

impl<F: Field, MK: GaloisField, BK: GaloisField> InputItem for GenericReportTestInput<F, MK, BK> {
impl<F, MK, BK> InputItem for GenericReportTestInput<F, MK, BK>
where
F: Field + U128Conversions,
MK: GaloisField + U128Conversions,
BK: GaloisField + U128Conversions,
{
fn from_str(s: &str) -> Self {
if let [ts, match_key, is_trigger_bit, breakdown_key, trigger_value] =
s.splitn(5, ',').collect::<Vec<_>>()[..]
Expand Down Expand Up @@ -190,7 +195,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() {
Expand Down
7 changes: 4 additions & 3 deletions ipa-core/src/ff/boolean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -158,12 +158,13 @@ impl From<bool> 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)
}
Expand Down Expand Up @@ -192,7 +193,7 @@ impl TryFrom<u128> for Boolean {

impl FromRandomU128 for Boolean {
fn from_random_u128(src: u128) -> Self {
Field::truncate_from(src)
Self::truncate_from(src)
}
}

Expand Down
14 changes: 8 additions & 6 deletions ipa-core/src/ff/boolean_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
};
Expand Down Expand Up @@ -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<T: Into<u128>>(v: T) -> Self {
let v = v.into();
let mut val = <Self as SharedValue>::ZERO;
Expand All @@ -148,6 +146,10 @@ macro_rules! boolean_array_impl_small {

val
}

fn as_u128(&self) -> u128 {
(*self).into()
}
}

impl TryFrom<u128> for $name {
Expand Down Expand Up @@ -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)
}
}

Expand Down
8 changes: 5 additions & 3 deletions ipa-core/src/ff/ec_prime_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -187,12 +187,14 @@ impl FieldVectorizable<1> for Fp25519 {
type ArrayAlias = StdArray<Self, 1>;
}

///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 {
Expand All @@ -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::<Sha256>::new(None, &v.to_le_bytes());
Expand All @@ -228,6 +229,7 @@ impl TryFrom<u128> for Fp25519 {
Ok(f)
}
}
// TODO(812): end remove impls

#[cfg(all(test, unit_test))]
mod test {
Expand Down
9 changes: 0 additions & 9 deletions ipa-core/src/ff/field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T: Into<u128>>(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<u128>`
fn as_u128(&self) -> u128;
}

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Expand Down
8 changes: 5 additions & 3 deletions ipa-core/src/ff/galois_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
Expand Down Expand Up @@ -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()
}
Expand Down Expand Up @@ -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)
}
}

Expand Down Expand Up @@ -503,7 +505,7 @@ macro_rules! bit_array_impl {
type Strategy = prop::strategy::Map<RangeInclusive<u128>, 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 _)
}
}

Expand Down
12 changes: 11 additions & 1 deletion ipa-core/src/ff/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -45,6 +45,16 @@ impl<T, Rhs, Output> AddSub<Rhs, Output> for T where
pub trait AddSubAssign<Rhs = Self>: AddAssign<Rhs> + SubAssign<Rhs> {}
impl<T, Rhs> AddSubAssign<Rhs> for T where T: AddAssign<Rhs> + SubAssign<Rhs> {}

pub trait U128Conversions: FromRandomU128 + TryFrom<u128, Error = crate::error::Error> {
/// 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<T: Into<u128>>(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
Expand Down
11 changes: 6 additions & 5 deletions ipa-core/src/ff/prime_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<u128>;

const PRIME: Self::PrimeInteger;
Expand Down Expand Up @@ -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
Expand All @@ -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)
}
}

Expand Down
2 changes: 1 addition & 1 deletion ipa-core/src/helpers/buffers/ordering_sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,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,
Expand Down
4 changes: 2 additions & 2 deletions ipa-core/src/helpers/buffers/unordered_receiver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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,
};

Expand Down
8 changes: 4 additions & 4 deletions ipa-core/src/helpers/gateway/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
};
Expand All @@ -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<F: Field>(channel: &SendingEnd<F>, i: usize) {
async fn send<V: Message + U128Conversions>(channel: &SendingEnd<V>, 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();
}
Expand Down
2 changes: 1 addition & 1 deletion ipa-core/src/helpers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading

0 comments on commit a1d91e8

Please sign in to comment.