Skip to content

Commit

Permalink
Coverage improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
andyleiserson committed Jan 26, 2024
1 parent d8cd1d1 commit b28335a
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 29 deletions.
13 changes: 13 additions & 0 deletions ipa-core/src/ff/boolean_array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,7 @@ macro_rules! boolean_array_impl {
use crate::secret_sharing::replicated::ReplicatedSecretSharing;
let bits = AdditiveShare::new(ONE, ONE);
let iter = bits.into_iter();
assert_eq!(iter.len(), $bits);
for (i, j) in iter.enumerate() {
if i == 0 {
assert_eq!(j, AdditiveShare::new(Boolean::ONE, Boolean::ONE));
Expand All @@ -471,6 +472,18 @@ macro_rules! boolean_array_impl {
}
}

#[test]
fn iterate_secret_shared_boolean_array_len() {
use crate::secret_sharing::replicated::ReplicatedSecretSharing;
let bits = AdditiveShare::new(ONE, ONE);
let mut iter = bits.into_iter();
assert_eq!(iter.len(), $bits);
for b in (0..$bits).rev() {
iter.next().unwrap();
assert_eq!(iter.len(), b);
}
}

#[test]
fn serde() {
let ba = thread_rng().gen::<$name>();
Expand Down
26 changes: 0 additions & 26 deletions ipa-core/src/ff/galois_field.rs
Original file line number Diff line number Diff line change
Expand Up @@ -703,31 +703,5 @@ bit_array_impl!(
v
}
}

impl From<Gf2> for bool {
fn from(value: Gf2) -> Self {
value != Gf2::ZERO
}
}

impl From<crate::ff::boolean::Boolean> for Gf2 {
fn from(value: crate::ff::boolean::Boolean) -> Self {
bool::from(value).into()
}
}

impl From<Gf2> for crate::ff::boolean::Boolean {
fn from(value: Gf2) -> Self {
bool::from(value).into()
}
}

impl std::ops::Not for Gf2 {
type Output = Self;

fn not(self) -> Self {
(!bool::from(self)).into()
}
}
}
);
107 changes: 107 additions & 0 deletions ipa-core/src/secret_sharing/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,3 +313,110 @@ where
}

impl<V: SharedValue, const N: usize> Message for StdArray<V, N> where Self: Serializable {}

#[cfg(all(test, unit_test))]
mod test {
use proptest::{
prelude::{prop, Arbitrary, Strategy},
proptest,
};

use super::*;

impl<V: SharedValue, const N: usize> Arbitrary for StdArray<V, N>
where
[V; N]: Arbitrary,
{
type Parameters = <[V; N] as Arbitrary>::Parameters;
type Strategy = prop::strategy::Map<<[V; N] as Arbitrary>::Strategy, fn([V; N]) -> Self>;

fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
<[V; N]>::arbitrary_with(args).prop_map(Self)
}
}

proptest! {
#[test]
fn add(a: StdArray<Fp32BitPrime, 2>, b: StdArray<Fp32BitPrime, 2>) {
let expected = StdArray([a.0[0] + b.0[0], a.0[1] + b.0[1]]);
let sum1 = &a + &b;
let sum2 = &a + b.clone();
let sum3 = a.clone() + &b;
let sum4 = a + b;
assert_eq!(sum1, expected);
assert_eq!(sum2, expected);
assert_eq!(sum3, expected);
assert_eq!(sum4, expected);
}

#[test]
fn add_assign(a: StdArray<Fp32BitPrime, 2>, b: StdArray<Fp32BitPrime, 2>) {
let expected = StdArray([a.0[0] + b.0[0], a.0[1] + b.0[1]]);
let mut sum1 = a.clone();
let mut sum2 = a.clone();
sum1 += &b;
sum2 += b;
assert_eq!(sum1, expected);
assert_eq!(sum2, expected);
}

#[test]
fn sub(a: StdArray<Fp32BitPrime, 2>, b: StdArray<Fp32BitPrime, 2>) {
let expected = StdArray([a.0[0] - b.0[0], a.0[1] - b.0[1]]);
let diff1 = &a - &b;
let diff2 = &a - b.clone();
let diff3 = a.clone() - &b;
let diff4 = a - b;
assert_eq!(diff1, expected);
assert_eq!(diff2, expected);
assert_eq!(diff3, expected);
assert_eq!(diff4, expected);
}

#[test]
fn sub_assign(a: StdArray<Fp32BitPrime, 2>, b: StdArray<Fp32BitPrime, 2>) {
let expected = StdArray([a.0[0] - b.0[0], a.0[1] - b.0[1]]);
let mut diff1 = a.clone();
let mut diff2 = a.clone();
diff1 -= &b;
diff2 -= b;
assert_eq!(diff1, expected);
assert_eq!(diff2, expected);
}

#[test]
fn mul_scalar(a: StdArray<Fp32BitPrime, 2>, b: Fp32BitPrime) {
let expected = StdArray([a.0[0] * b, a.0[1] * b]);
let b_ref = &b; // clippy complains inline ref to Copy type is needless
let prod1 = &a * b_ref;
let prod2 = &a * b;
let prod3 = a.clone() * b_ref;
let prod4 = a * b;
assert_eq!(prod1, expected);
assert_eq!(prod2, expected);
assert_eq!(prod3, expected);
assert_eq!(prod4, expected);
}

#[test]
fn into_iter(a: StdArray<Fp32BitPrime, 2>) {
let expected = a.clone();
let copy: StdArray<Fp32BitPrime, 2> = a.into_iter()
.collect::<Vec<_>>()
.try_into()
.unwrap();
assert_eq!(copy, expected);
}

#[test]
fn get_set(mut a: StdArray<Fp32BitPrime, 1>, b: Fp32BitPrime, c: Fp32BitPrime) {
assert_eq!(a.get(0), a.0[0]);
a.set(0, b);
assert_eq!(a.get(0), b);
*a.get_mut(0) = c;
assert_eq!(a.get(0), c);
let from_fn = StdArray::<Fp32BitPrime, 1>::from_fn(|i| a.0[i]);
assert_eq!(from_fn, a);
}
}
}
104 changes: 101 additions & 3 deletions ipa-core/src/secret_sharing/replicated/semi_honest/additive_share.rs
Original file line number Diff line number Diff line change
Expand Up @@ -419,10 +419,17 @@ where

