authorization, on a public ledger

How Alice updates a group on-chain.
And why three Bobs can't.

Open · Anonymous · Onchain. Every state change in an Onym group is gated by a ~700-byte PLONK proof. The chain checks the math; nobody — including us — gets to override it.

Measured against release tag v0.0.11 (2026-05-07) on Stellar testnet alpha.

5
policy contracts
30
verifying keys
~700 B
proof size
~$0.005
per update
MIT
licensed

the cast

One member. Three impostors.

Alice holds a valid witness to the current group commitment $C_g$. The three Bobs each try a different shortcut — none of them get past the verifier.

legitimate

Alice

Holds a valid Merkle witness to her leaf in the group whose commitment is C_g. Wants to add Carol.

outsider

Bob (outsider)

Has never been in the group. Wants to forge a membership witness from nothing.

policy violator

Bob (insider)

Real member of a sep-democracy group. Wants to admit someone without the quorum.

network observer

Bob (MITM)

Sees Alice's transaction on the wire. Wants to rewrite C_g' in flight.

the happy path

Alice updates the group.

A swim-lane through one legitimate update. Off-chain on the left — Alice's wallet computes the new root, builds the witness, and runs the prover. On-chain on the right — Stellar verifies the proof and swaps the commitment in storage. Click any primitive to dig in.

Off-chain · Alice's wallet
wire
On-chain · Stellar L1
step 01
Compute new root $C_g'$
Insert Carol's leaf, rehash the Merkle path up to the root.
step 02
Build R_Upd witness
Wire private inputs (sibling path, Alice's signing key) and public inputs ($C_g$, $C_g'$, epoch, policy tag) into the circuit.
step 03
PLONK prove → π
KZG commitments, BLS12-381 scalar math, Fiat-Shamir challenges hashed with Poseidon2. Out drops a ~700-byte proof.
tx
{ C_g, C_g', π }
~700 B
step 04
Verify proof π
Soroban contract calls the BLS12-381 host fn for the pairing check, Poseidon2 host fn for Fiat-Shamir replay. Pass / fail in one shot.
step 05
Swap $C_g \to C_g'$ in storage
Soroban writes the new commitment, increments the epoch counter, emits an event. Total: one ledger entry, ~$0.005.

Five steps; one ledger entry on success. No application-layer operator sees any of it — the trust shape is the Stellar validator set and the cryptographic assumptions in §5.

why it doesn't break

Three Bobs. Three ways to fail.

Same swim-lane. Pick an adversary and watch where the diagram red-flashes. Each Bob is stopped by a different layer of the construction.

Scroll up to watch the swim-lane react.

All three attacks reduce to a single observation: every public input — $C_g$, $C_g'$, epoch, policy tag — is bound into the proof. There is no surface for an outsider to fake a witness, an insider to skip the policy circuit, or a network observer to rewrite the destination commitment without making the pairing check reject.

the cryptographic stack

Seven pieces, stacked.

Click any node. The panel on the right swaps in concrete parameters, security assumptions, and the post-quantum stance.

role
params
security
caveats
pq stance
ref

SHA-256 sits outside the transaction path. It's how the SRS and verifying keys are pinned in the supply chain — distinct from the in-circuit hash that gates state changes.

references

Where these pieces come from.

Primary literature for every primitive Onym depends on. Links open in a new tab.

PLONK & proof systems

KZG polynomial commitments

BLS12-381

Poseidon & Poseidon2

SHA-256

Merkle tree

Fiat-Shamir transform

Quantum baseline

Stellar host functions

Honest about post-quantum: Onym is classically secure today and broken under Shor's algorithm on a CRQC. Migration paths (lattice-based polynomial commitments, hash-based SNARKs) are tracked but not deployed.