diff --git a/ferveo/src/refresh.rs b/ferveo/src/refresh.rs index 6dcc7a10..252fe1d1 100644 --- a/ferveo/src/refresh.rs +++ b/ferveo/src/refresh.rs @@ -46,48 +46,33 @@ impl UpdatableBlindedKeyShare { /// From PSS paper, section 4.2.3, (https://link.springer.com/content/pdf/10.1007/3-540-44750-4_27.pdf) pub fn apply_share_updates( &self, - share_updates: &[ShareUpdate], + update_transcripts: &HashMap>, + index: u32, ) -> UpdatableBlindedKeyShare { - // TODO: Validate commitments from share update // FIXME: Don't forget!!!!! + // Current participant receives update transcripts from other participants + let share_updates: Vec<_> = update_transcripts + .values() + .map(|update_transcript_from_producer| { + let update_for_participant = update_transcript_from_producer + .updates + .get(&index) + .cloned() + .unwrap(); + update_for_participant + }) + .collect(); + + // TODO: Validate commitments from share update + // FIXME: Don't forget!!!!! let updated_key_share = share_updates .iter() - .fold(self.0.blinded_key_share, |acc, delta| (acc + delta.update).into()); - UpdatableBlindedKeyShare(BlindedKeyShare{ + .fold(self.0.blinded_key_share, |acc, delta| { + (acc + delta.update).into() + }); + UpdatableBlindedKeyShare(BlindedKeyShare { validator_public_key: self.0.validator_public_key, - blinded_key_share: updated_key_share + blinded_key_share: updated_key_share, }) - - // let updates_for_participant: Vec<_> = - // update_transcripts_by_producer - // .values() - // .map(|update_transcript_from_producer| { - // // First, verify that the update transcript is valid - // // TODO: Find a better way to ensure they're always validated - // update_transcript_from_producer - // .verify_refresh(validator_keys_map, &fft_domain) - // .unwrap(); - - // let update_for_participant = - // update_transcript_from_producer - // .updates - // .get(&(p.index as u32)) - // .cloned() - // .unwrap(); - // update_for_participant - // }) - // .collect(); - - // // And creates a new, refreshed share - - // // TODO: Encapsulate this somewhere, originally from PrivateKeyShare.create_updated_key_share - // let updated_blinded_key_share: BlindedKeyShare = - // BlindedKeyShare { - // validator_public_key: participant_public_key, - // blinded_key_share: updates_for_participant.iter().fold( - // blinded_key_share.blinded_key_share, - // |acc, delta| (acc + delta.update).into(), - // ), - // }; } pub fn unblind_private_key_share( @@ -712,44 +697,38 @@ mod tests_refresh { }) .collect::>>(); + // Participants validate first all the update transcripts. + // TODO: Find a better way to ensure they're always validated + for update_transcript in update_transcripts_by_producer.values() { + update_transcript + .verify_refresh(validator_keys_map, &fft_domain) + .unwrap(); + } + // Participants refresh their shares with the updates from each other: let refreshed_shares = contexts .iter() .map(|p| { + let participant_index = p.index as u32; let blinded_key_share = p.public_decryption_contexts[p.index].blinded_key_share; - // Current participant receives update transcripts from other participants - let updates_for_participant: Vec<_> = - update_transcripts_by_producer - .values() - .map(|update_transcript_from_producer| { - // First, verify that the update transcript is valid - // TODO: Find a better way to ensure they're always validated - update_transcript_from_producer - .verify_refresh(validator_keys_map, &fft_domain) - .unwrap(); - - let update_for_participant = - update_transcript_from_producer - .updates - .get(&(p.index as u32)) - .cloned() - .unwrap(); - update_for_participant - }) - .collect(); - // And creates a new, refreshed share - let updated_blinded_key_share = UpdatableBlindedKeyShare(blinded_key_share) - .apply_share_updates(&updates_for_participant); - - let validator_keypair = ferveo_common::Keypair{ - decryption_key: p.setup_params.b + let updated_blinded_key_share = + UpdatableBlindedKeyShare(blinded_key_share) + .apply_share_updates( + &update_transcripts_by_producer, + participant_index, + ); + + let validator_keypair = ferveo_common::Keypair { + decryption_key: p.setup_params.b, }; - let updated_private_share = updated_blinded_key_share.unblind_private_key_share(&validator_keypair).unwrap(); + let updated_private_share = updated_blinded_key_share + .unblind_private_key_share(&validator_keypair) + .unwrap(); - (p.index as u32, updated_private_share) + (participant_index, updated_private_share) }) // We only need `threshold` refreshed shares to recover the original share .take(security_threshold) @@ -763,11 +742,8 @@ mod tests_refresh { .collect::>>(); let x_r = ScalarField::zero(); - let new_shared_private_key = combine_private_shares_at( - &x_r, - &domain_points, - &refreshed_shares - ); + let new_shared_private_key = + combine_private_shares_at(&x_r, &domain_points, &refreshed_shares); assert_eq!(shared_private_key, new_shared_private_key); } }