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
@@ -1,40 +1,67 @@
1
1
  import * as CoreEngine from '../core/Engine.js'
2
2
  import type * as Errors from '../core/Errors.js'
3
+ import * as Ed25519 from './Ed25519.js'
3
4
  import * as Hash from './Hash.js'
5
+ import * as Keystore from './Keystore.js'
6
+ import * as Mnemonic from './Mnemonic.js'
7
+ import * as P256 from './P256.js'
8
+ import * as X25519 from './X25519.js'
9
+
10
+ export {
11
+ AsyncScopeError,
12
+ get,
13
+ InvalidSlotValueError,
14
+ reset,
15
+ set,
16
+ UnknownPrimitiveError,
17
+ UnknownSlotError,
18
+ with,
19
+ } from '../core/Engine.js'
20
+ export type {
21
+ Bls,
22
+ Ecdh,
23
+ Ecdsa,
24
+ Eddsa,
25
+ Engine,
26
+ Hash,
27
+ Keystore,
28
+ Mnemonic,
29
+ } from '../core/Engine.js'
4
30
 
5
31
  /**
6
- * Creates and installs every Node.js implementation this entrypoint provides.
32
+ * Installs every Node.js implementation this entrypoint provides.
7
33
  *
8
- * The function is asynchronous to match the `ox/wasm` entrypoint, even though
9
- * Node's built-in cryptography needs no compilation. Call it once during
10
- * startup, before any cryptographic operation.
34
+ * Slots initialize in parallel and are installed atomically. Call this once
35
+ * during startup, before any cryptographic operation.
11
36
  *
12
37
  * @example
13
38
  * ```ts twoslash
14
39
  * // @noErrors
15
- * import { Hash } from 'ox'
16
- * import { Engine } from 'ox/node'
40
+ * import { Engine, Hash } from 'ox/node'
17
41
  *
18
- * await Engine.load()
42
+ * await Engine.install()
19
43
  *
20
44
  * Hash.sha256('0xdeadbeef')
21
45
  * ```
22
46
  *
23
47
  * @returns The engine that was installed.
24
48
  */
