diff --git a/src/faand.rs b/src/faand.rs index 3bcd496..cb47c7e 100644 --- a/src/faand.rs +++ b/src/faand.rs @@ -72,11 +72,17 @@ fn commit(value: &[u8]) -> Commitment { /// Verifies if a given value matches a previously generated commitment. fn open_commitment(commitment: &Commitment, value: &[u8]) -> bool { + if value.is_empty() { + return false; + } blake3::hash(value).as_bytes() == &commitment.0 } /// Hashes a Vec using blake3 and returns the resulting hash as `[u128; 2]`. pub fn hash_vec(data: &Vec) -> Result<[u128; 2], Error> { + if data.is_empty() { + return Err(Error::EmptyVector); + } let serialized_data = bincode::serialize(data).map_err(|_| Error::ConversionError)?; let mut hasher = blake3::Hasher::new(); @@ -105,11 +111,17 @@ pub(crate) async fn broadcast_and_verify< if n == 2 { return Ok(()); } + if vec.is_empty() { + return Err(Error::EmptyVector); + } // Step 1: Send the vector to all parties that does not included its already sent value // (for index i) and the value it received from the party it is sending to (index k). for k in (0..n).filter(|k| *k != i) { let mut modified_vec: Vec> = vec![None; n]; for j in (0..n).filter(|j| *j != i && *j != k) { + if vec[j].is_empty() { + return Err(Error::EmptyVector); + } modified_vec[j] = Some(hash_vec(&vec[j])?); } send_to(channel, k, phase, &modified_vec).await?; @@ -245,6 +257,10 @@ async fn fabitn( let deltas = vec![u128_to_block(delta.0); lprime]; // Step 2: Use the shared RNGs for key and MAC generation + if !(shared_two_by_two.len() == n && shared_two_by_two.iter().all(|row| row.len() == n)) { + return Err(Error::InvalidLength); + } + for k in (0..n).filter(|&k| k != i) { let (a, b) = if i < k { (i, k) } else { (k, i) }; @@ -505,6 +521,9 @@ async fn fhaand( yi: Vec, ) -> Result, Error> { // Step 1) Obtain x shares (input). + if xshares.len() != l { + return Err(Error::InvalidLength); + } // Step 2) Calculate v. let mut vi = vec![false; l]; @@ -569,6 +588,9 @@ async fn flaand( ) -> Result, Error> { // Triple computation. // Step 1) Triple computation [random authenticated shares as input parameters xshares, yshares, rshares]. + if xshares.len() != l || yshares.len() != l || rshares.len() != l { + return Err(Error::InvalidLength); + } // Step 2) Run Pi_HaAND to get back some v. let y = yshares.iter().take(l).map(|share| share.0).collect(); @@ -712,6 +734,9 @@ async fn faand( ) -> Result, Error> { let b = bucket_size(l); let lprime = l * b; + if xyr_shares.len() != 3 * lprime { + return Err(Error::InvalidLength); + } let (xshares, rest) = xyr_shares.split_at(lprime); let (yshares, rshares) = rest.split_at(lprime); @@ -735,6 +760,10 @@ async fn faand( // Step 3) For each bucket, combine b leaky ANDs into a single non-leaky AND. let d_values = check_dvalue((channel, delta), i, n, &buckets).await?; + if d_values.len() != buckets.len() { + //=l + return Err(Error::InvalidLength); + } let mut aand_triples = Vec::with_capacity(buckets.len()); for (bucket, d) in buckets.into_iter().zip(d_values.into_iter()) { @@ -754,6 +783,11 @@ pub(crate) async fn beaver_aand( shared_rand: &mut ChaCha20Rng, abc_shares: Vec, ) -> Result, Error> { + if alpha_beta_shares.len() != l { + //abc_shares length is checked in function faand + return Err(Error::InvalidLength); + } + let abc_triples = faand((channel, delta), i, n, l, shared_rand, abc_shares).await?; let len = abc_triples.len(); @@ -831,6 +865,9 @@ async fn check_dvalue( // Step (a) compute and check macs of d-values. let len = buckets.len(); let mut d_values: Vec> = vec![vec![]; len]; + if len == 0 { + return Err(Error::EmptyVector); + } for (j, bucket) in buckets.iter().enumerate() { let (_, y, _) = &bucket[0]; diff --git a/src/protocol.rs b/src/protocol.rs index 5886f69..dd2873f 100644 --- a/src/protocol.rs +++ b/src/protocol.rs @@ -402,11 +402,11 @@ pub async fn mpc( } } - let auth_bits: Vec; + let mut auth_bits: Vec = vec![]; if let Preprocessor::TrustedDealer(p_fpre) = p_fpre { send_to(channel, p_fpre, "AND shares", &and_shares).await?; auth_bits = recv_vec_from(channel, p_fpre, "AND shares", num_and_gates).await?; - } else { + } else if !xyz_shares.is_empty() { auth_bits = beaver_aand( (channel, delta), and_shares.clone(),