Skip to content

Commit 60cf671

Browse files
authored
Merge pull request #5 from xch-dev/verifications
Verification statements and add other builtins
2 parents 9d50d4a + 8b08ea0 commit 60cf671

File tree

3 files changed

+195
-10
lines changed

3 files changed

+195
-10
lines changed

docs/builtins.md

Lines changed: 176 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,39 @@ For example:
4141
let hash = sha256_inline("hello");
4242
```
4343

44-
### `calculate_coin_id`
44+
### `keccak256`
45+
46+
Calculates the [Keccak-256](https://en.wikipedia.org/wiki/SHA-3) hash of the bytes provided. This hash is calculated at runtime.
47+
48+
For example:
49+
50+
```rue
51+
let hash = keccak256("hello");
52+
```
53+
54+
### `keccak256_inline`
55+
56+
The same as `keccak256`, except the value will be calculated at compile time and inserted into the program. In some rare scenario, this may be an important optimization to avoid hashing the same large constant value many times. However, in most cases, you should just use the regular `keccak256` function.
57+
58+
For example:
59+
60+
```rue
61+
let hash = keccak256_inline("hello");
62+
```
63+
64+
### `coinid`
4565

4666
A builtin CLVM opcode for hashing the parent coin id, puzzle hash, and amount of a coin into its coin id. See the [Security](/docs/security.md#untrusted-values) section for an explanation of why this opcode exists. Essentially, it adds runtime checks to make sure that the length of the parent coin id and puzzle hash are 32.
4767

4868
For example:
4969

5070
```rue
51-
calculate_coin_id(parent_coin_id, puzzle_hash, amount)
71+
coinid(parent_coin_id, puzzle_hash, amount)
5272
```
5373

5474
### `substr`
5575

56-
Returns a substring of a byte value, given a range of indices.
76+
Returns a substring of a byte value, given a range of indices. Note that if either index is out of bounds, this will raise an error.
5777

5878
For example:
5979

@@ -62,3 +82,156 @@ substr("hello", 1, 4)
6282
```
6383

