ox 1.1.0 → 1.2.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.
Files changed (284) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/core/Engine.d.ts +43 -11
  3. package/dist/core/Engine.d.ts.map +1 -1
  4. package/dist/core/Engine.js +40 -10
  5. package/dist/core/Engine.js.map +1 -1
  6. package/dist/core/Hash.d.ts +36 -0
  7. package/dist/core/Hash.d.ts.map +1 -1
  8. package/dist/core/Hash.js +35 -0
  9. package/dist/core/Hash.js.map +1 -1
  10. package/dist/core/internal/engine.d.ts +8 -8
  11. package/dist/core/internal/engine.d.ts.map +1 -1
  12. package/dist/index.d.ts +5 -2
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +5 -2
  15. package/dist/index.js.map +1 -1
  16. package/dist/node/Ed25519.d.ts +33 -0
  17. package/dist/node/Ed25519.d.ts.map +1 -0
  18. package/dist/node/Ed25519.js +67 -0
  19. package/dist/node/Ed25519.js.map +1 -0
  20. package/dist/node/Engine.d.ts +29 -16
  21. package/dist/node/Engine.d.ts.map +1 -1
  22. package/dist/node/Engine.js +38 -14
  23. package/dist/node/Engine.js.map +1 -1
  24. package/dist/node/Hash.d.ts +17 -19
  25. package/dist/node/Hash.d.ts.map +1 -1
  26. package/dist/node/Hash.js +17 -19
  27. package/dist/node/Hash.js.map +1 -1
  28. package/dist/node/Keystore.d.ts +36 -0
  29. package/dist/node/Keystore.d.ts.map +1 -0
  30. package/dist/node/Keystore.js +72 -0
  31. package/dist/node/Keystore.js.map +1 -0
  32. package/dist/node/Mnemonic.d.ts +35 -0
  33. package/dist/node/Mnemonic.d.ts.map +1 -0
  34. package/dist/node/Mnemonic.js +46 -0
  35. package/dist/node/Mnemonic.js.map +1 -0
  36. package/dist/node/P256.d.ts +32 -0
  37. package/dist/node/P256.d.ts.map +1 -0
  38. package/dist/node/P256.js +34 -0
  39. package/dist/node/P256.js.map +1 -0
  40. package/dist/node/X25519.d.ts +31 -0
  41. package/dist/node/X25519.d.ts.map +1 -0
  42. package/dist/node/X25519.js +71 -0
  43. package/dist/node/X25519.js.map +1 -0
  44. package/dist/node/index.d.ts +95 -8
  45. package/dist/node/index.d.ts.map +1 -1
  46. package/dist/node/index.js +95 -8
  47. package/dist/node/index.js.map +1 -1
  48. package/dist/trusted-setups/Paths.d.ts +1 -0
  49. package/dist/trusted-setups/Paths.d.ts.map +1 -1
  50. package/dist/trusted-setups/Paths.js +1 -0
  51. package/dist/trusted-setups/Paths.js.map +1 -1
  52. package/dist/trusted-setups/Setups.d.ts +35 -0
  53. package/dist/trusted-setups/Setups.d.ts.map +1 -0
  54. package/dist/trusted-setups/Setups.js +29 -0
  55. package/dist/trusted-setups/Setups.js.map +1 -0
  56. package/dist/trusted-setups/index.d.ts +20 -0
  57. package/dist/trusted-setups/index.d.ts.map +1 -1
  58. package/dist/trusted-setups/index.js +20 -0
  59. package/dist/trusted-setups/index.js.map +1 -1
  60. package/dist/trusted-setups/internal/paths.d.ts.map +1 -1
  61. package/dist/trusted-setups/internal/paths.js +1 -1
  62. package/dist/trusted-setups/internal/paths.js.map +1 -1
  63. package/dist/trusted-setups/internal/setups/mainnet.d.ts +7 -0
  64. package/dist/trusted-setups/internal/setups/mainnet.d.ts.map +1 -0
  65. package/dist/trusted-setups/internal/setups/mainnet.js +11 -0
  66. package/dist/trusted-setups/internal/setups/mainnet.js.map +1 -0
  67. package/dist/wasm/Ed25519.d.ts +35 -0
  68. package/dist/wasm/Ed25519.d.ts.map +1 -0
  69. package/dist/wasm/Ed25519.js +88 -0
  70. package/dist/wasm/Ed25519.js.map +1 -0
  71. package/dist/wasm/Engine.d.ts +36 -26
  72. package/dist/wasm/Engine.d.ts.map +1 -1
  73. package/dist/wasm/Engine.js +44 -25
  74. package/dist/wasm/Engine.js.map +1 -1
  75. package/dist/wasm/Hash.d.ts +13 -19
  76. package/dist/wasm/Hash.d.ts.map +1 -1
  77. package/dist/wasm/Hash.js +21 -27
  78. package/dist/wasm/Hash.js.map +1 -1
  79. package/dist/wasm/Keystore.d.ts +51 -0
  80. package/dist/wasm/Keystore.d.ts.map +1 -0
  81. package/dist/wasm/Keystore.js +51 -0
  82. package/dist/wasm/Keystore.js.map +1 -0
  83. package/dist/wasm/Kzg.d.ts +112 -0
  84. package/dist/wasm/Kzg.d.ts.map +1 -0
  85. package/dist/wasm/Kzg.js +333 -0
  86. package/dist/wasm/Kzg.js.map +1 -0
  87. package/dist/wasm/Mnemonic.d.ts +33 -0
  88. package/dist/wasm/Mnemonic.d.ts.map +1 -0
  89. package/dist/wasm/Mnemonic.js +30 -0
  90. package/dist/wasm/Mnemonic.js.map +1 -0
  91. package/dist/wasm/Secp256k1.d.ts +55 -0
  92. package/dist/wasm/Secp256k1.d.ts.map +1 -0
  93. package/dist/wasm/Secp256k1.js +181 -0
  94. package/dist/wasm/Secp256k1.js.map +1 -0
  95. package/dist/wasm/X25519.d.ts +33 -0
  96. package/dist/wasm/X25519.d.ts.map +1 -0
  97. package/dist/wasm/X25519.js +53 -0
  98. package/dist/wasm/X25519.js.map +1 -0
  99. package/dist/wasm/index.d.ts +124 -12
  100. package/dist/wasm/index.d.ts.map +1 -1
  101. package/dist/wasm/index.js +124 -12
  102. package/dist/wasm/index.js.map +1 -1
  103. package/dist/wasm/internal/blake3.d.ts +11 -0
  104. package/dist/wasm/internal/blake3.d.ts.map +1 -0
  105. package/dist/wasm/internal/blake3.js +31 -0
  106. package/dist/wasm/internal/blake3.js.map +1 -0
  107. package/dist/wasm/internal/blake3.wasm.d.ts +3 -0
  108. package/dist/wasm/internal/blake3.wasm.d.ts.map +1 -0
  109. package/dist/wasm/internal/blake3.wasm.js +10 -0
  110. package/dist/wasm/internal/blake3.wasm.js.map +1 -0
  111. package/dist/wasm/internal/crypto25519.d.ts +16 -0
  112. package/dist/wasm/internal/crypto25519.d.ts.map +1 -0
  113. package/dist/wasm/internal/crypto25519.js +5 -0
  114. package/dist/wasm/internal/crypto25519.js.map +1 -0
  115. package/dist/wasm/internal/crypto25519.wasm.d.ts +3 -0
  116. package/dist/wasm/internal/crypto25519.wasm.d.ts.map +1 -0
  117. package/dist/wasm/internal/crypto25519.wasm.js +10 -0
  118. package/dist/wasm/internal/crypto25519.wasm.js.map +1 -0
  119. package/dist/wasm/internal/ed25519.d.ts +4 -0
  120. package/dist/wasm/internal/ed25519.d.ts.map +1 -0
  121. package/dist/wasm/internal/ed25519.js +21 -0
  122. package/dist/wasm/internal/ed25519.js.map +1 -0
  123. package/dist/wasm/internal/hashes.d.ts +12 -0
  124. package/dist/wasm/internal/hashes.d.ts.map +1 -0
  125. package/dist/wasm/internal/hashes.js +8 -0
  126. package/dist/wasm/internal/hashes.js.map +1 -0
  127. package/dist/wasm/internal/hashes.wasm.d.ts +4 -2
  128. package/dist/wasm/internal/hashes.wasm.d.ts.map +1 -1
  129. package/dist/wasm/internal/hashes.wasm.js +4 -2
  130. package/dist/wasm/internal/hashes.wasm.js.map +1 -1
  131. package/dist/wasm/internal/instantiate.d.ts +12 -0
  132. package/dist/wasm/internal/instantiate.d.ts.map +1 -1
  133. package/dist/wasm/internal/instantiate.js +23 -7
  134. package/dist/wasm/internal/instantiate.js.map +1 -1
  135. package/dist/wasm/internal/keystore.d.ts +10 -0
  136. package/dist/wasm/internal/keystore.d.ts.map +1 -0
  137. package/dist/wasm/internal/keystore.js +10 -0
  138. package/dist/wasm/internal/keystore.js.map +1 -0
  139. package/dist/wasm/internal/kzg.d.ts +17 -0
  140. package/dist/wasm/internal/kzg.d.ts.map +1 -0
  141. package/dist/wasm/internal/kzg.js +8 -0
  142. package/dist/wasm/internal/kzg.js.map +1 -0
  143. package/dist/wasm/internal/kzg.wasm.d.ts +3 -0
  144. package/dist/wasm/internal/kzg.wasm.d.ts.map +1 -0
  145. package/dist/wasm/internal/kzg.wasm.js +10 -0
  146. package/dist/wasm/internal/kzg.wasm.js.map +1 -0
  147. package/dist/wasm/internal/mnemonic.d.ts +4 -0
  148. package/dist/wasm/internal/mnemonic.d.ts.map +1 -0
  149. package/dist/wasm/internal/mnemonic.js +45 -0
  150. package/dist/wasm/internal/mnemonic.js.map +1 -0
  151. package/dist/wasm/internal/pbkdf2.d.ts +12 -0
  152. package/dist/wasm/internal/pbkdf2.d.ts.map +1 -0
  153. package/dist/wasm/internal/pbkdf2.js +51 -0
  154. package/dist/wasm/internal/pbkdf2.js.map +1 -0
  155. package/dist/wasm/internal/scrypt.d.ts +16 -0
  156. package/dist/wasm/internal/scrypt.d.ts.map +1 -0
  157. package/dist/wasm/internal/scrypt.js +78 -0
  158. package/dist/wasm/internal/scrypt.js.map +1 -0
  159. package/dist/wasm/internal/scrypt.wasm.d.ts +7 -0
  160. package/dist/wasm/internal/scrypt.wasm.d.ts.map +1 -0
  161. package/dist/wasm/internal/scrypt.wasm.js +14 -0
  162. package/dist/wasm/internal/scrypt.wasm.js.map +1 -0
  163. package/dist/wasm/internal/secp256k1.d.ts +16 -0
  164. package/dist/wasm/internal/secp256k1.d.ts.map +1 -0
  165. package/dist/wasm/internal/secp256k1.js +20 -0
  166. package/dist/wasm/internal/secp256k1.js.map +1 -0
  167. package/dist/wasm/internal/secp256k1.wasm.d.ts +3 -0
  168. package/dist/wasm/internal/secp256k1.wasm.d.ts.map +1 -0
  169. package/dist/wasm/internal/secp256k1.wasm.js +10 -0
  170. package/dist/wasm/internal/secp256k1.wasm.js.map +1 -0
  171. package/dist/wasm/internal/x25519.d.ts +4 -0
  172. package/dist/wasm/internal/x25519.d.ts.map +1 -0
  173. package/dist/wasm/internal/x25519.js +21 -0
  174. package/dist/wasm/internal/x25519.js.map +1 -0
  175. package/package.json +64 -2
  176. package/src/core/Engine.ts +84 -11
  177. package/src/core/Hash.ts +59 -0
  178. package/src/core/_test/Block.test.ts +9 -2
  179. package/src/core/_test/Engine.test-d.ts +56 -0
  180. package/src/core/_test/Engine.test.ts +95 -0
  181. package/src/core/_test/Hash.test-d.ts +18 -0
  182. package/src/core/_test/Hash.test.ts +100 -1
  183. package/src/core/_test/Hash.vectors.test.ts +7 -0
  184. package/src/core/_test/Transaction.test.ts +11 -2
  185. package/src/core/internal/engine.ts +8 -8
  186. package/src/index.ts +5 -2
  187. package/src/node/Ed25519.ts +87 -0
  188. package/src/node/Engine.ts +79 -23
  189. package/src/node/Hash.ts +25 -30
  190. package/src/node/Keystore.ts +103 -0
  191. package/src/node/Mnemonic.ts +68 -0
  192. package/src/node/P256.ts +48 -0
  193. package/src/node/X25519.ts +93 -0
  194. package/src/node/_test/Curves.fuzz.ts +76 -0
  195. package/src/node/_test/Ed25519.test-d.ts +35 -0
  196. package/src/node/_test/Ed25519.test.ts +220 -0
  197. package/src/node/_test/Engine.test-d.ts +28 -0
  198. package/src/node/_test/Engine.test.ts +62 -22
  199. package/src/node/_test/Hash.test-d.ts +16 -9
  200. package/src/node/_test/Hash.test.ts +10 -11
  201. package/src/node/_test/Keystore.fuzz.ts +58 -0
  202. package/src/node/_test/Keystore.test-d.ts +43 -0
  203. package/src/node/_test/Keystore.test.ts +198 -0
  204. package/src/node/_test/Mnemonic.fuzz.ts +31 -0
  205. package/src/node/_test/Mnemonic.test-d.ts +21 -0
  206. package/src/node/_test/Mnemonic.test.ts +98 -0
  207. package/src/node/_test/P256.test-d.ts +29 -0
  208. package/src/node/_test/P256.test.ts +102 -0
  209. package/src/node/_test/X25519.test-d.ts +28 -0
  210. package/src/node/_test/X25519.test.ts +239 -0
  211. package/src/node/index.ts +100 -8
  212. package/src/trusted-setups/Paths.ts +1 -0
  213. package/src/trusted-setups/README.md +39 -0
  214. package/src/trusted-setups/Setups.ts +46 -0
  215. package/src/trusted-setups/_test/Paths.test.ts +16 -0
  216. package/src/trusted-setups/_test/Setups.test-d.ts +7 -0
  217. package/src/trusted-setups/_test/Setups.test.ts +43 -0
  218. package/src/trusted-setups/_test/index.test.ts +1 -0
  219. package/src/trusted-setups/index.ts +21 -0
  220. package/src/trusted-setups/internal/paths.ts +4 -1
  221. package/src/trusted-setups/internal/setups/mainnet.source.json +7 -0
  222. package/src/trusted-setups/internal/setups/mainnet.ts +16 -0
  223. package/src/version.ts +1 -1
  224. package/src/wasm/Ed25519.ts +114 -0
  225. package/src/wasm/Engine.ts +78 -31
  226. package/src/wasm/Hash.bench.ts +2 -2
  227. package/src/wasm/Hash.ts +29 -50
  228. package/src/wasm/Keystore.bench.ts +26 -0
  229. package/src/wasm/Keystore.ts +66 -0
  230. package/src/wasm/Kzg.bench.ts +63 -0
  231. package/src/wasm/Kzg.ts +518 -0
  232. package/src/wasm/Mnemonic.ts +44 -0
  233. package/src/wasm/Secp256k1.bench.ts +79 -0
  234. package/src/wasm/Secp256k1.ts +248 -0
  235. package/src/wasm/X25519.ts +70 -0
  236. package/src/wasm/_test/Crypto25519.conformance.ts +57 -0
  237. package/src/wasm/_test/Crypto25519.fuzz.ts +187 -0
  238. package/src/wasm/_test/Ed25519.test-d.ts +28 -0
  239. package/src/wasm/_test/Ed25519.test.ts +168 -0
  240. package/src/wasm/_test/Ed25519.vectors.test.ts +73 -0
  241. package/src/wasm/_test/Engine.test-d.ts +29 -0
  242. package/src/wasm/_test/Engine.test.ts +59 -25
  243. package/src/wasm/_test/Hash.browser.test.ts +14 -7
  244. package/src/wasm/_test/Hash.fuzz.ts +58 -23
  245. package/src/wasm/_test/Hash.test-d.ts +16 -10
  246. package/src/wasm/_test/Hash.test.ts +148 -48
  247. package/src/wasm/_test/Hash.vectors.test.ts +15 -8
  248. package/src/wasm/_test/Keystore.browser.test.ts +73 -0
  249. package/src/wasm/_test/Keystore.fuzz.ts +163 -0
  250. package/src/wasm/_test/Keystore.test-d.ts +42 -0
  251. package/src/wasm/_test/Keystore.test.ts +477 -0
  252. package/src/wasm/_test/Keystore.vectors.test.ts +21 -0
  253. package/src/wasm/_test/Kzg.test-d.ts +19 -0
  254. package/src/wasm/_test/Kzg.test.ts +220 -0
  255. package/src/wasm/_test/Mnemonic.test-d.ts +17 -0
  256. package/src/wasm/_test/Mnemonic.test.ts +110 -0
  257. package/src/wasm/_test/Runtime.test.ts +9 -0
  258. package/src/wasm/_test/Secp256k1.test-d.ts +35 -0
  259. package/src/wasm/_test/Secp256k1.test.ts +354 -0
  260. package/src/wasm/_test/X25519.test-d.ts +21 -0
  261. package/src/wasm/_test/X25519.test.ts +194 -0
  262. package/src/wasm/_test/fixtures.ts +4 -0
  263. package/src/wasm/index.ts +130 -12
  264. package/src/wasm/internal/blake3.ts +45 -0
  265. package/src/wasm/internal/blake3.wasm.ts +11 -0
  266. package/src/wasm/internal/crypto25519.ts +43 -0
  267. package/src/wasm/internal/crypto25519.wasm.ts +11 -0
  268. package/src/wasm/internal/ed25519.ts +31 -0
  269. package/src/wasm/internal/hashes.ts +29 -0
  270. package/src/wasm/internal/hashes.wasm.ts +5 -2
  271. package/src/wasm/internal/instantiate.ts +29 -9
  272. package/src/wasm/internal/keystore.ts +19 -0
  273. package/src/wasm/internal/kzg.ts +50 -0
  274. package/src/wasm/internal/kzg.wasm.ts +11 -0
  275. package/src/wasm/internal/mnemonic.ts +56 -0
  276. package/src/wasm/internal/pbkdf2.ts +86 -0
  277. package/src/wasm/internal/scrypt.ts +131 -0
  278. package/src/wasm/internal/scrypt.wasm.ts +17 -0
  279. package/src/wasm/internal/secp256k1.ts +62 -0
  280. package/src/wasm/internal/secp256k1.wasm.ts +11 -0
  281. package/src/wasm/internal/x25519.ts +29 -0
  282. package/wasm/vendor/c-kzg-4844/LICENSE +201 -0
  283. package/wasm/vendor/c-kzg-4844/blst/LICENSE +201 -0
  284. package/src/trusted-setups/internal/setups/mainnet.txt +0 -4163
