@sip-protocol/sdk 0.7.2 → 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.
- package/LICENSE +21 -0
- package/README.md +267 -0
- package/dist/{TransportWebUSB-TQ7WZ4LE.mjs → TransportWebUSB-YQMAGJAJ.mjs} +12 -9
- package/dist/browser.d.mts +10 -4
- package/dist/browser.d.ts +10 -4
- package/dist/browser.js +48874 -18336
- package/dist/browser.mjs +674 -48
- package/dist/chunk-4GRJ5MAW.mjs +152 -0
- package/dist/chunk-5D7A3L3W.mjs +717 -0
- package/dist/chunk-64AYA5F5.mjs +7834 -0
- package/dist/chunk-GMDGB22A.mjs +379 -0
- package/dist/chunk-I534WKN7.mjs +328 -0
- package/dist/chunk-IBZVA5Y7.mjs +1003 -0
- package/dist/chunk-PRRZAWJE.mjs +223 -0
- package/dist/{chunk-UJCSKKID.mjs → chunk-XGB3TDIC.mjs} +13 -1
- package/dist/chunk-YWGJ77A2.mjs +33806 -0
- package/dist/{chunk-6WGN57S2.mjs → chunk-Z3K7W5S3.mjs} +48 -0
- package/dist/constants-LHAAUC2T.mjs +51 -0
- package/dist/dist-2OGQ7FED.mjs +3957 -0
- package/dist/dist-IFHPYLDX.mjs +254 -0
- package/dist/fulfillment_proof-ANHVPKTB.mjs +21 -0
- package/dist/funding_proof-ICFZ5LHY.mjs +21 -0
- package/dist/index-DXh2IGkz.d.ts +24681 -0
- package/dist/index-DeE1ZzA4.d.mts +24681 -0
- package/dist/index.d.mts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +48676 -17318
- package/dist/index.mjs +583 -19
- package/dist/interface-Bf7w1PLW.d.mts +679 -0
- package/dist/interface-Bf7w1PLW.d.ts +679 -0
- package/dist/{noir-DKfEzWy9.d.mts → noir-kzbLVTei.d.mts} +31 -21
- package/dist/{noir-DKfEzWy9.d.ts → noir-kzbLVTei.d.ts} +31 -21
- package/dist/proofs/halo2.d.mts +151 -0
- package/dist/proofs/halo2.d.ts +151 -0
- package/dist/proofs/halo2.js +350 -0
- package/dist/proofs/halo2.mjs +11 -0
- package/dist/proofs/kimchi.d.mts +160 -0
- package/dist/proofs/kimchi.d.ts +160 -0
- package/dist/proofs/kimchi.js +431 -0
- package/dist/proofs/kimchi.mjs +13 -0
- package/dist/proofs/noir.d.mts +1 -1
- package/dist/proofs/noir.d.ts +1 -1
- package/dist/proofs/noir.js +74 -18
- package/dist/proofs/noir.mjs +84 -24
- package/dist/solana-U3MEGU7W.mjs +280 -0
- package/dist/validity_proof-3POXLPNY.mjs +21 -0
- package/package.json +54 -21
- package/src/adapters/index.ts +41 -0
- package/src/adapters/jupiter.ts +571 -0
- package/src/adapters/near-intents.ts +135 -0
- package/src/advisor/advisor.ts +653 -0
- package/src/advisor/index.ts +54 -0
- package/src/advisor/tools.ts +303 -0
- package/src/advisor/types.ts +164 -0
- package/src/chains/ethereum/announcement.ts +536 -0
- package/src/chains/ethereum/bnb-optimizations.ts +474 -0
- package/src/chains/ethereum/commitment.ts +522 -0
- package/src/chains/ethereum/constants.ts +462 -0
- package/src/chains/ethereum/deployment.ts +596 -0
- package/src/chains/ethereum/gas-estimation.ts +538 -0
- package/src/chains/ethereum/index.ts +268 -0
- package/src/chains/ethereum/optimizations.ts +614 -0
- package/src/chains/ethereum/privacy-adapter.ts +855 -0
- package/src/chains/ethereum/registry.ts +584 -0
- package/src/chains/ethereum/rpc.ts +905 -0
- package/src/chains/ethereum/stealth.ts +491 -0
- package/src/chains/ethereum/token.ts +790 -0
- package/src/chains/ethereum/transfer.ts +637 -0
- package/src/chains/ethereum/types.ts +456 -0
- package/src/chains/ethereum/viewing-key.ts +455 -0
- package/src/chains/near/commitment.ts +608 -0
- package/src/chains/near/constants.ts +284 -0
- package/src/chains/near/function-call.ts +871 -0
- package/src/chains/near/history.ts +654 -0
- package/src/chains/near/implicit-account.ts +840 -0
- package/src/chains/near/index.ts +393 -0
- package/src/chains/near/native-transfer.ts +658 -0
- package/src/chains/near/nep141.ts +775 -0
- package/src/chains/near/privacy-adapter.ts +889 -0
- package/src/chains/near/resolver.ts +971 -0
- package/src/chains/near/rpc.ts +1016 -0
- package/src/chains/near/stealth.ts +419 -0
- package/src/chains/near/types.ts +317 -0
- package/src/chains/near/viewing-key.ts +876 -0
- package/src/chains/solana/anchor-transfer.ts +386 -0
- package/src/chains/solana/commitment.ts +577 -0
- package/src/chains/solana/constants.ts +126 -12
- package/src/chains/solana/ephemeral-keys.ts +543 -0
- package/src/chains/solana/index.ts +276 -1
- package/src/chains/solana/key-derivation.ts +418 -0
- package/src/chains/solana/kit-compat.ts +334 -0
- package/src/chains/solana/optimizations.ts +560 -0
- package/src/chains/solana/privacy-adapter.ts +605 -0
- package/src/chains/solana/providers/generic.ts +201 -0
- package/src/chains/solana/providers/helius-enhanced-types.ts +336 -0
- package/src/chains/solana/providers/helius-enhanced.ts +623 -0
- package/src/chains/solana/providers/helius.ts +402 -0
- package/src/chains/solana/providers/index.ts +85 -0
- package/src/chains/solana/providers/interface.ts +221 -0
- package/src/chains/solana/providers/quicknode.ts +409 -0
- package/src/chains/solana/providers/triton.ts +426 -0
- package/src/chains/solana/providers/webhook.ts +790 -0
- package/src/chains/solana/rpc-client.ts +1150 -0
- package/src/chains/solana/scan.ts +170 -73
- package/src/chains/solana/sol-transfer.ts +732 -0
- package/src/chains/solana/spl-transfer.ts +886 -0
- package/src/chains/solana/stealth-scanner.ts +703 -0
- package/src/chains/solana/sunspot-verifier.ts +453 -0
- package/src/chains/solana/transaction-builder.ts +755 -0
- package/src/chains/solana/transfer.ts +74 -5
- package/src/chains/solana/types.ts +77 -7
- package/src/chains/solana/utils.ts +110 -0
- package/src/chains/solana/viewing-key.ts +807 -0
- package/src/compliance/fireblocks.ts +921 -0
- package/src/compliance/index.ts +37 -0
- package/src/compliance/range-sas.ts +956 -0
- package/src/config/endpoints.ts +100 -0
- package/src/crypto.ts +11 -8
- package/src/errors.ts +82 -0
- package/src/evm/erc4337-relayer.ts +830 -0
- package/src/evm/index.ts +47 -0
- package/src/fees/calculator.ts +396 -0
- package/src/fees/index.ts +87 -0
- package/src/fees/near-contract.ts +429 -0
- package/src/fees/types.ts +268 -0
- package/src/index.ts +785 -1
- package/src/intent.ts +6 -3
- package/src/logger.ts +324 -0
- package/src/network/index.ts +80 -0
- package/src/network/proxy.ts +691 -0
- package/src/optimizations/index.ts +541 -0
- package/src/oracle/types.ts +1 -0
- package/src/privacy-backends/arcium-types.ts +727 -0
- package/src/privacy-backends/arcium.ts +719 -0
- package/src/privacy-backends/combined-privacy.ts +866 -0
- package/src/privacy-backends/cspl-token.ts +595 -0
- package/src/privacy-backends/cspl-types.ts +512 -0
- package/src/privacy-backends/cspl.ts +907 -0
- package/src/privacy-backends/health.ts +488 -0
- package/src/privacy-backends/inco-types.ts +323 -0
- package/src/privacy-backends/inco.ts +616 -0
- package/src/privacy-backends/index.ts +336 -0
- package/src/privacy-backends/interface.ts +906 -0
- package/src/privacy-backends/lru-cache.ts +343 -0
- package/src/privacy-backends/magicblock.ts +458 -0
- package/src/privacy-backends/mock.ts +258 -0
- package/src/privacy-backends/privacycash-types.ts +278 -0
- package/src/privacy-backends/privacycash.ts +456 -0
- package/src/privacy-backends/private-swap.ts +570 -0
- package/src/privacy-backends/rate-limiter.ts +683 -0
- package/src/privacy-backends/registry.ts +690 -0
- package/src/privacy-backends/router.ts +626 -0
- package/src/privacy-backends/shadowwire.ts +449 -0
- package/src/privacy-backends/sip-native.ts +256 -0
- package/src/privacy-logger.ts +191 -0
- package/src/production-safety.ts +373 -0
- package/src/proofs/aggregator.ts +1029 -0
- package/src/proofs/browser-composer.ts +1150 -0
- package/src/proofs/browser.ts +113 -25
- package/src/proofs/cache/index.ts +127 -0
- package/src/proofs/cache/interface.ts +545 -0
- package/src/proofs/cache/key-generator.ts +188 -0
- package/src/proofs/cache/lru-cache.ts +481 -0
- package/src/proofs/cache/multi-tier-cache.ts +575 -0
- package/src/proofs/cache/persistent-cache.ts +788 -0
- package/src/proofs/compliance-proof.ts +872 -0
- package/src/proofs/composer/base.ts +923 -0
- package/src/proofs/composer/index.ts +25 -0
- package/src/proofs/composer/interface.ts +518 -0
- package/src/proofs/composer/types.ts +383 -0
- package/src/proofs/converters/halo2.ts +452 -0
- package/src/proofs/converters/index.ts +208 -0
- package/src/proofs/converters/interface.ts +363 -0
- package/src/proofs/converters/kimchi.ts +462 -0
- package/src/proofs/converters/noir.ts +451 -0
- package/src/proofs/fallback.ts +888 -0
- package/src/proofs/halo2.ts +42 -0
- package/src/proofs/index.ts +471 -0
- package/src/proofs/interface.ts +13 -0
- package/src/proofs/kimchi.ts +42 -0
- package/src/proofs/lazy.ts +1004 -0
- package/src/proofs/mock.ts +25 -1
- package/src/proofs/noir.ts +111 -30
- package/src/proofs/orchestrator.ts +960 -0
- package/src/proofs/parallel/concurrency.ts +297 -0
- package/src/proofs/parallel/dependency-graph.ts +602 -0
- package/src/proofs/parallel/executor.ts +420 -0
- package/src/proofs/parallel/index.ts +131 -0
- package/src/proofs/parallel/interface.ts +685 -0
- package/src/proofs/parallel/worker-pool.ts +644 -0
- package/src/proofs/providers/halo2.ts +560 -0
- package/src/proofs/providers/index.ts +34 -0
- package/src/proofs/providers/kimchi.ts +641 -0
- package/src/proofs/validator.ts +881 -0
- package/src/proofs/verifier.ts +867 -0
- package/src/quantum/index.ts +112 -0
- package/src/quantum/winternitz-vault.ts +639 -0
- package/src/quantum/wots.ts +611 -0
- package/src/settlement/backends/direct-chain.ts +1 -0
- package/src/settlement/index.ts +9 -0
- package/src/settlement/router.ts +732 -46
- package/src/solana/index.ts +72 -0
- package/src/solana/jito-relayer.ts +687 -0
- package/src/solana/noir-verifier-types.ts +430 -0
- package/src/solana/noir-verifier.ts +816 -0
- package/src/stealth/address-derivation.ts +193 -0
- package/src/stealth/ed25519.ts +431 -0
- package/src/stealth/index.ts +233 -0
- package/src/stealth/meta-address.ts +221 -0
- package/src/stealth/secp256k1.ts +368 -0
- package/src/stealth/utils.ts +194 -0
- package/src/stealth.ts +50 -1504
- package/src/surveillance/algorithms/address-reuse.ts +143 -0
- package/src/surveillance/algorithms/cluster.ts +247 -0
- package/src/surveillance/algorithms/exchange.ts +295 -0
- package/src/surveillance/algorithms/temporal.ts +337 -0
- package/src/surveillance/analyzer.ts +442 -0
- package/src/surveillance/index.ts +64 -0
- package/src/surveillance/scoring.ts +372 -0
- package/src/surveillance/types.ts +264 -0
- package/src/sync/index.ts +106 -0
- package/src/sync/manager.ts +504 -0
- package/src/sync/mock-provider.ts +318 -0
- package/src/sync/oblivious.ts +625 -0
- package/src/tokens/index.ts +15 -0
- package/src/tokens/registry.ts +301 -0
- package/src/utils/deprecation.ts +94 -0
- package/src/utils/index.ts +9 -0
- package/src/wallet/ethereum/index.ts +68 -0
- package/src/wallet/ethereum/metamask-privacy.ts +420 -0
- package/src/wallet/ethereum/multi-wallet.ts +646 -0
- package/src/wallet/ethereum/privacy-adapter.ts +700 -0
- package/src/wallet/ethereum/types.ts +3 -1
- package/src/wallet/ethereum/walletconnect-adapter.ts +675 -0
- package/src/wallet/hardware/index.ts +10 -0
- package/src/wallet/hardware/ledger-privacy.ts +414 -0
- package/src/wallet/index.ts +71 -0
- package/src/wallet/near/adapter.ts +626 -0
- package/src/wallet/near/index.ts +86 -0
- package/src/wallet/near/meteor-wallet.ts +1153 -0
- package/src/wallet/near/my-near-wallet.ts +790 -0
- package/src/wallet/near/wallet-selector.ts +702 -0
- package/src/wallet/solana/adapter.ts +6 -4
- package/src/wallet/solana/index.ts +13 -0
- package/src/wallet/solana/privacy-adapter.ts +567 -0
- package/src/wallet/sui/types.ts +6 -4
- package/src/zcash/rpc-client.ts +13 -6
- package/dist/chunk-3INS3PR5.mjs +0 -884
- package/dist/chunk-3OVABDRH.mjs +0 -17096
- package/dist/chunk-DLDWZFYC.mjs +0 -1495
- package/dist/chunk-E6SZWREQ.mjs +0 -57
- package/dist/chunk-G33LB27A.mjs +0 -16166
- package/dist/chunk-HGU6HZRC.mjs +0 -231
- package/dist/chunk-L2K34JCU.mjs +0 -1496
- package/dist/chunk-SN4ZDTVW.mjs +0 -16166
- package/dist/constants-VOI7BSLK.mjs +0 -27
- package/dist/index-BYZbDjal.d.ts +0 -11390
- package/dist/index-CHB3KuOB.d.mts +0 -11859
- package/dist/index-CzWPI6Le.d.ts +0 -11859
- package/dist/index-xbWjohNq.d.mts +0 -11390
- package/dist/solana-5EMCTPTS.mjs +0 -46
- package/dist/solana-Q4NAVBTS.mjs +0 -46
|
@@ -0,0 +1,867 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proof Verification Pipeline
|
|
3
|
+
*
|
|
4
|
+
* Implements a verification pipeline for composed proofs from multiple ZK systems.
|
|
5
|
+
* Handles verification ordering, cross-validation of proof linkages, and provides
|
|
6
|
+
* detailed verification results.
|
|
7
|
+
*
|
|
8
|
+
* Key features:
|
|
9
|
+
* - Multi-provider verification routing
|
|
10
|
+
* - Dependency-based verification ordering
|
|
11
|
+
* - Cross-proof link validation
|
|
12
|
+
* - Batch verification optimization
|
|
13
|
+
* - Verification proof generation
|
|
14
|
+
* - Caching for repeated verifications
|
|
15
|
+
*
|
|
16
|
+
* @packageDocumentation
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { randomBytes, bytesToHex } from '@noble/hashes/utils'
|
|
20
|
+
|
|
21
|
+
import type {
|
|
22
|
+
ProofSystem,
|
|
23
|
+
SingleProof,
|
|
24
|
+
ComposedProof,
|
|
25
|
+
VerificationResult,
|
|
26
|
+
IndividualVerificationResult,
|
|
27
|
+
HexString,
|
|
28
|
+
} from '@sip-protocol/types'
|
|
29
|
+
|
|
30
|
+
import type { ComposableProofProvider } from './composer/interface'
|
|
31
|
+
|
|
32
|
+
// ─── Types ───────────────────────────────────────────────────────────────────
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Configuration for the verification pipeline
|
|
36
|
+
*/
|
|
37
|
+
export interface VerificationPipelineConfig {
|
|
38
|
+
/** Enable parallel verification where possible */
|
|
39
|
+
enableParallel: boolean
|
|
40
|
+
/** Maximum concurrent verifications */
|
|
41
|
+
maxConcurrent: number
|
|
42
|
+
/** Enable batch verification for same-system proofs */
|
|
43
|
+
enableBatch: boolean
|
|
44
|
+
/** Timeout for individual verification (ms) */
|
|
45
|
+
verificationTimeoutMs: number
|
|
46
|
+
/** Enable verification caching */
|
|
47
|
+
enableCache: boolean
|
|
48
|
+
/** Cache TTL in milliseconds */
|
|
49
|
+
cacheTtlMs: number
|
|
50
|
+
/** Enable verbose logging */
|
|
51
|
+
verbose: boolean
|
|
52
|
+
/** Strict mode - fail fast on first error */
|
|
53
|
+
strictMode: boolean
|
|
54
|
+
/** Generate verification proof */
|
|
55
|
+
generateVerificationProof: boolean
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Proof dependency graph node
|
|
60
|
+
*/
|
|
61
|
+
export interface ProofDependency {
|
|
62
|
+
/** Proof ID */
|
|
63
|
+
proofId: string
|
|
64
|
+
/** IDs of proofs this depends on */
|
|
65
|
+
dependsOn: string[]
|
|
66
|
+
/** IDs of proofs that depend on this */
|
|
67
|
+
dependedBy: string[]
|
|
68
|
+
/** Link hash connecting to previous proof */
|
|
69
|
+
linkHash?: HexString
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Verification order computed from dependency analysis
|
|
74
|
+
*/
|
|
75
|
+
export interface VerificationOrder {
|
|
76
|
+
/** Ordered list of proof IDs to verify */
|
|
77
|
+
order: string[]
|
|
78
|
+
/** Groups that can be verified in parallel */
|
|
79
|
+
parallelGroups: string[][]
|
|
80
|
+
/** Dependency graph */
|
|
81
|
+
dependencies: Map<string, ProofDependency>
|
|
82
|
+
/** Estimated total time */
|
|
83
|
+
estimatedTimeMs: number
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Detailed verification result
|
|
88
|
+
*/
|
|
89
|
+
export interface DetailedVerificationResult extends VerificationResult {
|
|
90
|
+
/** Verification order used */
|
|
91
|
+
verificationOrder: string[]
|
|
92
|
+
/** Cross-link validation results */
|
|
93
|
+
linkValidation: LinkValidationResult[]
|
|
94
|
+
/** Verification proof (if generated) */
|
|
95
|
+
verificationProof?: HexString
|
|
96
|
+
/** Cache hit information */
|
|
97
|
+
cacheStats: {
|
|
98
|
+
hits: number
|
|
99
|
+
misses: number
|
|
100
|
+
}
|
|
101
|
+
/** Per-system verification stats */
|
|
102
|
+
systemStats: Map<ProofSystem, SystemVerificationStats>
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Result of validating a cross-proof link
|
|
107
|
+
*/
|
|
108
|
+
export interface LinkValidationResult {
|
|
109
|
+
/** Source proof ID */
|
|
110
|
+
sourceProofId: string
|
|
111
|
+
/** Target proof ID */
|
|
112
|
+
targetProofId: string
|
|
113
|
+
/** Expected link hash */
|
|
114
|
+
expectedHash: HexString
|
|
115
|
+
/** Computed link hash */
|
|
116
|
+
computedHash: HexString
|
|
117
|
+
/** Whether link is valid */
|
|
118
|
+
valid: boolean
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Statistics for a proof system's verification
|
|
123
|
+
*/
|
|
124
|
+
export interface SystemVerificationStats {
|
|
125
|
+
/** Number of proofs verified */
|
|
126
|
+
proofsVerified: number
|
|
127
|
+
/** Number of successful verifications */
|
|
128
|
+
successCount: number
|
|
129
|
+
/** Number of failed verifications */
|
|
130
|
+
failCount: number
|
|
131
|
+
/** Total verification time */
|
|
132
|
+
totalTimeMs: number
|
|
133
|
+
/** Average verification time */
|
|
134
|
+
avgTimeMs: number
|
|
135
|
+
/** Whether batch verification was used */
|
|
136
|
+
usedBatch: boolean
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Progress event for verification
|
|
141
|
+
*/
|
|
142
|
+
export interface VerificationProgressEvent {
|
|
143
|
+
/** Current step */
|
|
144
|
+
step: number
|
|
145
|
+
/** Total steps */
|
|
146
|
+
totalSteps: number
|
|
147
|
+
/** Operation description */
|
|
148
|
+
operation: string
|
|
149
|
+
/** Proof being verified (if applicable) */
|
|
150
|
+
proofId?: string
|
|
151
|
+
/** Time elapsed */
|
|
152
|
+
elapsedMs: number
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Callback for verification progress
|
|
157
|
+
*/
|
|
158
|
+
export type VerificationProgressCallback = (event: VerificationProgressEvent) => void
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Options for pipeline verification
|
|
162
|
+
*/
|
|
163
|
+
export interface VerifyOptions {
|
|
164
|
+
/** Provider lookup function */
|
|
165
|
+
getProvider: (system: ProofSystem) => ComposableProofProvider | undefined
|
|
166
|
+
/** Progress callback */
|
|
167
|
+
onProgress?: VerificationProgressCallback
|
|
168
|
+
/** Abort signal */
|
|
169
|
+
abortSignal?: AbortSignal
|
|
170
|
+
/** Override config options */
|
|
171
|
+
config?: Partial<VerificationPipelineConfig>
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// ─── Default Configuration ───────────────────────────────────────────────────
|
|
175
|
+
|
|
176
|
+
const DEFAULT_PIPELINE_CONFIG: VerificationPipelineConfig = {
|
|
177
|
+
enableParallel: true,
|
|
178
|
+
maxConcurrent: 4,
|
|
179
|
+
enableBatch: true,
|
|
180
|
+
verificationTimeoutMs: 30000,
|
|
181
|
+
enableCache: true,
|
|
182
|
+
cacheTtlMs: 300000, // 5 minutes
|
|
183
|
+
verbose: false,
|
|
184
|
+
strictMode: false,
|
|
185
|
+
generateVerificationProof: false,
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// ─── Helper Functions ────────────────────────────────────────────────────────
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Generate unique ID
|
|
192
|
+
*/
|
|
193
|
+
function generateId(prefix: string): string {
|
|
194
|
+
return `${prefix}-${bytesToHex(randomBytes(8))}`
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Compute hash for cross-proof link validation
|
|
199
|
+
*/
|
|
200
|
+
function computeLinkHash(sourceProof: SingleProof, targetProof: SingleProof): HexString {
|
|
201
|
+
const combinedData = sourceProof.proof + targetProof.proof
|
|
202
|
+
let hash = 0
|
|
203
|
+
for (let i = 0; i < combinedData.length; i++) {
|
|
204
|
+
const char = combinedData.charCodeAt(i)
|
|
205
|
+
hash = ((hash << 5) - hash) + char
|
|
206
|
+
hash = hash & hash
|
|
207
|
+
}
|
|
208
|
+
return `0x${Math.abs(hash).toString(16).padStart(64, '0')}` as HexString
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
// ─── Verification Pipeline ───────────────────────────────────────────────────
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Verification Pipeline
|
|
216
|
+
*
|
|
217
|
+
* Orchestrates verification of composed proofs from multiple ZK systems.
|
|
218
|
+
*
|
|
219
|
+
* @example
|
|
220
|
+
* ```typescript
|
|
221
|
+
* const pipeline = new VerificationPipeline()
|
|
222
|
+
*
|
|
223
|
+
* const result = await pipeline.verify(composedProof, {
|
|
224
|
+
* getProvider: (system) => composer.getProviderForSystem(system),
|
|
225
|
+
* onProgress: (event) => console.log(event.operation),
|
|
226
|
+
* })
|
|
227
|
+
*
|
|
228
|
+
* if (result.valid) {
|
|
229
|
+
* console.log('All proofs verified!')
|
|
230
|
+
* }
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
export class VerificationPipeline {
|
|
234
|
+
private _config: VerificationPipelineConfig
|
|
235
|
+
private _cache: Map<string, { valid: boolean; expiresAt: number }> = new Map()
|
|
236
|
+
private _cacheHits = 0
|
|
237
|
+
private _cacheMisses = 0
|
|
238
|
+
|
|
239
|
+
constructor(config?: Partial<VerificationPipelineConfig>) {
|
|
240
|
+
this._config = { ...DEFAULT_PIPELINE_CONFIG, ...config }
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// ─── Configuration ─────────────────────────────────────────────────────────
|
|
244
|
+
|
|
245
|
+
get config(): VerificationPipelineConfig {
|
|
246
|
+
return { ...this._config }
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
updateConfig(config: Partial<VerificationPipelineConfig>): void {
|
|
250
|
+
this._config = { ...this._config, ...config }
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// ─── Main Verification ─────────────────────────────────────────────────────
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Verify a composed proof
|
|
257
|
+
*/
|
|
258
|
+
async verify(
|
|
259
|
+
composedProof: ComposedProof,
|
|
260
|
+
options: VerifyOptions,
|
|
261
|
+
): Promise<DetailedVerificationResult> {
|
|
262
|
+
const startTime = Date.now()
|
|
263
|
+
const config = { ...this._config, ...options.config }
|
|
264
|
+
const { getProvider, onProgress, abortSignal } = options
|
|
265
|
+
|
|
266
|
+
if (config.verbose) {
|
|
267
|
+
console.log(`[VerificationPipeline] Starting verification of ${composedProof.proofs.length} proofs`)
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Build dependency graph and compute verification order
|
|
271
|
+
const verificationOrder = this.computeVerificationOrder(composedProof)
|
|
272
|
+
|
|
273
|
+
// Initialize stats
|
|
274
|
+
const systemStats = new Map<ProofSystem, SystemVerificationStats>()
|
|
275
|
+
const results: IndividualVerificationResult[] = []
|
|
276
|
+
const linkValidation: LinkValidationResult[] = []
|
|
277
|
+
|
|
278
|
+
// Verify proofs based on computed order
|
|
279
|
+
if (config.enableParallel && verificationOrder.parallelGroups.length > 0) {
|
|
280
|
+
// Parallel verification with dependency ordering
|
|
281
|
+
await this.verifyParallel(
|
|
282
|
+
composedProof,
|
|
283
|
+
verificationOrder,
|
|
284
|
+
config,
|
|
285
|
+
getProvider,
|
|
286
|
+
results,
|
|
287
|
+
systemStats,
|
|
288
|
+
onProgress,
|
|
289
|
+
abortSignal,
|
|
290
|
+
startTime,
|
|
291
|
+
)
|
|
292
|
+
} else {
|
|
293
|
+
// Sequential verification
|
|
294
|
+
await this.verifySequential(
|
|
295
|
+
composedProof,
|
|
296
|
+
verificationOrder.order,
|
|
297
|
+
config,
|
|
298
|
+
getProvider,
|
|
299
|
+
results,
|
|
300
|
+
systemStats,
|
|
301
|
+
onProgress,
|
|
302
|
+
abortSignal,
|
|
303
|
+
startTime,
|
|
304
|
+
)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Validate cross-proof links
|
|
308
|
+
if (composedProof.proofs.length > 1) {
|
|
309
|
+
await this.validateLinks(composedProof, linkValidation, config)
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Check for abort
|
|
313
|
+
if (abortSignal?.aborted) {
|
|
314
|
+
return this.createAbortedResult(startTime, results, linkValidation, systemStats)
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Compute overall validity
|
|
318
|
+
const allProofsValid = results.every(r => r.valid)
|
|
319
|
+
const allLinksValid = linkValidation.every(l => l.valid)
|
|
320
|
+
const valid = allProofsValid && allLinksValid
|
|
321
|
+
|
|
322
|
+
// Generate verification proof if requested
|
|
323
|
+
let verificationProof: HexString | undefined
|
|
324
|
+
if (config.generateVerificationProof && valid) {
|
|
325
|
+
verificationProof = await this.generateVerificationProof(composedProof, results)
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
const totalTime = Date.now() - startTime
|
|
329
|
+
|
|
330
|
+
if (config.verbose) {
|
|
331
|
+
console.log(`[VerificationPipeline] Verification complete: valid=${valid}, time=${totalTime}ms`)
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
return {
|
|
335
|
+
valid,
|
|
336
|
+
results,
|
|
337
|
+
totalTimeMs: totalTime,
|
|
338
|
+
method: config.enableBatch ? 'batch' : (config.enableParallel ? 'individual' : 'individual'),
|
|
339
|
+
verificationOrder: verificationOrder.order,
|
|
340
|
+
linkValidation,
|
|
341
|
+
verificationProof,
|
|
342
|
+
cacheStats: {
|
|
343
|
+
hits: this._cacheHits,
|
|
344
|
+
misses: this._cacheMisses,
|
|
345
|
+
},
|
|
346
|
+
systemStats,
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Verify a single proof
|
|
352
|
+
*/
|
|
353
|
+
async verifySingle(
|
|
354
|
+
proof: SingleProof,
|
|
355
|
+
getProvider: (system: ProofSystem) => ComposableProofProvider | undefined,
|
|
356
|
+
): Promise<IndividualVerificationResult> {
|
|
357
|
+
const startTime = Date.now()
|
|
358
|
+
|
|
359
|
+
// Check cache
|
|
360
|
+
if (this._config.enableCache) {
|
|
361
|
+
const cached = this._cache.get(proof.id)
|
|
362
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
363
|
+
this._cacheHits++
|
|
364
|
+
return {
|
|
365
|
+
proofId: proof.id,
|
|
366
|
+
valid: cached.valid,
|
|
367
|
+
timeMs: Date.now() - startTime,
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
this._cacheMisses++
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
const provider = getProvider(proof.metadata.system)
|
|
374
|
+
if (!provider) {
|
|
375
|
+
return {
|
|
376
|
+
proofId: proof.id,
|
|
377
|
+
valid: false,
|
|
378
|
+
timeMs: Date.now() - startTime,
|
|
379
|
+
error: `No provider for system: ${proof.metadata.system}`,
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
try {
|
|
384
|
+
const valid = await provider.verifyProof(proof)
|
|
385
|
+
|
|
386
|
+
// Update cache
|
|
387
|
+
if (this._config.enableCache) {
|
|
388
|
+
this._cache.set(proof.id, {
|
|
389
|
+
valid,
|
|
390
|
+
expiresAt: Date.now() + this._config.cacheTtlMs,
|
|
391
|
+
})
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
return {
|
|
395
|
+
proofId: proof.id,
|
|
396
|
+
valid,
|
|
397
|
+
timeMs: Date.now() - startTime,
|
|
398
|
+
}
|
|
399
|
+
} catch (error) {
|
|
400
|
+
return {
|
|
401
|
+
proofId: proof.id,
|
|
402
|
+
valid: false,
|
|
403
|
+
timeMs: Date.now() - startTime,
|
|
404
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Batch verify proofs from the same system
|
|
411
|
+
*/
|
|
412
|
+
async verifyBatch(
|
|
413
|
+
proofs: SingleProof[],
|
|
414
|
+
getProvider: (system: ProofSystem) => ComposableProofProvider | undefined,
|
|
415
|
+
): Promise<IndividualVerificationResult[]> {
|
|
416
|
+
if (proofs.length === 0) return []
|
|
417
|
+
|
|
418
|
+
const system = proofs[0].metadata.system
|
|
419
|
+
const provider = getProvider(system)
|
|
420
|
+
|
|
421
|
+
if (!provider) {
|
|
422
|
+
return proofs.map(p => ({
|
|
423
|
+
proofId: p.id,
|
|
424
|
+
valid: false,
|
|
425
|
+
timeMs: 0,
|
|
426
|
+
error: `No provider for system: ${system}`,
|
|
427
|
+
}))
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
const startTime = Date.now()
|
|
431
|
+
|
|
432
|
+
// Use batch verification if available
|
|
433
|
+
if (provider.verifyBatch) {
|
|
434
|
+
try {
|
|
435
|
+
const batchResults = await provider.verifyBatch(proofs)
|
|
436
|
+
const timePerProof = (Date.now() - startTime) / proofs.length
|
|
437
|
+
|
|
438
|
+
return proofs.map((proof, i) => {
|
|
439
|
+
// Update cache
|
|
440
|
+
if (this._config.enableCache) {
|
|
441
|
+
this._cache.set(proof.id, {
|
|
442
|
+
valid: batchResults[i],
|
|
443
|
+
expiresAt: Date.now() + this._config.cacheTtlMs,
|
|
444
|
+
})
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
return {
|
|
448
|
+
proofId: proof.id,
|
|
449
|
+
valid: batchResults[i],
|
|
450
|
+
timeMs: timePerProof,
|
|
451
|
+
}
|
|
452
|
+
})
|
|
453
|
+
} catch (error) {
|
|
454
|
+
// Fall back to individual verification
|
|
455
|
+
return this.verifyIndividually(proofs, getProvider)
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
// Fall back to individual verification
|
|
460
|
+
return this.verifyIndividually(proofs, getProvider)
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
// ─── Verification Ordering ─────────────────────────────────────────────────
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Compute optimal verification order based on proof dependencies
|
|
467
|
+
*/
|
|
468
|
+
computeVerificationOrder(composedProof: ComposedProof): VerificationOrder {
|
|
469
|
+
const proofs = composedProof.proofs
|
|
470
|
+
const dependencies = new Map<string, ProofDependency>()
|
|
471
|
+
|
|
472
|
+
// Build dependency graph
|
|
473
|
+
for (let i = 0; i < proofs.length; i++) {
|
|
474
|
+
const proof = proofs[i]
|
|
475
|
+
const proofWithLink = proof as SingleProof & { linkHash?: HexString }
|
|
476
|
+
|
|
477
|
+
dependencies.set(proof.id, {
|
|
478
|
+
proofId: proof.id,
|
|
479
|
+
dependsOn: i > 0 ? [proofs[i - 1].id] : [], // Sequential dependency
|
|
480
|
+
dependedBy: i < proofs.length - 1 ? [proofs[i + 1].id] : [],
|
|
481
|
+
linkHash: proofWithLink.linkHash,
|
|
482
|
+
})
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// Use hints if available
|
|
486
|
+
if (composedProof.verificationHints) {
|
|
487
|
+
const hints = composedProof.verificationHints
|
|
488
|
+
return {
|
|
489
|
+
order: hints.verificationOrder,
|
|
490
|
+
parallelGroups: hints.parallelGroups,
|
|
491
|
+
dependencies,
|
|
492
|
+
estimatedTimeMs: hints.estimatedTimeMs,
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
// Compute optimal order using topological sort
|
|
497
|
+
const order = this.topologicalSort(dependencies)
|
|
498
|
+
|
|
499
|
+
// Identify parallel groups (proofs with no dependencies on each other)
|
|
500
|
+
const parallelGroups = this.identifyParallelGroups(dependencies, order)
|
|
501
|
+
|
|
502
|
+
// Estimate time
|
|
503
|
+
const estimatedTimeMs = proofs.length * 100 // Rough estimate
|
|
504
|
+
|
|
505
|
+
return {
|
|
506
|
+
order,
|
|
507
|
+
parallelGroups,
|
|
508
|
+
dependencies,
|
|
509
|
+
estimatedTimeMs,
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
private topologicalSort(dependencies: Map<string, ProofDependency>): string[] {
|
|
514
|
+
const visited = new Set<string>()
|
|
515
|
+
const result: string[] = []
|
|
516
|
+
|
|
517
|
+
const visit = (id: string) => {
|
|
518
|
+
if (visited.has(id)) return
|
|
519
|
+
visited.add(id)
|
|
520
|
+
|
|
521
|
+
const dep = dependencies.get(id)
|
|
522
|
+
if (dep) {
|
|
523
|
+
for (const depId of dep.dependsOn) {
|
|
524
|
+
visit(depId)
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
result.push(id)
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
for (const id of dependencies.keys()) {
|
|
532
|
+
visit(id)
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
return result
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
private identifyParallelGroups(
|
|
539
|
+
_dependencies: Map<string, ProofDependency>,
|
|
540
|
+
order: string[],
|
|
541
|
+
): string[][] {
|
|
542
|
+
// Group proofs into chunks for parallel verification
|
|
543
|
+
// In a more sophisticated implementation, we'd analyze the DAG for true independence
|
|
544
|
+
// For now, return groups based on order chunks
|
|
545
|
+
const groups: string[][] = []
|
|
546
|
+
let currentGroup: string[] = []
|
|
547
|
+
|
|
548
|
+
for (const id of order) {
|
|
549
|
+
currentGroup.push(id)
|
|
550
|
+
if (currentGroup.length >= 4) {
|
|
551
|
+
groups.push([...currentGroup])
|
|
552
|
+
currentGroup = []
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
if (currentGroup.length > 0) {
|
|
557
|
+
groups.push(currentGroup)
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
return groups
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
// ─── Private Verification Methods ──────────────────────────────────────────
|
|
564
|
+
|
|
565
|
+
private async verifySequential(
|
|
566
|
+
composedProof: ComposedProof,
|
|
567
|
+
order: string[],
|
|
568
|
+
config: VerificationPipelineConfig,
|
|
569
|
+
getProvider: (system: ProofSystem) => ComposableProofProvider | undefined,
|
|
570
|
+
results: IndividualVerificationResult[],
|
|
571
|
+
systemStats: Map<ProofSystem, SystemVerificationStats>,
|
|
572
|
+
onProgress?: VerificationProgressCallback,
|
|
573
|
+
abortSignal?: AbortSignal,
|
|
574
|
+
startTime?: number,
|
|
575
|
+
): Promise<void> {
|
|
576
|
+
const proofMap = new Map(composedProof.proofs.map(p => [p.id, p]))
|
|
577
|
+
|
|
578
|
+
for (let i = 0; i < order.length; i++) {
|
|
579
|
+
if (abortSignal?.aborted) return
|
|
580
|
+
|
|
581
|
+
const proofId = order[i]
|
|
582
|
+
const proof = proofMap.get(proofId)
|
|
583
|
+
|
|
584
|
+
if (!proof) {
|
|
585
|
+
results.push({
|
|
586
|
+
proofId,
|
|
587
|
+
valid: false,
|
|
588
|
+
timeMs: 0,
|
|
589
|
+
error: 'Proof not found',
|
|
590
|
+
})
|
|
591
|
+
continue
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
onProgress?.({
|
|
595
|
+
step: i + 1,
|
|
596
|
+
totalSteps: order.length,
|
|
597
|
+
operation: `Verifying proof ${i + 1}/${order.length}`,
|
|
598
|
+
proofId,
|
|
599
|
+
elapsedMs: Date.now() - (startTime || Date.now()),
|
|
600
|
+
})
|
|
601
|
+
|
|
602
|
+
const result = await this.verifySingle(proof, getProvider)
|
|
603
|
+
results.push(result)
|
|
604
|
+
|
|
605
|
+
// Update system stats
|
|
606
|
+
this.updateSystemStats(systemStats, proof.metadata.system, result, false)
|
|
607
|
+
|
|
608
|
+
// Strict mode - fail fast
|
|
609
|
+
if (config.strictMode && !result.valid) {
|
|
610
|
+
return
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
private async verifyParallel(
|
|
616
|
+
composedProof: ComposedProof,
|
|
617
|
+
verificationOrder: VerificationOrder,
|
|
618
|
+
config: VerificationPipelineConfig,
|
|
619
|
+
getProvider: (system: ProofSystem) => ComposableProofProvider | undefined,
|
|
620
|
+
results: IndividualVerificationResult[],
|
|
621
|
+
systemStats: Map<ProofSystem, SystemVerificationStats>,
|
|
622
|
+
onProgress?: VerificationProgressCallback,
|
|
623
|
+
abortSignal?: AbortSignal,
|
|
624
|
+
startTime?: number,
|
|
625
|
+
): Promise<void> {
|
|
626
|
+
const proofMap = new Map(composedProof.proofs.map(p => [p.id, p]))
|
|
627
|
+
const resultMap = new Map<string, IndividualVerificationResult>()
|
|
628
|
+
|
|
629
|
+
// Process groups in order (groups can be verified in parallel)
|
|
630
|
+
for (let groupIdx = 0; groupIdx < verificationOrder.parallelGroups.length; groupIdx++) {
|
|
631
|
+
if (abortSignal?.aborted) break
|
|
632
|
+
|
|
633
|
+
const group = verificationOrder.parallelGroups[groupIdx]
|
|
634
|
+
|
|
635
|
+
onProgress?.({
|
|
636
|
+
step: groupIdx + 1,
|
|
637
|
+
totalSteps: verificationOrder.parallelGroups.length,
|
|
638
|
+
operation: `Verifying group ${groupIdx + 1}/${verificationOrder.parallelGroups.length} (${group.length} proofs)`,
|
|
639
|
+
elapsedMs: Date.now() - (startTime || Date.now()),
|
|
640
|
+
})
|
|
641
|
+
|
|
642
|
+
// Group proofs by system for batch verification
|
|
643
|
+
if (config.enableBatch) {
|
|
644
|
+
const systemProofs = new Map<ProofSystem, SingleProof[]>()
|
|
645
|
+
|
|
646
|
+
for (const proofId of group) {
|
|
647
|
+
const proof = proofMap.get(proofId)
|
|
648
|
+
if (!proof) continue
|
|
649
|
+
|
|
650
|
+
const existing = systemProofs.get(proof.metadata.system) || []
|
|
651
|
+
existing.push(proof)
|
|
652
|
+
systemProofs.set(proof.metadata.system, existing)
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
// Batch verify each system's proofs
|
|
656
|
+
const batchPromises: Promise<IndividualVerificationResult[]>[] = []
|
|
657
|
+
|
|
658
|
+
for (const [, proofs] of systemProofs) {
|
|
659
|
+
batchPromises.push(this.verifyBatch(proofs, getProvider))
|
|
660
|
+
}
|
|
661
|
+
|
|
662
|
+
const batchResults = await Promise.all(batchPromises)
|
|
663
|
+
|
|
664
|
+
for (const batchResult of batchResults) {
|
|
665
|
+
for (const result of batchResult) {
|
|
666
|
+
resultMap.set(result.proofId, result)
|
|
667
|
+
|
|
668
|
+
const proof = proofMap.get(result.proofId)
|
|
669
|
+
if (proof) {
|
|
670
|
+
this.updateSystemStats(systemStats, proof.metadata.system, result, true)
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
} else {
|
|
675
|
+
// Parallel individual verification
|
|
676
|
+
const proofs = group.map(id => proofMap.get(id)).filter(Boolean) as SingleProof[]
|
|
677
|
+
const promises = proofs.map(proof => this.verifySingle(proof, getProvider))
|
|
678
|
+
|
|
679
|
+
const groupResults = await Promise.all(promises)
|
|
680
|
+
|
|
681
|
+
for (const result of groupResults) {
|
|
682
|
+
resultMap.set(result.proofId, result)
|
|
683
|
+
|
|
684
|
+
const proof = proofMap.get(result.proofId)
|
|
685
|
+
if (proof) {
|
|
686
|
+
this.updateSystemStats(systemStats, proof.metadata.system, result, false)
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
// Collect results in order
|
|
693
|
+
for (const proofId of verificationOrder.order) {
|
|
694
|
+
const result = resultMap.get(proofId)
|
|
695
|
+
if (result) {
|
|
696
|
+
results.push(result)
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
private async verifyIndividually(
|
|
702
|
+
proofs: SingleProof[],
|
|
703
|
+
getProvider: (system: ProofSystem) => ComposableProofProvider | undefined,
|
|
704
|
+
): Promise<IndividualVerificationResult[]> {
|
|
705
|
+
const results: IndividualVerificationResult[] = []
|
|
706
|
+
|
|
707
|
+
for (const proof of proofs) {
|
|
708
|
+
results.push(await this.verifySingle(proof, getProvider))
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
return results
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
// ─── Link Validation ───────────────────────────────────────────────────────
|
|
715
|
+
|
|
716
|
+
private async validateLinks(
|
|
717
|
+
composedProof: ComposedProof,
|
|
718
|
+
linkValidation: LinkValidationResult[],
|
|
719
|
+
config: VerificationPipelineConfig,
|
|
720
|
+
): Promise<void> {
|
|
721
|
+
const proofs = composedProof.proofs
|
|
722
|
+
|
|
723
|
+
for (let i = 1; i < proofs.length; i++) {
|
|
724
|
+
const sourceProof = proofs[i - 1]
|
|
725
|
+
const targetProof = proofs[i]
|
|
726
|
+
const proofWithLink = targetProof as SingleProof & { linkHash?: HexString }
|
|
727
|
+
|
|
728
|
+
if (proofWithLink.linkHash) {
|
|
729
|
+
const computedHash = computeLinkHash(sourceProof, targetProof)
|
|
730
|
+
const valid = computedHash === proofWithLink.linkHash
|
|
731
|
+
|
|
732
|
+
linkValidation.push({
|
|
733
|
+
sourceProofId: sourceProof.id,
|
|
734
|
+
targetProofId: targetProof.id,
|
|
735
|
+
expectedHash: proofWithLink.linkHash,
|
|
736
|
+
computedHash,
|
|
737
|
+
valid,
|
|
738
|
+
})
|
|
739
|
+
|
|
740
|
+
if (config.verbose && !valid) {
|
|
741
|
+
console.warn(`[VerificationPipeline] Link validation failed: ${sourceProof.id} -> ${targetProof.id}`)
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
// ─── Verification Proof Generation ─────────────────────────────────────────
|
|
748
|
+
|
|
749
|
+
private async generateVerificationProof(
|
|
750
|
+
composedProof: ComposedProof,
|
|
751
|
+
results: IndividualVerificationResult[],
|
|
752
|
+
): Promise<HexString> {
|
|
753
|
+
// Generate a proof attesting that verification succeeded
|
|
754
|
+
// In production, this would use a ZK circuit to prove verification
|
|
755
|
+
|
|
756
|
+
const validProofIds = results.filter(r => r.valid).map(r => r.proofId)
|
|
757
|
+
const timestamp = Date.now()
|
|
758
|
+
|
|
759
|
+
// Create verification attestation
|
|
760
|
+
const attestation = {
|
|
761
|
+
composedProofId: composedProof.id,
|
|
762
|
+
validProofIds,
|
|
763
|
+
timestamp,
|
|
764
|
+
verifierId: generateId('verifier'),
|
|
765
|
+
}
|
|
766
|
+
|
|
767
|
+
// Simple hash-based proof (in production, use actual ZK proof)
|
|
768
|
+
const data = JSON.stringify(attestation)
|
|
769
|
+
let hash = 0
|
|
770
|
+
for (let i = 0; i < data.length; i++) {
|
|
771
|
+
hash = ((hash << 5) - hash) + data.charCodeAt(i)
|
|
772
|
+
hash = hash & hash
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
return `0x${Math.abs(hash).toString(16).padStart(64, '0')}` as HexString
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
// ─── Stats and Cache ───────────────────────────────────────────────────────
|
|
779
|
+
|
|
780
|
+
private updateSystemStats(
|
|
781
|
+
stats: Map<ProofSystem, SystemVerificationStats>,
|
|
782
|
+
system: ProofSystem,
|
|
783
|
+
result: IndividualVerificationResult,
|
|
784
|
+
usedBatch: boolean,
|
|
785
|
+
): void {
|
|
786
|
+
const existing = stats.get(system) || {
|
|
787
|
+
proofsVerified: 0,
|
|
788
|
+
successCount: 0,
|
|
789
|
+
failCount: 0,
|
|
790
|
+
totalTimeMs: 0,
|
|
791
|
+
avgTimeMs: 0,
|
|
792
|
+
usedBatch: false,
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
existing.proofsVerified++
|
|
796
|
+
if (result.valid) {
|
|
797
|
+
existing.successCount++
|
|
798
|
+
} else {
|
|
799
|
+
existing.failCount++
|
|
800
|
+
}
|
|
801
|
+
existing.totalTimeMs += result.timeMs
|
|
802
|
+
existing.avgTimeMs = existing.totalTimeMs / existing.proofsVerified
|
|
803
|
+
existing.usedBatch = existing.usedBatch || usedBatch
|
|
804
|
+
|
|
805
|
+
stats.set(system, existing)
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
* Clear verification cache
|
|
810
|
+
*/
|
|
811
|
+
clearCache(): void {
|
|
812
|
+
this._cache.clear()
|
|
813
|
+
this._cacheHits = 0
|
|
814
|
+
this._cacheMisses = 0
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
/**
|
|
818
|
+
* Get cache statistics
|
|
819
|
+
*/
|
|
820
|
+
getCacheStats(): { size: number; hits: number; misses: number; hitRate: number } {
|
|
821
|
+
const total = this._cacheHits + this._cacheMisses
|
|
822
|
+
return {
|
|
823
|
+
size: this._cache.size,
|
|
824
|
+
hits: this._cacheHits,
|
|
825
|
+
misses: this._cacheMisses,
|
|
826
|
+
hitRate: total > 0 ? this._cacheHits / total : 0,
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
// ─── Result Helpers ────────────────────────────────────────────────────────
|
|
831
|
+
|
|
832
|
+
private createAbortedResult(
|
|
833
|
+
startTime: number,
|
|
834
|
+
results: IndividualVerificationResult[],
|
|
835
|
+
linkValidation: LinkValidationResult[],
|
|
836
|
+
systemStats: Map<ProofSystem, SystemVerificationStats>,
|
|
837
|
+
): DetailedVerificationResult {
|
|
838
|
+
return {
|
|
839
|
+
valid: false,
|
|
840
|
+
results,
|
|
841
|
+
totalTimeMs: Date.now() - startTime,
|
|
842
|
+
method: 'individual',
|
|
843
|
+
verificationOrder: [],
|
|
844
|
+
linkValidation,
|
|
845
|
+
cacheStats: {
|
|
846
|
+
hits: this._cacheHits,
|
|
847
|
+
misses: this._cacheMisses,
|
|
848
|
+
},
|
|
849
|
+
systemStats,
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
// ─── Factory Function ────────────────────────────────────────────────────────
|
|
855
|
+
|
|
856
|
+
/**
|
|
857
|
+
* Create a verification pipeline with optional configuration
|
|
858
|
+
*/
|
|
859
|
+
export function createVerificationPipeline(
|
|
860
|
+
config?: Partial<VerificationPipelineConfig>,
|
|
861
|
+
): VerificationPipeline {
|
|
862
|
+
return new VerificationPipeline(config)
|
|
863
|
+
}
|
|
864
|
+
|
|
865
|
+
// ─── Export Default Config ───────────────────────────────────────────────────
|
|
866
|
+
|
|
867
|
+
export { DEFAULT_PIPELINE_CONFIG }
|