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}