-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Expand file tree
/
Copy pathp2_delegated_puzzle_or_hidden_puzzle.clvm
More file actions
91 lines (76 loc) · 3.16 KB
/
Copy pathp2_delegated_puzzle_or_hidden_puzzle.clvm
File metadata and controls
91 lines (76 loc) · 3.16 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
; build a pay-to delegated puzzle or hidden puzzle
; coins can be unlocked by signing a delegated puzzle and its solution
; OR by revealing the hidden puzzle and the underlying original key
; glossary of parameter names:
; hidden_puzzle: a "hidden puzzle" that can be revealed and used as an alternate
; way to unlock the underlying funds
;
; synthetic_key_offset: a private key cryptographically generated using the hidden
; puzzle and as inputs `original_public_key`
;
; SYNTHETIC_PUBLIC_KEY: the public key that is the sum of `original_public_key` and the
; public key corresponding to `synthetic_key_offset`
;
; original_public_key: a public key, where knowledge of the corresponding private key
; represents ownership of the file
;
; delegated_puzzle: a delegated puzzle, as in "graftroot", which should return the
; desired conditions.
;
; solution: the solution to the delegated puzzle
(mod
; A puzzle should commit to `SYNTHETIC_PUBLIC_KEY`
;
; The solution should pass in 0 for `original_public_key` if it wants to use
; an arbitrary `delegated_puzzle` (and `solution`) signed by the
; `SYNTHETIC_PUBLIC_KEY` (whose corresponding private key can be calculated
; if you know the private key for `original_public_key`)
;
; Or you can solve the hidden puzzle by revealing the `original_public_key`,
; the hidden puzzle in `delegated_puzzle`, and a solution to the hidden puzzle.
(SYNTHETIC_PUBLIC_KEY original_public_key delegated_puzzle solution)
; "assert" is a macro that wraps repeated instances of "if"
; usage: (assert A0 A1 ... An R)
; all of A0, A1, ... An must evaluate to non-null, or an exception is raised
; return the value of R (if we get that far)
(defmacro assert items
(if (r items)
(list if (f items) (c assert (r items)) (q . (x)))
(f items)
)
)
(include condition_codes.clvm)
;; hash a tree
;; This is used to calculate a puzzle hash given a puzzle program.
(defun sha256tree1
(TREE)
(if (l TREE)
(sha256 2 (sha256tree1 (f TREE)) (sha256tree1 (r TREE)))
(sha256 1 TREE)
)
)
; "is_hidden_puzzle_correct" returns true iff the hidden puzzle is correctly encoded
(defun-inline is_hidden_puzzle_correct (SYNTHETIC_PUBLIC_KEY original_public_key delegated_puzzle)
(=
SYNTHETIC_PUBLIC_KEY
(point_add
original_public_key
(pubkey_for_exp (sha256 original_public_key (sha256tree1 delegated_puzzle)))
)
)
)
; "possibly_prepend_aggsig" is the main entry point
(defun-inline possibly_prepend_aggsig (SYNTHETIC_PUBLIC_KEY original_public_key delegated_puzzle conditions)
(if original_public_key
(assert
(is_hidden_puzzle_correct SYNTHETIC_PUBLIC_KEY original_public_key delegated_puzzle)
conditions
)
(c (list AGG_SIG_ME SYNTHETIC_PUBLIC_KEY (sha256tree1 delegated_puzzle)) conditions)
)
)
; main entry point
(possibly_prepend_aggsig
SYNTHETIC_PUBLIC_KEY original_public_key delegated_puzzle
(a delegated_puzzle solution))
)