@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.
- 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 +47556 -19603
- package/dist/browser.mjs +628 -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-3M3HNQCW.mjs → chunk-YWGJ77A2.mjs} +28656 -13103
- 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-DIBZHOOQ.d.ts → index-DXh2IGkz.d.ts} +21239 -10304
- package/dist/{index-8MQz13eJ.d.mts → index-DeE1ZzA4.d.mts} +21239 -10304
- package/dist/index.d.mts +9 -3
- package/dist/index.d.ts +9 -3
- package/dist/index.js +48396 -19623
- package/dist/index.mjs +537 -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 +252 -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 +47 -6
- 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 +186 -33
- package/src/chains/solana/providers/index.ts +31 -0
- package/src/chains/solana/providers/interface.ts +61 -18
- 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 +338 -67
- package/src/chains/solana/rpc-client.ts +1150 -0
- package/src/chains/solana/scan.ts +83 -66
- 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 +57 -6
- 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 +23 -0
- package/src/compliance/range-sas.ts +398 -33
- 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 +686 -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 +254 -4
- package/src/privacy-backends/interface.ts +649 -6
- 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.ts +13 -17
- package/src/privacy-backends/private-swap.ts +570 -0
- package/src/privacy-backends/rate-limiter.ts +683 -0
- package/src/privacy-backends/registry.ts +414 -2
- package/src/privacy-backends/router.ts +283 -3
- package/src/privacy-backends/shadowwire.ts +449 -0
- package/src/privacy-backends/sip-native.ts +3 -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 +110 -29
- 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/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-2XIVXWHA.mjs +0 -1930
- package/dist/chunk-3INS3PR5.mjs +0 -884
- package/dist/chunk-3OVABDRH.mjs +0 -17096
- package/dist/chunk-7RFRWDCW.mjs +0 -1504
- package/dist/chunk-DLDWZFYC.mjs +0 -1495
- package/dist/chunk-E6SZWREQ.mjs +0 -57
- package/dist/chunk-F6F73W35.mjs +0 -16166
- package/dist/chunk-G33LB27A.mjs +0 -16166
- package/dist/chunk-HGU6HZRC.mjs +0 -231
- package/dist/chunk-L2K34JCU.mjs +0 -1496
- package/dist/chunk-OFDBEIEK.mjs +0 -16166
- package/dist/chunk-SF7YSLF5.mjs +0 -1515
- package/dist/chunk-SN4ZDTVW.mjs +0 -16166
- package/dist/chunk-WWUSGOXE.mjs +0 -17129
- package/dist/constants-VOI7BSLK.mjs +0 -27
- package/dist/index-B71aXVzk.d.ts +0 -13264
- 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-pOIIuwfV.d.mts +0 -13264
- package/dist/index-xbWjohNq.d.mts +0 -11390
- package/dist/solana-4O4K45VU.mjs +0 -46
- package/dist/solana-5EMCTPTS.mjs +0 -46
- package/dist/solana-NDABAZ6P.mjs +0 -56
- package/dist/solana-Q4NAVBTS.mjs +0 -46
- package/dist/solana-ZYO63LY5.mjs +0 -46
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Halo2 Proof Format Converter
|
|
3
|
+
*
|
|
4
|
+
* Converts between Halo2 native proof format and SIP unified format.
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type {
|
|
10
|
+
SingleProof,
|
|
11
|
+
ProofMetadata,
|
|
12
|
+
HexString,
|
|
13
|
+
} from '@sip-protocol/types'
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
type ProofConverter,
|
|
17
|
+
type Halo2NativeProof,
|
|
18
|
+
type ConversionOptions,
|
|
19
|
+
type ConversionResult,
|
|
20
|
+
type ConversionMetadata,
|
|
21
|
+
type ValidationResult,
|
|
22
|
+
type ValidationError,
|
|
23
|
+
DEFAULT_CONVERSION_OPTIONS,
|
|
24
|
+
ProofConversionError,
|
|
25
|
+
InvalidProofError,
|
|
26
|
+
UnsupportedVersionError,
|
|
27
|
+
} from './interface'
|
|
28
|
+
|
|
29
|
+
// ─── Constants ───────────────────────────────────────────────────────────────
|
|
30
|
+
|
|
31
|
+
/** Converter version */
|
|
32
|
+
const CONVERTER_VERSION = '1.0.0'
|
|
33
|
+
|
|
34
|
+
/** Supported Halo2 versions */
|
|
35
|
+
const SUPPORTED_HALO2_VERSIONS = ['0.2', '0.3', '1.0']
|
|
36
|
+
|
|
37
|
+
/** Minimum k value for valid Halo2 proofs */
|
|
38
|
+
const MIN_K_VALUE = 4
|
|
39
|
+
|
|
40
|
+
/** Maximum k value for valid Halo2 proofs */
|
|
41
|
+
const MAX_K_VALUE = 28
|
|
42
|
+
|
|
43
|
+
// ─── Utility Functions ───────────────────────────────────────────────────────
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Convert Uint8Array to hex string
|
|
47
|
+
*/
|
|
48
|
+
function bytesToHex(bytes: Uint8Array): HexString {
|
|
49
|
+
return ('0x' + Array.from(bytes)
|
|
50
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
51
|
+
.join('')) as HexString
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Convert hex string to Uint8Array
|
|
56
|
+
*/
|
|
57
|
+
function hexToBytes(hex: HexString): Uint8Array {
|
|
58
|
+
const cleanHex = hex.startsWith('0x') ? hex.slice(2) : hex
|
|
59
|
+
const bytes = new Uint8Array(cleanHex.length / 2)
|
|
60
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
61
|
+
bytes[i] = parseInt(cleanHex.slice(i * 2, i * 2 + 2), 16)
|
|
62
|
+
}
|
|
63
|
+
return bytes
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Check if a Halo2 version is supported
|
|
68
|
+
*/
|
|
69
|
+
function isSupportedHalo2Version(version: string): boolean {
|
|
70
|
+
const majorMinor = version.split('.').slice(0, 2).join('.')
|
|
71
|
+
return SUPPORTED_HALO2_VERSIONS.some(v => majorMinor.startsWith(v))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ─── Halo2 Proof Converter ───────────────────────────────────────────────────
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Converter for Halo2 proofs
|
|
78
|
+
*
|
|
79
|
+
* Halo2 is a zkSNARK proving system used by Zcash and other projects.
|
|
80
|
+
* It uses the PLONK arithmetization with custom gates.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* const converter = new Halo2ProofConverter()
|
|
85
|
+
*
|
|
86
|
+
* // Convert to SIP format
|
|
87
|
+
* const result = converter.toSIP(halo2Proof)
|
|
88
|
+
* if (result.success) {
|
|
89
|
+
* console.log('SIP Proof:', result.result)
|
|
90
|
+
* }
|
|
91
|
+
* ```
|
|
92
|
+
*/
|
|
93
|
+
export class Halo2ProofConverter implements ProofConverter<Halo2NativeProof> {
|
|
94
|
+
readonly system = 'halo2' as const
|
|
95
|
+
readonly version = CONVERTER_VERSION
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Convert Halo2 native proof to SIP unified format
|
|
99
|
+
*/
|
|
100
|
+
toSIP(
|
|
101
|
+
nativeProof: Halo2NativeProof,
|
|
102
|
+
options: ConversionOptions = {},
|
|
103
|
+
): ConversionResult<SingleProof> {
|
|
104
|
+
const opts = { ...DEFAULT_CONVERSION_OPTIONS, ...options }
|
|
105
|
+
const startTime = Date.now()
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
// Validate if requested
|
|
109
|
+
if (opts.validateBeforeConversion) {
|
|
110
|
+
const validation = this.validateNative(nativeProof)
|
|
111
|
+
if (!validation.valid) {
|
|
112
|
+
return this._createErrorResult(
|
|
113
|
+
new InvalidProofError('halo2', 'sip', validation.errors),
|
|
114
|
+
startTime,
|
|
115
|
+
nativeProof.proofData.length,
|
|
116
|
+
)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Check version support
|
|
121
|
+
if (nativeProof.halo2Version && !isSupportedHalo2Version(nativeProof.halo2Version)) {
|
|
122
|
+
return this._createErrorResult(
|
|
123
|
+
new UnsupportedVersionError('halo2', nativeProof.halo2Version, SUPPORTED_HALO2_VERSIONS),
|
|
124
|
+
startTime,
|
|
125
|
+
nativeProof.proofData.length,
|
|
126
|
+
)
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Convert proof data to hex
|
|
130
|
+
const proofHex = bytesToHex(nativeProof.proofData)
|
|
131
|
+
|
|
132
|
+
// Convert public inputs to hex format
|
|
133
|
+
const publicInputsHex = nativeProof.publicInputs.map(input => {
|
|
134
|
+
if (input.startsWith('0x')) {
|
|
135
|
+
return input as HexString
|
|
136
|
+
}
|
|
137
|
+
const bigInt = BigInt(input)
|
|
138
|
+
return ('0x' + bigInt.toString(16).padStart(64, '0')) as HexString
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
// Convert verification key if present
|
|
142
|
+
const verificationKey = opts.includeVerificationKey && nativeProof.verificationKey
|
|
143
|
+
? (typeof nativeProof.verificationKey === 'string'
|
|
144
|
+
? nativeProof.verificationKey as HexString
|
|
145
|
+
: bytesToHex(nativeProof.verificationKey))
|
|
146
|
+
: undefined
|
|
147
|
+
|
|
148
|
+
// Build circuit identifier from k value and commitment
|
|
149
|
+
const circuitId = nativeProof.provingKeyCommitment
|
|
150
|
+
? `halo2-k${nativeProof.k || 'unknown'}-${nativeProof.provingKeyCommitment.slice(0, 16)}`
|
|
151
|
+
: `halo2-k${nativeProof.k || 'unknown'}`
|
|
152
|
+
|
|
153
|
+
// Build metadata
|
|
154
|
+
const metadata: ProofMetadata = {
|
|
155
|
+
system: 'halo2',
|
|
156
|
+
systemVersion: nativeProof.halo2Version || 'unknown',
|
|
157
|
+
circuitId,
|
|
158
|
+
circuitVersion: nativeProof.provingKeyCommitment || 'unknown',
|
|
159
|
+
generatedAt: Date.now(),
|
|
160
|
+
proofSizeBytes: nativeProof.proofData.length,
|
|
161
|
+
targetChainId: opts.targetChainId || undefined,
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Build SIP proof
|
|
165
|
+
const sipProof: SingleProof = {
|
|
166
|
+
id: opts.idGenerator(),
|
|
167
|
+
proof: proofHex,
|
|
168
|
+
publicInputs: publicInputsHex,
|
|
169
|
+
verificationKey,
|
|
170
|
+
metadata,
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
const outputSize = proofHex.length / 2 - 1
|
|
174
|
+
|
|
175
|
+
return {
|
|
176
|
+
success: true,
|
|
177
|
+
result: sipProof,
|
|
178
|
+
lossless: true,
|
|
179
|
+
warnings: this._collectWarnings(nativeProof),
|
|
180
|
+
conversionMetadata: this._createConversionMetadata(
|
|
181
|
+
'halo2',
|
|
182
|
+
'sip',
|
|
183
|
+
startTime,
|
|
184
|
+
nativeProof.proofData.length,
|
|
185
|
+
outputSize,
|
|
186
|
+
),
|
|
187
|
+
}
|
|
188
|
+
} catch (error) {
|
|
189
|
+
return this._createErrorResult(
|
|
190
|
+
error instanceof ProofConversionError
|
|
191
|
+
? error
|
|
192
|
+
: new ProofConversionError(
|
|
193
|
+
'UNKNOWN_ERROR',
|
|
194
|
+
error instanceof Error ? error.message : 'Unknown conversion error',
|
|
195
|
+
'halo2',
|
|
196
|
+
'sip',
|
|
197
|
+
error instanceof Error ? error : undefined,
|
|
198
|
+
),
|
|
199
|
+
startTime,
|
|
200
|
+
nativeProof.proofData.length,
|
|
201
|
+
)
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Convert SIP unified format to Halo2 native proof
|
|
207
|
+
*/
|
|
208
|
+
fromSIP(
|
|
209
|
+
sipProof: SingleProof,
|
|
210
|
+
options: ConversionOptions = {},
|
|
211
|
+
): ConversionResult<Halo2NativeProof> {
|
|
212
|
+
const opts = { ...DEFAULT_CONVERSION_OPTIONS, ...options }
|
|
213
|
+
const startTime = Date.now()
|
|
214
|
+
const inputSize = sipProof.proof.length / 2 - 1
|
|
215
|
+
|
|
216
|
+
try {
|
|
217
|
+
// Check if this is a Halo2 proof
|
|
218
|
+
if (!this.canConvertFromSIP(sipProof)) {
|
|
219
|
+
return this._createErrorResult(
|
|
220
|
+
new ProofConversionError(
|
|
221
|
+
'INVALID_INPUT',
|
|
222
|
+
`Cannot convert proof from system: ${sipProof.metadata.system}`,
|
|
223
|
+
sipProof.metadata.system,
|
|
224
|
+
'halo2',
|
|
225
|
+
),
|
|
226
|
+
startTime,
|
|
227
|
+
inputSize,
|
|
228
|
+
)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Convert proof hex to bytes
|
|
232
|
+
const proofData = hexToBytes(sipProof.proof)
|
|
233
|
+
|
|
234
|
+
// Convert public inputs from hex to field element strings
|
|
235
|
+
const publicInputs = sipProof.publicInputs.map(hex => {
|
|
236
|
+
const bigInt = BigInt(hex)
|
|
237
|
+
return bigInt.toString()
|
|
238
|
+
})
|
|
239
|
+
|
|
240
|
+
// Convert verification key if present
|
|
241
|
+
const verificationKey = sipProof.verificationKey
|
|
242
|
+
? hexToBytes(sipProof.verificationKey)
|
|
243
|
+
: undefined
|
|
244
|
+
|
|
245
|
+
// Extract k value from circuit ID if present
|
|
246
|
+
const kMatch = sipProof.metadata.circuitId.match(/k(\d+)/)
|
|
247
|
+
const k = kMatch ? parseInt(kMatch[1], 10) : undefined
|
|
248
|
+
|
|
249
|
+
// Build native proof
|
|
250
|
+
const nativeProof: Halo2NativeProof = {
|
|
251
|
+
system: 'halo2',
|
|
252
|
+
proofData,
|
|
253
|
+
publicInputs,
|
|
254
|
+
verificationKey,
|
|
255
|
+
provingKeyCommitment: sipProof.metadata.circuitVersion !== 'unknown'
|
|
256
|
+
? sipProof.metadata.circuitVersion as HexString
|
|
257
|
+
: undefined,
|
|
258
|
+
k,
|
|
259
|
+
halo2Version: sipProof.metadata.systemVersion,
|
|
260
|
+
nativeMetadata: opts.preserveNativeMetadata ? {
|
|
261
|
+
sipProofId: sipProof.id,
|
|
262
|
+
originalMetadata: sipProof.metadata,
|
|
263
|
+
} : undefined,
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
return {
|
|
267
|
+
success: true,
|
|
268
|
+
result: nativeProof,
|
|
269
|
+
lossless: true,
|
|
270
|
+
warnings: [],
|
|
271
|
+
conversionMetadata: this._createConversionMetadata(
|
|
272
|
+
'sip' as any,
|
|
273
|
+
'halo2',
|
|
274
|
+
startTime,
|
|
275
|
+
inputSize,
|
|
276
|
+
proofData.length,
|
|
277
|
+
),
|
|
278
|
+
}
|
|
279
|
+
} catch (error) {
|
|
280
|
+
return this._createErrorResult(
|
|
281
|
+
error instanceof ProofConversionError
|
|
282
|
+
? error
|
|
283
|
+
: new ProofConversionError(
|
|
284
|
+
'UNKNOWN_ERROR',
|
|
285
|
+
error instanceof Error ? error.message : 'Unknown conversion error',
|
|
286
|
+
'halo2',
|
|
287
|
+
'sip',
|
|
288
|
+
error instanceof Error ? error : undefined,
|
|
289
|
+
),
|
|
290
|
+
startTime,
|
|
291
|
+
inputSize,
|
|
292
|
+
)
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* Validate a Halo2 native proof structure
|
|
298
|
+
*/
|
|
299
|
+
validateNative(nativeProof: Halo2NativeProof): ValidationResult {
|
|
300
|
+
const errors: ValidationError[] = []
|
|
301
|
+
const warnings: string[] = []
|
|
302
|
+
|
|
303
|
+
// Check required fields
|
|
304
|
+
if (!nativeProof.proofData || nativeProof.proofData.length === 0) {
|
|
305
|
+
errors.push({
|
|
306
|
+
field: 'proofData',
|
|
307
|
+
message: 'Proof data is required and must not be empty',
|
|
308
|
+
code: 'REQUIRED_FIELD',
|
|
309
|
+
})
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
if (!nativeProof.publicInputs) {
|
|
313
|
+
errors.push({
|
|
314
|
+
field: 'publicInputs',
|
|
315
|
+
message: 'Public inputs array is required',
|
|
316
|
+
code: 'REQUIRED_FIELD',
|
|
317
|
+
})
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// Validate k value if present
|
|
321
|
+
if (nativeProof.k !== undefined) {
|
|
322
|
+
if (nativeProof.k < MIN_K_VALUE || nativeProof.k > MAX_K_VALUE) {
|
|
323
|
+
errors.push({
|
|
324
|
+
field: 'k',
|
|
325
|
+
message: `k value must be between ${MIN_K_VALUE} and ${MAX_K_VALUE}, got ${nativeProof.k}`,
|
|
326
|
+
code: 'INVALID_VALUE',
|
|
327
|
+
})
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
// Validate public inputs format
|
|
332
|
+
if (nativeProof.publicInputs) {
|
|
333
|
+
for (let i = 0; i < nativeProof.publicInputs.length; i++) {
|
|
334
|
+
const input = nativeProof.publicInputs[i]
|
|
335
|
+
try {
|
|
336
|
+
if (input.startsWith('0x')) {
|
|
337
|
+
BigInt(input)
|
|
338
|
+
} else {
|
|
339
|
+
BigInt(input)
|
|
340
|
+
}
|
|
341
|
+
} catch {
|
|
342
|
+
errors.push({
|
|
343
|
+
field: `publicInputs[${i}]`,
|
|
344
|
+
message: `Invalid field element format: ${input}`,
|
|
345
|
+
code: 'INVALID_FORMAT',
|
|
346
|
+
})
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
// Version warnings
|
|
352
|
+
if (nativeProof.halo2Version && !isSupportedHalo2Version(nativeProof.halo2Version)) {
|
|
353
|
+
warnings.push(`Halo2 version ${nativeProof.halo2Version} may not be fully supported`)
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Missing optional field warnings
|
|
357
|
+
if (!nativeProof.k) {
|
|
358
|
+
warnings.push('No k value specified - circuit parameters unknown')
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (!nativeProof.provingKeyCommitment) {
|
|
362
|
+
warnings.push('No proving key commitment - proof may not be fully traceable')
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return {
|
|
366
|
+
valid: errors.length === 0,
|
|
367
|
+
errors,
|
|
368
|
+
warnings,
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Check if a SIP proof can be converted to Halo2 format
|
|
374
|
+
*/
|
|
375
|
+
canConvertFromSIP(sipProof: SingleProof): boolean {
|
|
376
|
+
return sipProof.metadata.system === 'halo2'
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* Get supported Halo2 versions
|
|
381
|
+
*/
|
|
382
|
+
getSupportedVersions(): string[] {
|
|
383
|
+
return [...SUPPORTED_HALO2_VERSIONS]
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// ─── Private Helpers ─────────────────────────────────────────────────────────
|
|
387
|
+
|
|
388
|
+
private _createConversionMetadata(
|
|
389
|
+
sourceSystem: 'halo2' | 'sip',
|
|
390
|
+
targetSystem: 'halo2' | 'sip',
|
|
391
|
+
startTime: number,
|
|
392
|
+
originalSize: number,
|
|
393
|
+
convertedSize: number,
|
|
394
|
+
): ConversionMetadata {
|
|
395
|
+
return {
|
|
396
|
+
sourceSystem: sourceSystem === 'sip' ? 'halo2' : sourceSystem,
|
|
397
|
+
targetSystem,
|
|
398
|
+
convertedAt: Date.now(),
|
|
399
|
+
converterVersion: this.version,
|
|
400
|
+
conversionTimeMs: Date.now() - startTime,
|
|
401
|
+
originalSize,
|
|
402
|
+
convertedSize,
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
private _createErrorResult<T>(
|
|
407
|
+
error: ProofConversionError,
|
|
408
|
+
startTime: number,
|
|
409
|
+
inputSize: number,
|
|
410
|
+
): ConversionResult<T> {
|
|
411
|
+
return {
|
|
412
|
+
success: false,
|
|
413
|
+
error: error.message,
|
|
414
|
+
errorCode: error.code,
|
|
415
|
+
lossless: false,
|
|
416
|
+
conversionMetadata: this._createConversionMetadata(
|
|
417
|
+
error.sourceSystem as any,
|
|
418
|
+
error.targetSystem as any,
|
|
419
|
+
startTime,
|
|
420
|
+
inputSize,
|
|
421
|
+
0,
|
|
422
|
+
),
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
private _collectWarnings(nativeProof: Halo2NativeProof): string[] {
|
|
427
|
+
const warnings: string[] = []
|
|
428
|
+
|
|
429
|
+
if (!nativeProof.halo2Version) {
|
|
430
|
+
warnings.push('No Halo2 version specified - using unknown')
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (!nativeProof.k) {
|
|
434
|
+
warnings.push('No k value - circuit degree unknown')
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
if (!nativeProof.provingKeyCommitment) {
|
|
438
|
+
warnings.push('No proving key commitment - traceability limited')
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return warnings
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// ─── Factory Function ────────────────────────────────────────────────────────
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Create a new Halo2 proof converter instance
|
|
449
|
+
*/
|
|
450
|
+
export function createHalo2Converter(): Halo2ProofConverter {
|
|
451
|
+
return new Halo2ProofConverter()
|
|
452
|
+
}
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proof Format Converters
|
|
3
|
+
*
|
|
4
|
+
* Module for converting proofs between native formats (Noir, Halo2, Kimchi)
|
|
5
|
+
* and the unified SIP proof format.
|
|
6
|
+
*
|
|
7
|
+
* @packageDocumentation
|
|
8
|
+
* @module converters
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
// ─── Interface and Types ─────────────────────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
export type {
|
|
14
|
+
NativeProofFormat,
|
|
15
|
+
NoirNativeProof,
|
|
16
|
+
Halo2NativeProof,
|
|
17
|
+
KimchiNativeProof,
|
|
18
|
+
ConversionOptions,
|
|
19
|
+
ConversionResult,
|
|
20
|
+
ConversionMetadata,
|
|
21
|
+
ConversionErrorCode,
|
|
22
|
+
ProofConverter,
|
|
23
|
+
ValidationResult,
|
|
24
|
+
ValidationError,
|
|
25
|
+
AnyNativeProof,
|
|
26
|
+
ProofSystemToNativeMap,
|
|
27
|
+
} from './interface'
|
|
28
|
+
|
|
29
|
+
export {
|
|
30
|
+
ProofConversionError,
|
|
31
|
+
InvalidProofError,
|
|
32
|
+
UnsupportedVersionError,
|
|
33
|
+
DEFAULT_CONVERSION_OPTIONS,
|
|
34
|
+
} from './interface'
|
|
35
|
+
|
|
36
|
+
// ─── Noir Converter ──────────────────────────────────────────────────────────
|
|
37
|
+
|
|
38
|
+
export { NoirProofConverter, createNoirConverter } from './noir'
|
|
39
|
+
|
|
40
|
+
// ─── Halo2 Converter ─────────────────────────────────────────────────────────
|
|
41
|
+
|
|
42
|
+
export { Halo2ProofConverter, createHalo2Converter } from './halo2'
|
|
43
|
+
|
|
44
|
+
// ─── Kimchi Converter ────────────────────────────────────────────────────────
|
|
45
|
+
|
|
46
|
+
export { KimchiProofConverter, createKimchiConverter } from './kimchi'
|
|
47
|
+
|
|
48
|
+
// ─── Unified Converter Factory ───────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
import type { ProofSystem, SingleProof } from '@sip-protocol/types'
|
|
51
|
+
import type {
|
|
52
|
+
ProofConverter,
|
|
53
|
+
AnyNativeProof,
|
|
54
|
+
ConversionResult,
|
|
55
|
+
ConversionOptions,
|
|
56
|
+
} from './interface'
|
|
57
|
+
import { NoirProofConverter } from './noir'
|
|
58
|
+
import { Halo2ProofConverter } from './halo2'
|
|
59
|
+
import { KimchiProofConverter } from './kimchi'
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Unified converter that routes to the appropriate system-specific converter
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```typescript
|
|
66
|
+
* const converter = new UnifiedProofConverter()
|
|
67
|
+
*
|
|
68
|
+
* // Convert any native proof to SIP format
|
|
69
|
+
* const noirResult = converter.toSIP(noirProof)
|
|
70
|
+
* const halo2Result = converter.toSIP(halo2Proof)
|
|
71
|
+
* const kimchiResult = converter.toSIP(kimchiProof)
|
|
72
|
+
*
|
|
73
|
+
* // Convert SIP proof back to native format
|
|
74
|
+
* const nativeResult = converter.fromSIP(sipProof)
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export class UnifiedProofConverter {
|
|
78
|
+
private _converters: Map<ProofSystem, ProofConverter<AnyNativeProof>>
|
|
79
|
+
|
|
80
|
+
constructor() {
|
|
81
|
+
this._converters = new Map()
|
|
82
|
+
this._converters.set('noir', new NoirProofConverter() as ProofConverter<AnyNativeProof>)
|
|
83
|
+
this._converters.set('halo2', new Halo2ProofConverter() as ProofConverter<AnyNativeProof>)
|
|
84
|
+
this._converters.set('kimchi', new KimchiProofConverter() as ProofConverter<AnyNativeProof>)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Convert a native proof to SIP unified format
|
|
89
|
+
*/
|
|
90
|
+
toSIP(
|
|
91
|
+
nativeProof: AnyNativeProof,
|
|
92
|
+
options?: ConversionOptions,
|
|
93
|
+
): ConversionResult<SingleProof> {
|
|
94
|
+
const converter = this._converters.get(nativeProof.system)
|
|
95
|
+
if (!converter) {
|
|
96
|
+
return {
|
|
97
|
+
success: false,
|
|
98
|
+
error: `Unsupported proof system: ${nativeProof.system}`,
|
|
99
|
+
errorCode: 'INVALID_INPUT',
|
|
100
|
+
lossless: false,
|
|
101
|
+
conversionMetadata: {
|
|
102
|
+
sourceSystem: nativeProof.system,
|
|
103
|
+
targetSystem: 'sip',
|
|
104
|
+
convertedAt: Date.now(),
|
|
105
|
+
converterVersion: '1.0.0',
|
|
106
|
+
conversionTimeMs: 0,
|
|
107
|
+
originalSize: 0,
|
|
108
|
+
convertedSize: 0,
|
|
109
|
+
},
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return converter.toSIP(nativeProof, options)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Convert a SIP proof to native format
|
|
118
|
+
*/
|
|
119
|
+
fromSIP(
|
|
120
|
+
sipProof: SingleProof,
|
|
121
|
+
options?: ConversionOptions,
|
|
122
|
+
): ConversionResult<AnyNativeProof> {
|
|
123
|
+
const system = sipProof.metadata.system
|
|
124
|
+
const converter = this._converters.get(system)
|
|
125
|
+
|
|
126
|
+
if (!converter) {
|
|
127
|
+
return {
|
|
128
|
+
success: false,
|
|
129
|
+
error: `Unsupported proof system: ${system}`,
|
|
130
|
+
errorCode: 'INVALID_INPUT',
|
|
131
|
+
lossless: false,
|
|
132
|
+
conversionMetadata: {
|
|
133
|
+
sourceSystem: system,
|
|
134
|
+
targetSystem: system,
|
|
135
|
+
convertedAt: Date.now(),
|
|
136
|
+
converterVersion: '1.0.0',
|
|
137
|
+
conversionTimeMs: 0,
|
|
138
|
+
originalSize: 0,
|
|
139
|
+
convertedSize: 0,
|
|
140
|
+
},
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
return converter.fromSIP(sipProof, options)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Get converter for a specific proof system
|
|
149
|
+
*/
|
|
150
|
+
getConverter(system: ProofSystem): ProofConverter<AnyNativeProof> | undefined {
|
|
151
|
+
return this._converters.get(system)
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Get all supported proof systems
|
|
156
|
+
*/
|
|
157
|
+
getSupportedSystems(): ProofSystem[] {
|
|
158
|
+
return Array.from(this._converters.keys())
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Check if a proof system is supported
|
|
163
|
+
*/
|
|
164
|
+
isSystemSupported(system: ProofSystem): boolean {
|
|
165
|
+
return this._converters.has(system)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Register a custom converter for a proof system
|
|
170
|
+
*/
|
|
171
|
+
registerConverter(
|
|
172
|
+
system: ProofSystem,
|
|
173
|
+
converter: ProofConverter<AnyNativeProof>,
|
|
174
|
+
): void {
|
|
175
|
+
this._converters.set(system, converter)
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Create a unified proof converter
|
|
181
|
+
*/
|
|
182
|
+
export function createUnifiedConverter(): UnifiedProofConverter {
|
|
183
|
+
return new UnifiedProofConverter()
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// ─── Convenience Functions ───────────────────────────────────────────────────
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Convert a native proof to SIP format (convenience function)
|
|
190
|
+
*/
|
|
191
|
+
export function convertToSIP(
|
|
192
|
+
nativeProof: AnyNativeProof,
|
|
193
|
+
options?: ConversionOptions,
|
|
194
|
+
): ConversionResult<SingleProof> {
|
|
195
|
+
const converter = createUnifiedConverter()
|
|
196
|
+
return converter.toSIP(nativeProof, options)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Convert a SIP proof to native format (convenience function)
|
|
201
|
+
*/
|
|
202
|
+
export function convertFromSIP(
|
|
203
|
+
sipProof: SingleProof,
|
|
204
|
+
options?: ConversionOptions,
|
|
205
|
+
): ConversionResult<AnyNativeProof> {
|
|
206
|
+
const converter = createUnifiedConverter()
|
|
207
|
+
return converter.fromSIP(sipProof, options)
|
|
208
|
+
}
|