@@ -0,0 +1,220 @@
1
+ import { afterAll, beforeAll, describe, expect, test } from 'vp/test'
2
+ import { kzg as reference } from '../../../test/kzg.js'
3
+ import type * as Bytes from '../../core/Bytes.js'
4
+ import type * as CoreKzg from '../../core/Kzg.js'
5
+ import { mainnet as trustedSetup } from '../../trusted-setups/Setups.js'
6
+ import * as Kzg from '../Kzg.js'
7
+
8
+ const blob = Uint8Array.from({ length: 131_072 }, (_, index) =>
9
+ index % 32 === 31 ? index % 251 : 0,
10
+ )
11
+
12
+ let instance: Kzg.create.ReturnType
13
+ let commitment: Bytes.Bytes
14
+ let cells: readonly Bytes.Bytes[]
15
+ let proofs: readonly Bytes.Bytes[]
16
+
17
+ beforeAll(async () => {
18
+ instance = await Kzg.create({ trustedSetup })
19
+ commitment = instance.blobToKzgCommitment(blob)
20
+ ;({ cells, proofs } = instance.computeCellsAndKzgProofs(blob))
21
+ }, 120_000)
22
+
23
+ afterAll(() => {
24
+ instance.dispose()
25
+ })
26
+
27
+ describe('create', () => {
28
+ test('returns the injected Kzg.Kzg boundary', () => {
29
+ expect(instance satisfies CoreKzg.Kzg).toMatchInlineSnapshot(`
30
+ {
31
+ "blobToKzgCommitment": [Function],
32
+ "computeCells": [Function],
33
+ "computeCellsAndKzgProofs": [Function],
34
+ "dispose": [Function],
35
+ "recoverCellsAndKzgProofs": [Function],
36
+ "verifyCellKzgProofBatch": [Function],
37
+ }
38
+ `)
39
+ })
40
+
41
+ test('compiles concurrently into independently owned instances', async () => {
42
+ const [first, second] = await Promise.all([
43
+ Kzg.create({ trustedSetup }),
44
+ Kzg.create({ trustedSetup }),
45
+ ])
46
+
47
+ first.dispose()
48
+ expect(() => first.blobToKzgCommitment(blob)).toThrow(Kzg.DisposedError)
49
+ expect(second.blobToKzgCommitment(blob)).toEqual(commitment)
50
+ second.dispose()
51
+ second.dispose()
52
+ expect(() => second.computeCells(blob)).toThrowErrorMatchingInlineSnapshot(
53
+ `[Kzg.DisposedError: KZG instance has been disposed.]`,
54
+ )
55
+ }, 120_000)
56
+
57
+ test('rejects precomputation beyond the memory bound', async () => {
58
+ await expect(
59
+ Kzg.create({ precompute: 9, trustedSetup }),
60
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
61
+ `[Kzg.InvalidPrecomputeError: \`precompute\` must be an integer from 0 through 8. Got 9.]`,
62
+ )
63
+ })
64
+
65
+ test('rejects malformed trusted setup points', async () => {
66
+ await expect(
67
+ Kzg.create({
68
+ trustedSetup: {
69
+ ...trustedSetup,
70
+ g2_monomial: trustedSetup.g2_monomial.slice(1),
71
+ },
72
+ }),
73
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
74
+ `[Kzg.InvalidTrustedSetupError: \`g2_monomial\` must contain exactly 6240 bytes.]`,
75
+ )
76
+ })
77
+
78
+ test('rejects invalid trusted setup points', async () => {
79
+ const g1Lagrange = trustedSetup.g1_lagrange.slice()
80
+ g1Lagrange.fill(0, 0, 48)
81
+ await expect(
82
+ Kzg.create({
83
+ trustedSetup: {
84
+ ...trustedSetup,
85
+ g1_lagrange: g1Lagrange,
86
+ },
87
+ }),
88
+ ).rejects.toThrowErrorMatchingInlineSnapshot(
89
+ `[Kzg.InvalidTrustedSetupError: c-kzg rejected the trusted setup.]`,
90
+ )
91
+ }, 120_000)
92
+ })
93
+
94
+ describe('blobToKzgCommitment', () => {
95
+ test('conformance: matches the independent reference implementation', () => {
96
+ expect(commitment).toEqual(reference.blobToKzgCommitment(blob))
97
+ })
98
+
99
+ test('rejects a malformed blob', () => {
100
+ expect(() =>
101
+ instance.blobToKzgCommitment(new Uint8Array(31)),
102
+ ).toThrowErrorMatchingInlineSnapshot(
103
+ `[Kzg.InvalidInputError: \`blob\` must contain exactly 131072 bytes.]`,
104
+ )
105
+ })
106
+
107
+ test('reuses setup and scratch state', () => {
108
+ for (let i = 0; i < 100; i++)
109
+ expect(instance.blobToKzgCommitment(blob)).toEqual(commitment)
110
+ })
111
+ })
112
+
113
+ describe('computeCells', () => {
114
+ test('conformance: matches the independent reference implementation', () => {
115
+ expect(instance.computeCells(blob)).toEqual(reference.computeCells(blob))
116
+ }, 120_000)
117
+ })
118
+
119
+ describe('computeCellsAndKzgProofs', () => {
120
+ test('conformance: matches the independent reference implementation', () => {
121
+ const expected = reference.computeCellsAndKzgProofs(blob)
122
+ expect(cells).toEqual(expected.cells)
123
+ expect(proofs).toEqual(expected.proofs)
124
+ }, 120_000)
125
+ })
126
+
127
+ describe('recoverCellsAndKzgProofs', () => {
128
+ test('conformance: matches the independent reference implementation', () => {
129
+ const indices = cells.map((_, index) => index).filter((index) => index % 2)
130
+ const partial = cells.filter((_, index) => index % 2)
131
+ const expected = reference.recoverCellsAndKzgProofs(indices, partial)
132
+
133
+ expect(instance.recoverCellsAndKzgProofs(indices, partial)).toEqual(
134
+ expected,
135
+ )
136
+ }, 120_000)
137
+
138
+ test('accepts unordered indices', () => {
139
+ const indices = cells
140
+ .map((_, index) => index)
141
+ .filter((index) => index % 2)
142
+ .reverse()
143
+ const partial = indices.map((index) => cells[index]!)
144
+
145
+ expect(instance.recoverCellsAndKzgProofs(indices, partial)).toEqual({
146
+ cells,
147
+ proofs,
148
+ })
149
+ }, 120_000)
150
+
151
+ test('rejects duplicate indices', () => {
152
+ expect(() =>
153
+ instance.recoverCellsAndKzgProofs(
154
+ Array.from({ length: 64 }, () => 0),
155
+ cells.slice(0, 64),
156
+ ),
157
+ ).toThrowErrorMatchingInlineSnapshot(
158
+ `[Kzg.InvalidInputError: \`cellIndices\` must not contain duplicate indices.]`,
159
+ )
160
+ })
161
+ })
162
+
163
+ describe('verifyCellKzgProofBatch', () => {
164
+ const indices = Array.from({ length: 128 }, (_, index) => index)
165
+
166
+ test('conformance: matches the independent reference implementation', () => {
167
+ const commitments = cells.map(() => commitment)
168
+ expect(
169
+ instance.verifyCellKzgProofBatch(commitments, indices, cells, proofs),
170
+ ).toBe(
171
+ reference.verifyCellKzgProofBatch(commitments, indices, cells, proofs),
172
+ )
173
+ }, 120_000)
174
+
175
+ test('returns false for a corrupted cell', () => {
176
+ const corrupted = cells.map((cell, index) => {
177
+ if (index !== 7) return cell
178
+ const value = Uint8Array.from(cell)
179
+ value[0] = value[0]! ^ 1
180
+ return value
181
+ })
182
+ expect(
183
+ instance.verifyCellKzgProofBatch(
184
+ cells.map(() => commitment),
185
+ indices,
186
+ corrupted,
187
+ proofs,
188
+ ),
189
+ ).toMatchInlineSnapshot('false')
190
+ })
191
+
192
+ test('rejects mismatched input lengths', () => {
193
+ expect(() =>
194
+ instance.verifyCellKzgProofBatch(
195
+ [commitment],
196
+ [],
197
+ [cells[0]!],
198
+ [proofs[0]!],
199
+ ),
200
+ ).toThrowErrorMatchingInlineSnapshot(
201
+ `[Kzg.InvalidInputError: \`commitments\`, \`cellIndices\`, \`cells\`, and \`proofs\` must have the same non-zero length.]`,
202
+ )
203
+ })
204
+ })
205
+
206
+ test('exports', () => {
207
+ expect(Object.keys(Kzg)).toMatchInlineSnapshot(`
208
+ [
209
+ "create",
210
+ "DisposedError",
211
+ "InvalidInputError",
212
+ "InvalidPrecomputeError",
213
+ "InvalidTrustedSetupError",
214
+ "MemoryError",
215
+ "WasmError",
216
+ "versionedHashVersion",
217
+ "from",
218
+ ]
219
+ `)
220
+ })
@@ -0,0 +1,17 @@
1
+ import { expectTypeOf, test } from 'vp/test'
2
+ import type * as Engine from '../../core/Engine.js'
3
+ import * as core_Mnemonic from '../../core/Mnemonic.js'
4
+ import * as Mnemonic from '../Mnemonic.js'
5
+
6
+ type Slot = Awaited<ReturnType<typeof Mnemonic.engine>>
7
+
8
+ test('return type exposes Mnemonic.toSeed', () => {
9
+ expectTypeOf<Slot['toSeed']>().toEqualTypeOf<
10
+ NonNullable<Engine.Mnemonic['toSeed']>
11
+ >()
12
+ })
13
+
14
+ test('the WASM namespace exposes the public Mnemonic API', () => {
15
+ expectTypeOf(Mnemonic.toSeed).toEqualTypeOf(core_Mnemonic.toSeed)
16
+ expectTypeOf<typeof Mnemonic>().not.toHaveProperty('create')
17
+ })
@@ -0,0 +1,110 @@
1
+ import { mnemonicToSeedSync } from '@scure/bip39'
2
+ import { describe, expect, test } from 'vp/test'
3
+ import { vectors } from '../../../test/vectors/bip39/index.js'
4
+ import * as Mnemonic from '../Mnemonic.js'
5
+ import * as crypto25519 from '../internal/crypto25519.js'
6
+ import { wasmBase64 } from '../internal/crypto25519.wasm.js'
7
+ import * as internal from '../internal/instantiate.js'
8
+ import * as mnemonic_internal from '../internal/mnemonic.js'
9
+
10
+ describe('engine', () => {
11
+ test('vectors: matches the official English BIP-39 vector', async () => {
12
+ const { toSeed } = await Mnemonic.engine()
13
+
14
+ expect(
15
+ toHex(toSeed(vectors.english.mnemonic, vectors.english.passphrase)),
16
+ ).toBe(vectors.english.seed)
17
+ })
18
+
19
+ test('vectors: matches the official Japanese Unicode BIP-39 vector', async () => {
20
+ const { toSeed } = await Mnemonic.engine()
21
+
22
+ expect(
23
+ toHex(toSeed(vectors.japanese.mnemonic, vectors.japanese.passphrase)),
24
+ ).toBe(vectors.japanese.seed)
25
+ })
26
+
27
+ test('behavior: matches NFKD and every supported word count', async () => {
28
+ const { toSeed } = await Mnemonic.engine()
29
+
30
+ for (const count of [12, 15, 18, 21, 24]) {
31
+ const composed = Array.from({ length: count }, () => 'café').join(' ')
32
+ const decomposed = Array.from({ length: count }, () => 'cafe\u0301').join(
33
+ ' ',
34
+ )
35
+ expect(toSeed(composed, 'pássphrase')).toEqual(
36
+ toSeed(decomposed, 'pa\u0301ssphrase'),
37
+ )
38
+ expect(toSeed(composed, 'pássphrase')).toEqual(
39
+ mnemonicToSeedSync(composed, 'pássphrase'),
40
+ )
41
+ }
42
+ })
43
+
44
+ test('behavior: rejects the same malformed phrase shapes', async () => {
45
+ const { toSeed } = await Mnemonic.engine()
46
+
47
+ for (const count of [0, 1, 11, 13, 23, 25])
48
+ expect(() =>
49
+ toSeed(Array.from({ length: count }, () => 'word').join(' ')),
50
+ ).toThrowError('Invalid mnemonic')
51
+ expect(() => toSeed(1 as never)).toThrowError(
52
+ 'invalid mnemonic type: number',
53
+ )
54
+ })
55
+
56
+ test('behavior: outputs remain owned and staging memory is cleared', async () => {
57
+ const { toSeed } = await Mnemonic.engine()
58
+ const seed = toSeed(vectors.english.mnemonic, vectors.japanese.passphrase)
59
+ const snapshot = seed.slice()
60
+ toSeed(Array.from({ length: 24 }, () => 'word').join(' '), 'other')
61
+ expect(seed).toEqual(snapshot)
62
+
63
+ const passwordSize = new TextEncoder().encode(
64
+ vectors.english.mnemonic.normalize('NFKD'),
65
+ ).length
66
+ const saltSize = new TextEncoder().encode(
67
+ `mnemonic${vectors.japanese.passphrase}`.normalize('NFKD'),
68
+ ).length
69
+ const module = await crypto25519.load()
70
+ expect(
71
+ module
72
+ .view()
73
+ .subarray(
74
+ module.heapBase,
75
+ module.heapBase + passwordSize + saltSize + 64,
76
+ )
77
+ .every((byte) => byte === 0),
78
+ ).toBe(true)
79
+ })
80
+
81
+ test('behavior: clears password, salt, and output after a late trap', async () => {
82
+ const module = await internal.instantiate<crypto25519.Exports>(wasmBase64)
83
+ const vector = vectors.japanese
84
+ const exports: crypto25519.Exports = {
85
+ ...module.exports,
86
+ mnemonic_to_seed(...parameters) {
87
+ module.exports.mnemonic_to_seed(...parameters)
88
+ throw new WebAssembly.RuntimeError('forced late trap')
89
+ },
90
+ }
91
+
92
+ expect(() =>
93
+ mnemonic_internal.toSeed(
94
+ { ...module, exports },
95
+ vector.mnemonic,
96
+ vector.passphrase,
97
+ ),
98
+ ).toThrow(WebAssembly.RuntimeError)
99
+ expect(
100
+ module
101
+ .view()
102
+ .subarray(module.heapBase)
103
+ .every((byte) => byte === 0),
104
+ ).toBe(true)
105
+ })
106
+ })
107
+
108
+ function toHex(value: Uint8Array): string {
109
+ return Buffer.from(value).toString('hex')
110
+ }
@@ -19,3 +19,12 @@ test('memmove compares flat-memory offsets rather than C object pointers', () =>
19
19
  expect(body).toContain('if ((size_t)d < (size_t)s)')
20
20
  expect(body).not.toMatch(/if\s*\(\s*d\s*<\s*s\s*\)/)
21
21
  })
