lnurlcash-conformance 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,27 @@ exact version if you gate CI on the grade.
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## 0.7.0 - 2026-09-04
10
+
11
+ **`cash-derivation.json`: LUD-25's own seed-recoverable note secrets.** The
12
+ draft specifies a BIP-32 scheme under `m/139'` and the reference wallet
13
+ implements it; `derivation.json` remains, unchanged, as the pre-spec HMAC
14
+ scheme that notes are still outstanding under.
15
+
16
+ Every case carries `cashRoot`, the four `domainIndices`, a `hardened` flag per
17
+ index, the `domainNode` and the resulting `k1`. The flags are the point of the
18
+ file. `d1..d4` are raw uint32 and BIP-32 reads any index `>= 2^31` as hardened,
19
+ so which levels are hardened is decided by the mint's own host name - an
20
+ implementation that masks the top bit, or hardens all four, derives a
21
+ different tree and restores nothing, silently. Both hosts in the vector land
22
+ on a mix, so an implementation that gets it wrong cannot pass by luck.
23
+
24
+ `bip32Vector1` carries BIP-32's own published test vector 1, so a port can
25
+ prove its CKDpriv before blaming the LUD-25 path above it. The generator
26
+ implements BIP-32 from `@noble` primitives rather than importing a BIP-32
27
+ library, for the reason at the top of `tools/generate.mjs`: a vector produced
28
+ by the library under test proves nothing.
29
+
9
30
  ## 0.6.0 - 2026-09-03
10
31
 
11
32
  **Offline verification and mutation replay now grade the current LUD-25
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "lnurlcash-conformance",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Language-neutral conformance vectors, an adversarial mock mint, and a grader for LNURLcash (LUD-25) implementations",
5
5
  "author": "TheCryptoDonkey",
6
6
  "license": "MIT",
