fin-proof: the synthetic witness reveals a key with its first block

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
igneum-labs 2026-10-07 08:18:22 +00:00
parent dafc5871ae
commit a708c7a400

View file

@ -193,9 +193,7 @@ pub fn synth(fixtures: &[Fixture], keys: usize, voters: usize, window_blocks: u6
let k2 = &synth_keys[(i as usize * 7 + 3) % synth_keys.len()];
let block = ChainBlockWitness { number: n, block_hash: synth_hash("prefix", n), daa, blues: vec![BlueBlock { block_hash: synth_hash("prefix", n), key_hash: k.hash, daa }, BlueBlock { block_hash: synth_hash("prefix-side", n), key_hash: k2.hash, daa }] };
let mut w = FoldWitness::default();
if i == 0 {
w.reveals = synth_keys.iter().map(|k| Reveal { pubkey: k.pk, pop: k.sk.sign(&k.pk, DST_POP, &[]).compress() }).collect();
}
reveals_for(&state, &synth_keys, &block, &mut w);
fold_block(&mut state, &params, &block, &mut ring, &w, &bls).map_err(|e| anyhow!("prefix fold {n}: {e}"))?;
ring.take_witnesses();
let (_, total) = voters_at(&state.keys, daa, params.dust);
@ -212,6 +210,7 @@ pub fn synth(fixtures: &[Fixture], keys: usize, voters: usize, window_blocks: u6
let k2 = &synth_keys[(i * 5 + 1) % synth_keys.len()];
let block = ChainBlockWitness { number: n, block_hash: f.block.env.hash.0, daa, blues: vec![BlueBlock { block_hash: f.block.env.hash.0, key_hash: k.hash, daa }, BlueBlock { block_hash: synth_hash("side", n), key_hash: k2.hash, daa }] };
let mut w = FoldWitness::default();
reveals_for(&state, &synth_keys, &block, &mut w);
if i + 1 == fixtures.len() && fixtures.len() > cert_back && cert_back > 0 {
let (cp_number, cp_keys, cp_leaf) = tables[tables.len() - cert_back].clone();
let (vlist, _) = voters_at(&cp_keys, cp_leaf.daa, params.dust);
@ -247,3 +246,15 @@ pub fn synth(fixtures: &[Fixture], keys: usize, voters: usize, window_blocks: u6
}
Ok(FinWitnessFile { format: FORMAT.into(), params, root_state, blocks })
}
/// W1 as the tracker applies it: a key's reveal rides with its first block in the table.
fn reveals_for(state: &FinState, keys: &[SynthKey], block: &ChainBlockWitness, w: &mut FoldWitness) {
for b in &block.blues {
let known = igneum_fin_core::find_key(&state.keys, &b.key_hash).map(|i| state.keys[i].revealed()).unwrap_or(false);
if !known && !w.reveals.iter().any(|r| vote_key_hash(&r.pubkey) == b.key_hash) {
if let Some(k) = keys.iter().find(|k| k.hash == b.key_hash) {
w.reveals.push(Reveal { pubkey: k.pk, pop: k.sk.sign(&k.pk, DST_POP, &[]).compress() });
}
}
}
}