25
- export async function load(): Promise<load.ReturnType> {
26
- const engine = await create()
27
- CoreEngine.set(engine)
28
- return engine
49
+ export function install(): Promise<install.ReturnType> {
50
+ return CoreEngine.install({
51
+ Ed25519: Ed25519.engine(),
52
+ Hash: Hash.engine(),
53
+ Keystore: Keystore.engine(),
54
+ Mnemonic: Mnemonic.engine(),
55
+ P256: P256.engine(),
56
+ X25519: X25519.engine(),
57
+ })
29
58
  }
30
59
 
31
- export declare namespace load {
32
- type ReturnType = create.ReturnType
60
+ export declare namespace install {
61
+ /** Every slot this entrypoint installs, each with its primitives present. */
62
+ type ReturnType = engine.ReturnType
33
63
 
34
- type ErrorType =
35
- | create.ErrorType
36
- | CoreEngine.set.ErrorType
37
- | Errors.GlobalErrorType
64
+ type ErrorType = engine.ErrorType | CoreEngine.install.ErrorType
38
65
  }
39
66
 
40
67
  /**
@@ -50,20 +77,49 @@ export declare namespace load {
50
77
  * import { Engine, Hash } from 'ox'
51
78
  * import { Engine as NodeEngine } from 'ox/node'
52
79
  *
53
- * const node = await NodeEngine.create()
80
+ * const node = await NodeEngine.engine()
54
81
  *
55
82
  * Engine.with(node, () => Hash.sha256('0xdeadbeef'))
56
83
  * ```
57
84
  *
58
85
  * @returns An engine, ready to install.
59
86
  */
60
- export async function create(): Promise<create.ReturnType> {
61
- return { ...(await Hash.create()) }
87
+ export async function engine(): Promise<engine.ReturnType> {
88
+ const [ed25519, hash, keystore, mnemonic, p256, x25519] = await Promise.all([
89
+ Ed25519.engine(),
90
+ Hash.engine(),
91
+ Keystore.engine(),
92
+ Mnemonic.engine(),
93
+ P256.engine(),
94
+ X25519.engine(),
95
+ ])
96
+ return {
97
+ Ed25519: ed25519,
98
+ Hash: hash,
99
+ Keystore: keystore,
100
+ Mnemonic: mnemonic,
101
+ P256: p256,
102
+ X25519: x25519,
103
+ }
62
104
  }
63
105
 
64
- export declare namespace create {
106
+ export declare namespace engine {
65
107
  /** Every slot this entrypoint supplies, each with its primitives present. */
66
- type ReturnType = Hash.create.ReturnType
108
+ type ReturnType = {
109
+ Ed25519: Ed25519.engine.ReturnType
110
+ Hash: Hash.engine.ReturnType
111
+ Keystore: Keystore.engine.ReturnType
112
+ Mnemonic: Mnemonic.engine.ReturnType
113
+ P256: P256.engine.ReturnType
114
+ X25519: X25519.engine.ReturnType
115
+ }
67
116
 
68
- type ErrorType = Hash.create.ErrorType | Errors.GlobalErrorType
117
+ type ErrorType =
118
+ | Ed25519.engine.ErrorType
119
+ | Hash.engine.ErrorType
120
+ | Keystore.engine.ErrorType
121
+ | Mnemonic.engine.ErrorType
122
+ | P256.engine.ErrorType
123
+ | X25519.engine.ErrorType
124
+ | Errors.GlobalErrorType
69
125
  }
package/src/node/Hash.ts CHANGED
@@ -2,54 +2,49 @@ import * as crypto from 'node:crypto'
2
2
  import type * as Engine from '../core/Engine.js'
3
3
  import type * as Errors from '../core/Errors.js'
4
4
 
5
+ export * from '../core/Hash.js'
6
+
5
7
  /**
6
- * Creates Node.js implementations of the [`Hash`](/api/Hash) primitives, without
7
- * installing them.
8
+ * Creates a Node.js implementation of the [`Hash`](/api/Hash) engine slot,
9
+ * without installing it.
8
10
  *
9
- * Most callers want {@link ox#Engine.load} instead, which installs every
10
- * implementation this entrypoint provides. Reach for this to take the `Hash`
11
- * slot on its own, or to hold the implementation without touching the
12
- * installed engine.
11
+ * Most callers want [`Engine.install`](/node/crypto/Engine/install) instead,
12
+ * which installs every implementation this entrypoint provides. Reach for this
13
+ * to install or hold the `Hash` slot on its own.
13
14
  *
14
- * Node's `sha3-256` is not Ethereum Keccak256, so this engine deliberately
15
- * omits `keccak256`. Any earlier override remains installed; otherwise Ox uses
16
- * its default implementation.
15
+ * Node does not provide BLAKE3, and its `sha3-256` is not Ethereum Keccak256, so
16
+ * this engine deliberately omits `blake3` and `keccak256`. Any earlier override
17
+ * remains installed; otherwise Ox uses its default implementation.
17
18
  *
18
19
  * @example
19
20
  * ```ts twoslash
20
21
  * // @noErrors
21
- * import { Engine, Hash } from 'ox'
22
- * import * as NodeHash from 'ox/node/Hash'
22
+ * import { Engine } from 'ox'
23
+ * import { Hash } from 'ox/node'
23
24
  *
24
- * Engine.set(await NodeHash.create())
25
+ * await Engine.install({ Hash: Hash.engine() })
25
26
  *
26
27
  * Hash.sha256('0xdeadbeef')
27
28
  * ```
28
29
  *
29
- * @returns An engine supplying the `Hash` slot.
30
+ * @returns The raw `Hash` engine slot.
30
31
  */
31
- export function create(): Promise<create.ReturnType> {
32
+ export function engine(): Promise<engine.ReturnType> {
32
33
  return Promise.resolve({
33
- Hash: {
34
- hmacSha256: (key, message) =>
35
- new Uint8Array(
36
- crypto.createHmac('sha256', key).update(message).digest(),
37
- ),
38
- ripemd160: (input) =>
39
- new Uint8Array(crypto.hash('ripemd160', input, 'buffer')),
40
- sha256: (input) => new Uint8Array(crypto.hash('sha256', input, 'buffer')),
41
- },
34
+ hmacSha256: (key, message) =>
35
+ new Uint8Array(crypto.createHmac('sha256', key).update(message).digest()),
36
+ ripemd160: (input) =>
37
+ new Uint8Array(crypto.hash('ripemd160', input, 'buffer')),
38
+ sha256: (input) => new Uint8Array(crypto.hash('sha256', input, 'buffer')),
42
39
  })
43
40
  }
44
41
 
45
- export declare namespace create {
46
- /** The `Hash` slot, carrying every primitive this module implements. */
42
+ export declare namespace engine {
43
+ /** Every `Hash` primitive this module implements. */
47
44
  type ReturnType = {
48
- Hash: {
49
- [key in 'hmacSha256' | 'ripemd160' | 'sha256']-?: NonNullable<
50
- Engine.Hash[key]
51
- >
52
- }
45
+ [key in 'hmacSha256' | 'ripemd160' | 'sha256']-?: NonNullable<
46
+ Engine.Hash[key]
47
+ >
53
48
  }
54
49
 
55
50
  type ErrorType = Errors.GlobalErrorType
@@ -0,0 +1,103 @@
1
+ import * as crypto from 'node:crypto'
2
+ import type * as Engine from '../core/Engine.js'
3
+ import type * as Errors from '../core/Errors.js'
4
+
5
+ export * from '../core/Keystore.js'
6
+
7
+ /**
8
+ * Creates a Node.js implementation of the [`Keystore`](/api/Keystore) engine
9
+ * slot, without installing it.
10
+ *
11
+ * Most callers want [`Engine.install`](/node/crypto/Engine/install) instead,
12
+ * which installs every implementation this entrypoint provides. Reach for this
13
+ * to install or hold the `Keystore` slot on its own.
14
+ *
15
+ * This engine deliberately omits scrypt. OpenSSL rejects Ox's default scrypt
16
+ * parameter shape, so installing it would make valid existing calls fail.
17
+ *
18
+ * @example
19
+ * ```ts twoslash
20
+ * // @noErrors
21
+ * import { Engine } from 'ox'
22
+ * import { Keystore } from 'ox/node'
23
+ *
24
+ * await Engine.install({ Keystore: Keystore.engine() })
25
+ *
26
+ * Keystore.pbkdf2({ password: 'testpassword' })
27
+ * ```
28
+ *
29
+ * @returns The raw `Keystore` engine slot.
30
+ */
31
+ export function engine(): Promise<engine.ReturnType> {
32
+ return Promise.resolve({
33
+ aesCtrDecrypt: (key, iv, data) => {
34
+ const cipher = crypto.createDecipheriv(
35
+ `aes-${key.length * 8}-ctr`,
36
+ key,
37
+ iv,
38
+ )
39
+ return cipherData(cipher, data)
40
+ },
41
+ aesCtrEncrypt: (key, iv, data) => {
42
+ const cipher = crypto.createCipheriv(`aes-${key.length * 8}-ctr`, key, iv)
43
+ return cipherData(cipher, data)
44
+ },
45
+ pbkdf2Sha256: (password, salt, options) =>
46
+ copyAndClear(
47
+ crypto.pbkdf2Sync(password, salt, options.c, options.dkLen, 'sha256'),
48
+ ),
49
+ pbkdf2Sha256Async: (password, salt, options) =>
50
+ new Promise((resolve, reject) => {
51
+ crypto.pbkdf2(
52
+ password,
53
+ salt,
54
+ options.c,
55
+ options.dkLen,
56
+ 'sha256',
57
+ (error, key) => {
58
+ if (error) return reject(error)
59
+ try {
60
+ resolve(copyAndClear(key))
61
+ } catch (error) {
62
+ reject(error)
63
+ }
64
+ },
65
+ )
66
+ }),
67
+ })
68
+ }
69
+
70
+ export declare namespace engine {
71
+ /** Every `Keystore` primitive this module implements. */
72
+ type ReturnType = {
73
+ [key in
74
+ | 'aesCtrDecrypt'
75
+ | 'aesCtrEncrypt'
76
+ | 'pbkdf2Sha256'
77
+ | 'pbkdf2Sha256Async']-?: NonNullable<Engine.Keystore[key]>
78
+ }
79
+
80
+ type ErrorType = Errors.GlobalErrorType
81
+ }
82
+
83
+ function cipherData(
84
+ cipher: crypto.Cipheriv | crypto.Decipheriv,
85
+ data: Uint8Array,
86
+ ): Uint8Array {
87
+ const chunks: Buffer[] = []
88
+ try {
89
+ chunks.push(cipher.update(data))
90
+ chunks.push(cipher.final())
91
+ return copyAndClear(Buffer.concat(chunks))
92
+ } finally {
93
+ for (const chunk of chunks) chunk.fill(0)
94
+ }
95
+ }
96
+
97
+ function copyAndClear(value: Buffer): Uint8Array {
98
+ try {
99
+ return Uint8Array.from(value)
100
+ } finally {
101
+ value.fill(0)
102
+ }
103
+ }
@@ -0,0 +1,68 @@
1
+ import * as crypto from 'node:crypto'
2
+ import type * as Engine from '../core/Engine.js'
3
+ import type * as Errors from '../core/Errors.js'
4
+
5
+ export * from '../core/Mnemonic.js'
6
+
7
+ /**
8
+ * Creates a Node.js implementation of the [`Mnemonic`](/api/Mnemonic) engine
9
+ * slot, without installing it.
10
+ *
11
+ * Most callers want [`Engine.install`](/node/crypto/Engine/install) instead,
12
+ * which installs every implementation this entrypoint provides. Reach for this
13
+ * to install or hold the `Mnemonic` slot on its own.
14
+ *
15
+ * @example
16
+ * ```ts twoslash
17
+ * // @noErrors
18
+ * import { Engine } from 'ox'
19
+ * import { Mnemonic } from 'ox/node'
20
+ *
21
+ * await Engine.install({ Mnemonic: Mnemonic.engine() })
22
+ *
23
+ * Mnemonic.toSeed(
24
+ * 'test test test test test test test test test test test junk'
25
+ * )
26
+ * ```
27
+ *
28
+ * @returns The raw `Mnemonic` engine slot.
29
+ */
30
+ export function engine(): Promise<engine.ReturnType> {
31
+ return Promise.resolve({
32
+ toSeed: (mnemonic, passphrase = '') => {
33
+ if (typeof mnemonic !== 'string')
34
+ throw new TypeError(`invalid mnemonic type: ${typeof mnemonic}`)
35
+
36
+ const normalized = mnemonic.normalize('NFKD')
37
+ if (![12, 15, 18, 21, 24].includes(normalized.split(' ').length))
38
+ throw new Error('Invalid mnemonic')
39
+
40
+ return copyAndClear(
41
+ crypto.pbkdf2Sync(
42
+ normalized,
43
+ `mnemonic${passphrase}`.normalize('NFKD'),
44
+ 2048,
45
+ 64,
46
+ 'sha512',
47
+ ),
48
+ )
49
+ },
50
+ })
51
+ }
52
+
53
+ export declare namespace engine {
54
+ /** Every `Mnemonic` primitive this module implements. */
55
+ type ReturnType = {
56
+ [key in 'toSeed']-?: NonNullable<Engine.Mnemonic[key]>
57
+ }
58
+
59
+ type ErrorType = Errors.GlobalErrorType
60
+ }
61
+
62
+ function copyAndClear(value: Buffer): Uint8Array {
63
+ try {
64
+ return Uint8Array.from(value)
65
+ } finally {
66
+ value.fill(0)
67
+ }
68
+ }
@@ -0,0 +1,48 @@
1
+ import * as crypto from 'node:crypto'
2
+ import type * as Engine from '../core/Engine.js'
3
+ import type * as Errors from '../core/Errors.js'
4
+
5
+ export * from '../core/P256.js'
6
+
7
+ /**
8
+ * Creates a Node.js implementation of the [`P256`](/api/P256) engine slot,
9
+ * without installing it.
10
+ *
11
+ * Node's other P256 operations do not reproduce Ox's recovered-signature and
12
+ * compressed-shared-point contracts, so they remain on Ox's defaults.
13
+ *
14
+ * @example
15
+ * ```ts twoslash
16
+ * // @noErrors
17
+ * import { Engine } from 'ox'
18
+ * import { P256 } from 'ox/node'
19
+ *
20
+ * await Engine.install({ P256: P256.engine() })
21
+ *
22
+ * P256.getPublicKey({ privateKey: '0x...' })
23
+ * ```
24
+ *
25
+ * @returns The raw `P256` engine slot.
26
+ */
27
+ export function engine(): Promise<engine.ReturnType> {
28
+ return Promise.resolve({
29
+ getPublicKey: (privateKey) => {
30
+ if (privateKey.length !== 32)
31
+ throw new RangeError(
32
+ `P256 private key must be 32 bytes, got ${privateKey.length}`,
33
+ )
34
+ const ecdh = crypto.createECDH('prime256v1')
35
+ ecdh.setPrivateKey(privateKey)
36
+ return new Uint8Array(ecdh.getPublicKey(undefined, 'uncompressed'))
37
+ },
38
+ })
39
+ }
40
+
41
+ export declare namespace engine {
42
+ /** Every `P256` primitive this module implements. */
43
+ type ReturnType = {
44
+ getPublicKey: NonNullable<Engine.Ecdsa['getPublicKey']>
45
+ }
46
+
47
+ type ErrorType = Errors.GlobalErrorType
48
+ }
@@ -0,0 +1,93 @@
1
+ import * as crypto from 'node:crypto'
2
+ import type * as Engine from '../core/Engine.js'
3
+ import type * as Errors from '../core/Errors.js'
4
+
5
+ export * from '../core/X25519.js'
6
+
7
+ const privateKeyPrefix = Buffer.from('302e020100300506032b656e04220420', 'hex')
8
+ const publicKeyPrefix = Buffer.from('302a300506032b656e032100', 'hex')
9
+
10
+ /**
11
+ * Creates a Node.js implementation of the [`X25519`](/api/X25519) engine slot,
12
+ * without installing it.
13
+ *
14
+ * Random key generation remains on Ox's default implementation.
15
+ *
16
+ * @example
17
+ * ```ts twoslash
18
+ * // @noErrors
19
+ * import { Engine } from 'ox'
20
+ * import { X25519 } from 'ox/node'
21
+ *
22
+ * await Engine.install({ X25519: X25519.engine() })
23
+ *
24
+ * X25519.getPublicKey({ privateKey: '0x...' })
25
+ * ```
26
+ *
27
+ * @returns The raw `X25519` engine slot.
28
+ */
29
+ export function engine(): Promise<engine.ReturnType> {
30
+ return Promise.resolve({
31
+ getPublicKey: (privateKey) =>
32
+ rawPublicKey(crypto.createPublicKey(toPrivateKey(privateKey))),
33
+ getSharedSecret: (privateKey, publicKey) =>
34
+ copyAndClear(
35
+ crypto.diffieHellman({
36
+ privateKey: toPrivateKey(privateKey),
37
+ publicKey: toPublicKey(publicKey),
38
+ }),
39
+ ),
40
+ })
41
+ }
42
+
43
+ export declare namespace engine {
44
+ /** Every `X25519` primitive this module implements. */
45
+ type ReturnType = {
46
+ [key in 'getPublicKey' | 'getSharedSecret']-?: NonNullable<Engine.Ecdh[key]>
47
+ }
48
+
49
+ type ErrorType = Errors.GlobalErrorType
50
+ }
51
+
52
+ function copyAndClear(value: Buffer): Uint8Array {
53
+ try {
54
+ return Uint8Array.from(value)
55
+ } finally {
56
+ value.fill(0)
57
+ }
58
+ }
59
+
60
+ function assertLength(key: Uint8Array, type: 'private' | 'public'): void {
61
+ if (key.length !== 32)
62
+ throw new RangeError(
63
+ `X25519 ${type} key must be 32 bytes, got ${key.length}`,
64
+ )
65
+ }
66
+
67
+ function rawPublicKey(publicKey: crypto.KeyObject): Uint8Array {
68
+ const der = publicKey.export({ format: 'der', type: 'spki' })
69
+ return Uint8Array.from(der.subarray(-32))
70
+ }
71
+
72
+ function toPrivateKey(privateKey: Uint8Array): crypto.KeyObject {
73
+ assertLength(privateKey, 'private')
74
+ const der = Buffer.concat([privateKeyPrefix, privateKey])
75
+ try {
76
+ return crypto.createPrivateKey({
77
+ format: 'der',
78
+ key: der,
79
+ type: 'pkcs8',
80
+ })
81
+ } finally {
82
+ der.fill(0)
83
+ }
84
+ }
85
+
86
+ function toPublicKey(publicKey: Uint8Array): crypto.KeyObject {
87
+ assertLength(publicKey, 'public')
88
+ return crypto.createPublicKey({
89
+ format: 'der',
90
+ key: Buffer.concat([publicKeyPrefix, publicKey]),
91
+ type: 'spki',
92
+ })
93
+ }
@@ -0,0 +1,76 @@
1
+ import { fc, test } from '@fast-check/vitest'
2
+ import { ed25519, x25519 } from '@noble/curves/ed25519.js'
3
+ import { p256 } from '@noble/curves/nist.js'
4
+ import { describe, expect } from 'vp/test'
5
+ import { numRuns } from '../../../test/fuzz/numRuns.js'
6
+ import * as Ed25519 from '../Ed25519.js'
7
+ import * as P256 from '../P256.js'
8
+ import * as X25519 from '../X25519.js'
9
+
10
+ const arbitraryBytes = fc.uint8Array({ maxLength: 512 })
11
+ const arbitraryKey = fc.uint8Array({ maxLength: 32, minLength: 32 })
12
+ const arbitraryP256PrivateKey = fc
13
+ .tuple(
14
+ fc.integer({ max: 0xfe, min: 1 }),
15
+ fc.uint8Array({ maxLength: 31, minLength: 31 }),
16
+ )
17
+ .map(([first, rest]) => Uint8Array.of(first, ...rest))
18
+
19
+ describe('Ed25519', () => {
20
+ test.prop({ payload: arbitraryBytes, privateKey: arbitraryKey }, { numRuns })(
21
+ 'matches the default for arbitrary offset views',
22
+ async (options) => {
23
+ const engine = await Ed25519.engine()
24
+ const payload = offsetView(options.payload)
25
+ const privateKey = offsetView(options.privateKey)
26
+
27
+ expect(engine.getPublicKey(privateKey)).toEqual(
28
+ ed25519.getPublicKey(privateKey),
29
+ )
30
+ expect(engine.sign(payload, privateKey)).toEqual(
31
+ ed25519.sign(payload, privateKey),
32
+ )
33
+ expect(engine.toMontgomerySecret(privateKey)).toEqual(
34
+ ed25519.utils.toMontgomerySecret(privateKey),
35
+ )
36
+ },
37
+ )
38
+ })
39
+
40
+ describe('X25519', () => {
41
+ test.prop(
42
+ { privateKey: arbitraryKey, publicKeySeed: arbitraryKey },
43
+ { numRuns },
44
+ )('matches the default for arbitrary offset views', async (options) => {
45
+ const engine = await X25519.engine()
46
+ const privateKey = offsetView(options.privateKey)
47
+ const publicKey = offsetView(x25519.getPublicKey(options.publicKeySeed))
48
+
49
+ expect(engine.getPublicKey(privateKey)).toEqual(
50
+ x25519.getPublicKey(privateKey),
51
+ )
52
+ expect(engine.getSharedSecret(privateKey, publicKey)).toEqual(
53
+ x25519.getSharedSecret(privateKey, publicKey),
54
+ )
55
+ })
56
+ })
57
+
58
+ describe('P256', () => {
59
+ test.prop({ privateKey: arbitraryP256PrivateKey }, { numRuns })(
60
+ 'matches the default for arbitrary offset views',
61
+ async (options) => {
62
+ const engine = await P256.engine()
63
+ const privateKey = offsetView(options.privateKey)
64
+
65
+ expect(engine.getPublicKey(privateKey)).toEqual(
66
+ p256.getPublicKey(privateKey, false),
67
+ )
68
+ },
69
+ )
70
+ })
71
+
72
+ function offsetView(value: Uint8Array): Uint8Array {
73
+ const bytes = new Uint8Array(value.length + 4).fill(0xff)
74
+ bytes.set(value, 2)
75
+ return bytes.subarray(2, -2)
76
+ }
@@ -0,0 +1,35 @@
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 NodeEd25519 from '../Ed25519.js'
5
+
6
+ type Slot = Awaited<ReturnType<typeof NodeEd25519.engine>>
7
+
8
+ test('every implemented primitive is present', () => {
9
+ expectTypeOf<Slot['getPublicKey']>().toEqualTypeOf<
10
+ (privateKey: Uint8Array) => Uint8Array
11
+ >()
12
+ expectTypeOf<Slot['sign']>().toEqualTypeOf<
13
+ (payload: Uint8Array, privateKey: Uint8Array) => Uint8Array
14
+ >()
15
+ expectTypeOf<Slot['toMontgomerySecret']>().toEqualTypeOf<
16
+ (privateKey: Uint8Array) => Uint8Array
17
+ >()
18
+ })
19
+
20
+ test('unsupported primitives are absent', () => {
21
+ expectTypeOf<Slot>().not.toHaveProperty('randomSecretKey')
22
+ expectTypeOf<Slot>().not.toHaveProperty('toMontgomery')
23
+ expectTypeOf<Slot>().not.toHaveProperty('verify')
24
+ })
25
+
26
+ test('the result is the raw slot', () => {
27
+ expectTypeOf<{ Ed25519: Slot }>().toExtend<Engine.Engine>()
28
+ })
29
+
30
+ test('the Node namespace exposes the public Ed25519 API', () => {
31
+ expectTypeOf(NodeEd25519.getPublicKey).toEqualTypeOf(
32
+ core_Ed25519.getPublicKey,
33
+ )
34
+ expectTypeOf<typeof NodeEd25519>().not.toHaveProperty('create')
35
+ })