You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: bip-0379.md
+69-1Lines changed: 69 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -393,7 +393,75 @@ paths hit any of the limits.
393
393
394
394
## Test Vectors
395
395
396
-
TBD
396
+
### Conventions
397
+
398
+
One vector per line, no comments. `*.txt` is space separated, `*.tsv` tab
399
+
separated. Expressions contain no whitespace. A key argument is a letter
400
+
`A`..`Z` standing for the public key of the secret key `0x00…01` … `0x00…1a`,
401
+
serialized compressed in P2WSH and x-only in Tapscript. Hash arguments are
402
+
literal hex. A type string is the basic type (`B`/`V`/`K`/`W`) plus its
403
+
properties (`zondumsfe`) in arbitrary order, so compare sorted. Files with a
404
+
`_tap` suffix are Tapscript (`multi_a`, x-only, Schnorr), the others P2WSH.
405
+
406
+
### Files
407
+
408
+
| File | Lines | Line format | Asserts |
409
+
|------|-------|-------------|---------|
410
+
|`valid_from_alloy.txt`| 5,896 |`<expr> <type>`| parses, is a valid top level, has that type |
411
+
|`valid_8f1e8_from_alloy.txt`| 3,492 | same | same, corpus of an earlier upstream revision |
412
+
|`malleable_from_alloy.txt`| 7,024 | same | parses, but has no `m` property, i.e. is not sane |
413
+
|`conflict_from_alloy.txt`| 1,773 | same | parses, but mixes timelock kinds on one path |
414
+
|`edge_cases.txt`| 42 |`<expr>`| the only hand-written file: `thresh` at `k=1`/`k=n`, `multi` with 1 and 20 keys, all four hash fragments, the timelock boundaries (`499999999`/`500000000`, `4194304`/`4194305`), and the sugar forms |
415
+
|`invalid.txt`| 5,574 |`<expr>`| must be rejected (mostly type-check failures) |
416
+
|`opcodes.txt`| 18,184 |`<expr> <type> <ops>`| as above, plus the max ops of a satisfaction, i.e. the quantity the 201-op limit bounds |
417
+
|`props_from_rust[_tap].tsv`| 8,198 + header |`expr script_size op_count sat_witness_elements exec_stack mixed_timelocks non_malleable requires_sig sat_size`| the whole static analysis: type system, timelock mixing, all four resource limits. A two-field row ending in `PARSE_ERR` must be rejected (1,470 of them in the Tapscript file, from the `multi`→`multi_a` substitution) |
418
+
|`scripts_from_rust[_tap].tsv`| 8,198 |`<expr>\t<script hex>`| the translation table byte for byte, incl. `v:` collapsing into the `VERIFY` opcode and minimal number encoding. `ERR` = no encoding in that context |
419
+
|`redeem.json`| 46 cases | JSON | optional, and the only satisfaction vectors: `{miniscript, valid, can_sign_N, …}` plus an `identifiers` map of keys, preimages and hashes |
420
+
421
+
Signature sizes assumed by `sat_size`: 73 bytes ECDSA, 66 bytes Schnorr, each
422
+
element including its length prefix.
423
+
424
+
### Execution
425
+
426
+
There is a Golang based minimal harness script available that executes all test vectors against
427
+
the [Go implementation](https://github.com/btcsuite/btcd/pull/2568).
428
+
429
+
With at least `Go 1.25.0` installed, they can be run with:
430
+
431
+
```shell
432
+
$ cd bip-0379
433
+
$ go run main.go
434
+
```
435
+
436
+
### Provenance
437
+
438
+
The `*.txt` corpora come from rust-miniscript's `src/miniscript/ms_tests.rs` at
439
+
`59ad2ed`; the `*.tsv` tables were extracted from a patched rust-miniscript and
440
+
cross-checked against an
441
+
[independent Go implementation](https://github.com/btcsuite/btcd/pull/2568).
442
+
`redeem.json` comes from this project's end-to-end spend tests.
443
+
444
+
`props_from_rust[_tap].tsv` are generated after applying a
445
+
[bugfix in `rust-miniscript`](https://github.com/rust-bitcoin/rust-miniscript/pull/1015).
446
+
447
+
## Gaps
448
+
449
+
The generated corpora are dominated by `multi`, `sha256`, `after`, `andor` and
450
+
`or_d`; `older()`, `ripemd160()`, `hash256()`, `hash160()` and `and_n()` occur
451
+
only in the 42 hand-written lines, never in composition.
452
+
453
+
The following vector cases are currently missing:
454
+
1.`older()` alongside `after()` in the positions `after()` appears in, since
455
+
the two differ in the relative/absolute timelock analysis, and the generated
456
+
corpora only ever use `after()`.
457
+
2. One vector per resource limit at its boundary, in both contexts: 201 ops,
0 commit comments