diff --git a/src/bt.rs b/src/bt.rs index e8faca2f..6a884dd9 100644 --- a/src/bt.rs +++ b/src/bt.rs @@ -49,8 +49,7 @@ //! tree.insert(bits!(1, 1), 'f'); // TODO(#947): Remove these lines once the module gets used by Mastic implementation. -#[allow(dead_code)] - +#![allow(dead_code)] use core::fmt::Debug; use std::io::Cursor; diff --git a/src/flp/szk.rs b/src/flp/szk.rs index 9e89973f..2de22eba 100644 --- a/src/flp/szk.rs +++ b/src/flp/szk.rs @@ -253,13 +253,13 @@ impl ParameterizedDecode<(bool /// Szk query state. /// /// The state that needs to be stored by an Szk verifier between query() and decide(). -pub type SzkQueryState = Option>; +pub(crate) type SzkQueryState = Option>; /// Joint share type for the SZK proof. /// /// This is produced as the result of combining two query shares. /// It contains the re-computed joint randomness seed, if applicable. It is consumed by [`Szk::decide`]. -pub type SzkJointShare = Option>; +pub(crate) type SzkJointShare = Option>; impl Encode for SzkJointShare { fn encode(&self, bytes: &mut Vec) -> Result<(), CodecError> { @@ -492,7 +492,7 @@ where pub(crate) fn query( &self, input_share: &[T::Field], - proof_share: SzkProofShare, + proof_share: &SzkProofShare, verify_key: &[u8; SEED_SIZE], nonce: &[u8; 16], ) -> Result<(SzkQueryShare, SzkQueryState), SzkError> { @@ -515,11 +515,11 @@ where leader_blind_and_helper_joint_rand_part_opt, } => match leader_blind_and_helper_joint_rand_part_opt { Some((seed, helper_joint_rand_part)) => { - match self.derive_joint_rand_part(&seed, input_share, nonce) { + match self.derive_joint_rand_part(seed, input_share, nonce) { Ok(leader_joint_rand_part) => ( self.derive_joint_rand_and_seed( &leader_joint_rand_part, - &helper_joint_rand_part, + helper_joint_rand_part, ), leader_joint_rand_part, ), @@ -537,13 +537,13 @@ where leader_joint_rand_part_opt, } => match leader_joint_rand_part_opt { Some(leader_joint_rand_part) => match self.derive_joint_rand_part( - &proof_share_seed_and_blind, + proof_share_seed_and_blind, input_share, nonce, ) { Ok(helper_joint_rand_part) => ( self.derive_joint_rand_and_seed( - &leader_joint_rand_part, + leader_joint_rand_part, &helper_joint_rand_part, ), helper_joint_rand_part, @@ -581,7 +581,7 @@ where )) } - pub(crate) fn merge_verifiers( + pub(crate) fn merge_query_shares( &self, mut leader_share: SzkQueryShare, helper_share: SzkQueryShare, @@ -610,9 +610,10 @@ where Err(SzkError::Decide("failed to verify FLP proof".to_string())) } } - /// Returns true if the leader and helper derive identical joint randomness - /// seeds - pub fn decide( + + /// Returns true if the joint randomness seed used during the query phase + /// was correctly computed from both aggregators' parts. + pub(crate) fn decide( &self, query_state: SzkQueryState, joint_share: SzkJointShare, @@ -711,19 +712,14 @@ mod tests { let [l_proof_share, h_proof_share] = proof_shares.unwrap(); let (l_query_share, l_query_state) = szk_typ - .query( - &leader_input_share, - l_proof_share.clone(), - &verify_key, - &nonce, - ) + .query(&leader_input_share, &l_proof_share, &verify_key, &nonce) .unwrap(); let (h_query_share, h_query_state) = szk_typ - .query(&helper_input_share, h_proof_share, &verify_key, &nonce) + .query(&helper_input_share, &h_proof_share, &verify_key, &nonce) .unwrap(); let joint_share_result = - szk_typ.merge_verifiers(l_query_share.clone(), h_query_share.clone()); + szk_typ.merge_query_shares(l_query_share.clone(), h_query_share.clone()); let joint_share = match joint_share_result { Ok(joint_share) => { let leader_decision = szk_typ @@ -764,7 +760,8 @@ mod tests { ); } - let joint_share_res = szk_typ.merge_verifiers(mutated_query_share, h_query_share.clone()); + let joint_share_res = + szk_typ.merge_query_shares(mutated_query_share, h_query_share.clone()); let leader_decision = match joint_share_res { Ok(joint_share) => szk_typ.decide(l_query_state.clone(), joint_share).is_ok(), Err(_) => false, @@ -776,10 +773,11 @@ mod tests { mutated_input[0] *= T::Field::from(::Integer::try_from(23).unwrap()); let (mutated_query_share, mutated_query_state) = szk_typ - .query(&mutated_input, l_proof_share.clone(), &verify_key, &nonce) + .query(&mutated_input, &l_proof_share, &verify_key, &nonce) .unwrap(); - let joint_share_res = szk_typ.merge_verifiers(mutated_query_share, h_query_share.clone()); + let joint_share_res = + szk_typ.merge_query_shares(mutated_query_share, h_query_share.clone()); let leader_decision = match joint_share_res { Ok(joint_share) => szk_typ.decide(mutated_query_state, joint_share).is_ok(), @@ -793,7 +791,7 @@ mod tests { uncompressed_proof_share, leader_blind_and_helper_joint_rand_part_opt, } => ( - uncompressed_proof_share.clone(), + uncompressed_proof_share, leader_blind_and_helper_joint_rand_part_opt, ), _ => (vec![], None), @@ -807,12 +805,12 @@ mod tests { let (l_query_share, l_query_state) = szk_typ .query( &leader_input_share, - mutated_proof_share, + &mutated_proof_share, &verify_key, &nonce, ) .unwrap(); - let joint_share_res = szk_typ.merge_verifiers(l_query_share, h_query_share.clone()); + let joint_share_res = szk_typ.merge_query_shares(l_query_share, h_query_share.clone()); let leader_decision = match joint_share_res { Ok(joint_share) => szk_typ.decide(l_query_state.clone(), joint_share).is_ok(), diff --git a/src/vdaf/mastic.rs b/src/vdaf/mastic.rs index 3419560f..32931b68 100644 --- a/src/vdaf/mastic.rs +++ b/src/vdaf/mastic.rs @@ -5,7 +5,7 @@ //! [draft-mouris-cfrg-mastic-01]: https://www.ietf.org/archive/id/draft-mouris-cfrg-mastic-01.html use crate::{ - bt::{BinaryTree, Path}, + bt::BinaryTree, codec::{CodecError, Decode, Encode, ParameterizedDecode}, field::{decode_fieldvec, FieldElement}, flp::{ @@ -282,7 +282,6 @@ where 2 } } - impl Mastic where T: Type, @@ -531,14 +530,6 @@ where self.vidpf.weight_parameter * agg_param.level_and_prefixes.prefixes().len(), ); let mut cache_tree = BinaryTree::>>::default(); - let cache = VidpfEvalCache::>::init_from_key( - id, - &input_share.vidpf_key, - &self.vidpf.weight_parameter, - ); - cache_tree - .insert(Path::empty(), cache) - .expect("Should alwys be able to insert into empty tree at root"); for prefix in agg_param.level_and_prefixes.prefixes() { let mut value_share = self.vidpf.eval_with_cache( id, @@ -552,52 +543,46 @@ where output_shares.append(&mut value_share.share.0); } - let szk_verify_opt = if agg_param.require_weight_check { - let root_share = self.vidpf.eval_root_with_cache( + Ok(if agg_param.require_weight_check { + let MasticInputShare { + vidpf_key, + proof_share, + } = input_share; + let root_share = self.vidpf.get_root_weight_share( id, - &input_share.vidpf_key, + vidpf_key, public_share, &mut cache_tree, nonce, )?; - Some(self.szk.query( - root_share.as_ref(), - input_share.proof_share.clone(), - verify_key, - nonce, - )?) + let (szk_query_share, szk_query_state) = + self.szk + .query(root_share.as_ref(), proof_share, verify_key, nonce)?; + let verifier_len = szk_query_share.flp_verifier.len(); + ( + MasticPrepareState { + output_shares: MasticOutputShare::::from(output_shares), + szk_query_state, + verifier_len: Some(verifier_len), + }, + MasticPrepareShare { + vidpf_proof: eval_proof.into_seed(), + szk_query_share_opt: Some(szk_query_share), + }, + ) } else { - None - }; - - let (prep_share, prep_state) = - if let Some((szk_query_share, szk_query_state)) = szk_verify_opt { - let verifier_len = szk_query_share.flp_verifier.len(); - ( - MasticPrepareShare { - vidpf_proof: eval_proof.into_seed(), - szk_query_share_opt: Some(szk_query_share), - }, - MasticPrepareState { - output_shares: MasticOutputShare::::from(output_shares), - szk_query_state, - verifier_len: Some(verifier_len), - }, - ) - } else { - ( - MasticPrepareShare { - vidpf_proof: eval_proof.into_seed(), - szk_query_share_opt: None, - }, - MasticPrepareState { - output_shares: MasticOutputShare::::from(output_shares), - szk_query_state: None, - verifier_len: None, - }, - ) - }; - Ok((prep_state, prep_share)) + ( + MasticPrepareState { + output_shares: MasticOutputShare::::from(output_shares), + szk_query_state: None, + verifier_len: None, + }, + MasticPrepareShare { + vidpf_proof: eval_proof.into_seed(), + szk_query_share_opt: None, + }, + ) + }) } fn prepare_shares_to_prepare_message< @@ -631,7 +616,7 @@ where ) { (Some(leader_query_share), Some(helper_query_share)) => Ok(self .szk - .merge_verifiers(leader_query_share, helper_query_share)?), + .merge_query_shares(leader_query_share, helper_query_share)?), (None, None) => Ok(None), (_, _) => Err(VdafError::Uncategorized( "Only one of leader and helper query shares is present".to_string(), diff --git a/src/vidpf.rs b/src/vidpf.rs index 7c22cd2e..1e31d82b 100644 --- a/src/vidpf.rs +++ b/src/vidpf.rs @@ -326,7 +326,7 @@ impl Vidpf { Ok((next_state, y)) } - pub(crate) fn eval_root_with_cache( + pub(crate) fn get_root_weight_share( &self, id: VidpfServerId, key: &VidpfKey, @@ -470,7 +470,7 @@ impl VidpfDomainSepTag { /// Vidpf key. /// /// Private key of an aggregation server. -pub type VidpfKey = Seed<16>; +pub type VidpfKey = Seed; /// Vidpf server ID. /// @@ -634,17 +634,6 @@ pub struct VidpfEvalCache { } impl VidpfEvalCache { - pub(crate) fn init_from_key( - id: VidpfServerId, - key: &VidpfKey, - length: &W::ValueParameter, - ) -> Self { - Self { - state: VidpfEvalState::init_from_key(id, key), - share: W::zero(length), - } - } - fn to_share(&self) -> VidpfValueShare { VidpfValueShare:: { share: self.share.clone(), @@ -663,6 +652,7 @@ pub struct VidpfValueShare { /// Proof size in bytes. const VIDPF_PROOF_SIZE: usize = 32; +const VIDPF_SEED_SIZE: usize = 16; /// Allows to validate user input and shares after evaluation. type VidpfProof = [u8; VIDPF_PROOF_SIZE]; @@ -678,7 +668,7 @@ fn conditional_xor_proof(mut lhs: VidpfProof, rhs: &VidpfProof, choice: Choice) } /// Feeds a pseudorandom generator during evaluation. -type VidpfSeed = [u8; 16]; +type VidpfSeed = [u8; VIDPF_SEED_SIZE]; /// Contains the seeds and control bits produced by [`Vidpf::prg`]. struct VidpfPrgOutput {