Skip to content

Commit 3742300

Browse files
committed
Reworked docs about the bisection protocol; added note about the missing slashing of the bond
1 parent ed3ee45 commit 3742300

File tree

2 files changed

+59
-50
lines changed

2 files changed

+59
-50
lines changed

examples/game256/game256_contracts.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,17 @@
88
from matt.contracts import ClauseOutput, StandardClause, StandardAugmentedP2TR, StandardP2TR, ContractState
99
from matt.hub.fraud import Bisect_1, Computer, Leaf
1010
from matt.merkle import MerkleTree
11-
from matt.script_helpers import check_input_contract, check_output_contract, drop, dup, merkle_root, older
11+
from matt.script_helpers import check_input_contract, check_output_contract, dup, merkle_root, older
1212
from matt.utils import encode_wit_element
1313

14+
# Note: for simplicity, this contract does not yet implement bonds, nor slashing part of it after the fraud proof protocol.
1415

1516
# TODO: add forfait clauses whenever needed
1617

1718
# TODO: how to generalize what the contract does after the leaf? We should be able to compose clauses with some external code.
1819
# Do we need "clause" algebra?
1920

21+
2022
class G256_S0(StandardP2TR):
2123
def __init__(self, alice_pk: bytes, bob_pk: bytes, forfait_timeout: int = 10):
2224
self.alice_pk = alice_pk

matt/hub/fraud.py

+56-49
Original file line numberDiff line numberDiff line change
@@ -3,77 +3,77 @@
33

