Skip to content

Cryptographic Protocol

Commit / Reveal

For Round t, user i with private secret s_i ∈ {0,1}^128 chooses answer b_i ∈ {0,1} and publishes:

ci=HMAC-SHA256(siroundt,bi)

Where denotes concatenation and round_t is a public unique Round identifier.

During the Reveal phase, user i broadcasts (s_i, b_i). The Round Engine and any third-party verifier compute HMAC-SHA256(s_i ‖ round_t, b_i) and check it matches the previously published c_i. Mismatched reveals are rejected; non-revealers are eliminated from the Round but their commits remain in the Merkle Root for audit.

Why HMAC and not a plain hash

A plain commit H(s_i ‖ b_i) is vulnerable to two attacks:

  1. Rainbow precomputation. If s_i is short (mobile UX constrains us to ≤16-byte device-bound randomness), a precomputed table of H(s ‖ 0) and H(s ‖ 1) across the secret space can crack commits before reveal.
  2. Cross-Round replay. Without Round binding, a commit valid in Round t could be replayed as evidence in Round t' ≠ t.

HMAC with a properly-sized key (here, 128 bits) and Round binding (concatenating round_t into the keyed message) eliminates both. The HMAC construction's pseudorandomness under standard assumptions ensures that without s_i, an adversary's advantage in distinguishing b_i = 0 from b_i = 1 is negligible.

Where does s_i come from

Each user device generates s_i at Round entry via the browser's crypto.getRandomValues(new Uint8Array(16)). It is stored in the WebApp's session storage for the Round duration only. After Reveal, it is discarded. No user-typed secret is involved.

For users who clear their session mid-Round, the Round is forfeited (they cannot reveal a commit they no longer hold the key for). Reputation Score takes a small negative update.

Round Merkle Root

At Settle phase, the Engine computes:

roott=Merkle({(i,ci,bi,outcomei):iParticipantst})

The root is queued for batch settlement to TON every 24 hours. A single transaction on TON can commit ~5,760 Round roots (one per 60 seconds × 86,400 / 60 / 15 amortization).

Any participant can fetch a Merkle proof from the Engine and verify their inclusion against the on-chain root, without trusting the Engine.

Dispute window

A 24-hour dispute window allows on-chain challenges: a user submits a Merkle proof showing the on-chain root does not match the off-chain Engine claim. If the challenge succeeds, the round is voided and re-settled; the operator pays a 1,000 $POP penalty into the Treasury. Unchallenged roots become finalized.

Reputation Score

r_i ∈ [0, 1] is a Bayesian estimate of user honesty, updated each Round:

ri(t+1)=ri(t)λ(oi(t))ri(t)λ(oi(t))+(1ri(t))(1λ(oi(t)))

Where λ(o_i^{(t)}) is a likelihood function over observations (participation, reveal-on-time, deviation from minority probability, anomaly markers). Initial r_i = 0.5 (uninformed prior).

Reputation decays with inactivity at rate δ = 0.01 / day. Reputation cannot exceed 0.99 (epistemic humility) or fall below 0.01 (allows recovery).

The Reputation Score multiplies the Trust Ladder multiplier in settlement:

effective weighti=ri×αT(i)

Formal security argument

Under the assumption that HMAC-SHA256 is a pseudorandom function (PRF) and that s_i is uniformly random and unknown to the adversary, no efficient adversary can:

  1. Distinguish commit c_i = HMAC(s_i ‖ round_t, b_i) for b_i = 0 vs b_i = 1 with non-negligible advantage. (Hiding.)
  2. Find (s'_i, b'_i)(s_i, b_i) such that HMAC(s'_i ‖ round_t, b'_i) = c_i. (Binding, under HMAC's collision resistance.)
  3. Predict the next round seed without colluding with both DRAND and TON-VRF validator sets. (See Oracle & Randomness.)

These are the three properties required for a fair Commit / Reveal coordination game. The protocol does not require any additional cryptographic assumption.

Audit & open-source

The Round Engine and verification logic are open-sourced under MIT. The repository is at github.com/cashpop-protocol/round-engine. A full audit by Trail of Bits is targeted for Phase 2 (Q4 2026).

Built on TON.