6484
This would return `"ell"`
85+
86+
### `substr_start`
87+
88+
Returns a substring of a byte value, given a starting index. Note that if the index is out of bounds, this will raise an error.
89+
90+
For example:
91+
92+
```rue
93+
substr_start("hello", 1)
94+
```
95+
96+
This would return `"ello"`
97+
98+
### `g1_map`
99+
100+
Hashes the data to a BLS public key, with sha256 and ExpandMsgXmd.
101+
102+
For example:
103+
104+
```rue
105+
g1_map("hello")
106+
```
107+
108+
### `g1_map_dist`
109+
110+
Hashes the data to a BLS public key, with sha256 and ExpandMsgXmd. This function allows you to add a DST.
111+
112+
For example:
113+
114+
```rue
115+
g1_map_dst("hello", "dst")
116+
```
117+
118+
### `g2_map`
119+
120+
Hashes the data to a BLS signature, with sha256 and ExpandMsgXmd.
121+
122+
For example:
123+
124+
```rue
125+
g2_map("hello")
126+
```
127+
128+
### `g2_map_dst`
129+
130+
Hashes the data to a BLS signature, with sha256 and ExpandMsgXmd. This function allows you to add a DST.
131+
132+
For example:
133+
134+
```rue
135+
g2_map_dst("hello", "dst")
136+
```
137+
138+
### `pubkey_for_exp`
139+
140+
Maps an exponent (secret key) to a G1 point (public key).
141+
142+
For example:
143+
144+
```rue
145+
pubkey_for_exp("hello")
146+
```
147+
148+
### `modpow`
149+
150+
Computes `(base ^ exponent) % modulus`. Base may be negative, exponent must not be, modulus must not be 0.
151+
152+
For example:
153+
154+
```rue
155+
modpow(5, 50, 45)
156+
```
157+
158+
## Verifications
159+
160+
The following CLVM operators return `nil` on success, and raise if they fail:
161+
162+
1. `bls_pairing_identity`
163+
2. `bls_verify`
164+
3. `secp256k1_verify`
165+
4. `secp256r1_verify`
166+
167+
As such, they would be difficult to use if they were implemented as builtin functions. Instead, Rue provides verification **statements**, which can be called similarly to functions but can't directly be used as an expression. You can think of these like specialized `assert` statements, since they will raise if the verification fails, and continue on if not.
168+
169+
These are automatically optimized such that ordinary references to `nil` after the verification statements in the block are replaced with the verification expression (since it returns `nil` anyways). If there aren't any possible substitutions, the rest of the block will be wrapped in a cons pair, with the verifications happening first, and then unwrapped back into the expression value of the block. And finally, if multiple verifications need to be done in a group, the `all` operator will be used, since it will always return `nil` as well.
170+
171+
All of this is to say that the compiler will pick the most efficient way to insert these verifications into your program without disrupting its behavior at runtime.
172+
173+
:::note
174+
It's not currently possible to dynamically construct the arguments to these verifications from a list at runtime. This is a limitation that seems to exist in Chialisp as well. This may be possible in the future.
175+
:::
176+
177+
### `bls_pairing_identity`
178+
179+
Accepts a flattened sequence of public key and signature pairs, and verifies that the pairing of all pairs is the identity. Otherwise, this will raise.
180+
181+
For example:
182+
183+
```rue
184+
bls_pairing_identity(
185+
0xa3050a67e4771030dade87560e175206a1a93c44461619de07a4e50bfe11ef80f8eaa4956f4648b7ff26c6551dd6ee90,
186+
0xa6242cc5b80eb338a96b41035738eb9973d2c0f892fc52e47e55fc288da1a595a3577b0f995be3d2f4ff71b1948181840e95e79f176f657ade50780f1d77179e82133987025bdeaf37b0052c7dee524a17746b3270eb18a18701ab8157049734,
187+
0xae0154514ac83b8efea5b2eee425fc41ead032bb04b8a977eff85e80f9dd8940833c0d7d85921bf18fe84f639f417cca,
188+
0xa446e176d5aba64e9714fab391b917ea6be087e3d11c5b6bf1fa15d87bf267cfc8dbd479cd2f5a94b78f4ca9aa77850810078fb439e70559c2ea0bbddc5a1b749f5d50a6b466adb1ccd67a62a351997b9a81309b3bddff6168051dc74432d5d5,
189+
0xb066ce9e6484fe574ed55003449fae4d08652f85de45d718c2397c667cd80ed5571458d58c7d28b101ab1ef986973e77,
190+
0x8708f12e05766a8ecbba88e978b9236d4bf998b33f6924258ec9a333190df64a050fe15b9085608c2277f032845c523e16cc1d2dbd4457cd431d18b1419fe45a098205482ee4d41915506f2687778103f32f3cac3ce6cca176d002fffd756860,
191+
0xb7f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb,
192+
0xac168cd0efa5188f370bbe566dfbbb8c8c69a985e7cad8eed7b136ebdcd6338f1d5781e8fd340963fa96a5704a3b7b15046be60b3d17ec1f962191e90b39b36b5ff81548e0baf6f6564f83dbe50258df62f271fdba7a042ed530eeb6a15b794c,
193+
);
194+
```
195+
196+
### `bls_verify`
197+
198+
Accepts a signature followed by a flattened sequence of public key and message pairs, and verifies that the aggregate signature is valid. Otherwise, this will raise.
199+
200+
For example:
201+
202+
```rue
203+
bls_verify(
204+
0x80c37921e62092ef55f85f9eccb21bd80cfaafc0bce9cbdd6999b1a8cabadc8f23720f0261efafaf53cbcc74580b9432007b66d824668900a94934f184bc41bf9ccf9ec141c6f7da610aa7296cd0a181ae8fe176b607aa4c367f15ee0cb985d7,
205+
0x8b202593319bce41b090f3309986de59861ab1e2ff32aef871d83f9aac232c7253c01f1f649c6f69879c441286319de4,
206+
0x39cb1950dba19a7bee9924b5bd2b29f190ffe4ef,
207+
);
208+
```
209+
210+
### `secp256k1_verify`
211+
212+
Verifies a signature that uses the secp256r1 curve against its message hash and signature.
213+
214+
For example:
215+
216+
```rue
217+
secp256k1_verify(
218+
0x02390b19842e100324163334b16947f66125b76d4fa4a11b9ccdde9b7398e64076,
219+
0x85932e4d075615be881398cc765f9f78204033f0ef5f832ac37e732f5f0cbda2,
220+
0x481477e62a1d02268127ae89cc58929e09ad5d30229721965ae35965d098a5f630205a7e69f4cb8084f16c7407ed7312994ffbf87ba5eb1aee16682dd324943e,
221+
);
222+
223+
```
224+
225+
### `secp256r1_verify`
226+
227+
Verifies a signature that uses the secp256r1 curve against its message hash and signature.
228+
229+
For example:
230+
231+
```rue
232+
secp256r1_verify(
233+
0x033e1a1b2ccbc35883c60fdfc3f4a02175096ade6271fe85517ca5772594bbd0dc,
234+
0x85932e4d075615be881398cc765f9f78204033f0ef5f832ac37e732f5f0cbda2,
235+
0xeae2f488080919bd0a7069c24cdd9c6ce2db423861b0c9d4236cdadbd0005f6d8f3709e6eb19249fd9c8bea664aba35218e67ea4b0f2239488dc3147f336e1e6,
236+
);
237+
```