44
"""
55
Definitions:
6-
Let a computation for a computation trace y = f(x) be
6+
Let the sequence of intermediate values for a computation y = f(x) with n steps be
77
88
x = x_0 ==> x_1 ==> x_2 ==> ... ==> x_n = y
99
10-
each x_i is itself a hash of something, specific to the computation.
10+
The meaning of each x_i is specific to the computation.
1111
12-
TODO: clean up these docs, they are incoherent
12+
We assume that n is a power of 2 for convenience (no-operation steps can be added accordingly).
1313
14-
where n is a power of 2 for convenience. For now, assume each step is performing exactly
15-
the same computation, for example: double the previous element.
14+
We define the hashed state h_i = H(x_i) for each i in 0, ..., n. where H is the sha256 hash of x.
1615
17-
We know define h_i = H(x_i) for each i in 0, ..., n.
16+
(more generally, if the state x itself is composed of multiple values, h_i should be a commitment to
17+
the entire state, for example via a Merkle tree).
1818
19-
We define the trace leaves to be:
20-
H(h_0||h_1), H(h_1||h_2), ...
21-
that is, a commitment to the state before the computation, and the state after.
19+
For any (i, j) such that 0 <= i <= j < n and such that j - i + 1 is a power of 2, we define the trace t_{i, j} as follows:
2220
23-
Formally, let h_i = H(h_i || h_{i+1}) for i = 0, ..., n - 1.
24-
25-
From there, we can define the aggregate trace commitment for any pair i, j with i < j where j - i + 1 is a power of two:
26-
27-
Similarly, for any pair i, j such that j - i + 1 == 2^t >= 2
28-
h_{i, j} = H(x_i||x_{j+1}||h_{i, i+m-1}||h_{i+m, j}) where m = (j - i + 1)/2
29-
30-
We call h_{i, j; a} the value of h_{i, j} according to Alice, and h_{i, j; b} the value according to Bob.
31-
32-
That is, each aggregate trace commitment commits to:
33-
- the computation state before the leftmost leaf in the subtree is executed
34-
- the computation state after the rightmost leaf in the subtree is executed
35-
- the aggregate computation trace root for the left half
36-
- the aggregate computation trace root for the right half
21+
// sha256(h_i || h_{i+1}) if i == j
22+
t_{i, j} = {
23+
\\ sha256(h_i || h_{i+1} || t_{i, i + m - 1} || t_{i + m, j}) otherwise
3724
25+
where m = (j - i + 1) / 2, and || represents the concatenation.
26+
27+
That is: if i == j, then the trace represents a single computational step, and it commits to just the state before,
28+
and the state after the execution of the computational step. If i < j, then the trace represents commits to:
29+
- the state before the i-th computational step
30+
- the state after the j-th computational step
31+
- the sub-trace of the first half of the computation (from i to i + m - 1)
32+
- the sub-trace of the second half of the computation (from i + m to j)
3833
39-
Each internal node of the corresponds to a pair i, j with i < j, and such that j - i + 1 is a power of 2.
40-
The "partial trace" of its node represents a computation with intermediate values
41-
x_i, x_{i + 1}, ..., x_j
34+
Clearly, t_{0, n - 1} is the trace of the entire computationm, and it defines a corresponding Merkle tree.
4235
43-
We define the hashed state:
44-
h_i = sha256(x_i) for any 0 <= i <= n
36+
The bisection protocol is an interactive protocol between two parties Alice and Bob, who disagree on the final result
37+
y of the computation (but they agree on the initial state x = x_0).
38+
Therefore:
39+
- Alice claims the hashed states to be [h_{0; a}, h_{1; a}, ... h_{n; a}]
40+
- Bob claims the hashed states to be [h_{0; b}, h_{1; b}, ... h_{n; b}]
41+
where h_{0; a} = h_{0; b} = h_0, since they agree on the initial state x.
4542
46-
Since Alice and Bob disagree on the hashed states, we call h_{i; a} and h_{i; b} Alice's and Bob's claimed states, respectively.
47-
48-
For each 0 <= i <= j < n such that m = (j - i + 1)/2 is integer, we define the computation trace t_{i, j} as follows:
4943
50-
// sha256(h_i || h_{i+1}) if i == j
51-
t_{i, j} = {
52-
\\ sha256(h_i || h_{i+1} || t_{i, i + m - 1} || t_{i + m, j}) otherwise
44+
The protocol starts at the "root" of the trace, that is, an internal node that represents t_{0, n-1}.
45+
The protocol guarantees the following invariant:
5346
54-
Since Alice and Bob disagree on the trace, we call t_{i, j; a} and t_{i, j; a} the traces claimed by Alice and Bob, respectively.
47+
Bisection invariant:
48+
For any node (i, j) reached in the protocol, h_{i; a} = h_{i; a}, while h_{j; a} != h_{j; b}.
5549
56-
The entry state for an internal node of the bisection protocol contains the following info:
50+
That is, Alice and Bob agree on the state at the beginning of the computation represented by the sub-trace, but disagree
51+
on the final state of the computation.
52+
Let's call t_{i, j; a} (resp. t_{i, j; b}) the value of the sub-trace t_{i; j} according to Alice (resp. Bob).
5753
58-
- The state h_i at the beginning of the computation (invariant: both parties agree)
59-
- The state x_{j; a} at the end of the computation, according to Alice
60-
- The state x_{j; b} at the end of the computation, according to Bob
61-
- The root t_{i, j; a} of the computation trace in the subtree, according to Alice
62-
- The root t_{i, j; b} of the computation trace in the subtree, according to Bob
54+
Each bisection step of the protocol requires two transitions:
55+
- Alice reveals the value that define the commitment t_{i, j; a}, including the mid-state h_{i + m; a}
56+
- Bob then does the same; if h_{i + m; a} != h_{i + m; b}, then the protocol repeats on the left child
57+
(first half of the computation, from i to i + m - 1). Otherwise, h_{i + m; a} = h_{i + m; b}, and the
58+
protocol repeats on the right child (second half of the computation, from i + m to j).
6359
64-
All the bisection contracts have a forfait condition in case the other party doesn't participate; omitted for simplicity.
60+
Once a leaf (l, l) is reached, a single computational step is part of the commitment:
61+
- Both parties agree that the initial hashed state is h_l
62+
- Alice claims the final hashed state is h_{l + 1; a}
63+
- Bob claims the final hashed state is h_{l + 1; b}
6564
65+
Clearly, only the honest party can exibit the value of x_l, and the contract can adjudicate this part as the winner.
6666
67-
IF i < j, it's an internal node.
68-
In the following, n := j - i + 1, and m = n/2. Therefore:
69-
The left child of t_{i, j} is t_{i, i + m - 1}
70-
The right child of t_{i, j} is t_{i + m, j}
67+
Summing up, the following specs define the two contracts Bisect_1 (Alice's turn) and Bisect_2 (Bob's turn), and the
68+
final Leaf contract.
7169
70+
(Alice's turn)
7271
Bisect_1(alice_pk, bob_pk, i, j)[h_i, h_{j+1; a}, h_{j+1; b}, t_{i, j; a}, t_{i, j; b}]
7372
- Alice: reveals h_{i+m; a}, t_{i, i+m-1; a}, t_{i+m, j; a}
7473
(the scripts checks the equation for t_{i, j; a}
7574
==> Bisect_2(*)[*, h_{i+m; a}, t_{i, i+m-1; a}, t_{i+m, j; a}]
7675
76+
(Bob's turn)
7777
Bisect_2(alice_pk, bob_pk, i, j)[h_i, h_{j+1; a}, h_{j+1; b}, t_{i, j; a}, t_{i, j; b}, h_{i+m; a}, t_{i, i+m-1; a}, t_{i+m, j; a}]
7878
- Bob: reveals h_{i+m; b}, t_{i, i+m-1; b}, t_{i+m, j; b} such that h_{i+m; a} != h_{i+m; b} # disagree on the left child
7979
(the scripts checks the equation for t_{i, j; b}
@@ -82,12 +82,19 @@
8282
(the scripts checks the equation for t_{i, j; b}
8383
==> Bisect_1(alice_pk, bob_pk, i+m, j)[x_{i+m}, x_{j+1; a}, x_{j+1; b}, h_{i+m, j; a}, h_{i+m, j; b}]
8484
85-
IF i == j, it's a leaf.
85+
Both the contract also have a 'forfait' condition that allows the other party to win the challenge,
86+
in case the party who holds the turn refuses to comply.
87+
88+
IF i == j, it's a Leaf, representing the i_th computational step
8689
8790
Leaf(alice_pk, bob_pk)[h_start, h_{end; a}, h_{end; b}]
88-
- Alice: reveal x_start, take the money if h_{end; a} is the hash of f(x_start)
89-
- Bob: reveal x_start, take the money if h_{end; b} is the hash of f(x_start)
91+
- Alice: reveal x_start such that h_start = H(x_start); take the money if h_{end; a} is the hash of the execution of the i-th step on x_start
92+
- Bob: reveal reveal x_start such that h_start = H(x_start); take the money if h_{end; b} is the hash of the execution of the i-th step on x_start
9093
94+
95+
96+
Omitted from this description and implementation: committing a bond, and slashing part of it in case of a loss (awarding only part of it to the winner).
97+
9198
"""
9299

93100

0 commit comments

Comments
 (0)