diff --git a/ipa-core/src/ff/boolean.rs b/ipa-core/src/ff/boolean.rs index ec6d9f6ad..1afcdbdf2 100644 --- a/ipa-core/src/ff/boolean.rs +++ b/ipa-core/src/ff/boolean.rs @@ -16,6 +16,16 @@ impl Block for bool { #[derive(Clone, Copy, PartialEq, Debug, Eq)] pub struct Boolean(bool); +impl Boolean { + pub const TRUE: Boolean = Self(true); + pub const FALSE: Boolean = Self(false); + + #[must_use] + pub fn as_u128(&self) -> u128 { + bool::from(*self).into() + } +} + impl ExtendableField for Boolean { type ExtendedField = Gf32Bit; @@ -134,7 +144,7 @@ impl Field for Boolean { const ONE: Boolean = Boolean(true); fn as_u128(&self) -> u128 { - bool::from(*self).into() + Boolean::as_u128(self) } fn truncate_from>(v: T) -> Self { diff --git a/ipa-core/src/protocol/boolean/generate_random_bits.rs b/ipa-core/src/protocol/boolean/generate_random_bits.rs index d97cd4cb9..952002c3e 100644 --- a/ipa-core/src/protocol/boolean/generate_random_bits.rs +++ b/ipa-core/src/protocol/boolean/generate_random_bits.rs @@ -4,7 +4,7 @@ use futures::stream::{iter as stream_iter, StreamExt}; use crate::{ error::Error, - ff::{ArrayAccessReplicated, PrimeField}, + ff::{boolean::Boolean, ArrayAccessReplicated, PrimeField}, helpers::Role, protocol::{ basics::SecureMul, @@ -47,21 +47,21 @@ impl ArrayAccessReplicated for RawRandomBits { } impl<'a> BorrowReplicated for RawRandomBitsIndex<'a> { - type Output = bool; + type Output = Boolean; - fn borrow_left(&self) -> &bool { + fn borrow_left(&self) -> &Self::Output { if ((self.bits.left >> self.index) & 1) == 1 { - &true + &Boolean::TRUE } else { - &false + &Boolean::FALSE } } - fn borrow_right(&self) -> &bool { + fn borrow_right(&self) -> &Self::Output { if ((self.bits.right >> self.index) & 1) == 1 { - &true + &Boolean::TRUE } else { - &false + &Boolean::FALSE } } } diff --git a/ipa-core/src/protocol/modulus_conversion/convert_shares.rs b/ipa-core/src/protocol/modulus_conversion/convert_shares.rs index 93bd94242..78e68f045 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::{ArrayAccessReplicated, Field, Gf2, PrimeField}, + ff::{boolean::Boolean, ArrayAccessReplicated, Field, Gf2, PrimeField}, helpers::Role, protocol::{ basics::{SecureMul, ZeroPositions}, @@ -73,14 +73,14 @@ impl BitConversionTriple> { /// /// # Panics /// If any bits in the bitwise shared input cannot be converted into the given field `F` - /// without truncation or if the bit index is out of range for `B`. + /// without truncation. #[must_use] - pub fn new, T: BorrowReplicated>( - helper_role: Role, - src: &T, - ) -> Self { - let left = F::try_from(u128::from((*src.borrow_left()).into())).unwrap(); - let right = F::try_from(u128::from((*src.borrow_right()).into())).unwrap(); + pub fn new(helper_role: Role, src: &B) -> Self + where + B: BorrowReplicated, + { + let left = F::try_from(src.borrow_left().as_u128()).unwrap(); + let right = F::try_from(src.borrow_right().as_u128()).unwrap(); Self(match helper_role { Role::H1 => [ Replicated::new(left, F::ZERO), @@ -143,12 +143,11 @@ pub trait ToBitConversionTriples: Sized { } } -impl ToBitConversionTriples for Replicated +impl ToBitConversionTriples for Replicated where Self: ArrayAccessReplicated, - for<'a> ::Ref<'a>: BorrowReplicated, + for<'a> ::Ref<'a>: BorrowReplicated, B: SharedValue, - G: Copy + Into, { type Residual = (); 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 e6d258578..d0cd19fe2 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 @@ -7,7 +7,7 @@ use generic_array::{ArrayLength, GenericArray}; use typenum::Unsigned; use crate::{ - ff::{ArrayAccess, ArrayAccessReplicated, Expand, Field, Gf2, Serializable}, + ff::{boolean::Boolean, ArrayAccess, ArrayAccessReplicated, Expand, Field, Serializable}, secret_sharing::{ replicated::ReplicatedSecretSharing, Linear as LinearSecretSharing, SecretSharing, SharedValue, @@ -71,25 +71,27 @@ pub trait BorrowReplicatedMut: BorrowReplicated { fn borrow_right_mut(&mut self) -> &mut Self::Output; } +// This exists as a special case so we can provide an impl of `BorrowReplicated` that +// returns `bool` rather than `Gf2`. #[derive(Clone, Copy)] -pub struct AdditiveShareGf2(Gf2, Gf2); +pub struct BooleanAdditiveShare(Boolean, Boolean); -impl BorrowReplicated for AdditiveShareGf2 { - type Output = bool; +impl BorrowReplicated for BooleanAdditiveShare { + type Output = Boolean; - fn borrow_left(&self) -> &bool { + fn borrow_left(&self) -> &Self::Output { if self.0.into() { - &true + &Boolean::TRUE } else { - &false + &Boolean::FALSE } } - fn borrow_right(&self) -> &bool { + fn borrow_right(&self) -> &Self::Output { if self.1.into() { - &true + &Boolean::TRUE } else { - &false + &Boolean::FALSE } } } @@ -97,21 +99,21 @@ impl BorrowReplicated for AdditiveShareGf2 { impl BorrowReplicated for AdditiveShare { type Output = V; - fn borrow_left(&self) -> &V { + fn borrow_left(&self) -> &Self::Output { &self.0 } - fn borrow_right(&self) -> &V { + fn borrow_right(&self) -> &Self::Output { &self.1 } } impl BorrowReplicatedMut for AdditiveShare { - fn borrow_left_mut(&mut self) -> &mut V { + fn borrow_left_mut(&mut self) -> &mut Self::Output { &mut self.0 } - fn borrow_right_mut(&mut self) -> &mut V { + fn borrow_right_mut(&mut self) -> &mut Self::Output { &mut self.1 } } @@ -339,18 +341,18 @@ where // This would ideally be an `AdditiveShareRef` type that holds two references, // but due to Galois fields not being indexable for `Gf2` values currently, // it is not done that way. - type Ref<'a> = AdditiveShareGf2; + type Ref<'a> = BooleanAdditiveShare; fn get(&self, index: usize) -> Option> { self.0 .get(index) .zip(self.1.get(index)) - .map(|v| AdditiveShareGf2(bool::from(v.0).into(), bool::from(v.1).into())) + .map(|v| BooleanAdditiveShare(bool::from(v.0).into(), bool::from(v.1).into())) } fn set(&mut self, index: usize, e: Self::Ref<'_>) { - self.0.set(index, >::from(e.0).into()); - self.1.set(index, >::from(e.1).into()); + self.0.set(index, >::from(e.0).into()); + self.1.set(index, >::from(e.1).into()); } }