Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

v0 source pure

Package commitreveal implements the commit-then-reveal scheme as a pure, reusable package.

Readme View source

gno.land/p/moul/x/daily/commitreveal/v0

Commit–reveal schemeCommit, 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:

  • Length-prefixed hashing. With plain concatenation ("ab","cd…") and ("abc","d…") produce identical bytes, so one commitment could be opened two different ways. The lengths are hashed in.
  • Constant-time digest comparison. A short-circuiting check leaks, through timing, how many leading bytes of a guess were right — 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.

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.

Overview

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).

Constants 3

const DigestLen

1const DigestLen = 32
source

DigestLen is the length in bytes of a commitment digest (SHA-256).

const MaxValueLen

1const MaxValueLen = 4096
source

MaxValueLen bounds the committed value so gas stays predictable.

const MinSaltLen

1const MinSaltLen = 16
source

MinSaltLen is the shortest salt accepted. Short salts make a small-domain commitment brute-forceable, which defeats the whole scheme.

Variables 1

var ErrShortSalt, ErrLongValue, ErrMismatch, ErrBadHexDigest

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)
source

Functions 5

func Commit

1func Commit(value, salt string) (string, error)
source

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.

func MustCommit

1func MustCommit(value, salt string) string
source

MustCommit is Commit, panicking on invalid input. For tests and for callers that have already validated.

func Open

1func Open(commitment, value, salt string) error
source

Open verifies and reports why it failed, for callers wanting a reason rather than a bool.

func ValidCommitment

1func ValidCommitment(s string) bool
source

ValidCommitment reports whether s is well-formed as a commitment: hex, and exactly DigestLen bytes. It says nothing about what it commits to.

func Verify

1func Verify(commitment, value, salt string) bool
source

Verify reports whether value and salt open the given commitment. The digest comparison is constant-time.

Imports 3

  • crypto/sha256 stdlib
  • encoding/hex stdlib
  • errors stdlib

Source Files 3