22
+
23
+ test('KZG artifact loads only when create runs', () => {
24
+ const source = readFileSync(new URL('../Kzg.ts', import.meta.url), 'utf8')
25
+
26
+ expect(source).not.toMatch(
27
+ /^import(?!\s+type\b)[^\n]*['"]\.\/internal\/kzg\.js['"]/m,
28
+ )
29
+ expect(source).toContain("await import('./internal/kzg.js')")
30
+ })
@@ -0,0 +1,35 @@
1
+ import { expectTypeOf, test } from 'vp/test'
2
+ import type * as Engine from '../../core/Engine.js'
3
+ import * as core_Secp256k1 from '../../core/Secp256k1.js'
4
+ import * as Secp256k1 from '../Secp256k1.js'
5
+
6
+ type Slot = Awaited<ReturnType<typeof Secp256k1.engine>>
7
+
8
+ test('return type exposes only deterministic Secp256k1 primitives', () => {
9
+ expectTypeOf<Slot['getPublicKey']>().toEqualTypeOf<
10
+ NonNullable<Engine.Ecdsa['getPublicKey']>
11
+ >()
12
+ expectTypeOf<Slot['getSharedSecret']>().toEqualTypeOf<
13
+ NonNullable<Engine.Ecdsa['getSharedSecret']>
14
+ >()
15
+ expectTypeOf<Slot['recoverPublicKey']>().toEqualTypeOf<
16
+ NonNullable<Engine.Ecdsa['recoverPublicKey']>
17
+ >()
18
+ expectTypeOf<Slot['sign']>().toEqualTypeOf<
19
+ NonNullable<Engine.Ecdsa['sign']>
20
+ >()
21
+ expectTypeOf<Slot['verify']>().toEqualTypeOf<
22
+ NonNullable<Engine.Ecdsa['verify']>
23
+ >()
24
+ expectTypeOf<Slot>().not.toHaveProperty('randomSecretKey')
25
+ })
26
+
27
+ test('the WASM namespace exposes the public Secp256k1 API', () => {
28
+ expectTypeOf(Secp256k1.getPublicKey).toEqualTypeOf(
29
+ core_Secp256k1.getPublicKey,
30
+ )
31
+ expectTypeOf(Secp256k1.randomPrivateKey).toEqualTypeOf(
32
+ core_Secp256k1.randomPrivateKey,
33
+ )
34
+ expectTypeOf<typeof Secp256k1>().not.toHaveProperty('create')
35
+ })