Expand description
Proactive share refresh for P-256 threshold shares (Herzberg et al. 1995).
Each party generates a random polynomial g_i(x) of degree T-1 with g_i(0) = 0, distributes evaluations g_i(j) to party j, and each party adds the received refresh contributions to their existing share.
The key invariant: sum_i g_i(0) = 0, so the aggregate secret is unchanged and the public key doesn’t change. Previously compromised shares become useless after refresh because the attacker doesn’t know the refresh contributions.
§Usage
use confium_tc_cmp20::inprocess;
use confium_tc_cmp20::refresh;
// 1. Initial keygen.
let kg = inprocess::keygen(2, 3).unwrap();
// 2. Each party generates refresh contributions.
let contributions = refresh::generate_refresh_contributions(2, 3);
// 3. Each party applies the refresh to their share.
let refreshed_shares: Vec<Vec<u8>> = kg.shares.iter().enumerate()
.map(|(i, share)| refresh::apply_to_share(share, i as u32 + 1, &contributions))
.collect();
// 4. Sign with refreshed shares — same joint public key.
let sig = inprocess::sign(&refreshed_shares[..2], 2, b"refreshed").unwrap();Structs§
- Refresh
Contribution - One party’s refresh contribution:
(source_party_index, target_party_index, refresh_scalar_bytes).
Functions§
- apply_
to_ share - Apply refresh contributions to a CMP20 share blob. The share’s internal scalar x_i is replaced with x_i + sum(g_j(i)) for all contributions directed at party_index.
- generate_
refresh_ contributions - Generate refresh contributions for all (N-1) × N party pairs.
- verify_
zero_ sum - Verify that a set of refresh contributions preserves the aggregate secret: sum_i g_i(0) must be zero. If this check fails, the refresh round is malformed and the shares are compromised.