ox 1.0.5 → 1.1.2

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 (337) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/dist/core/Base64.d.ts +10 -21
  3. package/dist/core/Base64.d.ts.map +1 -1
  4. package/dist/core/Base64.js +8 -127
  5. package/dist/core/Base64.js.map +1 -1
  6. package/dist/core/BinaryStateTree.d.ts.map +1 -1
  7. package/dist/core/BinaryStateTree.js +2 -2
  8. package/dist/core/BinaryStateTree.js.map +1 -1
  9. package/dist/core/Bls.d.ts.map +1 -1
  10. package/dist/core/Bls.js +19 -44
  11. package/dist/core/Bls.js.map +1 -1
  12. package/dist/core/Ed25519.d.ts.map +1 -1
  13. package/dist/core/Ed25519.js +7 -6
  14. package/dist/core/Ed25519.js.map +1 -1
  15. package/dist/core/Engine.d.ts +156 -0
  16. package/dist/core/Engine.d.ts.map +1 -0
  17. package/dist/core/Engine.js +210 -0
  18. package/dist/core/Engine.js.map +1 -0
  19. package/dist/core/Hash.d.ts +4 -4
  20. package/dist/core/Hash.d.ts.map +1 -1
  21. package/dist/core/Hash.js +9 -12
  22. package/dist/core/Hash.js.map +1 -1
  23. package/dist/core/Keystore.d.ts.map +1 -1
  24. package/dist/core/Keystore.js +15 -10
  25. package/dist/core/Keystore.js.map +1 -1
  26. package/dist/core/Mnemonic.d.ts.map +1 -1
  27. package/dist/core/Mnemonic.js +3 -2
  28. package/dist/core/Mnemonic.js.map +1 -1
  29. package/dist/core/P256.d.ts.map +1 -1
  30. package/dist/core/P256.js +8 -9
  31. package/dist/core/P256.js.map +1 -1
  32. package/dist/core/Secp256k1.d.ts.map +1 -1
  33. package/dist/core/Secp256k1.js +8 -9
  34. package/dist/core/Secp256k1.js.map +1 -1
  35. package/dist/core/WebCryptoP256.d.ts.map +1 -1
  36. package/dist/core/WebCryptoP256.js +2 -2
  37. package/dist/core/WebCryptoP256.js.map +1 -1
  38. package/dist/core/X25519.d.ts.map +1 -1
  39. package/dist/core/X25519.js +4 -3
  40. package/dist/core/X25519.js.map +1 -1
  41. package/dist/core/internal/bls.d.ts +12 -0
  42. package/dist/core/internal/bls.d.ts.map +1 -0
  43. package/dist/core/internal/bls.js +79 -0
  44. package/dist/core/internal/bls.js.map +1 -0
  45. package/dist/core/internal/codec/base64.d.ts +84 -0
  46. package/dist/core/internal/codec/base64.d.ts.map +1 -0
  47. package/dist/core/internal/codec/base64.js +177 -0
  48. package/dist/core/internal/codec/base64.js.map +1 -0
  49. package/dist/core/internal/codec/hex.d.ts +49 -4
  50. package/dist/core/internal/codec/hex.d.ts.map +1 -1
  51. package/dist/core/internal/codec/hex.js +109 -35
  52. package/dist/core/internal/codec/hex.js.map +1 -1
  53. package/dist/core/internal/curves.d.ts +17 -0
  54. package/dist/core/internal/curves.d.ts.map +1 -0
  55. package/dist/core/internal/curves.js +17 -0
  56. package/dist/core/internal/curves.js.map +1 -0
  57. package/dist/core/internal/ed25519.d.ts +14 -0
  58. package/dist/core/internal/ed25519.d.ts.map +1 -0
  59. package/dist/core/internal/ed25519.js +29 -0
  60. package/dist/core/internal/ed25519.js.map +1 -0
  61. package/dist/core/internal/engine.d.ts +278 -0
  62. package/dist/core/internal/engine.d.ts.map +1 -0
  63. package/dist/core/internal/engine.js +131 -0
  64. package/dist/core/internal/engine.js.map +1 -0
  65. package/dist/core/internal/hash.d.ts +12 -0
  66. package/dist/core/internal/hash.d.ts.map +1 -0
  67. package/dist/core/internal/hash.js +30 -0
  68. package/dist/core/internal/hash.js.map +1 -0
  69. package/dist/core/internal/keystore.d.ts +14 -0
  70. package/dist/core/internal/keystore.d.ts.map +1 -0
  71. package/dist/core/internal/keystore.js +32 -0
  72. package/dist/core/internal/keystore.js.map +1 -0
  73. package/dist/core/internal/mnemonic.d.ts +4 -0
  74. package/dist/core/internal/mnemonic.d.ts.map +1 -0
  75. package/dist/core/internal/mnemonic.js +14 -0
  76. package/dist/core/internal/mnemonic.js.map +1 -0
  77. package/dist/core/internal/p256.d.ts +14 -0
  78. package/dist/core/internal/p256.d.ts.map +1 -0
  79. package/dist/core/internal/p256.js +36 -0
  80. package/dist/core/internal/p256.js.map +1 -0
  81. package/dist/core/internal/secp256k1.d.ts +14 -0
  82. package/dist/core/internal/secp256k1.d.ts.map +1 -0
  83. package/dist/core/internal/secp256k1.js +36 -0
  84. package/dist/core/internal/secp256k1.js.map +1 -0
  85. package/dist/core/internal/x25519.d.ts +8 -0
  86. package/dist/core/internal/x25519.d.ts.map +1 -0
  87. package/dist/core/internal/x25519.js +20 -0
  88. package/dist/core/internal/x25519.js.map +1 -0
  89. package/dist/index.d.ts +38 -0
  90. package/dist/index.d.ts.map +1 -1
  91. package/dist/index.docs.d.ts +2 -0
  92. package/dist/index.docs.d.ts.map +1 -1
  93. package/dist/index.docs.js +2 -0
  94. package/dist/index.docs.js.map +1 -1
  95. package/dist/index.js +38 -0
  96. package/dist/index.js.map +1 -1
  97. package/dist/node/Ed25519.d.ts +33 -0
  98. package/dist/node/Ed25519.d.ts.map +1 -0
  99. package/dist/node/Ed25519.js +67 -0
  100. package/dist/node/Ed25519.js.map +1 -0
  101. package/dist/node/Engine.d.ts +68 -0
  102. package/dist/node/Engine.d.ts.map +1 -0
  103. package/dist/node/Engine.js +75 -0
  104. package/dist/node/Engine.js.map +1 -0
  105. package/dist/node/Hash.d.ts +37 -0
  106. package/dist/node/Hash.d.ts.map +1 -0
  107. package/dist/node/Hash.js +35 -0
  108. package/dist/node/Hash.js.map +1 -0
  109. package/dist/node/Keystore.d.ts +36 -0
  110. package/dist/node/Keystore.d.ts.map +1 -0
  111. package/dist/node/Keystore.js +72 -0
  112. package/dist/node/Keystore.js.map +1 -0
  113. package/dist/node/Mnemonic.d.ts +35 -0
  114. package/dist/node/Mnemonic.d.ts.map +1 -0
  115. package/dist/node/Mnemonic.js +46 -0
  116. package/dist/node/Mnemonic.js.map +1 -0
  117. package/dist/node/P256.d.ts +32 -0
  118. package/dist/node/P256.d.ts.map +1 -0
  119. package/dist/node/P256.js +34 -0
  120. package/dist/node/P256.js.map +1 -0
  121. package/dist/node/X25519.d.ts +31 -0
  122. package/dist/node/X25519.d.ts.map +1 -0
  123. package/dist/node/X25519.js +71 -0
  124. package/dist/node/X25519.js.map +1 -0
  125. package/dist/node/index.d.ts +126 -0
  126. package/dist/node/index.d.ts.map +1 -0
  127. package/dist/node/index.js +126 -0
  128. package/dist/node/index.js.map +1 -0
  129. package/dist/tempo/VirtualMaster.d.ts +2 -0
  130. package/dist/tempo/VirtualMaster.d.ts.map +1 -1
  131. package/dist/tempo/VirtualMaster.js +19 -5
  132. package/dist/tempo/VirtualMaster.js.map +1 -1
  133. package/dist/tempo/internal/mine.wasm.d.ts +2 -4
  134. package/dist/tempo/internal/mine.wasm.d.ts.map +1 -1
  135. package/dist/tempo/internal/mine.wasm.js +7 -12
  136. package/dist/tempo/internal/mine.wasm.js.map +1 -1
  137. package/dist/tempo/internal/virtualMasterPool.js +4 -1
  138. package/dist/tempo/internal/virtualMasterPool.js.map +1 -1
  139. package/dist/wasm/Ed25519.d.ts +35 -0
  140. package/dist/wasm/Ed25519.d.ts.map +1 -0
  141. package/dist/wasm/Ed25519.js +88 -0
  142. package/dist/wasm/Ed25519.js.map +1 -0
  143. package/dist/wasm/Engine.d.ts +71 -0
  144. package/dist/wasm/Engine.d.ts.map +1 -0
  145. package/dist/wasm/Engine.js +76 -0
  146. package/dist/wasm/Engine.js.map +1 -0
  147. package/dist/wasm/Hash.d.ts +43 -0
  148. package/dist/wasm/Hash.d.ts.map +1 -0
  149. package/dist/wasm/Hash.js +64 -0
  150. package/dist/wasm/Hash.js.map +1 -0
  151. package/dist/wasm/Keystore.d.ts +37 -0
  152. package/dist/wasm/Keystore.d.ts.map +1 -0
  153. package/dist/wasm/Keystore.js +34 -0
  154. package/dist/wasm/Keystore.js.map +1 -0
  155. package/dist/wasm/Mnemonic.d.ts +33 -0
  156. package/dist/wasm/Mnemonic.d.ts.map +1 -0
  157. package/dist/wasm/Mnemonic.js +30 -0
  158. package/dist/wasm/Mnemonic.js.map +1 -0
  159. package/dist/wasm/X25519.d.ts +33 -0
  160. package/dist/wasm/X25519.d.ts.map +1 -0
  161. package/dist/wasm/X25519.js +53 -0
  162. package/dist/wasm/X25519.js.map +1 -0
  163. package/dist/wasm/index.d.ts +115 -0
  164. package/dist/wasm/index.d.ts.map +1 -0
  165. package/dist/wasm/index.js +115 -0
  166. package/dist/wasm/index.js.map +1 -0
  167. package/dist/wasm/internal/blake3.d.ts +11 -0
  168. package/dist/wasm/internal/blake3.d.ts.map +1 -0
  169. package/dist/wasm/internal/blake3.js +31 -0
  170. package/dist/wasm/internal/blake3.js.map +1 -0
  171. package/dist/wasm/internal/blake3.wasm.d.ts +3 -0
  172. package/dist/wasm/internal/blake3.wasm.d.ts.map +1 -0
  173. package/dist/wasm/internal/blake3.wasm.js +10 -0
  174. package/dist/wasm/internal/blake3.wasm.js.map +1 -0
  175. package/dist/wasm/internal/crypto25519.d.ts +16 -0
  176. package/dist/wasm/internal/crypto25519.d.ts.map +1 -0
  177. package/dist/wasm/internal/crypto25519.js +5 -0
  178. package/dist/wasm/internal/crypto25519.js.map +1 -0
  179. package/dist/wasm/internal/crypto25519.wasm.d.ts +3 -0
  180. package/dist/wasm/internal/crypto25519.wasm.d.ts.map +1 -0
  181. package/dist/wasm/internal/crypto25519.wasm.js +10 -0
  182. package/dist/wasm/internal/crypto25519.wasm.js.map +1 -0
  183. package/dist/wasm/internal/ed25519.d.ts +4 -0
  184. package/dist/wasm/internal/ed25519.d.ts.map +1 -0
  185. package/dist/wasm/internal/ed25519.js +21 -0
  186. package/dist/wasm/internal/ed25519.js.map +1 -0
  187. package/dist/wasm/internal/hash.d.ts +9 -0
  188. package/dist/wasm/internal/hash.d.ts.map +1 -0
  189. package/dist/wasm/internal/hash.js +26 -0
  190. package/dist/wasm/internal/hash.js.map +1 -0
  191. package/dist/wasm/internal/hashes.d.ts +12 -0
  192. package/dist/wasm/internal/hashes.d.ts.map +1 -0
  193. package/dist/wasm/internal/hashes.js +8 -0
  194. package/dist/wasm/internal/hashes.js.map +1 -0
  195. package/dist/wasm/internal/hashes.wasm.d.ts +7 -0
  196. package/dist/wasm/internal/hashes.wasm.d.ts.map +1 -0
  197. package/dist/wasm/internal/hashes.wasm.js +14 -0
  198. package/dist/wasm/internal/hashes.wasm.js.map +1 -0
  199. package/dist/wasm/internal/instantiate.d.ts +56 -0
  200. package/dist/wasm/internal/instantiate.d.ts.map +1 -0
  201. package/dist/wasm/internal/instantiate.js +92 -0
  202. package/dist/wasm/internal/instantiate.js.map +1 -0
  203. package/dist/wasm/internal/mnemonic.d.ts +4 -0
  204. package/dist/wasm/internal/mnemonic.d.ts.map +1 -0
  205. package/dist/wasm/internal/mnemonic.js +45 -0
  206. package/dist/wasm/internal/mnemonic.js.map +1 -0
  207. package/dist/wasm/internal/pbkdf2.d.ts +12 -0
  208. package/dist/wasm/internal/pbkdf2.d.ts.map +1 -0
  209. package/dist/wasm/internal/pbkdf2.js +51 -0
  210. package/dist/wasm/internal/pbkdf2.js.map +1 -0
  211. package/dist/wasm/internal/x25519.d.ts +4 -0
  212. package/dist/wasm/internal/x25519.d.ts.map +1 -0
  213. package/dist/wasm/internal/x25519.js +21 -0
  214. package/dist/wasm/internal/x25519.js.map +1 -0
  215. package/dist/zod/TypedData.d.ts +12 -12
  216. package/package.json +81 -1
  217. package/src/core/Base64.ts +19 -166
  218. package/src/core/BinaryStateTree.ts +2 -3
  219. package/src/core/Bls.ts +27 -77
  220. package/src/core/Ed25519.ts +7 -7
  221. package/src/core/Engine.ts +308 -0
  222. package/src/core/Hash.ts +9 -12
  223. package/src/core/Keystore.ts +17 -17
  224. package/src/core/Mnemonic.ts +3 -6
  225. package/src/core/P256.ts +15 -24
  226. package/src/core/Rlp_tx.bench.ts +2 -4
  227. package/src/core/Secp256k1.ts +9 -14
  228. package/src/core/TxEnvelopeEip1559.bench.ts +0 -5
  229. package/src/core/WebCryptoP256.ts +2 -2
  230. package/src/core/X25519.ts +4 -3
  231. package/src/core/_test/AbiParameters.adversarial.fuzz.ts +1 -2
  232. package/src/core/_test/AbiParameters.fuzz.ts +1 -2
  233. package/src/core/_test/Base.fuzz.ts +1 -2
  234. package/src/core/_test/Cbor.fuzz.ts +1 -2
  235. package/src/core/_test/Engine.fuzz.ts +293 -0
  236. package/src/core/_test/Engine.test-d.ts +140 -0
  237. package/src/core/_test/Engine.test.ts +618 -0
  238. package/src/core/_test/Hash.vectors.test.ts +64 -0
  239. package/src/core/_test/Hex.fuzz.ts +1 -2
  240. package/src/core/_test/Rlp.fuzz.ts +1 -2
  241. package/src/core/_test/Signature.fuzz.ts +1 -2
  242. package/src/core/_test/curves.test.ts +7 -0
  243. package/src/core/_test/index.test.ts +1 -0
  244. package/src/core/internal/bls.ts +121 -0
  245. package/src/core/internal/codec/_test/base64.conformance.ts +156 -0
  246. package/src/core/internal/codec/_test/hex.conformance.ts +204 -0
  247. package/src/core/internal/codec/_test/hex.fuzz.ts +234 -0
  248. package/src/core/internal/codec/_test/hex.test.ts +124 -0
  249. package/src/core/internal/codec/base64.ts +222 -0
  250. package/src/core/internal/codec/hex.ts +115 -34
  251. package/src/core/internal/curves.ts +18 -0
  252. package/src/core/internal/ed25519.ts +64 -0
  253. package/src/core/internal/engine.ts +410 -0
  254. package/src/core/internal/hash.ts +48 -0
  255. package/src/core/internal/keystore.ts +107 -0
  256. package/src/core/internal/mnemonic.ts +18 -0
  257. package/src/core/internal/p256.ts +91 -0
  258. package/src/core/internal/secp256k1.ts +91 -0
  259. package/src/core/internal/x25519.ts +40 -0
  260. package/src/index.docs.ts +2 -0
  261. package/src/index.ts +39 -0
  262. package/src/node/Ed25519.ts +87 -0
  263. package/src/node/Engine.ts +125 -0
  264. package/src/node/Hash.ts +51 -0
  265. package/src/node/Keystore.ts +103 -0
  266. package/src/node/Mnemonic.ts +68 -0
  267. package/src/node/P256.ts +48 -0
  268. package/src/node/X25519.ts +93 -0
  269. package/src/node/_test/Curves.fuzz.ts +76 -0
  270. package/src/node/_test/Ed25519.test-d.ts +35 -0
  271. package/src/node/_test/Ed25519.test.ts +220 -0
  272. package/src/node/_test/Engine.test-d.ts +28 -0
  273. package/src/node/_test/Engine.test.ts +102 -0
  274. package/src/node/_test/Hash.test-d.ts +32 -0
  275. package/src/node/_test/Hash.test.ts +101 -0
  276. package/src/node/_test/Keystore.fuzz.ts +58 -0
  277. package/src/node/_test/Keystore.test-d.ts +43 -0
  278. package/src/node/_test/Keystore.test.ts +198 -0
  279. package/src/node/_test/Mnemonic.fuzz.ts +31 -0
  280. package/src/node/_test/Mnemonic.test-d.ts +21 -0
  281. package/src/node/_test/Mnemonic.test.ts +98 -0
  282. package/src/node/_test/P256.test-d.ts +29 -0
  283. package/src/node/_test/P256.test.ts +102 -0
  284. package/src/node/_test/X25519.test-d.ts +28 -0
  285. package/src/node/_test/X25519.test.ts +239 -0
  286. package/src/node/index.ts +132 -0
  287. package/src/tempo/VirtualMaster.test.ts +75 -0
  288. package/src/tempo/VirtualMaster.ts +28 -6
  289. package/src/tempo/internal/mine.wasm.ts +7 -13
  290. package/src/tempo/internal/virtualMasterPool.ts +4 -1
  291. package/src/tsconfig.json +2 -1
  292. package/src/version.ts +1 -1
  293. package/src/wasm/Ed25519.ts +114 -0
  294. package/src/wasm/Engine.ts +121 -0
  295. package/src/wasm/Hash.bench.ts +60 -0
  296. package/src/wasm/Hash.ts +88 -0
  297. package/src/wasm/Keystore.ts +48 -0
  298. package/src/wasm/Mnemonic.ts +44 -0
  299. package/src/wasm/X25519.ts +70 -0
  300. package/src/wasm/_test/Crypto25519.conformance.ts +57 -0
  301. package/src/wasm/_test/Crypto25519.fuzz.ts +187 -0
  302. package/src/wasm/_test/Ed25519.test-d.ts +28 -0
  303. package/src/wasm/_test/Ed25519.test.ts +168 -0
  304. package/src/wasm/_test/Ed25519.vectors.test.ts +73 -0
  305. package/src/wasm/_test/Engine.test-d.ts +28 -0
  306. package/src/wasm/_test/Engine.test.ts +96 -0
  307. package/src/wasm/_test/Hash.browser.test.ts +54 -0
  308. package/src/wasm/_test/Hash.fuzz.ts +223 -0
  309. package/src/wasm/_test/Hash.test-d.ts +33 -0
  310. package/src/wasm/_test/Hash.test.ts +311 -0
  311. package/src/wasm/_test/Hash.vectors.test.ts +124 -0
  312. package/src/wasm/_test/Keystore.browser.test.ts +42 -0
  313. package/src/wasm/_test/Keystore.fuzz.ts +113 -0
  314. package/src/wasm/_test/Keystore.test-d.ts +33 -0
  315. package/src/wasm/_test/Keystore.test.ts +192 -0
  316. package/src/wasm/_test/Keystore.vectors.test.ts +21 -0
  317. package/src/wasm/_test/Mnemonic.test-d.ts +17 -0
  318. package/src/wasm/_test/Mnemonic.test.ts +110 -0
  319. package/src/wasm/_test/Runtime.test.ts +21 -0
  320. package/src/wasm/_test/X25519.test-d.ts +21 -0
  321. package/src/wasm/_test/X25519.test.ts +194 -0
  322. package/src/wasm/_test/fixtures.ts +4 -0
  323. package/src/wasm/_test/runtime.wasm.ts +11 -0
  324. package/src/wasm/index.ts +120 -0
  325. package/src/wasm/internal/blake3.ts +45 -0
  326. package/src/wasm/internal/blake3.wasm.ts +11 -0
  327. package/src/wasm/internal/crypto25519.ts +43 -0
  328. package/src/wasm/internal/crypto25519.wasm.ts +11 -0
  329. package/src/wasm/internal/ed25519.ts +31 -0
  330. package/src/wasm/internal/hash.ts +50 -0
  331. package/src/wasm/internal/hashes.ts +29 -0
  332. package/src/wasm/internal/hashes.wasm.ts +17 -0
  333. package/src/wasm/internal/instantiate.ts +135 -0
  334. package/src/wasm/internal/mnemonic.ts +56 -0
  335. package/src/wasm/internal/pbkdf2.ts +86 -0
  336. package/src/wasm/internal/x25519.ts +29 -0
  337. package/src/tempo/internal/mine.c +0 -182
