use crate::reshare::lagrange::FieldElement;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RefreshParams {
pub algorithm: String,
pub num_parties: u32,
pub threshold: u32,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RefreshContribution {
pub from_party: u32,
pub to_party: u32,
pub bytes: Vec<u8>,
}
pub fn apply_refresh(
old_share: &FieldElement,
contributions: &[RefreshContribution],
) -> FieldElement {
let mut new_bytes = old_share.0.clone();
for c in contributions {
for (i, b) in c.bytes.iter().enumerate() {
if i < new_bytes.len() {
new_bytes[i] ^= b;
}
}
}
FieldElement::new(new_bytes)
}
pub fn verify_refresh_preserves_aggregate(
party_zero_contributions: &[RefreshContribution],
) -> bool {
let mut sum = vec![0u8; 32];
for c in party_zero_contributions {
for (i, b) in c.bytes.iter().enumerate() {
if i < sum.len() {
sum[i] = sum[i].wrapping_add(*b);
}
}
}
sum.iter().all(|b| *b == 0)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn refresh_changes_share() {
let old = FieldElement::new(vec![0u8; 32]);
let contribs = vec![RefreshContribution {
from_party: 0,
to_party: 0,
bytes: vec![0xFF; 32],
}];
let new = apply_refresh(&old, &contribs);
assert_ne!(new.0, old.0);
}
#[test]
fn refresh_preserves_secret_when_balanced() {
let contribs = vec![
RefreshContribution {
from_party: 0,
to_party: 0,
bytes: vec![0x80; 32],
},
RefreshContribution {
from_party: 1,
to_party: 0,
bytes: vec![0x80; 32],
},
];
assert!(verify_refresh_preserves_aggregate(&contribs));
}
}