Skip to content

Commit 9d29a66

Browse files
committed
Add some tests and a simple test runner
1 parent 1529951 commit 9d29a66

File tree

7 files changed

+272
-123
lines changed

7 files changed

+272
-123
lines changed

src/stdlib/stdlib.minsc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,15 @@ fn _debug_nonfn($v) = if !isFunction($v) then debug($v) else $v;
6969

7070
dyn fn log::env($label) = log("variables:\n----\n" + env::pretty() + "\n----");
7171
dyn fn log::debug_env($label) = log("variables:\n----\n" + env::debug() + "\n----");
72+
73+
// Testing
74+
T = [];
75+
dyn fn test($topic, $test) {
76+
T = T + [ $topic ];
77+
$indent = if len(T) > 1 then join(fillArray(len(T)-1, "··"), "")+" " else "";
78+
print("[TEST] " + $indent + join(T, " · "));
79+
t::assert(if isFunction($test) then $test(T) else $test);
80+
}
81+
dyn fn t::assert($bool) = $bool || throw("["+last(T)+"] Assertion failed");
82+
dyn fn t::eq($a, $b) = ($a == $b) || throw("["+last(T)+"] Not equal: "+$a+" != "+$b);
83+
it = test;

tests/keys.minsc

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
test("Keys", |T| {
2+
test("Key generation & byte encoding", |T| {
3+
$sk = xpriv::rand();
4+
$pk = pubkey($sk);
5+
6+
t::eq(typeof($sk), "seckey");
7+
t::eq(len(bytes($sk)), 78);
8+
t::eq(seckey(bytes($sk)), $sk);
9+
10+
t::eq(typeof($pk), "pubkey");
11+
t::eq(len(bytes($pk)), 78);
12+
t::eq(pubkey(bytes($pk)), $pk)
13+
});
14+
15+
test("Signing & Verification", |T| {
16+
$sk = xpriv::rand(), $pk = pubkey($sk);
17+
$H1 = hash::sha256("Hello"), $H2 = hash::sha256("Hello2");
18+
19+
test("ECDSA", |T| {
20+
t::assert(ecdsa::verify($pk, $H1, ecdsa::sign($sk, $H1)));
21+
t::assert(!ecdsa::verify($pk, $H2, ecdsa::sign($sk, $H1)));
22+
23+
it("Is deterministic (RFC 6979)", |T|
24+
t::eq(ecdsa::sign($sk, $H1), ecdsa::sign($sk, $H1)));
25+
26+
it("Uses DER by default", len(ecdsa::sign($sk, $H1)) >= 70); // 70-73
27+
28+
it("Supports compact encoding", |T|
29+
t::eq(len(ecdsa::sign($sk, $H1, true)), 64));
30+
});
31+
32+
test("Schnorr", |T| {
33+
t::assert(schnorr::verify($pk, $H1, schnorr::sign($sk, $H1)));
34+
t::assert(!schnorr::verify($pk, $H1, schnorr::sign($sk, $H2)));
35+
36+
it("Is deterministic without aux_rand", |T| {
37+
t::eq(schnorr::sign($sk, $H1), schnorr::sign($sk, $H1));
38+
t::assert(schnorr::sign($sk, $H1, true) != schnorr::sign($sk, $H1, true));
39+
})
40+
})
41+
});
42+
43+
44+
test("BIP32 Test Vectors", |T| {
45+
mainnet = _$$_RECKLESSLY_RISK_MY_BITCOINS_$$_;
46+
47+
test("Test 1", |T| {
48+
$sk = xpriv::from_seed(0x000102030405060708090a0b0c0d0e0f, mainnet);
49+
$pk = pubkey($sk);
50+
51+
t::eq($sk, xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi);
52+
t::eq($pk, xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8);
53+
54+
t::eq(bytes($sk), 0x0488ade4000000000000000000873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d50800e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35);
55+
t::eq(bytes($pk), 0x0488b21e000000000000000000873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d5080339a36013301597daef41fbe593a02cc513d0b55527ec2df1050e2e8ff49c85c2);
56+
});
57+
58+
test("Test 2", |T| {
59+
$sk = xpriv::from_seed(0xfffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542, mainnet);
60+
$pk = pubkey($sk);
61+
62+
t::eq($sk, xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U);
63+
t::eq($pk, xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB);
64+
});
65+
});
66+
})

