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

render_example_test.gno

2.30 Kb · 54 lines
 1package commitrevealdemo
 2
 3// ExampleRender pins the realm's Render output as a testable example.
 4func ExampleRender() {
 5	print(Render(""))
 6	// Output:
 7	// # Commit–Reveal
 8	//
 9	// Bind to a choice without disclosing it, demoing the [`p/moul/x/daily/commitreveal`](/p/moul/x/daily/commitreveal/v0) library.
10	//
11	// ## The problem
12	//
13	// A transaction is public before it executes. In a sealed-bid auction or a simultaneous-move game, whoever moves last reads everyone else's move and wins for free.
14	//
15	// ## Phase 1 — commit
16	//
17	// Each player publishes only `H(value ‖ salt)`. Nothing about the move leaks, but neither can change it later.
18	//
19	// | player | commitment |
20	// |---|---|
21	// | alice | `11811a2d4eede29f…` |
22	// | bob | `db066e8c917e07d5…` |
23	//
24	// ## Phase 2 — reveal
25	//
26	// Now the values and salts are published and checked against the commitments recorded earlier:
27	//
28	// | check | result |
29	// |---|---|
30	// | alice opens with `rock` | ✅ accepted |
31	// | bob opens with `paper` | ✅ accepted |
32	// | bob tries `scissors` instead | ❌ `commitreveal: reveal does not match the commitment` |
33	// | bob claims alice's commitment | ❌ `commitreveal: reveal does not match the commitment` |
34	//
35	// Bob cannot switch his move after seeing Alice's, and cannot pass off her commitment as his own.
36	//
37	// ## Why the salt is mandatory
38	//
39	// Rock-paper-scissors has three possible moves. Without a salt there are exactly three possible hashes, and hashing all three breaks the scheme outright. The library refuses a salt shorter than `16` bytes rather than leaving that as advice:
40	//
41	// - `Commit("rock", "tooshort")` → `commitreveal: salt is shorter than MinSaltLen`
42	//
43	// The salt also keeps two players who pick the *same* move from publishing the same commitment:
44	//
45	// | same move, different salt | commitment |
46	// |---|---|
47	// | player 1 | `a5d84fa94157acca…` |
48	// | player 2 | `ccbc5d0b7ab1e84d…` |
49	//
50	// ## Two details that are easy to get wrong
51	//
52	// - **Length-prefixed hashing.** With plain concatenation `("ab","cd…")` and `("abc","d…")` hash identically, so one commitment could be opened two different ways.
53	// - **Constant-time comparison.** A short-circuiting check leaks, through timing, how many leading bytes of a guess were right — enough to rebuild a commitment byte by byte.
54}