docs/operators.md

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,22 @@ slug: /operators
1616
| `/` | `4 / 2` | Divides two `Int` values and returns the quotient. |
1717
| `%` | `3 % 2` | Divides two `Int` values and returns the remainder. |
1818

19+
:::note
20+
The `+` operator can be used with `Bytes` values to concatenate them together.
21+
22+
The `+`, `-`, and `*` operators can be used with `PublicKey` or `Signature` values to perform the corresponding BLS math operations (ie point addition, subtraction, or multiplication).
23+
:::
24+
1925
### Unary
2026

2127
| Op | Example | Description |
2228
| --- | ------- | -------------------------------------------------- |
2329
| `+` | `+42` | An unnecessary no-op. |
2430
| `-` | `-42` | Returns the negative equivalent of an `Int` value. |
2531

26-
## Bytes
27-
28-
| Op | Example | Description |
29-
| --- | ----------- | -------------------------------------------------- |
30-
| `+` | `"A" + "B"` | Concatenates two values with the `Bytes` together. |
32+
:::note
33+
The `-` operator can be used with `PublicKey` or `Signature` values to negate them.
34+
:::
3135

3236
## Bitwise
3337

@@ -62,3 +66,10 @@ slug: /operators
6266
:::note
6367
The comparison operators can also be used with `Bytes` values, and the special byte-specific `>s` operator is used to implement this in [CLVM](https://chialisp.com/operators/#comparison).
6468
:::
69+
70+
## Equality
71+
72+
| Op | Example | Description |
73+
| ---- | -------- | ------------------------------------------------ |
74+
| `==` | `1 == 2` | If the left side is equal to the right side. |
75+
| `!=` | `1 != 2` | If the left side is not equal to the right side. |

src/theme/prism-rue.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Prism.languages.rue = {
55
},
66
"function-call": {
77
pattern:
8-
/\b[a-zA-Z_][a-zA-Z0-9_]*\s*(?:::\s*<.*?>\s*)?(?=\s*(?:\(|<.*?>\())/,
8+
/\b(?!(?:bls_pairing_identity|bls_verify|secp256k1_verify|secp256r1_verify)\b)[a-zA-Z_][a-zA-Z0-9_]*\s*(?:::\s*<.*?>\s*)?(?=\s*(?:\(|<.*?>\())/,
99
alias: "function",
1010
},
1111
field: {
@@ -30,7 +30,8 @@ Prism.languages.rue = {
3030
/[+\-*?%!\^~]|<[<=]?|>[>=]?|=[=>]?|!=?|\.(?:\.\.)?|::|->?|&&?|\|\|?/,
3131
punctuation: /[(){}[\],:]/,
3232
"control-flow": {
33-
pattern: /\b(?:if|else|return|raise|assert)\b/,
33+
pattern:
34+
/\b(?:if|else|return|raise|assert|bls_pairing_identity|bls_verify|secp256k1_verify|secp256r1_verify)\b/,
3435
alias: "keyword",
3536
},
3637
binding: {

0 commit comments

Comments
 (0)