Poseidon2 Transcript Visualizer — a step-by-step visualizer of a Poseidon2 Fiat–Shamir transcript over the BN254 scalar field

Poseidon2 Transcript Visualizer

A production Fiat–Shamir transcript, stepped one stage at a time. Not one challenge at a time — one constant added, one S-box evaluated, one matrix applied: the width-3 Poseidon2 permutation over BN254 running inside a persistent duplex challenger, with every field element on screen at every point. It answers the question you actually have when two implementations disagree on a challenge: which of the sixty-four rounds, or which of the six duplex rules, did we do differently?

Launch the visualizer → Opens in a new tab · no install, no network · needs 1024 × 560 or wider

Scope. The transcript and nothing else: no proving system, no arithmetization, no commitment scheme — only what goes into the sponge, what comes out, and in what order, because that is the part independent implementations most often disagree about. Everything on screen is computed in BigInt arithmetic modulo the BN254 scalar modulus, from the reference round constants.

The suite

The width-3 BN254 Poseidon2 instance driving a rate-2 / capacity-1 duplex challenger — the Plonky3 transcript framing on the Horizen Labs permutation:

ParameterValue
FieldBN254 scalar field Fr — not the curve base field, the most common way to get this suite wrong
State widtht = 3, as rate 2 + capacity 1
S-boxx → x5 — three field multiplications each
RoundsRF = 8 full and RP = 56 partial, split four–fifty-six–four
Constantsthe exact RC3 table from the reference instance, never regenerated at runtime
External and internal rounds, side by side

Poseidon2's whole economy is the partial round, so the two round types get two separate machines, both permanently on screen; the one matching the current round fills with values while the other stays dark.

  • In an external round — four at the start, four at the end — all three lanes take a round constant and an S-box, and the layer is ME. Nine multiplications.
  • In an internal round — the fifty-six in the middle — only lane 0 takes a constant and an S-box, and the layer is MI. Three multiplications.

The two matrices differ in exactly one entry: the bottom-right is 2 in ME and 3 in MI. One permutation costs 80 S-box evaluations and 240 field multiplications, where sixty-four full rounds would need 192 S-boxes.

The four rules that are easy to get wrong

Four lines of the duplex change every challenge downstream if written differently, and the loaded transcript walks into each one:

RuleWhat breaks without it
Absorption overwritesA sponge that adds into the rate lanes instead produces entirely different challenges from the same inputs.
Unused rate lanes are zeroedLeaving lane 1 holding the previous output would silently bind the challenge to unrelated history.
The length is bound into the capacitystate[2] += n keeps absorbing one element distinct from absorbing two whose second is zero.
Challenges come off the endpop() takes the last output, so the first challenge is s1 and the second is s0. Reversing it makes every challenge wrong.

These are Plonky3's rules, not a variant of them, and the visualizer reproduces its DuplexChallenger challenges exactly. Length binding landed in Plonky3 #1769 in June 2026; an implementation pinned to anything earlier will produce different challenges from the same inputs.

Two more behaviours get their own moment: observing new material invalidates any challenge still in the output buffer, and a sample() with nothing buffered and nothing left to squeeze runs a permutation with no absorb at all.

The loaded transcript

Eight calls, four permutations, three challenges, on one continuous state — the shortest script that walks into every rule above:

  • Five elements go in, one at a time, so the sponge permutes twice and the fifth is still buffered.
  • A challenge is asked for on a partial buffer, exercising the zero-padded lane and the length tag together.
  • A second challenge comes free off the same permutation, from the other rate lane.
  • A third is asked for with nothing left, so the duplex permutes with no absorb at all.
What is on screen

The duplex sponge, drawn with the capacity off the input–output path; both round machines; a phase rail on which skipped phases are struck through; a sentence of narration per stage; all three lanes at their full 254 bits; and a spec drawer with both matrices, all 64 rounds of RC3, and the mandatory known-answer test on [0, 1, 2], run in the page. Stepping backwards restores every value exactly.

Launch the visualizer → Keys: → step · ← back · Enter run · K skip the permutation