@@ -0,0 +1,160 @@
1
+ {
2
+ "version": 1,
3
+ "spec": "LUD-25 draft (lnurl/luds#301)",
4
+ "description": "LUD-25's specified seed-recoverable note secrets, the BIP-32 scheme under m/139'. cashRoot is m/139' as privateKey||chainCode hex (64 bytes, no version/depth/fingerprint framing). domainIndices are the four raw uint32 read big-endian from the first 16 bytes of HMAC-SHA256(key = the private key at m/139'/0, msg = utf8(host)); they are used as BIP-32 child indices exactly as they fall, so `hardened` records which of them land >= 2^31 by magnitude - an implementation that masks the top bit or hardens all four derives a different tree and will restore nothing. domainNode is m/139'/d1/d2/d3/d4. k1 is the private key at the hardened child `index` of that node, 32 bytes lowercase hex, and the mint sees only sha256(k1) as ever. host is the mint host exactly as the wallet stores it, with the port when there is one. seedHex is the 64-byte BIP39 seed with no passphrase. bip32Vector1 is BIP-32's own published test vector 1, so CKDpriv itself can be checked first.",
5
+ "scheme": {
6
+ "purpose": "m/139'",
7
+ "hashingKey": "m/139'/0",
8
+ "domainMsg": "host",
9
+ "secretPath": "m/139'/d1/d2/d3/d4/i'",
10
+ "hardenedByMagnitudeOnly": true
11
+ },
12
+ "bip32Vector1": [
13
+ {
14
+ "index": null,
15
+ "node": "e8f32e723decf4051aefac8e2c93c9c5b214313817cdb01a1494b917c8436b35873dff81c02f525623fd1fe5167eac3a55a049de3d314bb42ee227ffed37d508"
16
+ },
17
+ {
18
+ "index": 2147483648,
19
+ "hardened": true,
20
+ "node": "edb2e14f9ee77d26dd93b4ecede8d16ed408ce149b6cd80b0715a2d911a0afea47fdacbd0f1097043b78c63c20c34ef4ed9a111d980047ad16282c7ae6236141"
21
+ },
22
+ {
23
+ "index": 1,
24
+ "hardened": false,
25
+ "node": "3c6cb8d0f6a264c91ea8b5030fadaa8e538b020f0a387421a12de9319dc933682a7857631386ba23dacac34180dd1983734e444fdbf774041578e9b6adb37c19"
26
+ },
27
+ {
28
+ "index": 2147483650,
29
+ "hardened": true,
30
+ "node": "cbce0d719ecf7431d88e6a89fa1483e02e35092af60c042b1df2ff59fa424dca04466b9cc8e161e966409ca52986c584f07e9dc81f735db683c3ff6ec7b1503f"
31
+ },
32
+ {
33
+ "index": 2,
34
+ "hardened": false,
35
+ "node": "0f479245fb19a38a1954c5c7c0ebab2f9bdfd96a17563ef28a6a4b1a2a764ef4cfb71883f01676f587d023cc53a35bc7f88f724b1f8c2892ac1275ac822a3edd"
36
+ },
37
+ {
38
+ "index": 1000000000,
39
+ "hardened": false,
40
+ "node": "471b76e389e528d6de6d816857e012c5455051cad6660850e58372a6c3e6e7c8c783e67b921d2beb8f6b389cc646d7263b4145701dadd2161548a8b078e65e9e"
41
+ }
42
+ ],
43
+ "cases": [
44
+ {
45
+ "name": "standard mnemonic, index 0",
46
+ "mnemonic": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
47
+ "seedHex": "5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4",
48
+ "host": "mint.example",
49
+ "index": 0,
50
+ "cashRoot": "c7a2496e9b453a67c5d2a1f04936ec1259440d45454c795a99a66269e4cd3005111e1cc966fca2fe32f054f14caceab90449e536d94cf6935ea12a087e414f60",
51
+ "domainIndices": [
52
+ 2589708612,
53
+ 3693348916,
54
+ 172082394,
55
+ 3793182078
56
+ ],
57
+ "hardened": [
58
+ true,
59
+ true,
60
+ false,
61
+ true
62
+ ],
63
+ "domainNode": "72056e5cde21458b13689c3950904dfd327415a506d064290e5e5f4296a40543dd5e9504ddb6eefbafa4ad3b00ad421858fafc0ed9ea4abd9cb68793f845cfc1",
64
+ "k1": "de5b81405a12e1297b350d80e2ad85043ed5b9436a0c5592d3302778de330499",
65
+ "noteId": "7db9da2845cd45c1c3c2e302d6135da46823e245f756b830ef59ac324b769e02"
66
+ },
67
+ {
68
+ "name": "standard mnemonic, index 1",
69
+ "mnemonic": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
70
+ "seedHex": "5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4",
71
+ "host": "mint.example",
72
+ "index": 1,
73
+ "cashRoot": "c7a2496e9b453a67c5d2a1f04936ec1259440d45454c795a99a66269e4cd3005111e1cc966fca2fe32f054f14caceab90449e536d94cf6935ea12a087e414f60",
74
+ "domainIndices": [
75
+ 2589708612,
76
+ 3693348916,
77
+ 172082394,
78
+ 3793182078
79
+ ],
80
+ "hardened": [
81
+ true,
82
+ true,
83
+ false,
84
+ true
85
+ ],
86
+ "domainNode": "72056e5cde21458b13689c3950904dfd327415a506d064290e5e5f4296a40543dd5e9504ddb6eefbafa4ad3b00ad421858fafc0ed9ea4abd9cb68793f845cfc1",
87
+ "k1": "267570df5ba8098d728e839a698f729c2df6fa7b8b7ae7c9c7ffa7dda3417e1d",
88
+ "noteId": "99b98cb845940e0d6401e176aaca1446365aa315201803861e17f3c530ed1dcf"
89
+ },
90
+ {
91
+ "name": "standard mnemonic, index 20 (one past a 20-index gap limit)",
92
+ "mnemonic": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
93
+ "seedHex": "5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4",
94
+ "host": "mint.example",
95
+ "index": 20,
96
+ "cashRoot": "c7a2496e9b453a67c5d2a1f04936ec1259440d45454c795a99a66269e4cd3005111e1cc966fca2fe32f054f14caceab90449e536d94cf6935ea12a087e414f60",
97
+ "domainIndices": [
98
+ 2589708612,
99
+ 3693348916,
100
+ 172082394,
101
+ 3793182078
102
+ ],
103
+ "hardened": [
104
+ true,
105
+ true,
106
+ false,
107
+ true
108
+ ],
109
+ "domainNode": "72056e5cde21458b13689c3950904dfd327415a506d064290e5e5f4296a40543dd5e9504ddb6eefbafa4ad3b00ad421858fafc0ed9ea4abd9cb68793f845cfc1",
110
+ "k1": "1f2b8080d4c9431b1dec780abb4eee3c4aaf7ff03f7dd126a7e005ec7af372e0",
111
+ "noteId": "0daebdd7f9355a215c511cadc96e73f586e07238c352b43b21c080713b79cbfc"
112
+ },
113
+ {
114
+ "name": "a second mnemonic, same host and index",
115
+ "mnemonic": "legal winner thank year wave sausage worth useful legal winner thank yellow",
116
+ "seedHex": "878386efb78845b3355bd15ea4d39ef97d179cb712b77d5c12b6be415fffeffe5f377ba02bf3f8544ab800b955e51fbff09828f682052a20faa6addbbddfb096",
117
+ "host": "mint.example",
118
+ "index": 0,
119
+ "cashRoot": "e58252908e0c10965d15d1e3894cbf206a2102c20eb9519e466e2e0e852075d430afaa22bb69ef2151cdffacc463e51068e854152b0b7c08fa2f93e6b8d16741",
120
+ "domainIndices": [
121
+ 3862277158,
122
+ 545631060,
123
+ 182776155,
124
+ 2195829862
125
+ ],
126
+ "hardened": [
127
+ true,
128
+ false,
129
+ false,
130
+ true
131
+ ],
132
+ "domainNode": "df3c9156afc2e416286df9bbfda49c6ab72305ba3d65ae0b7e2214caf581b111959d96bc0c075185ff7304214496a78f43b22ea511f97a7bf408454a7e3d3a85",
133
+ "k1": "d5376fa38f01b39d55be6dc0ea8f3aa6b91f37c183c5a394bb7e30b624855a78",
134
+ "noteId": "5b4ba51285373e8a8c0414e6b3607ea0a6b70968c94f2b9f73ffdfdedfba1c15"
135
+ },
136
+ {
137
+ "name": "a host carrying a port",
138
+ "mnemonic": "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about",
139
+ "seedHex": "5eb00bbddcf069084889a8ab9155568165f5c453ccb85e70811aaed6f6da5fc19a5ac40b389cd370d086206dec8aa6c43daea6690f20ad3d8d48b2d2ce9e38e4",
140
+ "host": "127.0.0.1:8899",
141
+ "index": 0,
142
+ "cashRoot": "c7a2496e9b453a67c5d2a1f04936ec1259440d45454c795a99a66269e4cd3005111e1cc966fca2fe32f054f14caceab90449e536d94cf6935ea12a087e414f60",
143
+ "domainIndices": [
144
+ 2087962263,
145
+ 3073061246,
146
+ 2281736429,
147
+ 1205328740
148
+ ],
149
+ "hardened": [
150
+ false,
151
+ true,
152
+ true,
153
+ false
154
+ ],
155
+ "domainNode": "80bdd2d71f0235bd9e22d5838a4a4f346cf5415309ada559942a409a630e102ce214425b89b36d03d4835fdf6592d2619c74d37b746711b4ed85759ea1d358a6",
156
+ "k1": "d7bcc5c9e7015ca2688ed10e24db3f82163d5b59fc887e5dd346abf2426b1270",
157
+ "noteId": "1a8a732d7ec9811654183ecbb27b1887dec947a42c877a12bd93f952837a3887"
158
+ }
159
+ ]
160
+ }
@@ -6,6 +6,7 @@
6
6
  "files": [
7
7
  "signature.json",
8
8
  "derivation.json",
9
+ "cash-derivation.json",
9
10
  "bech32.json",
10
11
  "url-admission.json",
11
12
  "input-resolution.json",