@@ -0,0 +1,44 @@
1
+ import type * as Engine from '../core/Engine.js'
2
+ import type * as Errors from '../core/Errors.js'
3
+ import * as crypto25519 from './internal/crypto25519.js'
4
+ import * as internal from './internal/instantiate.js'
5
+ import * as mnemonic from './internal/mnemonic.js'
6
+
7
+ export * from '../core/Mnemonic.js'
8
+ export { MemoryError } from './internal/instantiate.js'
9
+
10
+ /**
11
+ * Compiles the WASM implementation of [`Mnemonic.toSeed`](/api/Mnemonic/toSeed),
12
+ * without installing it.
13
+ *
14
+ * @example
15
+ * ```ts twoslash
16
+ * // @noErrors
17
+ * import { Engine } from 'ox'
18
+ * import { Mnemonic } from 'ox/wasm'
19
+ *
20
+ * await Engine.install({ Mnemonic: Mnemonic.engine() })
21
+ *
22
+ * Mnemonic.toSeed(
23
+ * 'test test test test test test test test test test test junk'
24
+ * )
25
+ * ```
26
+ *
27
+ * @returns The WASM implementation of the `Mnemonic` slot.
28
+ */
29
+ export async function engine(): Promise<engine.ReturnType> {
30
+ const module = await crypto25519.load()
31
+
32
+ return {
33
+ toSeed: (value, passphrase) => mnemonic.toSeed(module, value, passphrase),
34
+ }
35
+ }
36
+
37
+ export declare namespace engine {
38
+ /** Every `Mnemonic` primitive this module implements. */
39
+ type ReturnType = {
40
+ toSeed: NonNullable<Engine.Mnemonic['toSeed']>
41
+ }
42
+
43
+ type ErrorType = internal.MemoryError | Errors.GlobalErrorType
44
+ }
@@ -0,0 +1,70 @@
1
+ import type * as Engine from '../core/Engine.js'
2
+ import type * as Errors from '../core/Errors.js'
3
+ import * as crypto25519 from './internal/crypto25519.js'
4
+ import * as internal from './internal/instantiate.js'
5
+ import * as x25519 from './internal/x25519.js'
6
+
7
+ export * from '../core/X25519.js'
8
+ export { MemoryError } from './internal/instantiate.js'
9
+
10
+ const keySize = 32
11
+
12
+ /**
13
+ * Compiles WASM implementations of selected [`X25519`](/api/X25519)
14
+ * primitives, without installing them.
15
+ *
16
+ * Random key generation remains on Ox's default implementation.
17
+ *
18
+ * @example
19
+ * ```ts twoslash
20
+ * // @noErrors
21
+ * import { Engine } from 'ox'
22
+ * import { X25519 } from 'ox/wasm'
23
+ *
24
+ * await Engine.install({ X25519: X25519.engine() })
25
+ *
26
+ * X25519.getPublicKey({ privateKey: '0x...' })
27
+ * ```
28
+ *
29
+ * @returns The WASM implementation of part of the `X25519` slot.
30
+ */
31
+ export async function engine(): Promise<engine.ReturnType> {
32
+ const module = await crypto25519.load()
33
+
34
+ return {
35
+ getPublicKey(privateKey) {
36
+ assertLength(privateKey, 'private')
37
+ module.reserve(keySize * 2)
38
+ const privateKeyPtr = module.heapBase
39
+ const publicKeyPtr = privateKeyPtr + keySize
40
+ try {
41
+ module.view().set(privateKey, privateKeyPtr)
42
+ module.exports.x25519_get_public_key(privateKeyPtr, publicKeyPtr)
43
+ return module.view().slice(publicKeyPtr, publicKeyPtr + keySize)
44
+ } finally {
45
+ module.exports.zero(privateKeyPtr, keySize * 2)
46
+ }
47
+ },
48
+ getSharedSecret(privateKey, publicKey) {
49
+ assertLength(privateKey, 'private')
50
+ assertLength(publicKey, 'public')
51
+ return x25519.getSharedSecret(module, privateKey, publicKey)
52
+ },
53
+ }
54
+ }
55
+
56
+ export declare namespace engine {
57
+ /** Every `X25519` primitive this module implements. */
58
+ type ReturnType = {
59
+ [key in 'getPublicKey' | 'getSharedSecret']-?: NonNullable<Engine.Ecdh[key]>
60
+ }
61
+
62
+ type ErrorType = internal.MemoryError | Errors.GlobalErrorType
63
+ }
64
+
65
+ function assertLength(key: Uint8Array, type: 'private' | 'public'): void {
66
+ if (key.length !== keySize)
67
+ throw new RangeError(
68
+ `X25519 ${type} key must be ${keySize} bytes, got ${key.length}`,
69
+ )
70
+ }
@@ -0,0 +1,57 @@
1
+ import { ed25519, x25519 } from '@noble/curves/ed25519.js'
2
+ import { mnemonicToSeedSync } from '@scure/bip39'
3
+ import { describe, expect, test } from 'vp/test'
4
+ import { vectors } from '../../../test/vectors/bip39/index.js'
5
+ import * as Ed25519 from '../Ed25519.js'
6
+ import * as Mnemonic from '../Mnemonic.js'
7
+ import * as X25519 from '../X25519.js'
8
+
9
+ describe('crypto25519 WASM', () => {
10
+ test('behavior: Ed25519 works in this runtime', async () => {
11
+ const engine = await Ed25519.engine()
12
+ const privateKey = fromHex(
13
+ '9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60',
14
+ )
15
+ const payload = new TextEncoder().encode('browser conformance')
16
+ const publicKey = engine.getPublicKey(privateKey)
17
+ const signature = engine.sign(payload, privateKey)
18
+
19
+ expect(publicKey).toEqual(ed25519.getPublicKey(privateKey))
20
+ expect(signature).toEqual(ed25519.sign(payload, privateKey))
21
+ expect(engine.verify(signature, payload, publicKey)).toBe(true)
22
+ })
23
+
24
+ test('behavior: X25519 works in this runtime', async () => {
25
+ const engine = await X25519.engine()
26
+ const privateKey = fromHex(
27
+ '77076d0a7318a57d3c16c17251b26645df4c2f87ebc0992ab177fba51db92c2a',
28
+ )
29
+ const peerPrivateKey = fromHex(
30
+ '5dab087e624a8a4b79e17f8b83800ee66f3bb1292618b6fd1c2f8b27ff88e0eb',
31
+ )
32
+ const publicKey = x25519.getPublicKey(peerPrivateKey)
33
+
34
+ expect(engine.getPublicKey(privateKey)).toEqual(
35
+ x25519.getPublicKey(privateKey),
36
+ )
37
+ expect(engine.getSharedSecret(privateKey, publicKey)).toEqual(
38
+ x25519.getSharedSecret(privateKey, publicKey),
39
+ )
40
+ })
41
+
42
+ test('behavior: Unicode BIP-39 works in this runtime', async () => {
43
+ const engine = await Mnemonic.engine()
44
+ const vector = vectors.japanese
45
+
46
+ expect(engine.toSeed(vector.mnemonic, vector.passphrase)).toEqual(
47
+ mnemonicToSeedSync(vector.mnemonic, vector.passphrase),
48
+ )
49
+ })
50
+ })
51
+
52
+ function fromHex(value: string): Uint8Array {
53
+ const bytes = new Uint8Array(value.length / 2)
54
+ for (let index = 0; index < bytes.length; index++)
55
+ bytes[index] = Number.parseInt(value.slice(index * 2, index * 2 + 2), 16)
56
+ return bytes
57
+ }
@@ -0,0 +1,187 @@
1
+ import { fc, test } from '@fast-check/vitest'
2
+ import { ed25519, x25519 } from '@noble/curves/ed25519.js'
3
+ import { mnemonicToSeedSync } from '@scure/bip39'
4
+ import { beforeAll, describe, expect } from 'vp/test'
5
+ import { numRuns } from '../../../test/fuzz/numRuns.js'
6
+ import * as Ed25519 from '../Ed25519.js'
7
+ import * as Mnemonic from '../Mnemonic.js'
8
+ import * as X25519 from '../X25519.js'
9
+ import { x25519LowOrder } from './fixtures.js'
10
+
11
+ let ed25519Engine: Ed25519.engine.ReturnType
12
+ let mnemonicEngine: Mnemonic.engine.ReturnType
13
+ let x25519Engine: X25519.engine.ReturnType
14
+
15
+ beforeAll(async () => {
16
+ ed25519Engine = await Ed25519.engine()
17
+ mnemonicEngine = await Mnemonic.engine()
18
+ x25519Engine = await X25519.engine()
19
+ })
20
+
21
+ const arbitraryKey = fc.uint8Array({ maxLength: 32, minLength: 32 })
22
+ const arbitraryPayload = fc.oneof(
23
+ fc.uint8Array({ maxLength: 512 }),
24
+ fc
25
+ .constantFrom(0, 1, 31, 32, 63, 64, 65, 127, 128, 129, 1024, 4096)
26
+ .chain((size) => fc.uint8Array({ maxLength: size, minLength: size })),
27
+ )
28
+ const arbitraryWord = fc.oneof(
29
+ fc
30
+ .string({ maxLength: 16, minLength: 1 })
31
+ .filter((value) => !value.normalize('NFKD').includes(' ')),
32
+ fc.constantFrom('café', 'cafe\u0301', 'あおぞら', '㍍ガバヴァ'),
33
+ )
34
+ const arbitraryMnemonic = fc
35
+ .tuple(
36
+ fc.constantFrom(12, 15, 18, 21, 24),
37
+ fc.array(arbitraryWord, { maxLength: 24, minLength: 24 }),
38
+ )
39
+ .map(([count, words]) => words.slice(0, count).join(' '))
40
+
41
+ describe('Ed25519', () => {
42
+ test.prop(
43
+ { payload: arbitraryPayload, privateKey: arbitraryKey },
44
+ { numRuns },
45
+ )('matches the default for arbitrary subviews', (options) => {
46
+ const payload = offsetView(options.payload)
47
+ const privateKey = offsetView(options.privateKey)
48
+ const publicKey = ed25519Engine.getPublicKey(privateKey)
49
+ const signature = ed25519Engine.sign(payload, privateKey)
50
+
51
+ expect(publicKey).toEqual(ed25519.getPublicKey(privateKey))
52
+ expect(signature).toEqual(ed25519.sign(payload, privateKey))
53
+ expect(ed25519Engine.verify(signature, payload, publicKey)).toBe(true)
54
+ expect(
55
+ ed25519Engine.verify(signature, Uint8Array.of(...payload, 1), publicKey),
56
+ ).toBe(false)
57
+ expect(ed25519Engine.toMontgomerySecret(privateKey)).toEqual(
58
+ ed25519.utils.toMontgomerySecret(privateKey),
59
+ )
60
+ })
61
+
62
+ test.prop(
63
+ {
64
+ payload: arbitraryPayload,
65
+ publicKey: arbitraryKey,
66
+ signature: fc.uint8Array({ maxLength: 64, minLength: 64 }),
67
+ },
68
+ { numRuns },
69
+ )('verification matches ZIP-215 for arbitrary encodings', (options) => {
70
+ expect(
71
+ ed25519Engine.verify(
72
+ options.signature,
73
+ options.payload,
74
+ options.publicKey,
75
+ ),
76
+ ).toBe(
77
+ ed25519.verify(options.signature, options.payload, options.publicKey),
78
+ )
79
+ })
80
+ })
81
+
82
+ describe('X25519', () => {
83
+ test.prop(
84
+ { privateKey: arbitraryKey, publicKeySeed: arbitraryKey },
85
+ { numRuns },
86
+ )('matches the default for arbitrary subviews', (options) => {
87
+ const privateKey = offsetView(options.privateKey)
88
+ const publicKey = offsetView(x25519.getPublicKey(options.publicKeySeed))
89
+
90
+ expect(x25519Engine.getPublicKey(privateKey)).toEqual(
91
+ x25519.getPublicKey(privateKey),
92
+ )
93
+ expect(x25519Engine.getSharedSecret(privateKey, publicKey)).toEqual(
94
+ x25519.getSharedSecret(privateKey, publicKey),
95
+ )
96
+ })
97
+
98
+ test.prop(
99
+ {
100
+ highBit: fc.boolean(),
101
+ privateKey: arbitraryKey,
102
+ vector: fc.constantFrom(...x25519LowOrder),
103
+ },
104
+ { numRuns },
105
+ )(
106
+ 'rejects arbitrary private keys paired with low-order points',
107
+ (options) => {
108
+ const publicKey = fromHex(options.vector.publicKey)
109
+ if (options.highBit) publicKey[31]! |= 0x80
110
+ expect(() =>
111
+ x25519Engine.getSharedSecret(options.privateKey, publicKey),
112
+ ).toThrow()
113
+ },
114
+ )
115
+ })
116
+
117
+ describe('Mnemonic', () => {
118
+ test.prop(
119
+ {
120
+ mnemonic: arbitraryMnemonic,
121
+ passphrase: fc.string({ maxLength: 64 }),
122
+ },
123
+ { numRuns },
124
+ )('matches the default for arbitrary normalized text', (options) => {
125
+ expect(mnemonicEngine.toSeed(options.mnemonic, options.passphrase)).toEqual(
126
+ mnemonicToSeedSync(options.mnemonic, options.passphrase),
127
+ )
128
+ })
129
+ })
130
+
131
+ describe('memory', () => {
132
+ test.prop(
133
+ {
134
+ operations: fc.array(
135
+ fc.record({
136
+ payload: arbitraryPayload,
137
+ privateKey: arbitraryKey,
138
+ publicKeySeed: arbitraryKey,
139
+ }),
140
+ { maxLength: 8, minLength: 2 },
141
+ ),
142
+ },
143
+ { numRuns },
144
+ )(
145
+ 'interleaved providers remain isolated and outputs stay owned',
146
+ (options) => {
147
+ const held: Uint8Array[] = []
148
+ const snapshots: Uint8Array[] = []
149
+
150
+ for (const operation of options.operations) {
151
+ const edPublicKey = ed25519Engine.getPublicKey(operation.privateKey)
152
+ const signature = ed25519Engine.sign(
153
+ operation.payload,
154
+ operation.privateKey,
155
+ )
156
+ const xPublicKey = x25519.getPublicKey(operation.publicKeySeed)
157
+ const sharedSecret = x25519Engine.getSharedSecret(
158
+ operation.privateKey,
159
+ xPublicKey,
160
+ )
161
+ expect(
162
+ ed25519Engine.verify(signature, operation.payload, edPublicKey),
163
+ ).toBe(true)
164
+ expect(sharedSecret).toEqual(
165
+ x25519.getSharedSecret(operation.privateKey, xPublicKey),
166
+ )
167
+ held.push(signature, sharedSecret)
168
+ snapshots.push(signature.slice(), sharedSecret.slice())
169
+ }
170
+
171
+ expect(held).toEqual(snapshots)
172
+ },
173
+ )
174
+ })
175
+
176
+ function offsetView(value: Uint8Array): Uint8Array {
177
+ const bytes = new Uint8Array(value.length + 4).fill(0xff)
178
+ bytes.set(value, 2)
179
+ return bytes.subarray(2, -2)
180
+ }
181
+
182
+ function fromHex(value: string): Uint8Array {
183
+ const bytes = new Uint8Array(value.length / 2)
184
+ for (let index = 0; index < bytes.length; index++)
185
+ bytes[index] = Number.parseInt(value.slice(index * 2, index * 2 + 2), 16)
186
+ return bytes
187
+ }
@@ -0,0 +1,28 @@
1
+ import { expectTypeOf, test } from 'vp/test'
2
+ import type * as Engine from '../../core/Engine.js'
3
+ import * as core_Ed25519 from '../../core/Ed25519.js'
4
+ import * as Ed25519 from '../Ed25519.js'
5
+
6
+ type Slot = Awaited<ReturnType<typeof Ed25519.engine>>
7
+
8
+ test('return type exposes only implemented Ed25519 primitives', () => {
9
+ expectTypeOf<Slot['getPublicKey']>().toEqualTypeOf<
10
+ NonNullable<Engine.Eddsa['getPublicKey']>
11
+ >()
12
+ expectTypeOf<Slot['sign']>().toEqualTypeOf<
13
+ NonNullable<Engine.Eddsa['sign']>
14
+ >()
15
+ expectTypeOf<Slot['toMontgomerySecret']>().toEqualTypeOf<
16
+ NonNullable<Engine.Eddsa['toMontgomerySecret']>
17
+ >()
18
+ expectTypeOf<Slot['verify']>().toEqualTypeOf<
19
+ NonNullable<Engine.Eddsa['verify']>
20
+ >()
21
+ expectTypeOf<Slot>().not.toHaveProperty('randomSecretKey')
22
+ expectTypeOf<Slot>().not.toHaveProperty('toMontgomery')
23
+ })
24
+
25
+ test('the WASM namespace exposes the public Ed25519 API', () => {
26
+ expectTypeOf(Ed25519.getPublicKey).toEqualTypeOf(core_Ed25519.getPublicKey)
27
+ expectTypeOf<typeof Ed25519>().not.toHaveProperty('create')
28
+ })
@@ -0,0 +1,168 @@
1
+ import { ed25519 } from '@noble/curves/ed25519.js'
2
+ import { describe, expect, test } from 'vp/test'
3
+ import * as Ed25519 from '../Ed25519.js'
4
+ import * as crypto25519 from '../internal/crypto25519.js'
5
+ import { wasmBase64 } from '../internal/crypto25519.wasm.js'
6
+ import * as ed25519_internal from '../internal/ed25519.js'
7
+ import * as internal from '../internal/instantiate.js'
8
+
9
+ const privateKey = fromHex(
10
+ '9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60',
11
+ )
12
+
13
+ describe('engine', () => {
14
+ test('behavior: exposes only semantics-compatible primitives', async () => {
15
+ const engine = await Ed25519.engine()
16
+
17
+ expect(Object.keys(engine).sort()).toMatchInlineSnapshot(`
18
+ [
19
+ "getPublicKey",
20
+ "sign",
21
+ "toMontgomerySecret",
22
+ "verify",
23
+ ]
24
+ `)
25
+ })
26
+
27
+ test('behavior: signs and verifies boundary-sized messages', async () => {
28
+ const engine = await Ed25519.engine()
29
+
30
+ for (const size of [0, 1, 31, 32, 63, 64, 65, 127, 128, 129, 1024]) {
31
+ const payload = Uint8Array.from(
32
+ { length: size },
33
+ (_, index) => (index * 29 + size) % 251,
34
+ )
35
+ const signature = engine.sign(payload, privateKey)
36
+ const publicKey = engine.getPublicKey(privateKey)
37
+
38
+ expect(signature).toEqual(ed25519.sign(payload, privateKey))
39
+ expect(engine.verify(signature, payload, publicKey)).toBe(true)
40
+ expect(
41
+ engine.verify(signature, Uint8Array.of(...payload, 1), publicKey),
42
+ ).toBe(false)
43
+ }
44
+ })
45
+
46
+ test('behavior: matches private-key conversion', async () => {
47
+ const engine = await Ed25519.engine()
48
+
49
+ expect(engine.toMontgomerySecret(privateKey)).toEqual(
50
+ ed25519.utils.toMontgomerySecret(privateKey),
51
+ )
52
+ })
53
+
54
+ test('behavior: respects subviews and leaves inputs immutable', async () => {
55
+ const engine = await Ed25519.engine()
56
+ const key = offsetView(privateKey)
57
+ const payload = offsetView(new Uint8Array(257).fill(0xa5))
58
+ const keyBefore = key.slice()
59
+ const payloadBefore = payload.slice()
60
+ const publicKey = offsetView(engine.getPublicKey(key))
61
+ const signature = offsetView(engine.sign(payload, key))
62
+ const publicKeyBefore = publicKey.slice()
63
+ const signatureBefore = signature.slice()
64
+
65
+ expect(engine.getPublicKey(key)).toEqual(ed25519.getPublicKey(key))
66
+ expect(engine.verify(signature, payload, publicKey)).toBe(true)
67
+ expect(engine.toMontgomerySecret(key)).toEqual(
68
+ ed25519.utils.toMontgomerySecret(key),
69
+ )
70
+ expect({ key, payload, publicKey, signature }).toEqual({
71
+ key: keyBefore,
72
+ payload: payloadBefore,
73
+ publicKey: publicKeyBefore,
74
+ signature: signatureBefore,
75
+ })
76
+ })
77
+
78
+ test('behavior: rejects malformed key and signature lengths', async () => {
79
+ const engine = await Ed25519.engine()
80
+ const publicKey = engine.getPublicKey(privateKey)
81
+
82
+ for (const size of [0, 1, 31, 33, 63, 64]) {
83
+ if (size !== 32) {
84
+ expect(() => engine.getPublicKey(new Uint8Array(size))).toThrowError(
85
+ `Ed25519 private key must be 32 bytes, got ${size}`,
86
+ )
87
+ expect(() =>
88
+ engine.sign(new Uint8Array(), new Uint8Array(size)),
89
+ ).toThrowError(`Ed25519 private key must be 32 bytes, got ${size}`)
90
+ }
91
+ if (size !== 64)
92
+ expect(() =>
93
+ engine.verify(new Uint8Array(size), new Uint8Array(), publicKey),
94
+ ).toThrowError(`Ed25519 signature must be 64 bytes, got ${size}`)
95
+ }
96
+
97
+ expect(() =>
98
+ engine.verify(new Uint8Array(64), new Uint8Array(), new Uint8Array(31)),
99
+ ).toThrowError('Ed25519 public key must be 32 bytes, got 31')
100
+ })
101
+
102
+ test('behavior: outputs are owned across calls and memory growth', async () => {
103
+ const engine = await Ed25519.engine()
104
+ const publicKey = engine.getPublicKey(privateKey)
105
+ const signature = engine.sign(new Uint8Array(), privateKey)
106
+ const snapshots = [publicKey.slice(), signature.slice()]
107
+
108
+ engine.sign(new Uint8Array(1024 * 1024).fill(0x5a), privateKey)
109
+
110
+ expect([publicKey, signature]).toEqual(snapshots)
111
+ expect(engine.getPublicKey(privateKey) === publicKey).toBe(false)
112
+ })
113
+
114
+ test('behavior: clears the shared staging region', async () => {
115
+ const engine = await Ed25519.engine()
116
+ const payload = new Uint8Array(1024).fill(0xa5)
117
+ engine.sign(payload, privateKey)
118
+
119
+ const module = await crypto25519.load()
120
+ const size = 32 + payload.length + 64
121
+ expect(
122
+ module
123
+ .view()
124
+ .subarray(module.heapBase, module.heapBase + size)
125
+ .every((byte) => byte === 0),
126
+ ).toBe(true)
127
+ })
128
+
129
+ test('behavior: clears the complete region after a late trap', async () => {
130
+ const module = await internal.instantiate<crypto25519.Exports>(wasmBase64)
131
+ const payload = new Uint8Array(1024).fill(0xa5)
132
+ const exports: crypto25519.Exports = {
133
+ ...module.exports,
134
+ ed25519_sign(...parameters) {
135
+ module.exports.ed25519_sign(...parameters)
136
+ throw new WebAssembly.RuntimeError('forced late trap')
137
+ },
138
+ }
139
+
140
+ expect(() =>
141
+ ed25519_internal.sign({ ...module, exports }, payload, privateKey),
142
+ ).toThrow(WebAssembly.RuntimeError)
143
+ expect(
144
+ module
145
+ .view()
146
+ .subarray(module.heapBase, module.heapBase + 32 + payload.length + 64)
147
+ .every((byte) => byte === 0),
148
+ ).toBe(true)
149
+ })
150
+
151
+ test('behavior: rejects a workspace beyond wasm32 without growing', async () => {
152
+ const module = await internal.instantiate<crypto25519.Exports>(wasmBase64)
153
+ const memory = module.view().length
154
+
155
+ expect(() => module.reserve(0x1_0000_0000)).toThrow(internal.MemoryError)
156
+ expect(module.view()).toHaveLength(memory)
157
+ })
158
+ })
159
+
160
+ function fromHex(value: string): Uint8Array {
161
+ return Uint8Array.from(Buffer.from(value, 'hex'))
162
+ }
163
+
164
+ function offsetView(value: Uint8Array): Uint8Array {
165
+ const bytes = new Uint8Array(value.length + 4).fill(0xff)
166
+ bytes.set(value, 2)
167
+ return bytes.subarray(2, -2)
168
+ }
@@ -0,0 +1,73 @@
1
+ import * as fs from 'node:fs'
2
+ import { describe, expect, test } from 'vp/test'
3
+ import * as Ed25519 from '../Ed25519.js'
4
+
5
+ type Zip215Vector = {
6
+ sig_bytes: string
7
+ valid_legacy: boolean
8
+ valid_zip215: boolean
9
+ vk_bytes: string
10
+ }
11
+
12
+ const zip215 = JSON.parse(
13
+ fs.readFileSync(
14
+ new URL('../../../test/vectors/ed25519/zip215.json', import.meta.url),
15
+ 'utf8',
16
+ ),
17
+ ) as readonly Zip215Vector[]
18
+
19
+ const rfc8032 = [
20
+ {
21
+ message: '',
22
+ publicKey:
23
+ 'd75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a',
24
+ seed: '9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60',
25
+ signature:
26
+ 'e5564300c360ac729086e2cc806e828a84877f1eb8e5d974d873e065224901555fb8821590a33bacc61e39701cf9b46bd25bf5f0595bbe24655141438e7a100b',
27
+ },
28
+ {
29
+ message: '72',
30
+ publicKey:
31
+ '3d4017c3e843895a92b70aa74d1b7ebc9c982ccf2ec4968cc0cd55f12af4660c',
32
+ seed: '4ccd089b28ff96da9db6c346ec114e0f5b8a319f35aba624da8cf6ed4fb8a6fb',
33
+ signature:
34
+ '92a009a9f0d4cab8720e820b5f642540a2b27b5416503f8fb3762223ebdb69da085ac1e43e15996e458f3613d0f11d8c387b2eaeb4302aeeb00d291612bb0c00',
35
+ },
36
+ ] as const
37
+
38
+ describe('engine', () => {
39
+ test('vectors: matches RFC 8032 key, signature, and verification cases', async () => {
40
+ const engine = await Ed25519.engine()
41
+
42
+ for (const vector of rfc8032) {
43
+ const seed = fromHex(vector.seed)
44
+ const message = fromHex(vector.message)
45
+ const publicKey = fromHex(vector.publicKey)
46
+ const signature = fromHex(vector.signature)
47
+
48
+ expect(engine.getPublicKey(seed)).toEqual(publicKey)
49
+ expect(engine.sign(message, seed)).toEqual(signature)
50
+ expect(engine.verify(signature, message, publicKey)).toBe(true)
51
+ }
52
+ })
53
+
54
+ test('vectors: matches all 196 ZIP-215 compliance cases', async () => {
55
+ const engine = await Ed25519.engine()
56
+ const message = new TextEncoder().encode('Zcash')
57
+
58
+ expect(zip215).toHaveLength(196)
59
+ for (const vector of zip215)
60
+ expect(
61
+ engine.verify(
62
+ fromHex(vector.sig_bytes),
63
+ message,
64
+ fromHex(vector.vk_bytes),
65
+ ),
66
+ JSON.stringify(vector),
67
+ ).toBe(vector.valid_zip215)
68
+ })
69
+ })
70
+
71
+ function fromHex(value: string): Uint8Array {
72
+ return Uint8Array.from(Buffer.from(value, 'hex'))
73
+ }
@@ -0,0 +1,28 @@
1
+ import { Engine } from 'ox/wasm'
2
+ import { expectTypeOf, test } from 'vp/test'
3
+ import * as CoreEngine from '../../core/Engine.js'
4
+
5
+ type Installed = Awaited<ReturnType<typeof Engine.install>>
6
+ type Uninstalled = Awaited<ReturnType<typeof Engine.engine>>
7
+
8
+ test('install and engine expose the same precise engine', () => {
9
+ expectTypeOf<Installed>().toEqualTypeOf<Uninstalled>()
10
+ expectTypeOf<Installed['Hash']['sha256']>().toEqualTypeOf<
11
+ (input: Uint8Array) => Uint8Array
12
+ >()
13
+ })
14
+
15
+ test('the WASM Engine namespace exposes synchronous core operations', () => {
16
+ expectTypeOf(Engine.get).toEqualTypeOf(CoreEngine.get)
17
+ expectTypeOf(Engine.InvalidSlotValueError).toEqualTypeOf(
18
+ CoreEngine.InvalidSlotValueError,
19
+ )
20
+ expectTypeOf(Engine.reset).toEqualTypeOf(CoreEngine.reset)
21
+ expectTypeOf(Engine.set).toEqualTypeOf(CoreEngine.set)
22
+ expectTypeOf(Engine.with).toEqualTypeOf(CoreEngine.with)
23
+ })
24
+
25
+ test('the replaced aliases are absent', () => {
26
+ expectTypeOf<typeof Engine>().not.toHaveProperty('create')
27
+ expectTypeOf<typeof Engine>().not.toHaveProperty('load')
28
+ })