diff --git a/ferveo/src/pvss.rs b/ferveo/src/pvss.rs index 903c4b62..7e954780 100644 --- a/ferveo/src/pvss.rs +++ b/ferveo/src/pvss.rs @@ -373,6 +373,58 @@ impl PubliclyVerifiableSS { ) } + pub fn refresh( + &self, + update_transcripts: &HashMap>, + validator_keys_map: &HashMap, + ) -> Result { + let num_shares = self.shares.len(); + let fft_domain = + ark_poly::GeneralEvaluationDomain::::new( + num_shares, + ) + .unwrap(); + + // First, verify that all update transcript are valid + // TODO: Consider what to do with failed verifications + // TODO: Find a better way to ensure they're always validated + for update_transcript in update_transcripts.values() { + update_transcript + .verify_refresh(validator_keys_map, &fft_domain) + .unwrap(); + } + + // Participants refresh their shares with the updates from each other: + // TODO: Here we're just iterating over all current shares, + // implicitly assuming all of them will be refreshed. + // Generalize to allow refreshing just a subset of the shares. + let updated_blinded_shares: Vec = self + .shares + .iter() + .enumerate() + .map(|(index, share)| { + let blinded_key_share = ferveo_tdec::BlindedKeyShare { + blinded_key_share: *share, + validator_public_key: validator_keys_map + .get(&(index as u32)) + .unwrap() + .into_affine(), + }; + let updated_share = UpdatableBlindedKeyShare(blinded_key_share) + .apply_share_updates(update_transcripts, index as u32); + updated_share.0.blinded_key_share + }) + .collect(); + + let refresed_aggregate_transcript = Self { + coeffs: self.coeffs.clone(), + shares: updated_blinded_shares, + sigma: self.sigma, + phantom: Default::default(), + }; + + Ok(refresed_aggregate_transcript) + } } #[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]