Skip to main content

circuit_recover_public_key

Function circuit_recover_public_key 

Source
pub fn circuit_recover_public_key(
    builder: &CircuitBuilder,
    public_param: &[Wire; 2],
    epoch: Wire,
    chain_tips: &[[Wire; 2]; 42],
    digits: &[Wire; 42],
) -> [[Wire; 2]; 42]
Expand description

In-circuit form of recover_public_key, spending only the hashes a verifier walks.

A chain’s tail is CHAIN_LENGTH - 1 - digit hashes, and the target sum fixes the total across all chains at NUM_CHAIN_HASHES however the digits fall. So rather than give every chain room for its longest possible tail — V * (CHAIN_LENGTH - 1) hashes, two thirds of them discarded — the tails are concatenated into one list of exactly that total, hinted, and pinned by constraints. Each entry carries its input digest, its chain, its digit, and the number of hashes that chain has already done; its output is the hash, not a hinted value, so nothing has to check it.

§What pins the list

Walking the list, every rule is local, which is what leaves the entries with nothing to look up:

  • chain only ever increases, so a chain’s entries are one contiguous run.
  • Within a run the step advances by one, the digit holds, and each input is the previous output.
  • A run opens at step zero, and so does the list.

Then one lookup per chain finds that chain’s last entry, and checks it belongs to this chain, carries this chain’s digit, and sits at the last position — digit + step == CHAIN_LENGTH - 2, since the last hash of a chain starts one below the chain’s end. Its output is the chain’s end. The offset is hinted; it needs no pinning of its own, because what it lands on is checked.

A run’s length is therefore exactly CHAIN_LENGTH - 1 - digit, and the list is exactly NUM_CHAIN_HASHES long, which the target sum makes the sum of those lengths. No chain that owes hashes can be missing a run: if one were, the entries would not add up.

What a run starts from is left free. The tip is a hint, and verification only needs some preimage that walks a chain of the right length onto the committed public key — a prover with nothing to reveal would have to invert the hash to find one. A chain whose digit is CHAIN_LENGTH - 1 owes no hashes at all, and its end is simply the value the signature revealed.