const DigestLen
DigestLen is the length in bytes of a commitment digest (SHA-256).
Package commitreveal implements the commit-then-reveal scheme as a pure, reusable package.
gno.land/p/moul/x/daily/commitreveal/v0Commit–reveal scheme — Commit, MustCommit, Verify, Open,
ValidCommitment, MinSaltLen, MaxValueLen, DigestLen.
1import "gno.land/p/moul/x/daily/commitreveal/v0"
2
3c, _ := commitreveal.Commit("rock", "alice-secret-salt-1") // phase 1: publish c
4commitreveal.Open(c, "rock", "alice-secret-salt-1") // phase 2: nil
5commitreveal.Open(c, "paper", "alice-secret-salt-1") // ErrMismatch
A transaction is public before it executes, so a naive sealed-bid auction or
simultaneous-move game lets whoever moves last read everyone else's move and win
for free. Commit–reveal splits the action: publish H(value ‖ salt) first, open
it later.
The salt is enforced, not advised. Rock-paper-scissors has three possible
moves, so an unsalted commitment has three possible hashes and is broken by
trying all of them. Commit refuses a salt shorter than MinSaltLen (16), and
Verify enforces the same floor — a short salt cannot be smuggled past it.
Two details that are easy to get wrong, both tested:
("ab","cd…") and
("abc","d…") produce identical bytes, so one commitment could be opened two
different ways. The lengths are hashed in.This package computes and checks commitments. It stores nothing and knows nothing about phases or deadlines; the realm owns that.
Live demo: r/moul/x/daily/commitrevealdemo
· render it at /r/moul/x/daily/commitrevealdemo/v0.
Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.
🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.
Package commitreveal implements the commit-then-reveal scheme as a pure, reusable package.
The problem it solves: anything submitted to a chain is public before it is executed, so a naive sealed-bid auction or simultaneous-move game lets the last player read everyone else's move and win for free. Commit-reveal splits the action in two — first publish H(value || salt), later publish the value and salt. The commitment binds you to a choice without disclosing it.
The SALT is not optional and this package refuses to let a caller skip it. Without one, a commitment over a small domain is trivially brute-forced: a rock-paper-scissors move has three possible hashes, so hashing all three breaks the scheme entirely. MinSaltLen is enforced at commit time rather than left as advice in a comment.
Verification is CONSTANT-TIME over the digest. A short-circuiting comparison leaks, through timing, how many leading bytes of a guess were right, which is enough to reconstruct a commitment byte by byte.
This package computes and checks commitments; it stores nothing and knows nothing about phases or deadlines. The realm owns that.
A live demo of this package is at r/moul/x/daily/commitrevealdemo(/r/moul/x/daily/commitrevealdemo/v0).
DigestLen is the length in bytes of a commitment digest (SHA-256).
MaxValueLen bounds the committed value so gas stays predictable.
MinSaltLen is the shortest salt accepted. Short salts make a small-domain commitment brute-forceable, which defeats the whole scheme.
1var (
2 ErrShortSalt = errors.New("commitreveal: salt is shorter than MinSaltLen")
3 ErrLongValue = errors.New("commitreveal: value exceeds MaxValueLen")
4 ErrMismatch = errors.New("commitreveal: reveal does not match the commitment")
5 ErrBadHexDigest = errors.New("commitreveal: commitment is not a valid hex digest")
6)Commit returns the hex-encoded commitment for value and salt.
The salt is length-prefixed rather than simply concatenated: with plain concatenation, ("ab","cd") and ("a","bcd") hash identically, so one commitment could be opened two different ways.
MustCommit is Commit, panicking on invalid input. For tests and for callers that have already validated.
Open verifies and reports why it failed, for callers wanting a reason rather than a bool.
ValidCommitment reports whether s is well-formed as a commitment: hex, and exactly DigestLen bytes. It says nothing about what it commits to.
Verify reports whether value and salt open the given commitment. The digest comparison is constant-time.