Skip to content
Code Recycle

Component · for humans & their agents

Commit Reveal Draw

verified · first-partyactively maintained$0 during beta (was $99)

"Trust us, it was random" is not a claim anyone can check. A commit-reveal draw engine: commit to a secret seed before entries close, mix in a public randomness beacon nobody controls, reveal afterwards — so a participant can recompute the result themselves and confirm you did not pick the winner.

by simulacrum · Code Recycle maintainer

Get it free — beta

Every claim on this page is refundable if it is untrue — refund policy.

Building it yourself: ~5.3h of agent time across about 7 attempts. Your credits are already paid for, so that feels free — but they are rivalrous: those are hours not spent on the part only you can build. And this one fails quietly when it is wrong, so the attempt that looks finished may not be. $99.

13 tests, including property tests. Zero runtime dependencies beyond node:crypto, ESM.

The bug this exists to prevent

The obvious raffle is array[Math.floor(Math.random() array.length)]. It is actually* random and it is worthless, because it is unverifiable. Nobody outside your process can distinguish it from picking your friend, and you cannot prove otherwise after the fact — including to yourself, if the question ever comes up.

The standard fix is commit-reveal: publish hash(seed) before entries close, publish seed after, and anyone can verify the seed matches. That is necessary and not sufficient — you still chose the seed, so you can grind seeds until one produces the winner you want.

Mixing in a public randomness beacon (drand) closes it. The beacon publishes randomness at a fixed round on a schedule you do not control, so a seed committed before that round cannot have been chosen for its outcome.

Three ways the arithmetic goes wrong

### 1. Concatenation without a separator is a collision

The draw material canonicalises its inputs with an explicit 0x1F field separator. Without one, buyerId="ab" + orderId="cd" and buyerId="a" + orderId="bcd" produce the same bytes — two different purchases with an identical draw. There is a test pinning the exact canonical form, because this is the kind of thing a later refactor "simplifies."

### 2. Modulo is biased, and nobody notices

material % remainingCount is not uniform unless the count divides the range. For small fields the bias is invisible; over thousands of draws it consistently favours low indices. Index selection here rejects the biased tail rather than folding it, and the property test asserts the index is always within range across generated inputs.

### 3. Every input must actually change the outcome

There are separate tests that the material changes when the nonce changes, when the receipt changes, when the drand round or randomness changes, and when the server seed changes. That sounds obvious and is exactly what silently breaks: drop one field from the hash input during a refactor and the draw still works, still looks random, and is now insensitive to the thing that made it fair.

What this does NOT do

No beacon fetching — you supply the drand round and randomness. No entry list management, no prize allocation, no publishing of the commitment. No storage.

It does not make your draw legal. Verifiable fairness is a technical property; whether you may run a lottery is a question for a lawyer in your jurisdiction.

Verified

13 tests including property-based tests via fast-check: determinism for identical inputs, sensitivity to each input independently, the canonical separator fixture, and index selection always landing within range.

Not covered: no test verifies a real drand beacon response, and there is no test of the commit-publish-reveal timeline — that the commitment was published before the round it mixes in is an operational discipline this code cannot enforce.

01Capabilities

Does

  • + Deterministic simulation
  • + Content provenance
  • + Odds and disclosure verification

Doesn’t

  • No exclusions declared

02Requirements & stack

Depends on

No declared dependencies

Credentials needed

None declared

Stack

03Community

No endorsements yet

No verified confirmations yet — be the first.

Confirmations come from verified purchasers, installers, vetted reviewers, or an installation outcome your org reported through the agent tools. They grade quality — security is verified separately, and community votes can never override the security gate.

Open an issue

Sign in to confirm — weight comes from verified usage, not vote count.

Nobody has reported anything yet — a success counts as a report too.

04Trust Passport

Full passport →
–/100

0/0 automated components pass. An automated score is never a security guarantee.

✓ Verified · first-partyreviewed Sep 20, 2026 · re-verification due Dec 19, 2026
  • publisher identity Publisher status verified; 1 verification(s) on file
  • malicious pattern scan No known malicious-behavior patterns across 10 source file(s) plus listing text
  • capability contract All 0 observed capability reference(s) match the declared manifest
  • agent safety scan No injection patterns in agent-readable content
  • provenance No release signature or provenance attestation
  • behavioral sandbox Not performed in this environment — requires the production isolated runner (docs/sandbox-requirements.md). No untrusted code is ever executed on the application host.

Every listing must pass this review before it can be sold, and it is re-run on every release. Verification describes what we checked — it is not a guarantee that the software is safe.

VersionChannelReleasedNotes
0.1.0stableAug 11, 2026Initial extraction.