tests/multisig.minsc

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
test("Multisig 2-of-2", |T| {
2+
$alice_sk = tprv8ZgxMBicQKsPfJtqwiW9WhjJHPZtDo8aUbCkkcG8sjHbpZqjghF6ZJ1Tze9fUHrhYyXSNfw5VPbCKEkoFKaDRUzctbSxmxSWNfAGDonxcTG/ *;
3+
$bob_sk = tprv8ZgxMBicQKsPd13DKoKTUp2N6yMvzzUq2GUXTgJ28VoRpEXEJTnXCAqXBHm6sCAMgPNR9fwjcpzCWRpV9uqu85YEtSwb4dCoBGrPP84mLrR/ *;
4+
5+
$alice = tpubD6NzVbkrYhZ4YmvdqNAjv7PQrR5pP8KV3toY38JSJ15zf46WK64gjndLAmKEJp4z2xhPnC6h7T5pdQ1uT9dSUJBUF5YX6tBEZpMgDytLgS5/ *;
6+
$bob = tpubD6NzVbkrYhZ4WU51DSz3tDgUfzssAKfjba5JkCLKYmbpeimzvrc7NfTPMStAugvBbyrii2jQKxDofyWVt2Kfxhjd2wz7BGAjNn35HnN7u2L/ *;
7+
8+
$multisig = wsh($alice && $bob);
9+
assert::eq(address($multisig/0), tb1q58leaajpyvm5zpr5kxpuzfqth2sy94ka2zmat7l2eezcvl355slsjlap8g);
10+
log("Multisig", $multisig);
11+
12+
$psbt = psbt [
13+
"input": [
14+
"prevout": b44c2d14732744392c555f0e96f6f4bce28ea1be4dd812dbbd29450610f3a7ae:1,
15+
"utxo": $multisig/0:2 BTC,
16+
],
17+
"outputs": [
18+
bcrt1ql8nqx3q3v7napchr6ewy4tpyq5y08ywat84pen: 1.9 BTC,
19+
$multisig/1:0.05 BTC, // change back to multisig
20+
],
21+
];
22+
23+
assert::eq(psbt::fee($psbt), 0.05 BTC);
24+
25+
// $signed_both = psbt::sign($psbt, [$alice_sk, $bob_sk]);
26+
$signed_alice = psbt::sign($psbt, $alice_sk);
27+
$signed_both = psbt::sign($signed_alice, $bob_sk);
28+
29+
$tx = psbt::extract(psbt::finalize($signed_both));
30+
31+
t::eq($tx, tx(0x02000000000101aea7f310064529bddb12d84dbea18ee2bcf4f6960e5f552c39442773142d4cb40100000000ffffffff02802b530b00000000160014f9e603441167a7d0e2e3d65c4aac240508f391dd404b4c0000000000220020f4bf33f97b51cbb176f2ada61dc7522d67e376c911453dcde837217cc586a52203483045022100aedd28d1bcc6d204e43ba0bbe1b302ff9b407022df512014907b695cc6fb05460220015a63904700d93654fd68849ae53e3950822ea284b23be38351046caa84b731014730440220259b7e95f73adebc4d3b3c0dfdb36c21390d9a738d757ecd4c5af10a392c505802204aefd85a3a078965c063252d4de480103ddd7d01b57be7dfefca8a843948c42d014621024f68a514e61e0f54f71212a0054023193665fa49f6b8edfc8c8c98565538a500ad2102345043eedf475c5d6aae23473bc1a9e617435ee0a0061c079e04f67dcb67bd35ac00000000));
32+
log("Final TX", pretty($tx));
33+
34+
})

0 commit comments

Comments
 (0)