@sip-protocol/sdk 0.7.3 → 0.7.4

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 (264) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +267 -0
  3. package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
  4. package/dist/browser.d.mts +10 -4
  5. package/dist/browser.d.ts +10 -4
  6. package/dist/browser.js +47556 -19603
  7. package/dist/browser.mjs +628 -48
  8. package/dist/chunk-4GRJ5MAW.mjs +152 -0
  9. package/dist/chunk-5D7A3L3W.mjs +717 -0
  10. package/dist/chunk-64AYA5F5.mjs +7834 -0
  11. package/dist/chunk-GMDGB22A.mjs +379 -0
  12. package/dist/chunk-I534WKN7.mjs +328 -0
  13. package/dist/chunk-IBZVA5Y7.mjs +1003 -0
  14. package/dist/chunk-PRRZAWJE.mjs +223 -0
  15. package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
  16. package/dist/{chunk-3M3HNQCW.mjs → chunk-YWGJ77A2.mjs} +28656 -13103
  17. package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
  18. package/dist/constants-LHAAUC2T.mjs +51 -0
  19. package/dist/dist-2OGQ7FED.mjs +3957 -0
  20. package/dist/dist-IFHPYLDX.mjs +254 -0
  21. package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
  22. package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
  23. package/dist/{index-DIBZHOOQ.d.ts → index-DXh2IGkz.d.ts} +21239 -10304
  24. package/dist/{index-8MQz13eJ.d.mts → index-DeE1ZzA4.d.mts} +21239 -10304
  25. package/dist/index.d.mts +9 -3
  26. package/dist/index.d.ts +9 -3
  27. package/dist/index.js +48396 -19623
  28. package/dist/index.mjs +537 -19
  29. package/dist/interface-Bf7w1PLW.d.mts +679 -0
  30. package/dist/interface-Bf7w1PLW.d.ts +679 -0
  31. package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
  32. package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
  33. package/dist/proofs/halo2.d.mts +151 -0
  34. package/dist/proofs/halo2.d.ts +151 -0
  35. package/dist/proofs/halo2.js +350 -0
  36. package/dist/proofs/halo2.mjs +11 -0
  37. package/dist/proofs/kimchi.d.mts +160 -0
  38. package/dist/proofs/kimchi.d.ts +160 -0
  39. package/dist/proofs/kimchi.js +431 -0
  40. package/dist/proofs/kimchi.mjs +13 -0
  41. package/dist/proofs/noir.d.mts +1 -1
  42. package/dist/proofs/noir.d.ts +1 -1
  43. package/dist/proofs/noir.js +74 -18
  44. package/dist/proofs/noir.mjs +84 -24
  45. package/dist/solana-U3MEGU7W.mjs +280 -0
  46. package/dist/validity_proof-3POXLPNY.mjs +21 -0
  47. package/package.json +54 -21
  48. package/src/adapters/index.ts +41 -0
  49. package/src/adapters/jupiter.ts +571 -0
  50. package/src/adapters/near-intents.ts +135 -0
  51. package/src/advisor/advisor.ts +653 -0
  52. package/src/advisor/index.ts +54 -0
  53. package/src/advisor/tools.ts +303 -0
  54. package/src/advisor/types.ts +164 -0
  55. package/src/chains/ethereum/announcement.ts +536 -0
  56. package/src/chains/ethereum/bnb-optimizations.ts +474 -0
  57. package/src/chains/ethereum/commitment.ts +522 -0
  58. package/src/chains/ethereum/constants.ts +462 -0
  59. package/src/chains/ethereum/deployment.ts +596 -0
  60. package/src/chains/ethereum/gas-estimation.ts +538 -0
  61. package/src/chains/ethereum/index.ts +268 -0
  62. package/src/chains/ethereum/optimizations.ts +614 -0
  63. package/src/chains/ethereum/privacy-adapter.ts +855 -0
  64. package/src/chains/ethereum/registry.ts +584 -0
  65. package/src/chains/ethereum/rpc.ts +905 -0
  66. package/src/chains/ethereum/stealth.ts +491 -0
  67. package/src/chains/ethereum/token.ts +790 -0
  68. package/src/chains/ethereum/transfer.ts +637 -0
  69. package/src/chains/ethereum/types.ts +456 -0
  70. package/src/chains/ethereum/viewing-key.ts +455 -0
  71. package/src/chains/near/commitment.ts +608 -0
  72. package/src/chains/near/constants.ts +284 -0
  73. package/src/chains/near/function-call.ts +871 -0
  74. package/src/chains/near/history.ts +654 -0
  75. package/src/chains/near/implicit-account.ts +840 -0
  76. package/src/chains/near/index.ts +393 -0
  77. package/src/chains/near/native-transfer.ts +658 -0
  78. package/src/chains/near/nep141.ts +775 -0
  79. package/src/chains/near/privacy-adapter.ts +889 -0
  80. package/src/chains/near/resolver.ts +971 -0
  81. package/src/chains/near/rpc.ts +1016 -0
  82. package/src/chains/near/stealth.ts +419 -0
  83. package/src/chains/near/types.ts +317 -0
  84. package/src/chains/near/viewing-key.ts +876 -0
  85. package/src/chains/solana/anchor-transfer.ts +386 -0
  86. package/src/chains/solana/commitment.ts +577 -0
  87. package/src/chains/solana/constants.ts +126 -12
  88. package/src/chains/solana/ephemeral-keys.ts +543 -0
  89. package/src/chains/solana/index.ts +252 -1
  90. package/src/chains/solana/key-derivation.ts +418 -0
  91. package/src/chains/solana/kit-compat.ts +334 -0
  92. package/src/chains/solana/optimizations.ts +560 -0
  93. package/src/chains/solana/privacy-adapter.ts +605 -0
  94. package/src/chains/solana/providers/generic.ts +47 -6
  95. package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
  96. package/src/chains/solana/providers/helius-enhanced.ts +623 -0
  97. package/src/chains/solana/providers/helius.ts +186 -33
  98. package/src/chains/solana/providers/index.ts +31 -0
  99. package/src/chains/solana/providers/interface.ts +61 -18
  100. package/src/chains/solana/providers/quicknode.ts +409 -0
  101. package/src/chains/solana/providers/triton.ts +426 -0
  102. package/src/chains/solana/providers/webhook.ts +338 -67
  103. package/src/chains/solana/rpc-client.ts +1150 -0
  104. package/src/chains/solana/scan.ts +83 -66
  105. package/src/chains/solana/sol-transfer.ts +732 -0
  106. package/src/chains/solana/spl-transfer.ts +886 -0
  107. package/src/chains/solana/stealth-scanner.ts +703 -0
  108. package/src/chains/solana/sunspot-verifier.ts +453 -0
  109. package/src/chains/solana/transaction-builder.ts +755 -0
  110. package/src/chains/solana/transfer.ts +74 -5
  111. package/src/chains/solana/types.ts +57 -6
  112. package/src/chains/solana/utils.ts +110 -0
  113. package/src/chains/solana/viewing-key.ts +807 -0
  114. package/src/compliance/fireblocks.ts +921 -0
  115. package/src/compliance/index.ts +23 -0
  116. package/src/compliance/range-sas.ts +398 -33
  117. package/src/config/endpoints.ts +100 -0
  118. package/src/crypto.ts +11 -8
  119. package/src/errors.ts +82 -0
  120. package/src/evm/erc4337-relayer.ts +830 -0
  121. package/src/evm/index.ts +47 -0
  122. package/src/fees/calculator.ts +396 -0
  123. package/src/fees/index.ts +87 -0
  124. package/src/fees/near-contract.ts +429 -0
  125. package/src/fees/types.ts +268 -0
  126. package/src/index.ts +686 -1
  127. package/src/intent.ts +6 -3
  128. package/src/logger.ts +324 -0
  129. package/src/network/index.ts +80 -0
  130. package/src/network/proxy.ts +691 -0
  131. package/src/optimizations/index.ts +541 -0
  132. package/src/oracle/types.ts +1 -0
  133. package/src/privacy-backends/arcium-types.ts +727 -0
  134. package/src/privacy-backends/arcium.ts +719 -0
  135. package/src/privacy-backends/combined-privacy.ts +866 -0
  136. package/src/privacy-backends/cspl-token.ts +595 -0
  137. package/src/privacy-backends/cspl-types.ts +512 -0
  138. package/src/privacy-backends/cspl.ts +907 -0
  139. package/src/privacy-backends/health.ts +488 -0
  140. package/src/privacy-backends/inco-types.ts +323 -0
  141. package/src/privacy-backends/inco.ts +616 -0
  142. package/src/privacy-backends/index.ts +254 -4
  143. package/src/privacy-backends/interface.ts +649 -6
  144. package/src/privacy-backends/lru-cache.ts +343 -0
  145. package/src/privacy-backends/magicblock.ts +458 -0
  146. package/src/privacy-backends/mock.ts +258 -0
  147. package/src/privacy-backends/privacycash.ts +13 -17
  148. package/src/privacy-backends/private-swap.ts +570 -0
  149. package/src/privacy-backends/rate-limiter.ts +683 -0
  150. package/src/privacy-backends/registry.ts +414 -2
  151. package/src/privacy-backends/router.ts +283 -3
  152. package/src/privacy-backends/shadowwire.ts +449 -0
  153. package/src/privacy-backends/sip-native.ts +3 -0
  154. package/src/privacy-logger.ts +191 -0
  155. package/src/production-safety.ts +373 -0
  156. package/src/proofs/aggregator.ts +1029 -0
  157. package/src/proofs/browser-composer.ts +1150 -0
  158. package/src/proofs/browser.ts +113 -25
  159. package/src/proofs/cache/index.ts +127 -0
  160. package/src/proofs/cache/interface.ts +545 -0
  161. package/src/proofs/cache/key-generator.ts +188 -0
  162. package/src/proofs/cache/lru-cache.ts +481 -0
  163. package/src/proofs/cache/multi-tier-cache.ts +575 -0
  164. package/src/proofs/cache/persistent-cache.ts +788 -0
  165. package/src/proofs/compliance-proof.ts +872 -0
  166. package/src/proofs/composer/base.ts +923 -0
  167. package/src/proofs/composer/index.ts +25 -0
  168. package/src/proofs/composer/interface.ts +518 -0
  169. package/src/proofs/composer/types.ts +383 -0
  170. package/src/proofs/converters/halo2.ts +452 -0
  171. package/src/proofs/converters/index.ts +208 -0
  172. package/src/proofs/converters/interface.ts +363 -0
  173. package/src/proofs/converters/kimchi.ts +462 -0
  174. package/src/proofs/converters/noir.ts +451 -0
  175. package/src/proofs/fallback.ts +888 -0
  176. package/src/proofs/halo2.ts +42 -0
  177. package/src/proofs/index.ts +471 -0
  178. package/src/proofs/interface.ts +13 -0
  179. package/src/proofs/kimchi.ts +42 -0
  180. package/src/proofs/lazy.ts +1004 -0
  181. package/src/proofs/mock.ts +25 -1
  182. package/src/proofs/noir.ts +110 -29
  183. package/src/proofs/orchestrator.ts +960 -0
  184. package/src/proofs/parallel/concurrency.ts +297 -0
  185. package/src/proofs/parallel/dependency-graph.ts +602 -0
  186. package/src/proofs/parallel/executor.ts +420 -0
  187. package/src/proofs/parallel/index.ts +131 -0
  188. package/src/proofs/parallel/interface.ts +685 -0
  189. package/src/proofs/parallel/worker-pool.ts +644 -0
  190. package/src/proofs/providers/halo2.ts +560 -0
  191. package/src/proofs/providers/index.ts +34 -0
  192. package/src/proofs/providers/kimchi.ts +641 -0
  193. package/src/proofs/validator.ts +881 -0
  194. package/src/proofs/verifier.ts +867 -0
  195. package/src/quantum/index.ts +112 -0
  196. package/src/quantum/winternitz-vault.ts +639 -0
  197. package/src/quantum/wots.ts +611 -0
  198. package/src/settlement/backends/direct-chain.ts +1 -0
  199. package/src/settlement/index.ts +9 -0
  200. package/src/settlement/router.ts +732 -46
  201. package/src/solana/index.ts +72 -0
  202. package/src/solana/jito-relayer.ts +687 -0
  203. package/src/solana/noir-verifier-types.ts +430 -0
  204. package/src/solana/noir-verifier.ts +816 -0
  205. package/src/stealth/address-derivation.ts +193 -0
  206. package/src/stealth/ed25519.ts +431 -0
  207. package/src/stealth/index.ts +233 -0
  208. package/src/stealth/meta-address.ts +221 -0
  209. package/src/stealth/secp256k1.ts +368 -0
  210. package/src/stealth/utils.ts +194 -0
  211. package/src/stealth.ts +50 -1504
  212. package/src/sync/index.ts +106 -0
  213. package/src/sync/manager.ts +504 -0
  214. package/src/sync/mock-provider.ts +318 -0
  215. package/src/sync/oblivious.ts +625 -0
  216. package/src/tokens/index.ts +15 -0
  217. package/src/tokens/registry.ts +301 -0
  218. package/src/utils/deprecation.ts +94 -0
  219. package/src/utils/index.ts +9 -0
  220. package/src/wallet/ethereum/index.ts +68 -0
  221. package/src/wallet/ethereum/metamask-privacy.ts +420 -0
  222. package/src/wallet/ethereum/multi-wallet.ts +646 -0
  223. package/src/wallet/ethereum/privacy-adapter.ts +700 -0
  224. package/src/wallet/ethereum/types.ts +3 -1
  225. package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
  226. package/src/wallet/hardware/index.ts +10 -0
  227. package/src/wallet/hardware/ledger-privacy.ts +414 -0
  228. package/src/wallet/index.ts +71 -0
  229. package/src/wallet/near/adapter.ts +626 -0
  230. package/src/wallet/near/index.ts +86 -0
  231. package/src/wallet/near/meteor-wallet.ts +1153 -0
  232. package/src/wallet/near/my-near-wallet.ts +790 -0
  233. package/src/wallet/near/wallet-selector.ts +702 -0
  234. package/src/wallet/solana/adapter.ts +6 -4
  235. package/src/wallet/solana/index.ts +13 -0
  236. package/src/wallet/solana/privacy-adapter.ts +567 -0
  237. package/src/wallet/sui/types.ts +6 -4
  238. package/src/zcash/rpc-client.ts +13 -6
  239. package/dist/chunk-2XIVXWHA.mjs +0 -1930
  240. package/dist/chunk-3INS3PR5.mjs +0 -884
  241. package/dist/chunk-3OVABDRH.mjs +0 -17096
  242. package/dist/chunk-7RFRWDCW.mjs +0 -1504
  243. package/dist/chunk-DLDWZFYC.mjs +0 -1495
  244. package/dist/chunk-E6SZWREQ.mjs +0 -57
  245. package/dist/chunk-F6F73W35.mjs +0 -16166
  246. package/dist/chunk-G33LB27A.mjs +0 -16166
  247. package/dist/chunk-HGU6HZRC.mjs +0 -231
  248. package/dist/chunk-L2K34JCU.mjs +0 -1496
  249. package/dist/chunk-OFDBEIEK.mjs +0 -16166
  250. package/dist/chunk-SF7YSLF5.mjs +0 -1515
  251. package/dist/chunk-SN4ZDTVW.mjs +0 -16166
  252. package/dist/chunk-WWUSGOXE.mjs +0 -17129
  253. package/dist/constants-VOI7BSLK.mjs +0 -27
  254. package/dist/index-B71aXVzk.d.ts +0 -13264
  255. package/dist/index-BYZbDjal.d.ts +0 -11390
  256. package/dist/index-CHB3KuOB.d.mts +0 -11859
  257. package/dist/index-CzWPI6Le.d.ts +0 -11859
  258. package/dist/index-pOIIuwfV.d.mts +0 -13264
  259. package/dist/index-xbWjohNq.d.mts +0 -11390
  260. package/dist/solana-4O4K45VU.mjs +0 -46
  261. package/dist/solana-5EMCTPTS.mjs +0 -46
  262. package/dist/solana-NDABAZ6P.mjs +0 -56
  263. package/dist/solana-Q4NAVBTS.mjs +0 -46
  264. package/dist/solana-ZYO63LY5.mjs +0 -46
