ox 1.1.2 → 1.3.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 (296) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/dist/core/AbiFunction.d.ts +1 -1
  3. package/dist/core/AbiFunction.d.ts.map +1 -1
  4. package/dist/core/AbiFunction.js +6 -2
  5. package/dist/core/AbiFunction.js.map +1 -1
  6. package/dist/core/AbiParameters.d.ts +1 -1
  7. package/dist/core/AbiParameters.d.ts.map +1 -1
  8. package/dist/core/AbiParameters.js +1 -13
  9. package/dist/core/AbiParameters.js.map +1 -1
  10. package/dist/core/AesGcm.d.ts +36 -1
  11. package/dist/core/AesGcm.d.ts.map +1 -1
  12. package/dist/core/AesGcm.js +44 -0
  13. package/dist/core/AesGcm.js.map +1 -1
  14. package/dist/core/Ed25519.d.ts +46 -1
  15. package/dist/core/Ed25519.d.ts.map +1 -1
  16. package/dist/core/Ed25519.js +43 -0
  17. package/dist/core/Ed25519.js.map +1 -1
  18. package/dist/core/Engine.d.ts +1 -1
  19. package/dist/core/Engine.d.ts.map +1 -1
  20. package/dist/core/Engine.js.map +1 -1
  21. package/dist/core/Hash.d.ts +200 -1
  22. package/dist/core/Hash.d.ts.map +1 -1
  23. package/dist/core/Hash.js +207 -0
  24. package/dist/core/Hash.js.map +1 -1
  25. package/dist/core/Hex.d.ts.map +1 -1
  26. package/dist/core/Hex.js +1 -4
  27. package/dist/core/Hex.js.map +1 -1
  28. package/dist/core/Rlp.d.ts +32 -0
  29. package/dist/core/Rlp.d.ts.map +1 -1
  30. package/dist/core/Rlp.js +146 -0
  31. package/dist/core/Rlp.js.map +1 -1
  32. package/dist/core/Secp256k1.d.ts +46 -1
  33. package/dist/core/Secp256k1.d.ts.map +1 -1
  34. package/dist/core/Secp256k1.js +48 -0
  35. package/dist/core/Secp256k1.js.map +1 -1
  36. package/dist/core/WebAuthn.d.ts +224 -0
  37. package/dist/core/WebAuthn.d.ts.map +1 -0
  38. package/dist/core/WebAuthn.js +343 -0
  39. package/dist/core/WebAuthn.js.map +1 -0
  40. package/dist/core/WebAuthnP256.d.ts +46 -50
  41. package/dist/core/WebAuthnP256.d.ts.map +1 -1
  42. package/dist/core/WebAuthnP256.js +44 -50
  43. package/dist/core/WebAuthnP256.js.map +1 -1
  44. package/dist/core/internal/abiParameters.d.ts +7 -87
  45. package/dist/core/internal/abiParameters.d.ts.map +1 -1
  46. package/dist/core/internal/abiParameters.js +339 -194
  47. package/dist/core/internal/abiParameters.js.map +1 -1
  48. package/dist/core/internal/engine.d.ts +35 -2
  49. package/dist/core/internal/engine.d.ts.map +1 -1
  50. package/dist/core/internal/engine.js +12 -1
  51. package/dist/core/internal/engine.js.map +1 -1
  52. package/dist/core/internal/hash.d.ts +10 -0
  53. package/dist/core/internal/hash.d.ts.map +1 -1
  54. package/dist/core/internal/hash.js +26 -1
  55. package/dist/core/internal/hash.js.map +1 -1
  56. package/dist/index.d.ts +23 -14
  57. package/dist/index.d.ts.map +1 -1
  58. package/dist/index.js +23 -14
  59. package/dist/index.js.map +1 -1
  60. package/dist/node/Engine.d.ts +1 -1
  61. package/dist/node/Engine.d.ts.map +1 -1
  62. package/dist/node/Engine.js.map +1 -1
  63. package/dist/node/Hash.d.ts +6 -4
  64. package/dist/node/Hash.d.ts.map +1 -1
  65. package/dist/node/Hash.js +35 -3
  66. package/dist/node/Hash.js.map +1 -1
  67. package/dist/tempo/AuthorizationTempo.d.ts +6 -6
  68. package/dist/tempo/AuthorizationTempo.js +6 -6
  69. package/dist/tempo/KeyAuthorization.d.ts +3 -8
  70. package/dist/tempo/KeyAuthorization.d.ts.map +1 -1
  71. package/dist/tempo/KeyAuthorization.js +3 -8
  72. package/dist/tempo/KeyAuthorization.js.map +1 -1
  73. package/dist/tempo/SignatureEnvelope.d.ts +8 -8
  74. package/dist/tempo/SignatureEnvelope.js +8 -8
  75. package/dist/trusted-setups/Paths.d.ts +1 -0
  76. package/dist/trusted-setups/Paths.d.ts.map +1 -1
  77. package/dist/trusted-setups/Paths.js +1 -0
  78. package/dist/trusted-setups/Paths.js.map +1 -1
  79. package/dist/trusted-setups/Setups.d.ts +35 -0
  80. package/dist/trusted-setups/Setups.d.ts.map +1 -0
  81. package/dist/trusted-setups/Setups.js +29 -0
  82. package/dist/trusted-setups/Setups.js.map +1 -0
  83. package/dist/trusted-setups/index.d.ts +20 -0
  84. package/dist/trusted-setups/index.d.ts.map +1 -1
  85. package/dist/trusted-setups/index.js +20 -0
  86. package/dist/trusted-setups/index.js.map +1 -1
  87. package/dist/trusted-setups/internal/paths.d.ts.map +1 -1
  88. package/dist/trusted-setups/internal/paths.js +1 -1
  89. package/dist/trusted-setups/internal/paths.js.map +1 -1
  90. package/dist/trusted-setups/internal/setups/mainnet.d.ts +7 -0
  91. package/dist/trusted-setups/internal/setups/mainnet.d.ts.map +1 -0
  92. package/dist/trusted-setups/internal/setups/mainnet.js +11 -0
  93. package/dist/trusted-setups/internal/setups/mainnet.js.map +1 -0
  94. package/dist/wasm/Engine.d.ts +4 -3
  95. package/dist/wasm/Engine.d.ts.map +1 -1
  96. package/dist/wasm/Engine.js +5 -5
  97. package/dist/wasm/Engine.js.map +1 -1
  98. package/dist/wasm/Hash.d.ts +1 -1
  99. package/dist/wasm/Hash.d.ts.map +1 -1
  100. package/dist/wasm/Hash.js +5 -0
  101. package/dist/wasm/Hash.js.map +1 -1
  102. package/dist/wasm/Keystore.d.ts +23 -9
  103. package/dist/wasm/Keystore.d.ts.map +1 -1
  104. package/dist/wasm/Keystore.js +30 -13
  105. package/dist/wasm/Keystore.js.map +1 -1
  106. package/dist/wasm/Kzg.d.ts +112 -0
  107. package/dist/wasm/Kzg.d.ts.map +1 -0
  108. package/dist/wasm/Kzg.js +333 -0
  109. package/dist/wasm/Kzg.js.map +1 -0
  110. package/dist/wasm/Secp256k1.d.ts +55 -0
  111. package/dist/wasm/Secp256k1.d.ts.map +1 -0
  112. package/dist/wasm/Secp256k1.js +181 -0
  113. package/dist/wasm/Secp256k1.js.map +1 -0
  114. package/dist/wasm/index.d.ts +44 -1
  115. package/dist/wasm/index.d.ts.map +1 -1
  116. package/dist/wasm/index.js +44 -1
  117. package/dist/wasm/index.js.map +1 -1
  118. package/dist/wasm/internal/blake3.d.ts +10 -1
  119. package/dist/wasm/internal/blake3.d.ts.map +1 -1
  120. package/dist/wasm/internal/blake3.js +12 -1
  121. package/dist/wasm/internal/blake3.js.map +1 -1
  122. package/dist/wasm/internal/blake3.wasm.d.ts +3 -1
  123. package/dist/wasm/internal/blake3.wasm.d.ts.map +1 -1
  124. package/dist/wasm/internal/blake3.wasm.js +3 -1
  125. package/dist/wasm/internal/blake3.wasm.js.map +1 -1
  126. package/dist/wasm/internal/hash.d.ts +9 -0
  127. package/dist/wasm/internal/hash.d.ts.map +1 -1
  128. package/dist/wasm/internal/hash.js +13 -1
  129. package/dist/wasm/internal/hash.js.map +1 -1
  130. package/dist/wasm/internal/hashState.d.ts +25 -0
  131. package/dist/wasm/internal/hashState.d.ts.map +1 -0
  132. package/dist/wasm/internal/hashState.js +105 -0
  133. package/dist/wasm/internal/hashState.js.map +1 -0
  134. package/dist/wasm/internal/hashes.d.ts +12 -1
  135. package/dist/wasm/internal/hashes.d.ts.map +1 -1
  136. package/dist/wasm/internal/hashes.js +18 -1
  137. package/dist/wasm/internal/hashes.js.map +1 -1
  138. package/dist/wasm/internal/hashes.wasm.d.ts +11 -3
  139. package/dist/wasm/internal/hashes.wasm.d.ts.map +1 -1
  140. package/dist/wasm/internal/hashes.wasm.js +11 -3
  141. package/dist/wasm/internal/hashes.wasm.js.map +1 -1
  142. package/dist/wasm/internal/instantiate.d.ts +12 -0
  143. package/dist/wasm/internal/instantiate.d.ts.map +1 -1
  144. package/dist/wasm/internal/instantiate.js +23 -7
  145. package/dist/wasm/internal/instantiate.js.map +1 -1
  146. package/dist/wasm/internal/keystore.d.ts +10 -0
  147. package/dist/wasm/internal/keystore.d.ts.map +1 -0
  148. package/dist/wasm/internal/keystore.js +10 -0
  149. package/dist/wasm/internal/keystore.js.map +1 -0
  150. package/dist/wasm/internal/kzg.d.ts +17 -0
  151. package/dist/wasm/internal/kzg.d.ts.map +1 -0
  152. package/dist/wasm/internal/kzg.js +8 -0
  153. package/dist/wasm/internal/kzg.js.map +1 -0
  154. package/dist/wasm/internal/kzg.wasm.d.ts +3 -0
  155. package/dist/wasm/internal/kzg.wasm.d.ts.map +1 -0
  156. package/dist/wasm/internal/kzg.wasm.js +10 -0
  157. package/dist/wasm/internal/kzg.wasm.js.map +1 -0
  158. package/dist/wasm/internal/scrypt.d.ts +16 -0
  159. package/dist/wasm/internal/scrypt.d.ts.map +1 -0
  160. package/dist/wasm/internal/scrypt.js +78 -0
  161. package/dist/wasm/internal/scrypt.js.map +1 -0
  162. package/dist/wasm/internal/scrypt.wasm.d.ts +7 -0
  163. package/dist/wasm/internal/scrypt.wasm.d.ts.map +1 -0
  164. package/dist/wasm/internal/scrypt.wasm.js +14 -0
  165. package/dist/wasm/internal/scrypt.wasm.js.map +1 -0
  166. package/dist/wasm/internal/secp256k1.d.ts +16 -0
  167. package/dist/wasm/internal/secp256k1.d.ts.map +1 -0
  168. package/dist/wasm/internal/secp256k1.js +20 -0
  169. package/dist/wasm/internal/secp256k1.js.map +1 -0
  170. package/dist/wasm/internal/secp256k1.wasm.d.ts +3 -0
  171. package/dist/wasm/internal/secp256k1.wasm.d.ts.map +1 -0
  172. package/dist/wasm/internal/secp256k1.wasm.js +10 -0
  173. package/dist/wasm/internal/secp256k1.wasm.js.map +1 -0
  174. package/dist/webauthn/Authentication.d.ts +2 -0
  175. package/dist/webauthn/Authentication.d.ts.map +1 -1
  176. package/dist/webauthn/Authentication.js +2 -1
  177. package/dist/webauthn/Authentication.js.map +1 -1
  178. package/dist/webauthn/Registration.d.ts.map +1 -1
  179. package/dist/webauthn/Registration.js +2 -1
  180. package/dist/webauthn/Registration.js.map +1 -1
  181. package/dist/webauthn/Types.d.ts +27 -6
  182. package/dist/webauthn/Types.d.ts.map +1 -1
  183. package/dist/webauthn/internal/utils.d.ts.map +1 -1
  184. package/dist/webauthn/internal/utils.js +35 -9
  185. package/dist/webauthn/internal/utils.js.map +1 -1
  186. package/dist/zod/TypedData.d.ts +2 -2
  187. package/package.json +27 -2
  188. package/src/benchmarks/Ox.bench.ts +6 -0
  189. package/src/benchmarks/OxNode.bench.ts +8 -0
  190. package/src/benchmarks/OxV0.bench.ts +4 -0
  191. package/src/benchmarks/OxWasm.bench.ts +22 -0
  192. package/src/core/AbiFunction.ts +5 -5
  193. package/src/core/AbiParameters.ts +8 -20
  194. package/src/core/AesGcm.ts +86 -1
  195. package/src/core/Ed25519.ts +87 -1
  196. package/src/core/Engine.ts +1 -0
  197. package/src/core/Hash.ts +321 -1
  198. package/src/core/Hex.ts +1 -4
  199. package/src/core/Rlp.ts +172 -5
  200. package/src/core/Secp256k1.ts +92 -1
  201. package/src/core/WebAuthn.ts +579 -0
  202. package/src/core/WebAuthnP256.ts +47 -50
  203. package/src/core/_test/AbiFunction.test.ts +9 -0
  204. package/src/core/_test/AbiParameters.differential.fuzz.ts +156 -0
  205. package/src/core/_test/AbiParameters.encode.test.ts +22 -0
  206. package/src/core/_test/AbiParameters.fuzz.ts +4 -0
  207. package/src/core/_test/AesGcm.test.ts +76 -0
  208. package/src/core/_test/Block.test.ts +9 -2
  209. package/src/core/_test/Ed25519.test-d.ts +13 -1
  210. package/src/core/_test/Ed25519.test.ts +120 -1
  211. package/src/core/_test/Engine.test-d.ts +9 -0
  212. package/src/core/_test/Engine.test.ts +1 -1
  213. package/src/core/_test/Hash.test-d.ts +41 -0
  214. package/src/core/_test/Hash.test.ts +278 -1
  215. package/src/core/_test/Hash.vectors.test.ts +1 -2
  216. package/src/core/_test/Hex.test.ts +2 -0
  217. package/src/core/_test/Rlp.test-d.ts +18 -0
  218. package/src/core/_test/Rlp.test.ts +109 -0
  219. package/src/core/_test/Secp256k1.test-d.ts +14 -0
  220. package/src/core/_test/Secp256k1.test.ts +91 -1
  221. package/src/core/_test/Transaction.test.ts +11 -2
  222. package/src/core/_test/WebAuthn.test-d.ts +142 -0
  223. package/src/core/_test/WebAuthn.test.ts +766 -0
  224. package/src/core/_test/index.test.ts +1 -0
  225. package/src/core/internal/abiParameters.ts +466 -326
  226. package/src/core/internal/engine.ts +47 -2
  227. package/src/core/internal/hash.ts +53 -1
  228. package/src/index.ts +24 -14
  229. package/src/node/Engine.ts +1 -0
  230. package/src/node/Hash.ts +43 -6
  231. package/src/node/_test/Engine.test-d.ts +1 -0
  232. package/src/node/_test/Engine.test.ts +2 -0
  233. package/src/node/_test/Hash.test-d.ts +11 -0
  234. package/src/node/_test/Hash.test.ts +46 -0
  235. package/src/tempo/AuthorizationTempo.ts +6 -6
  236. package/src/tempo/KeyAuthorization.ts +3 -8
  237. package/src/tempo/SignatureEnvelope.ts +8 -8
  238. package/src/trusted-setups/Paths.ts +1 -0
  239. package/src/trusted-setups/README.md +39 -0
  240. package/src/trusted-setups/Setups.ts +46 -0
  241. package/src/trusted-setups/_test/Paths.test.ts +16 -0
  242. package/src/trusted-setups/_test/Setups.test-d.ts +7 -0
  243. package/src/trusted-setups/_test/Setups.test.ts +43 -0
  244. package/src/trusted-setups/_test/index.test.ts +1 -0
  245. package/src/trusted-setups/index.ts +21 -0
  246. package/src/trusted-setups/internal/paths.ts +4 -1
  247. package/src/trusted-setups/internal/setups/mainnet.source.json +7 -0
  248. package/src/trusted-setups/internal/setups/mainnet.ts +16 -0
  249. package/src/version.ts +1 -1
  250. package/src/wasm/Engine.ts +9 -6
  251. package/src/wasm/Hash.ts +10 -0
  252. package/src/wasm/Keystore.bench.ts +26 -0
  253. package/src/wasm/Keystore.ts +32 -14
  254. package/src/wasm/Kzg.bench.ts +63 -0
  255. package/src/wasm/Kzg.ts +518 -0
  256. package/src/wasm/Secp256k1.bench.ts +79 -0
  257. package/src/wasm/Secp256k1.ts +248 -0
  258. package/src/wasm/_test/Engine.test-d.ts +2 -0
  259. package/src/wasm/_test/Engine.test.ts +5 -0
  260. package/src/wasm/_test/Hash.browser.test.ts +31 -0
  261. package/src/wasm/_test/Hash.test-d.ts +17 -0
  262. package/src/wasm/_test/Hash.test.ts +252 -3
  263. package/src/wasm/_test/Keystore.browser.test.ts +31 -0
  264. package/src/wasm/_test/Keystore.fuzz.ts +50 -0
  265. package/src/wasm/_test/Keystore.test-d.ts +10 -1
  266. package/src/wasm/_test/Keystore.test.ts +289 -4
  267. package/src/wasm/_test/Kzg.test-d.ts +19 -0
  268. package/src/wasm/_test/Kzg.test.ts +220 -0
  269. package/src/wasm/_test/Runtime.test.ts +9 -0
  270. package/src/wasm/_test/Secp256k1.test-d.ts +35 -0
  271. package/src/wasm/_test/Secp256k1.test.ts +354 -0
  272. package/src/wasm/index.ts +46 -1
  273. package/src/wasm/internal/blake3.ts +23 -2
  274. package/src/wasm/internal/blake3.wasm.ts +4 -1
  275. package/src/wasm/internal/hash.ts +27 -1
  276. package/src/wasm/internal/hashState.ts +154 -0
  277. package/src/wasm/internal/hashes.ts +56 -15
  278. package/src/wasm/internal/hashes.wasm.ts +15 -3
  279. package/src/wasm/internal/instantiate.ts +29 -9
  280. package/src/wasm/internal/keystore.ts +19 -0
  281. package/src/wasm/internal/kzg.ts +50 -0
  282. package/src/wasm/internal/kzg.wasm.ts +11 -0
  283. package/src/wasm/internal/scrypt.ts +131 -0
  284. package/src/wasm/internal/scrypt.wasm.ts +17 -0
  285. package/src/wasm/internal/secp256k1.ts +62 -0
  286. package/src/wasm/internal/secp256k1.wasm.ts +11 -0
  287. package/src/webauthn/Authentication.ts +4 -0
  288. package/src/webauthn/Registration.ts +2 -0
  289. package/src/webauthn/Types.ts +32 -2
  290. package/src/webauthn/_test/Authentication.test.ts +123 -1
  291. package/src/webauthn/_test/Registration.test.ts +26 -6
  292. package/src/webauthn/_test/WebAuthn.browser.test.ts +28 -0
  293. package/src/webauthn/internal/utils.ts +41 -8
  294. package/wasm/vendor/c-kzg-4844/LICENSE +201 -0
  295. package/wasm/vendor/c-kzg-4844/blst/LICENSE +201 -0
  296. package/src/trusted-setups/internal/setups/mainnet.txt +0 -4163