#[cfg(all(test, unit_test))]
mod tests {
use super::AdditiveShare;
use proptest::{
prelude::{prop, Arbitrary, Strategy},
proptest,
};

use super::*;
use crate::{
ff::{Field, Fp31},
secret_sharing::replicated::ReplicatedSecretSharing,
ff::{Field, Fp31, Fp32BitPrime},
secret_sharing::{
replicated::ReplicatedSecretSharing, SharedValue, StdArray, Vectorizable,
},
};

fn secret_share(
Expand Down Expand Up @@ -565,4 +572,95 @@ mod tests {
mult_by_constant_test_case((0, 0, 1), 2, 2);
mult_by_constant_test_case((0, 0, 0), 2, 0);
}

impl<V: SharedValue, const N: usize> Arbitrary for AdditiveShare<V, N>
where
V: Vectorizable<N, Array = StdArray<V, N>>,
StdArray<V, N>: Arbitrary,
{
type Parameters = <(StdArray<V, N>, StdArray<V, N>) as Arbitrary>::Parameters;
type Strategy = prop::strategy::Map<
<(StdArray<V, N>, StdArray<V, N>) as Arbitrary>::Strategy,
fn((StdArray<V, N>, StdArray<V, N>)) -> Self,
>;

fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
<(StdArray<V, N>, StdArray<V, N>)>::arbitrary_with(args)
.prop_map(|(l, r)| AdditiveShare::new_arr(l, r))
}
}

proptest! {
#[test]
fn vector_add_assign_proptest(a: AdditiveShare<Fp32BitPrime, 32>, b: AdditiveShare<Fp32BitPrime, 32>) {
let left_sum = a.left_arr() + b.left_arr();
let right_sum = a.right_arr() + b.right_arr();
let expected = AdditiveShare::new_arr(left_sum, right_sum);
let mut sum1 = a.clone();
let mut sum2 = a;
sum1 += &b;
sum2 += b;
assert_eq!(sum1, expected);
assert_eq!(sum2, expected);
}

#[test]
fn sub_proptest(a: AdditiveShare<Fp32BitPrime>, b: AdditiveShare<Fp32BitPrime>) {
let left_diff = a.left() - b.left();
let right_diff = a.right() - b.right();
let expected = AdditiveShare::new(left_diff, right_diff);
let diff1 = &a - &b;
let diff2 = &a - b.clone();
let diff3 = a.clone() - &b;
let diff4 = a - b;
assert_eq!(diff1, expected);
assert_eq!(diff2, expected);
assert_eq!(diff3, expected);
assert_eq!(diff4, expected);
}

#[test]
fn vector_sub_proptest(a: AdditiveShare<Fp32BitPrime, 32>, b: AdditiveShare<Fp32BitPrime, 32>) {
let left_diff = a.left_arr() - b.left_arr();
let right_diff = a.right_arr() - b.right_arr();
let expected = AdditiveShare::new_arr(left_diff, right_diff);
let diff1 = &a - &b;
let diff2 = &a - b.clone();
let diff3 = a.clone() - &b;
let diff4 = a - b;
assert_eq!(diff1, expected);
assert_eq!(diff2, expected);
assert_eq!(diff3, expected);
assert_eq!(diff4, expected);
}

#[test]
fn vector_sub_assign_proptest(a: AdditiveShare<Fp32BitPrime, 32>, b: AdditiveShare<Fp32BitPrime, 32>) {
let left_diff = a.left_arr() - b.left_arr();
let right_diff = a.right_arr() - b.right_arr();
let expected = AdditiveShare::new_arr(left_diff, right_diff);
let mut diff1 = a.clone();
let mut diff2 = a;
diff1 -= &b;
diff2 -= b;
assert_eq!(diff1, expected);
assert_eq!(diff2, expected);
}

#[test]
fn vector_mul_scalar_proptest(a: AdditiveShare<Fp32BitPrime, 32>, b: Fp32BitPrime) {
let left_prod = a.left_arr() * b;
let right_prod = a.right_arr() * b;
let expected = AdditiveShare::new_arr(left_prod, right_prod);
let b_ref = &b; // clippy complains inline ref to Copy type is needless
let prod1 = &a * b_ref;
let prod2 = &a * b;
let prod3 = a.clone() * b_ref;
let prod4 = a * b;
assert_eq!(prod1, expected);
assert_eq!(prod2, expected);
assert_eq!(prod3, expected);
assert_eq!(prod4, expected);
}
}
}

0 comments on commit b28335a

Please sign in to comment.