@@ -0,0 +1,881 @@
1
+ /**
2
+ * Cross-System Proof Validation
3
+ *
4
+ * Implements validation logic that ensures proofs from different ZK systems
5
+ * can be correctly composed together. This includes validating input/output
6
+ * compatibility, field consistency, and proof linkage integrity.
7
+ *
8
+ * Key features:
9
+ * - Field element compatibility validation
10
+ * - Public input/output type matching
11
+ * - Proof commitment linkage verification
12
+ * - Curve compatibility validation
13
+ * - Semantic validation (proof meaning consistency)
14
+ * - Detailed validation error reports
15
+ *
16
+ * @packageDocumentation
17
+ */
18
+
19
+ import type {
20
+ ProofSystem,
21
+ SingleProof,
22
+ ComposedProof,
23
+ HexString,
24
+ } from '@sip-protocol/types'
25
+
26
+ // ─── Types ───────────────────────────────────────────────────────────────────
27
+
28
+ /**
29
+ * Elliptic curve used by a proof system
30
+ */
31
+ export type EllipticCurve =
32
+ | 'bn254' // Used by Noir (default), Groth16
33
+ | 'bls12-381' // Used by some Plonk implementations
34
+ | 'pallas' // Part of Pasta curves (Halo2, Kimchi)
35
+ | 'vesta' // Part of Pasta curves (Halo2, Kimchi)
36
+ | 'secp256k1' // Bitcoin curve (rarely used for ZK)
37
+ | 'ed25519' // Edwards curve
38
+
39
+ /**
40
+ * Field characteristics for a proof system
41
+ */
42
+ export interface FieldCharacteristics {
43
+ /** Field modulus (prime p) */
44
+ modulus: bigint
45
+ /** Scalar field size */
46
+ scalarFieldSize: number
47
+ /** Base field size */
48
+ baseFieldSize: number
49
+ /** Whether the field is a prime field */
50
+ isPrimeField: boolean
51
+ }
52
+
53
+ /**
54
+ * System compatibility information
55
+ */
56
+ export interface SystemInfo {
57
+ /** Proof system identifier */
58
+ system: ProofSystem
59
+ /** Primary curve used */
60
+ primaryCurve: EllipticCurve
61
+ /** Secondary curve (for cycle of curves) */
62
+ secondaryCurve?: EllipticCurve
63
+ /** Field characteristics */
64
+ field: FieldCharacteristics
65
+ /** Whether system supports recursion */
66
+ supportsRecursion: boolean
67
+ /** Whether system supports IVC (incremental verifiable computation) */
68
+ supportsIVC: boolean
69
+ }
70
+
71
+ /**
72
+ * Validation result for a single check
73
+ */
74
+ export interface ValidationCheck {
75
+ /** Check identifier */
76
+ checkId: string
77
+ /** Human-readable check name */
78
+ name: string
79
+ /** Whether check passed */
80
+ passed: boolean
81
+ /** Severity if failed */
82
+ severity: 'error' | 'warning' | 'info'
83
+ /** Detailed message */
84
+ message: string
85
+ /** Additional context */
86
+ context?: Record<string, unknown>
87
+ }
88
+
89
+ /**
90
+ * Comprehensive validation report
91
+ */
92
+ export interface ValidationReport {
93
+ /** Overall validation result */
94
+ valid: boolean
95
+ /** List of checks performed */
96
+ checks: ValidationCheck[]
97
+ /** Number of errors */
98
+ errorCount: number
99
+ /** Number of warnings */
100
+ warningCount: number
101
+ /** Total validation time (ms) */
102
+ validationTimeMs: number
103
+ /** Proofs validated */
104
+ proofsValidated: number
105
+ /** Systems involved */
106
+ systemsInvolved: ProofSystem[]
107
+ /** Compatibility matrix */
108
+ compatibilityMatrix?: CompatibilityEntry[][]
109
+ /** Recommendations for composition */
110
+ recommendations: string[]
111
+ }
112
+
113
+ /**
114
+ * Entry in compatibility matrix
115
+ */
116
+ export interface CompatibilityEntry {
117
+ /** Source system */
118
+ sourceSystem: ProofSystem
119
+ /** Target system */
120
+ targetSystem: ProofSystem
121
+ /** Whether systems are compatible */
122
+ compatible: boolean
123
+ /** Compatibility level */
124
+ level: 'full' | 'partial' | 'none'
125
+ /** Required conversions */
126
+ requiredConversions: string[]
127
+ }
128
+
129
+ /**
130
+ * Validation options
131
+ */
132
+ export interface ValidationOptions {
133
+ /** Skip field compatibility check */
134
+ skipFieldCheck?: boolean
135
+ /** Skip curve compatibility check */
136
+ skipCurveCheck?: boolean
137
+ /** Skip input/output matching */
138
+ skipInputOutputCheck?: boolean
139
+ /** Skip linkage verification */
140
+ skipLinkageCheck?: boolean
141
+ /** Strict mode - fail on warnings */
142
+ strictMode?: boolean
143
+ /** Custom system info overrides */
144
+ systemOverrides?: Partial<Record<ProofSystem, Partial<SystemInfo>>>
145
+ }
146
+
147
+ // ─── Constants ───────────────────────────────────────────────────────────────
148
+
149
+ /**
150
+ * BN254 field modulus (used by Noir)
151
+ */
152
+ const BN254_MODULUS = BigInt('21888242871839275222246405745257275088548364400416034343698204186575808495617')
153
+
154
+ /**
155
+ * Pallas field modulus (used by Halo2, Kimchi)
156
+ */
157
+ const PALLAS_MODULUS = BigInt('28948022309329048855892746252171976963363056481941560715954676764349967630337')
158
+
159
+ /**
160
+ * Vesta field modulus (used by Halo2, Kimchi)
161
+ */
162
+ const VESTA_MODULUS = BigInt('28948022309329048855892746252171976963363056481941647379679742748393362948097')
163
+
164
+ /**
165
+ * BLS12-381 scalar field modulus
166
+ */
167
+ const BLS12_381_MODULUS = BigInt('52435875175126190479447740508185965837690552500527637822603658699938581184513')
168
+
169
+ /**
170
+ * Default system information for known proof systems
171
+ */
172
+ export const SYSTEM_INFO: Record<ProofSystem, SystemInfo> = {
173
+ noir: {
174
+ system: 'noir',
175
+ primaryCurve: 'bn254',
176
+ field: {
177
+ modulus: BN254_MODULUS,
178
+ scalarFieldSize: 254,
179
+ baseFieldSize: 254,
180
+ isPrimeField: true,
181
+ },
182
+ supportsRecursion: true,
183
+ supportsIVC: false,
184
+ },
185
+ halo2: {
186
+ system: 'halo2',
187
+ primaryCurve: 'pallas',
188
+ secondaryCurve: 'vesta',
189
+ field: {
190
+ modulus: PALLAS_MODULUS,
191
+ scalarFieldSize: 255,
192
+ baseFieldSize: 255,
193
+ isPrimeField: true,
194
+ },
195
+ supportsRecursion: true,
196
+ supportsIVC: true,
197
+ },
198
+ kimchi: {
199
+ system: 'kimchi',
200
+ primaryCurve: 'pallas',
201
+ secondaryCurve: 'vesta',
202
+ field: {
203
+ modulus: PALLAS_MODULUS,
204
+ scalarFieldSize: 255,
205
+ baseFieldSize: 255,
206
+ isPrimeField: true,
207
+ },
208
+ supportsRecursion: true,
209
+ supportsIVC: true,
210
+ },
211
+ groth16: {
212
+ system: 'groth16',
213
+ primaryCurve: 'bn254',
214
+ field: {
215
+ modulus: BN254_MODULUS,
216
+ scalarFieldSize: 254,
217
+ baseFieldSize: 254,
218
+ isPrimeField: true,
219
+ },
220
+ supportsRecursion: false,
221
+ supportsIVC: false,
222
+ },
223
+ plonk: {
224
+ system: 'plonk',
225
+ primaryCurve: 'bls12-381',
226
+ field: {
227
+ modulus: BLS12_381_MODULUS,
228
+ scalarFieldSize: 255,
229
+ baseFieldSize: 381,
230
+ isPrimeField: true,
231
+ },
232
+ supportsRecursion: true,
233
+ supportsIVC: false,
234
+ },
235
+ }
236
+
237
+ /**
238
+ * Curve family groupings for compatibility
239
+ */
240
+ const CURVE_FAMILIES: Record<string, EllipticCurve[]> = {
241
+ pasta: ['pallas', 'vesta'],
242
+ bn: ['bn254'],
243
+ bls: ['bls12-381'],
244
+ }
245
+
246
+ // ─── Cross-System Validator ──────────────────────────────────────────────────
247
+
248
+ /**
249
+ * CrossSystemValidator
250
+ *
251
+ * Validates that proofs from different ZK systems can be correctly
252
+ * composed together.
253
+ *
254
+ * @example
255
+ * ```typescript
256
+ * const validator = new CrossSystemValidator()
257
+ *
258
+ * const report = validator.validate([noirProof, halo2Proof])
259
+ *
260
+ * if (!report.valid) {
261
+ * console.log('Validation errors:', report.checks.filter(c => !c.passed))
262
+ * }
263
+ * ```
264
+ */
265
+ export class CrossSystemValidator {
266
+ private _options: ValidationOptions
267
+ private _systemInfo: Record<ProofSystem, SystemInfo>
268
+
269
+ constructor(options: ValidationOptions = {}) {
270
+ this._options = options
271
+ this._systemInfo = { ...SYSTEM_INFO }
272
+
273
+ // Apply any overrides
274
+ if (options.systemOverrides) {
275
+ for (const [system, override] of Object.entries(options.systemOverrides)) {
276
+ const systemKey = system as ProofSystem
277
+ if (this._systemInfo[systemKey]) {
278
+ this._systemInfo[systemKey] = {
279
+ ...this._systemInfo[systemKey],
280
+ ...override,
281
+ }
282
+ }
283
+ }
284
+ }
285
+ }
286
+
287
+ // ─── Main Validation ─────────────────────────────────────────────────────
288
+
289
+ /**
290
+ * Validate proofs for cross-system composition
291
+ */
292
+ validate(proofs: SingleProof[], options?: ValidationOptions): ValidationReport {
293
+ const startTime = Date.now()
294
+ const opts = { ...this._options, ...options }
295
+ const checks: ValidationCheck[] = []
296
+ const systems = new Set<ProofSystem>()
297
+
298
+ // Collect systems involved
299
+ for (const proof of proofs) {
300
+ systems.add(proof.metadata.system)
301
+ }
302
+
303
+ const systemsArray = Array.from(systems)
304
+
305
+ // Perform validation checks
306
+ if (!opts.skipFieldCheck) {
307
+ checks.push(...this.validateFieldCompatibility(proofs))
308
+ }
309
+
310
+ if (!opts.skipCurveCheck) {
311
+ checks.push(...this.validateCurveCompatibility(systemsArray))
312
+ }
313
+
314
+ if (!opts.skipInputOutputCheck) {
315
+ checks.push(...this.validateInputOutputMatching(proofs))
316
+ }
317
+
318
+ if (!opts.skipLinkageCheck) {
319
+ checks.push(...this.validateLinkageIntegrity(proofs))
320
+ }
321
+
322
+ // Add semantic validation
323
+ checks.push(...this.validateSemanticConsistency(proofs))
324
+
325
+ // Count errors and warnings
326
+ const errorCount = checks.filter(c => !c.passed && c.severity === 'error').length
327
+ const warningCount = checks.filter(c => !c.passed && c.severity === 'warning').length
328
+
329
+ // Determine overall validity
330
+ const valid = opts.strictMode
331
+ ? errorCount === 0 && warningCount === 0
332
+ : errorCount === 0
333
+
334
+ // Build compatibility matrix
335
+ const compatibilityMatrix = this.buildCompatibilityMatrix(systemsArray)
336
+
337
+ // Generate recommendations
338
+ const recommendations = this.generateRecommendations(proofs, checks)
339
+
340
+ return {
341
+ valid,
342
+ checks,
343
+ errorCount,
344
+ warningCount,
345
+ validationTimeMs: Date.now() - startTime,
346
+ proofsValidated: proofs.length,
347
+ systemsInvolved: systemsArray,
348
+ compatibilityMatrix,
349
+ recommendations,
350
+ }
351
+ }
352
+
353
+ /**
354
+ * Validate a composed proof
355
+ */
356
+ validateComposed(composedProof: ComposedProof, options?: ValidationOptions): ValidationReport {
357
+ return this.validate(composedProof.proofs, options)
358
+ }
359
+
360
+ /**
361
+ * Quick check if two systems are compatible
362
+ */
363
+ areSystemsCompatible(system1: ProofSystem, system2: ProofSystem): boolean {
364
+ const info1 = this._systemInfo[system1]
365
+ const info2 = this._systemInfo[system2]
366
+
367
+ if (!info1 || !info2) return false
368
+
369
+ // Same system is always compatible
370
+ if (system1 === system2) return true
371
+
372
+ // Check curve family compatibility
373
+ const family1 = this.getCurveFamily(info1.primaryCurve)
374
+ const family2 = this.getCurveFamily(info2.primaryCurve)
375
+
376
+ return family1 === family2
377
+ }
378
+
379
+ /**
380
+ * Get system information
381
+ */
382
+ getSystemInfo(system: ProofSystem): SystemInfo | undefined {
383
+ return this._systemInfo[system]
384
+ }
385
+
386
+ // ─── Field Validation ────────────────────────────────────────────────────
387
+
388
+ private validateFieldCompatibility(proofs: SingleProof[]): ValidationCheck[] {
389
+ const checks: ValidationCheck[] = []
390
+
391
+ // Group proofs by system
392
+ const proofsBySystem = new Map<ProofSystem, SingleProof[]>()
393
+ for (const proof of proofs) {
394
+ const system = proof.metadata.system
395
+ const existing = proofsBySystem.get(system) || []
396
+ existing.push(proof)
397
+ proofsBySystem.set(system, existing)
398
+ }
399
+
400
+ // Validate field sizes between different systems
401
+ const systems = Array.from(proofsBySystem.keys())
402
+ for (let i = 0; i < systems.length; i++) {
403
+ for (let j = i + 1; j < systems.length; j++) {
404
+ const system1 = systems[i]
405
+ const system2 = systems[j]
406
+ const info1 = this._systemInfo[system1]
407
+ const info2 = this._systemInfo[system2]
408
+
409
+ if (!info1 || !info2) continue
410
+
411
+ // Check if field sizes are compatible
412
+ const sizeDiff = Math.abs(info1.field.scalarFieldSize - info2.field.scalarFieldSize)
413
+ const passed = sizeDiff <= 1 // Allow 1-bit difference
414
+
415
+ checks.push({
416
+ checkId: `field-size-${system1}-${system2}`,
417
+ name: `Field Size Compatibility: ${system1} <-> ${system2}`,
418
+ passed,
419
+ severity: passed ? 'info' : 'warning',
420
+ message: passed
421
+ ? `Field sizes are compatible (${info1.field.scalarFieldSize} vs ${info2.field.scalarFieldSize} bits)`
422
+ : `Field size mismatch: ${system1} uses ${info1.field.scalarFieldSize}-bit field, ${system2} uses ${info2.field.scalarFieldSize}-bit field`,
423
+ context: {
424
+ system1FieldSize: info1.field.scalarFieldSize,
425
+ system2FieldSize: info2.field.scalarFieldSize,
426
+ },
427
+ })
428
+
429
+ // Check modulus compatibility
430
+ const modulusCompatible = info1.field.modulus === info2.field.modulus
431
+
432
+ checks.push({
433
+ checkId: `field-modulus-${system1}-${system2}`,
434
+ name: `Field Modulus Compatibility: ${system1} <-> ${system2}`,
435
+ passed: modulusCompatible,
436
+ severity: modulusCompatible ? 'info' : 'warning',
437
+ message: modulusCompatible
438
+ ? 'Fields use the same modulus'
439
+ : `Different field moduli - may require value conversion`,
440
+ context: {
441
+ sameModulus: modulusCompatible,
442
+ },
443
+ })
444
+ }
445
+ }
446
+
447
+ return checks
448
+ }
449
+
450
+ // ─── Curve Validation ────────────────────────────────────────────────────
451
+
452
+ private validateCurveCompatibility(systems: ProofSystem[]): ValidationCheck[] {
453
+ const checks: ValidationCheck[] = []
454
+
455
+ // Build curve family map
456
+ const familyCount = new Map<string, ProofSystem[]>()
457
+ for (const system of systems) {
458
+ const info = this._systemInfo[system]
459
+ if (!info) continue
460
+
461
+ const family = this.getCurveFamily(info.primaryCurve)
462
+ const existing = familyCount.get(family) || []
463
+ existing.push(system)
464
+ familyCount.set(family, existing)
465
+ }
466
+
467
+ // Check if all systems use curves from the same family
468
+ const families = Array.from(familyCount.keys())
469
+ const allSameFamily = families.length === 1
470
+
471
+ checks.push({
472
+ checkId: 'curve-family-check',
473
+ name: 'Curve Family Consistency',
474
+ passed: allSameFamily,
475
+ severity: allSameFamily ? 'info' : 'error',
476
+ message: allSameFamily
477
+ ? `All systems use ${families[0]} curve family`
478
+ : `Multiple curve families detected: ${families.join(', ')}. Cross-family composition requires special handling.`,
479
+ context: {
480
+ families: Object.fromEntries(familyCount),
481
+ },
482
+ })
483
+
484
+ // For each pair, check direct curve compatibility
485
+ for (let i = 0; i < systems.length; i++) {
486
+ for (let j = i + 1; j < systems.length; j++) {
487
+ const system1 = systems[i]
488
+ const system2 = systems[j]
489
+ const info1 = this._systemInfo[system1]
490
+ const info2 = this._systemInfo[system2]
491
+
492
+ if (!info1 || !info2) continue
493
+
494
+ const sameCurve = info1.primaryCurve === info2.primaryCurve
495
+ const cycleCompatible = this.areCycleCompatible(info1, info2)
496
+
497
+ checks.push({
498
+ checkId: `curve-compat-${system1}-${system2}`,
499
+ name: `Curve Compatibility: ${system1} <-> ${system2}`,
500
+ passed: sameCurve || cycleCompatible,
501
+ severity: sameCurve || cycleCompatible ? 'info' : 'warning',
502
+ message: sameCurve
503
+ ? `Both use ${info1.primaryCurve} curve`
504
+ : cycleCompatible
505
+ ? `Compatible via Pasta cycle (${info1.primaryCurve}/${info2.primaryCurve})`
506
+ : `Different curves: ${info1.primaryCurve} vs ${info2.primaryCurve}`,
507
+ context: {
508
+ curve1: info1.primaryCurve,
509
+ curve2: info2.primaryCurve,
510
+ sameCurve,
511
+ cycleCompatible,
512
+ },
513
+ })
514
+ }
515
+ }
516
+
517
+ return checks
518
+ }
519
+
520
+ private getCurveFamily(curve: EllipticCurve): string {
521
+ for (const [family, curves] of Object.entries(CURVE_FAMILIES)) {
522
+ if (curves.includes(curve)) {
523
+ return family
524
+ }
525
+ }
526
+ return 'unknown'
527
+ }
528
+
529
+ private areCycleCompatible(info1: SystemInfo, info2: SystemInfo): boolean {
530
+ // Pasta curves form a cycle (Pallas/Vesta)
531
+ const pastaCurves: EllipticCurve[] = ['pallas', 'vesta']
532
+ const info1IsPasta = pastaCurves.includes(info1.primaryCurve) ||
533
+ Boolean(info1.secondaryCurve && pastaCurves.includes(info1.secondaryCurve))
534
+ const info2IsPasta = pastaCurves.includes(info2.primaryCurve) ||
535
+ Boolean(info2.secondaryCurve && pastaCurves.includes(info2.secondaryCurve))
536
+
537
+ return info1IsPasta && info2IsPasta
538
+ }
539
+
540
+ // ─── Input/Output Validation ─────────────────────────────────────────────
541
+
542
+ private validateInputOutputMatching(proofs: SingleProof[]): ValidationCheck[] {
543
+ const checks: ValidationCheck[] = []
544
+
545
+ // Check if public inputs are properly formatted
546
+ for (const proof of proofs) {
547
+ const hasValidInputs = proof.publicInputs.every(input =>
548
+ typeof input === 'string' && input.startsWith('0x')
549
+ )
550
+
551
+ checks.push({
552
+ checkId: `input-format-${proof.id}`,
553
+ name: `Public Input Format: ${proof.id}`,
554
+ passed: hasValidInputs,
555
+ severity: hasValidInputs ? 'info' : 'error',
556
+ message: hasValidInputs
557
+ ? `All ${proof.publicInputs.length} public inputs are properly formatted`
558
+ : 'Some public inputs are not in valid hex format',
559
+ context: {
560
+ proofId: proof.id,
561
+ inputCount: proof.publicInputs.length,
562
+ },
563
+ })
564
+ }
565
+
566
+ // Check for input/output linkage between sequential proofs
567
+ for (let i = 0; i < proofs.length - 1; i++) {
568
+ const current = proofs[i]
569
+ const next = proofs[i + 1]
570
+
571
+ // Check if proofs have overlapping public inputs (suggesting linkage)
572
+ const currentInputsSet = new Set(current.publicInputs)
573
+ const hasOverlap = next.publicInputs.some(input => currentInputsSet.has(input))
574
+
575
+ checks.push({
576
+ checkId: `input-linkage-${current.id}-${next.id}`,
577
+ name: `Input Linkage: ${current.id} -> ${next.id}`,
578
+ passed: true, // This is informational
579
+ severity: 'info',
580
+ message: hasOverlap
581
+ ? 'Proofs share common public inputs (linked)'
582
+ : 'Proofs have independent public inputs',
583
+ context: {
584
+ sourceProofId: current.id,
585
+ targetProofId: next.id,
586
+ hasOverlap,
587
+ },
588
+ })
589
+ }
590
+
591
+ return checks
592
+ }
593
+
594
+ // ─── Linkage Validation ──────────────────────────────────────────────────
595
+
596
+ private validateLinkageIntegrity(proofs: SingleProof[]): ValidationCheck[] {
597
+ const checks: ValidationCheck[] = []
598
+
599
+ // Check proof chain integrity
600
+ for (let i = 1; i < proofs.length; i++) {
601
+ const prevProof = proofs[i - 1]
602
+ const currProof = proofs[i]
603
+ const currWithLink = currProof as SingleProof & { linkHash?: HexString }
604
+
605
+ if (currWithLink.linkHash) {
606
+ // Verify the link hash
607
+ const expectedHash = this.computeLinkHash(prevProof, currProof)
608
+ const linkValid = expectedHash === currWithLink.linkHash
609
+
610
+ checks.push({
611
+ checkId: `link-integrity-${currProof.id}`,
612
+ name: `Link Integrity: ${prevProof.id} -> ${currProof.id}`,
613
+ passed: linkValid,
614
+ severity: linkValid ? 'info' : 'error',
615
+ message: linkValid
616
+ ? 'Proof linkage hash verified'
617
+ : 'Proof linkage hash mismatch - chain integrity compromised',
618
+ context: {
619
+ expectedHash,
620
+ actualHash: currWithLink.linkHash,
621
+ },
622
+ })
623
+ }
624
+ }
625
+
626
+ // Check timestamp ordering
627
+ let timestampOrdered = true
628
+ for (let i = 1; i < proofs.length; i++) {
629
+ if (proofs[i].metadata.generatedAt < proofs[i - 1].metadata.generatedAt) {
630
+ timestampOrdered = false
631
+ break
632
+ }
633
+ }
634
+
635
+ checks.push({
636
+ checkId: 'timestamp-ordering',
637
+ name: 'Proof Timestamp Ordering',
638
+ passed: timestampOrdered,
639
+ severity: timestampOrdered ? 'info' : 'warning',
640
+ message: timestampOrdered
641
+ ? 'Proofs are correctly ordered by generation time'
642
+ : 'Proofs are not in chronological order - may indicate incorrect composition',
643
+ })
644
+
645
+ return checks
646
+ }
647
+
648
+ private computeLinkHash(sourceProof: SingleProof, targetProof: SingleProof): HexString {
649
+ const combinedData = sourceProof.proof + targetProof.proof
650
+ let hash = 0
651
+ for (let i = 0; i < combinedData.length; i++) {
652
+ const char = combinedData.charCodeAt(i)
653
+ hash = ((hash << 5) - hash) + char
654
+ hash = hash & hash
655
+ }
656
+ return `0x${Math.abs(hash).toString(16).padStart(64, '0')}` as HexString
657
+ }
658
+
659
+ // ─── Semantic Validation ─────────────────────────────────────────────────
660
+
661
+ private validateSemanticConsistency(proofs: SingleProof[]): ValidationCheck[] {
662
+ const checks: ValidationCheck[] = []
663
+
664
+ // Check circuit ID consistency within same-system proofs
665
+ const circuitsBySystem = new Map<ProofSystem, Set<string>>()
666
+ for (const proof of proofs) {
667
+ const system = proof.metadata.system
668
+ const existing = circuitsBySystem.get(system) || new Set()
669
+ existing.add(proof.metadata.circuitId)
670
+ circuitsBySystem.set(system, existing)
671
+ }
672
+
673
+ for (const [system, circuits] of circuitsBySystem) {
674
+ checks.push({
675
+ checkId: `circuit-diversity-${system}`,
676
+ name: `Circuit Diversity: ${system}`,
677
+ passed: true, // Informational
678
+ severity: 'info',
679
+ message: `${system} proofs use ${circuits.size} distinct circuit(s): ${Array.from(circuits).join(', ')}`,
680
+ context: {
681
+ system,
682
+ circuitCount: circuits.size,
683
+ circuits: Array.from(circuits),
684
+ },
685
+ })
686
+ }
687
+
688
+ // Check for expired proofs
689
+ const now = Date.now()
690
+ for (const proof of proofs) {
691
+ const expiresAt = proof.metadata.expiresAt
692
+ if (expiresAt) {
693
+ const expired = expiresAt < now
694
+
695
+ checks.push({
696
+ checkId: `proof-expiry-${proof.id}`,
697
+ name: `Proof Expiry: ${proof.id}`,
698
+ passed: !expired,
699
+ severity: expired ? 'error' : 'info',
700
+ message: expired
701
+ ? `Proof expired at ${new Date(expiresAt).toISOString()}`
702
+ : expiresAt
703
+ ? `Proof valid until ${new Date(expiresAt).toISOString()}`
704
+ : 'Proof has no expiry',
705
+ context: {
706
+ proofId: proof.id,
707
+ expiresAt,
708
+ expired,
709
+ },
710
+ })
711
+ }
712
+ }
713
+
714
+ // Check proof size consistency
715
+ const proofSizes = proofs.map(p => p.metadata.proofSizeBytes)
716
+ const avgSize = proofSizes.reduce((a, b) => a + b, 0) / proofSizes.length
717
+ const maxDeviation = Math.max(...proofSizes.map(s => Math.abs(s - avgSize)))
718
+ const sizeConsistent = maxDeviation < avgSize * 2 // Within 200% of average
719
+
720
+ checks.push({
721
+ checkId: 'proof-size-consistency',
722
+ name: 'Proof Size Consistency',
723
+ passed: sizeConsistent,
724
+ severity: sizeConsistent ? 'info' : 'warning',
725
+ message: sizeConsistent
726
+ ? `Proof sizes are consistent (avg: ${Math.round(avgSize)} bytes)`
727
+ : `High proof size variance detected (avg: ${Math.round(avgSize)}, max deviation: ${Math.round(maxDeviation)})`,
728
+ context: {
729
+ averageSize: Math.round(avgSize),
730
+ maxDeviation: Math.round(maxDeviation),
731
+ sizes: proofSizes,
732
+ },
733
+ })
734
+
735
+ return checks
736
+ }
737
+
738
+ // ─── Compatibility Matrix ────────────────────────────────────────────────
739
+
740
+ private buildCompatibilityMatrix(systems: ProofSystem[]): CompatibilityEntry[][] {
741
+ const matrix: CompatibilityEntry[][] = []
742
+
743
+ for (const source of systems) {
744
+ const row: CompatibilityEntry[] = []
745
+ for (const target of systems) {
746
+ row.push(this.getCompatibilityEntry(source, target))
747
+ }
748
+ matrix.push(row)
749
+ }
750
+
751
+ return matrix
752
+ }
753
+
754
+ private getCompatibilityEntry(source: ProofSystem, target: ProofSystem): CompatibilityEntry {
755
+ const sourceInfo = this._systemInfo[source]
756
+ const targetInfo = this._systemInfo[target]
757
+
758
+ if (!sourceInfo || !targetInfo) {
759
+ return {
760
+ sourceSystem: source,
761
+ targetSystem: target,
762
+ compatible: false,
763
+ level: 'none',
764
+ requiredConversions: ['unknown-system'],
765
+ }
766
+ }
767
+
768
+ // Same system - full compatibility
769
+ if (source === target) {
770
+ return {
771
+ sourceSystem: source,
772
+ targetSystem: target,
773
+ compatible: true,
774
+ level: 'full',
775
+ requiredConversions: [],
776
+ }
777
+ }
778
+
779
+ // Check curve family
780
+ const sourceFamily = this.getCurveFamily(sourceInfo.primaryCurve)
781
+ const targetFamily = this.getCurveFamily(targetInfo.primaryCurve)
782
+
783
+ if (sourceFamily === targetFamily) {
784
+ // Same curve family - partial compatibility
785
+ return {
786
+ sourceSystem: source,
787
+ targetSystem: target,
788
+ compatible: true,
789
+ level: 'partial',
790
+ requiredConversions: ['format-conversion'],
791
+ }
792
+ }
793
+
794
+ // Different curve families - requires field conversion
795
+ return {
796
+ sourceSystem: source,
797
+ targetSystem: target,
798
+ compatible: true,
799
+ level: 'partial',
800
+ requiredConversions: ['field-conversion', 'format-conversion'],
801
+ }
802
+ }
803
+
804
+ // ─── Recommendations ─────────────────────────────────────────────────────
805
+
806
+ private generateRecommendations(proofs: SingleProof[], checks: ValidationCheck[]): string[] {
807
+ const recommendations: string[] = []
808
+
809
+ // Check for curve incompatibilities
810
+ const curveErrors = checks.filter(c =>
811
+ c.checkId.startsWith('curve-') && !c.passed
812
+ )
813
+ if (curveErrors.length > 0) {
814
+ recommendations.push(
815
+ 'Consider using proof systems from the same curve family (e.g., Halo2 + Kimchi for Pasta curves, or Noir + Groth16 for BN254)'
816
+ )
817
+ }
818
+
819
+ // Check for field mismatches
820
+ const fieldWarnings = checks.filter(c =>
821
+ c.checkId.startsWith('field-') && !c.passed
822
+ )
823
+ if (fieldWarnings.length > 0) {
824
+ recommendations.push(
825
+ 'Field element values may need conversion when composing proofs from different systems'
826
+ )
827
+ }
828
+
829
+ // Check for expired proofs
830
+ const expiredProofs = checks.filter(c =>
831
+ c.checkId.startsWith('proof-expiry-') && !c.passed
832
+ )
833
+ if (expiredProofs.length > 0) {
834
+ recommendations.push(
835
+ 'Regenerate expired proofs before composition'
836
+ )
837
+ }
838
+
839
+ // Suggest batching for same-system proofs
840
+ const proofsBySystem = new Map<ProofSystem, number>()
841
+ for (const proof of proofs) {
842
+ const count = proofsBySystem.get(proof.metadata.system) || 0
843
+ proofsBySystem.set(proof.metadata.system, count + 1)
844
+ }
845
+
846
+ for (const [system, count] of proofsBySystem) {
847
+ if (count > 2) {
848
+ const info = this._systemInfo[system]
849
+ if (info?.supportsRecursion) {
850
+ recommendations.push(
851
+ `Consider using recursive aggregation for the ${count} ${system} proofs`
852
+ )
853
+ }
854
+ }
855
+ }
856
+
857
+ // General optimization suggestion
858
+ if (proofs.length > 5) {
859
+ recommendations.push(
860
+ 'For large compositions, consider using parallel verification to improve performance'
861
+ )
862
+ }
863
+
864
+ return recommendations
865
+ }
866
+ }
867
+
868
+ // ─── Factory Function ────────────────────────────────────────────────────────
869
+
870
+ /**
871
+ * Create a cross-system validator with optional configuration
872
+ */
873
+ export function createCrossSystemValidator(
874
+ options?: ValidationOptions
875
+ ): CrossSystemValidator {
876
+ return new CrossSystemValidator(options)
877
+ }
878
+
879
+ // ─── Export Constants ────────────────────────────────────────────────────────
880
+
881
+ export { BN254_MODULUS, PALLAS_MODULUS, VESTA_MODULUS, BLS12_381_MODULUS }