@@ -0,0 +1,518 @@
1
+ import * as Bytes from '../core/Bytes.js'
2
+ import * as Errors from '../core/Errors.js'
3
+ import * as Hex from '../core/Hex.js'
4
+ import type * as CoreKzg from '../core/Kzg.js'
5
+ import type * as kzg from './internal/kzg.js'
6
+
7
+ export * from '../core/Kzg.js'
8
+
9
+ const blobSize = 131_072
10
+ const cellSize = 2_048
11
+ const cellsPerBlob = 128
12
+ const commitmentSize = 48
13
+ const g1Points = 4_096
14
+ const g2Points = 65
15
+ const proofSize = 48
16
+
17
+ /**
18
+ * Trusted setup points accepted by `create`.
19
+ *
20
+ * Point arrays use the established Ethereum trusted-setup field names. Each
21
+ * field may also be supplied as one packed byte array.
22
+ */
23
+ export type TrustedSetup = {
24
+ /** 4,096 G1 points in Lagrange form. */
25
+ readonly g1_lagrange: Bytes.Bytes | readonly string[]
26
+ /** 4,096 G1 points in monomial form. */
27
+ readonly g1_monomial: Bytes.Bytes | readonly string[]
28
+ /** 65 G2 points in monomial form. */
29
+ readonly g2_monomial: Bytes.Bytes | readonly string[]
30
+ }
31
+
32
+ /**
33
+ * Creates an independently owned WASM implementation of [`Kzg.Kzg`](/api/Kzg).
34
+ *
35
+ * The factory compiles the c-kzg artifact once per JavaScript realm. Every call
36
+ * instantiates separate WASM memory and trusted-setup state. Call `dispose` when
37
+ * the instance is no longer needed.
38
+ *
39
+ * Operations on an instance are synchronous and run to completion. JavaScript
40
+ * workers do not share an instance, so create one in each worker that needs KZG.
41
+ *
42
+ * @example
43
+ * ```ts twoslash
44
+ * // @noErrors
45
+ * import { Setups } from 'ox/trusted-setups'
46
+ * import { Kzg } from 'ox/wasm'
47
+ *
48
+ * const kzg = await Kzg.create({
49
+ * trustedSetup: Setups.mainnet
50
+ * })
51
+ * // Pass `kzg` anywhere that accepts `Kzg.Kzg`.
52
+ *
53
+ * kzg.dispose()
54
+ * ```
55
+ *
56
+ * @param options - Trusted setup and precomputation options.
57
+ * @returns An initialized KZG implementation with explicit disposal.
58
+ */
59
+ export async function create(
60
+ options: create.Options,
61
+ ): Promise<create.ReturnType> {
62
+ const { trustedSetup } = options
63
+ const precompute = options.precompute ?? 0
64
+ if (!Number.isInteger(precompute) || precompute < 0 || precompute > 8)
65
+ throw new InvalidPrecomputeError({ precompute })
66
+
67
+ const setup = {
68
+ g1Lagrange: normalizePoints(
69
+ trustedSetup.g1_lagrange,
70
+ g1Points,
71
+ commitmentSize,
72
+ 'g1_lagrange',
73
+ ),
74
+ g1Monomial: normalizePoints(
75
+ trustedSetup.g1_monomial,
76
+ g1Points,
77
+ commitmentSize,
78
+ 'g1_monomial',
79
+ ),
80
+ g2Monomial: normalizePoints(
81
+ trustedSetup.g2_monomial,
82
+ g2Points,
83
+ 96,
84
+ 'g2_monomial',
85
+ ),
86
+ }
87
+
88
+ const { instantiate } = await import('./internal/kzg.js')
89
+ let module: Awaited<ReturnType<typeof instantiate>> | undefined =
90
+ await instantiate()
91
+
92
+ const getModule = () => {
93
+ if (!module) throw new DisposedError()
94
+ return module
95
+ }
96
+
97
+ try {
98
+ const initialized = getModule()
99
+ withBuffers(
100
+ initialized,
101
+ [setup.g1Monomial, setup.g1Lagrange, setup.g2Monomial],
102
+ [],
103
+ ([g1Monomial, g1Lagrange, g2Monomial]) => {
104
+ assertReturn(
105
+ initialized.exports.kzg_initialize(
106
+ g1Monomial!,
107
+ g1Lagrange!,
108
+ g2Monomial!,
109
+ precompute,
110
+ ),
111
+ 'initialize',
112
+ )
113
+ },
114
+ )
115
+ } catch (error) {
116
+ module?.exports.kzg_dispose()
117
+ module = undefined
118
+ throw error
119
+ }
120
+
121
+ const instance: create.ReturnType = {
122
+ blobToKzgCommitment(blob) {
123
+ assertBytes(blob, blobSize, 'blob')
124
+ return withBuffers(
125
+ getModule(),
126
+ [blob],
127
+ [commitmentSize],
128
+ ([blob], [out]) => {
129
+ const module = getModule()
130
+ assertReturn(
131
+ module.exports.kzg_blob_to_kzg_commitment(out!, blob!),
132
+ 'blobToKzgCommitment',
133
+ )
134
+ },
135
+ )[0]!
136
+ },
137
+ computeCells(blob) {
138
+ assertBytes(blob, blobSize, 'blob')
139
+ const bytes = withBuffers(
140
+ getModule(),
141
+ [blob],
142
+ [cellsPerBlob * cellSize],
143
+ ([blob], [cells]) => {
144
+ const module = getModule()
145
+ assertReturn(
146
+ module.exports.kzg_compute_cells(cells!, blob!),
147
+ 'computeCells',
148
+ )
149
+ },
150
+ )[0]!
151
+ return split(bytes, cellSize)
152
+ },
153
+ computeCellsAndKzgProofs(blob) {
154
+ assertBytes(blob, blobSize, 'blob')
155
+ const [cells, proofs] = withBuffers(
156
+ getModule(),
157
+ [blob],
158
+ [cellsPerBlob * cellSize, cellsPerBlob * proofSize],
159
+ ([blob], [cells, proofs]) => {
160
+ const module = getModule()
161
+ assertReturn(
162
+ module.exports.kzg_compute_cells_and_kzg_proofs(
163
+ cells!,
164
+ proofs!,
165
+ blob!,
166
+ ),
167
+ 'computeCellsAndKzgProofs',
168
+ )
169
+ },
170
+ )
171
+ return {
172
+ cells: split(cells!, cellSize),
173
+ proofs: split(proofs!, proofSize),
174
+ }
175
+ },
176
+ dispose() {
177
+ if (!module) return
178
+ const initialized = module
179
+ module = undefined
180
+ initialized.exports.kzg_dispose()
181
+ },
182
+ recoverCellsAndKzgProofs(cellIndices, cells) {
183
+ if (cellIndices.length !== cells.length)
184
+ throw new InvalidInputError({
185
+ message: '`cellIndices` and `cells` must have the same length.',
186
+ })
187
+ if (cells.length < 64 || cells.length > cellsPerBlob)
188
+ throw new InvalidInputError({
189
+ message: '`cells` must contain between 64 and 128 cells.',
190
+ })
191
+ assertCellIndices(cellIndices, true)
192
+ for (const cell of cells) assertBytes(cell, cellSize, 'cell')
193
+
194
+ const values = cellIndices
195
+ .map((index, i) => ({ cell: cells[i]!, index }))
196
+ .sort((a, b) => a.index - b.index)
197
+ const indices = values.map(({ index }) => index)
198
+ const sortedCells = values.map(({ cell }) => cell)
199
+
200
+ const [recoveredCells, proofs] = withBuffers(
201
+ getModule(),
202
+ [encodeIndices(indices), concat(sortedCells)],
203
+ [cellsPerBlob * cellSize, cellsPerBlob * proofSize],
204
+ ([indices, cells], [recoveredCells, proofs]) => {
205
+ const module = getModule()
206
+ assertReturn(
207
+ module.exports.kzg_recover_cells_and_kzg_proofs(
208
+ recoveredCells!,
209
+ proofs!,
210
+ indices!,
211
+ cells!,
212
+ values.length,
213
+ ),
214
+ 'recoverCellsAndKzgProofs',
215
+ )
216
+ },
217
+ )
218
+ return {
219
+ cells: split(recoveredCells!, cellSize),
220
+ proofs: split(proofs!, proofSize),
221
+ }
222
+ },
223
+ verifyCellKzgProofBatch(commitments, cellIndices, cells, proofs) {
224
+ const count = commitments.length
225
+ if (
226
+ count === 0 ||
227
+ cellIndices.length !== count ||
228
+ cells.length !== count ||
229
+ proofs.length !== count
230
+ )
231
+ throw new InvalidInputError({
232
+ message:
233
+ '`commitments`, `cellIndices`, `cells`, and `proofs` must have the same non-zero length.',
234
+ })
235
+ assertCellIndices(cellIndices, false)
236
+ for (const commitment of commitments)
237
+ assertBytes(commitment, commitmentSize, 'commitment')
238
+ for (const cell of cells) assertBytes(cell, cellSize, 'cell')
239
+ for (const proof of proofs) assertBytes(proof, proofSize, 'proof')
240
+
241
+ return (
242
+ withBuffers(
243
+ getModule(),
244
+ [
245
+ concat(commitments),
246
+ encodeIndices(cellIndices),
247
+ concat(cells),
248
+ concat(proofs),
249
+ ],
250
+ [4],
251
+ ([commitments, indices, cells, proofs], [verified]) => {
252
+ const module = getModule()
253
+ assertReturn(
254
+ module.exports.kzg_verify_cell_kzg_proof_batch(
255
+ verified!,
256
+ commitments!,
257
+ indices!,
258
+ cells!,
259
+ proofs!,
260
+ count,
261
+ ),
262
+ 'verifyCellKzgProofBatch',
263
+ )
264
+ },
265
+ )[0]![0] === 1
266
+ )
267
+ },
268
+ }
269
+ return instance
270
+ }
271
+
272
+ export declare namespace create {
273
+ /** Options for `create`. */
274
+ type Options = {
275
+ /**
276
+ * Fixed-base MSM window from 0 through 8.
277
+ *
278
+ * `0` performs no fixed-base precomputation and uses the least memory.
279
+ * Larger values improve proof generation at an exponential memory cost.
280
+ *
281
+ * @default 0
282
+ */
283
+ precompute?: number | undefined
284
+ /** Ethereum trusted-setup points. */
285
+ trustedSetup: TrustedSetup
286
+ }
287
+
288
+ /** An initialized KZG implementation with explicit lifecycle ownership. */
289
+ type ReturnType = CoreKzg.Kzg & {
290
+ /**
291
+ * Releases the trusted setup and makes every operation throw.
292
+ *
293
+ * Disposal is idempotent.
294
+ */
295
+ dispose(): void
296
+ }
297
+
298
+ type ErrorType =
299
+ | DisposedError
300
+ | InvalidInputError
301
+ | InvalidPrecomputeError
302
+ | InvalidTrustedSetupError
303
+ | MemoryError
304
+ | WasmError
305
+ | Errors.GlobalErrorType
306
+ }
307
+
308
+ function assertBytes(value: Bytes.Bytes, size: number, name: string) {
309
+ if (!(value instanceof Uint8Array) || value.length !== size)
310
+ throw new InvalidInputError({
311
+ message: `\`${name}\` must contain exactly ${size} bytes.`,
312
+ })
313
+ }
314
+
315
+ function assertCellIndices(indices: readonly number[], unique: boolean) {
316
+ const seen = new Set<number>()
317
+ for (const index of indices) {
318
+ if (!Number.isInteger(index) || index < 0 || index >= cellsPerBlob)
319
+ throw new InvalidInputError({
320
+ message: '`cellIndices` must contain integers from 0 through 127.',
321
+ })
322
+ if (unique && seen.has(index))
323
+ throw new InvalidInputError({
324
+ message: '`cellIndices` must not contain duplicate indices.',
325
+ })
326
+ seen.add(index)
327
+ }
328
+ }
329
+
330
+ function assertReturn(value: number, operation: string) {
331
+ if (value === 0) return
332
+ if (value === 1)
333
+ throw operation === 'initialize'
334
+ ? new InvalidTrustedSetupError()
335
+ : new InvalidInputError({ message: `c-kzg rejected \`${operation}\`.` })
336
+ if (value === 3) throw new MemoryError()
337
+ throw new WasmError({ operation })
338
+ }
339
+
340
+ function concat(values: readonly Bytes.Bytes[]) {
341
+ const size = values.reduce((size, value) => size + value.length, 0)
342
+ const result = new Uint8Array(size)
343
+ let offset = 0
344
+ for (const value of values) {
345
+ result.set(value, offset)
346
+ offset += value.length
347
+ }
348
+ return result
349
+ }
350
+
351
+ function encodeIndices(indices: readonly number[]) {
352
+ const bytes = new Uint8Array(indices.length * 8)
353
+ const view = new DataView(bytes.buffer)
354
+ for (let i = 0; i < indices.length; i++)
355
+ view.setBigUint64(i * 8, BigInt(indices[i]!), true)
356
+ return bytes
357
+ }
358
+
359
+ function normalizePoints(
360
+ value: Bytes.Bytes | readonly string[],
361
+ count: number,
362
+ size: number,
363
+ name: keyof TrustedSetup,
364
+ ) {
365
+ const expected = count * size
366
+ if (value instanceof Uint8Array) {
367
+ if (value.length !== expected)
368
+ throw new InvalidTrustedSetupError({
369
+ message: `\`${name}\` must contain exactly ${expected} bytes.`,
370
+ })
371
+ return Uint8Array.from(value)
372
+ }
373
+ if (!Array.isArray(value) || value.length !== count)
374
+ throw new InvalidTrustedSetupError({
375
+ message: `\`${name}\` must contain exactly ${count} points.`,
376
+ })
377
+
378
+ const result = new Uint8Array(expected)
379
+ for (let i = 0; i < value.length; i++) {
380
+ const point = value[i]!
381
+ try {
382
+ const bytes = Hex.toBytes(point as Hex.Hex)
383
+ if (bytes.length !== size) throw new Error()
384
+ result.set(bytes, i * size)
385
+ } catch {
386
+ throw new InvalidTrustedSetupError({
387
+ message: `\`${name}[${i}]\` must be a ${size}-byte hex value.`,
388
+ })
389
+ }
390
+ }
391
+ return result
392
+ }
393
+
394
+ function split(value: Bytes.Bytes, size: number) {
395
+ const result: Bytes.Bytes[] = []
396
+ for (let offset = 0; offset < value.length; offset += size)
397
+ result.push(value.slice(offset, offset + size))
398
+ return result
399
+ }
400
+
401
+ function withBuffers(
402
+ module: Awaited<ReturnType<typeof kzg.instantiate>>,
403
+ inputs: readonly Bytes.Bytes[],
404
+ outputs: readonly number[],
405
+ call: (inputs: readonly number[], outputs: readonly number[]) => void,
406
+ ) {
407
+ const inputPointers: number[] = []
408
+ const outputPointers: number[] = []
409
+
410
+ try {
411
+ for (const input of inputs)
412
+ inputPointers.push(allocate(module, input.length))
413
+ for (const size of outputs) outputPointers.push(allocate(module, size))
414
+
415
+ const view = module.view()
416
+ for (let i = 0; i < inputs.length; i++)
417
+ view.set(inputs[i]!, inputPointers[i]!)
418
+
419
+ call(inputPointers, outputPointers)
420
+
421
+ return outputs.map((size, i) =>
422
+ module.view().slice(outputPointers[i]!, outputPointers[i]! + size),
423
+ )
424
+ } catch (cause) {
425
+ if (cause instanceof Errors.BaseError) throw cause
426
+ throw new WasmError({ cause: cause as Error })
427
+ } finally {
428
+ for (let i = 0; i < inputs.length; i++) {
429
+ const pointer = inputPointers[i]
430
+ if (!pointer) continue
431
+ module.exports.zero(pointer, inputs[i]!.length)
432
+ module.exports.dealloc(pointer)
433
+ }
434
+ for (let i = 0; i < outputs.length; i++) {
435
+ const pointer = outputPointers[i]
436
+ if (!pointer) continue
437
+ module.exports.zero(pointer, outputs[i]!)
438
+ module.exports.dealloc(pointer)
439
+ }
440
+ }
441
+ }
442
+
443
+ function allocate(
444
+ module: Awaited<ReturnType<typeof kzg.instantiate>>,
445
+ size: number,
446
+ ) {
447
+ const pointer = module.exports.alloc(size)
448
+ if (!pointer) throw new MemoryError()
449
+ return pointer
450
+ }
451
+
452
+ /** Thrown when an operation is called after its KZG instance was disposed. */
453
+ export class DisposedError extends Errors.BaseError {
454
+ override readonly name = 'Kzg.DisposedError'
455
+
456
+ constructor() {
457
+ super('KZG instance has been disposed.')
458
+ }
459
+ }
460
+
461
+ /** Thrown when a KZG operation receives malformed input. */
462
+ export class InvalidInputError extends Errors.BaseError {
463
+ override readonly name = 'Kzg.InvalidInputError'
464
+
465
+ constructor({ message }: { message: string }) {
466
+ super(message)
467
+ }
468
+ }
469
+
470
+ /** Thrown when `precompute` is outside the supported memory bound. */
471
+ export class InvalidPrecomputeError extends Errors.BaseError {
472
+ override readonly name = 'Kzg.InvalidPrecomputeError'
473
+
474
+ constructor({ precompute }: { precompute: number }) {
475
+ super(
476
+ `\`precompute\` must be an integer from 0 through 8. Got ${precompute}.`,
477
+ )
478
+ }
479
+ }
480
+
481
+ /** Thrown when c-kzg rejects the trusted setup. */
482
+ export class InvalidTrustedSetupError extends Errors.BaseError {
483
+ override readonly name = 'Kzg.InvalidTrustedSetupError'
484
+
485
+ constructor(options: { message?: string | undefined } = {}) {
486
+ super(options.message ?? 'c-kzg rejected the trusted setup.')
487
+ }
488
+ }
489
+
490
+ /** Thrown when the KZG artifact reaches its 128 MiB memory limit. */
491
+ export class MemoryError extends Errors.BaseError {
492
+ override readonly name = 'Kzg.MemoryError'
493
+
494
+ constructor() {
495
+ super('KZG WASM memory limit was exceeded.', {
496
+ metaMessages: [
497
+ 'The artifact grows memory on demand up to 128 MiB.',
498
+ 'Use a smaller `precompute` value or batch fewer proofs.',
499
+ ],
500
+ })
501
+ }
502
+ }
503
+
504
+ /** Thrown when the KZG artifact traps or reports an internal error. */
505
+ export class WasmError extends Errors.BaseError<Error | undefined> {
506
+ override readonly name = 'Kzg.WasmError'
507
+
508
+ constructor(
509
+ options: { cause?: Error | undefined; operation?: string | undefined } = {},
510
+ ) {
511
+ super('KZG WASM operation failed.', {
512
+ cause: options.cause,
513
+ metaMessages: options.operation
514
+ ? [`Operation: ${options.operation}`]
515
+ : undefined,
516
+ })
517
+ }
518
+ }
@@ -0,0 +1,79 @@
1
+ import { secp256k1 } from '@noble/curves/secp256k1.js'
2
+ import { bench, describe } from 'vp/test'
3
+ import { engine as wasmEngine } from './Secp256k1.js'
4
+
5
+ const wasm = await wasmEngine()
6
+ const privateKey = new Uint8Array(32)
7
+ privateKey[31] = 1
8
+ const privateKeyB = new Uint8Array(32)
9
+ privateKeyB[31] = 2
10
+ const payload = Uint8Array.from({ length: 32 }, (_, index) => index)
11
+ const publicKey = secp256k1.getPublicKey(privateKey, false)
12
+ const publicKeyB = secp256k1.getPublicKey(privateKeyB, false)
13
+ const signature = secp256k1.sign(payload, privateKey, {
14
+ extraEntropy: false,
15
+ format: 'recovered',
16
+ lowS: true,
17
+ prehash: false,
18
+ })
19
+ const signOptions = { extraEntropy: false, prehash: false } as const
20
+ const verifyOptions = { prehash: false } as const
21
+
22
+ describe('getPublicKey', () => {
23
+ bench('ox', () => {
24
+ secp256k1.getPublicKey(privateKey, false)
25
+ })
26
+
27
+ bench('ox/wasm', () => {
28
+ wasm.getPublicKey(privateKey)
29
+ })
30
+ })
31
+
32
+ describe('getSharedSecret', () => {
33
+ bench('ox', () => {
34
+ secp256k1.getSharedSecret(privateKey, publicKeyB, true)
35
+ })
36
+
37
+ bench('ox/wasm', () => {
38
+ wasm.getSharedSecret(privateKey, publicKeyB)
39
+ })
40
+ })
41
+
42
+ describe('recoverPublicKey', () => {
43
+ bench('ox', () => {
44
+ secp256k1.Signature.fromBytes(signature, 'recovered')
45
+ .recoverPublicKey(payload)
46
+ .toBytes(false)
47
+ })
48
+
49
+ bench('ox/wasm', () => {
50
+ wasm.recoverPublicKey(signature, payload)
51
+ })
52
+ })
53
+
54
+ describe('sign', () => {
55
+ bench('ox', () => {
56
+ secp256k1.sign(payload, privateKey, {
57
+ ...signOptions,
58
+ format: 'recovered',
59
+ lowS: true,
60
+ })
61
+ })
62
+
63
+ bench('ox/wasm', () => {
64
+ wasm.sign(payload, privateKey, signOptions)
65
+ })
66
+ })
67
+
68
+ describe('verify', () => {
69
+ bench('ox', () => {
70
+ secp256k1.verify(signature.slice(1), payload, publicKey, {
71
+ lowS: true,
72
+ ...verifyOptions,
73
+ })
74
+ })
75
+
76
+ bench('ox/wasm', () => {
77
+ wasm.verify(signature.slice(1), payload, publicKey, verifyOptions)
78
+ })
79
+ })