enigma-memory 0.1.18 → 0.1.22
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/README.md +76 -24
- package/apps/cli/bin/enigma-desktop.mjs +140 -0
- package/apps/cli/bin/enigma-terminal.mjs +78 -0
- package/apps/cli/bin/enigma.mjs +1923 -285
- package/apps/desktop/electron-main.cjs +217 -0
- package/apps/desktop/package.json +12 -0
- package/apps/desktop/src/app.js +264 -7
- package/apps/desktop/src/index.html +3514 -1373
- package/apps/desktop/src/launch-electron.mjs +51 -0
- package/apps/desktop/src/server.mjs +2914 -0
- package/apps/desktop/src/styles.css +2972 -260
- package/apps/desktop/src/zk-browser-prove.mjs +53 -0
- package/apps/desktop/src/zk-state.mjs +1789 -0
- package/apps/gateway/bin/enigma-gateway.mjs +102 -5
- package/apps/gateway/src/server.mjs +271 -8
- package/apps/ios/EnigmaCore/Package.swift +12 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/EnigmaAPIClient.swift +227 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/Models.swift +278 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/PKCE.swift +96 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/PrivacyMinimizer.swift +187 -0
- package/apps/ios/EnigmaCore/Sources/EnigmaCore/ToolModels.swift +129 -0
- package/apps/ios/EnigmaCore/Tests/EnigmaCoreTests/EnigmaCoreTests.swift +42 -0
- package/apps/ios/EnigmaIOS/Enigma/AppModel.swift +346 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AccentColor.colorset/Contents.json +12 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AppIcon.appiconset/Contents.json +11 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/AppIcon.appiconset/EnigmaAppIcon.png +0 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/Contents.json +3 -0
- package/apps/ios/EnigmaIOS/Enigma/Assets.xcassets/LaunchBackground.colorset/Contents.json +12 -0
- package/apps/ios/EnigmaIOS/Enigma/ChatView.swift +181 -0
- package/apps/ios/EnigmaIOS/Enigma/CouncilView.swift +78 -0
- package/apps/ios/EnigmaIOS/Enigma/CreateView.swift +152 -0
- package/apps/ios/EnigmaIOS/Enigma/EnigmaApp.swift +52 -0
- package/apps/ios/EnigmaIOS/Enigma/Info.plist +52 -0
- package/apps/ios/EnigmaIOS/Enigma/NaturalLanguagePrivacyTagger.swift +26 -0
- package/apps/ios/EnigmaIOS/Enigma/OAuthClient.swift +321 -0
- package/apps/ios/EnigmaIOS/Enigma/OnboardingView.swift +105 -0
- package/apps/ios/EnigmaIOS/Enigma/PrivateVaultView.swift +275 -0
- package/apps/ios/EnigmaIOS/Enigma/SecureStore.swift +76 -0
- package/apps/ios/EnigmaIOS/Enigma/SettingsView.swift +60 -0
- package/apps/ios/EnigmaIOS/Enigma/Theme.swift +80 -0
- package/apps/ios/EnigmaIOS/EnigmaIOS.xcodeproj/project.pbxproj +211 -0
- package/apps/ios/EnigmaIOS/EnigmaIOS.xcodeproj/xcshareddata/xcschemes/Enigma.xcscheme +23 -0
- package/apps/native-host/README.md +19 -8
- package/apps/native-host/bin/enigma-native-host.mjs +229 -13
- package/apps/relay/bin/enigma-relay.mjs +103 -5
- package/apps/relay/src/federation-runtime.mjs +618 -0
- package/apps/relay/src/server.mjs +310 -9
- package/apps/verifier/bin/enigma-verify.mjs +327 -11
- package/cortex-v3/circuits/build/intent_vk_bytes.json +35 -0
- package/cortex-v3/circuits/build/sale_vk_bytes.json +35 -0
- package/cortex-v3/circuits/build/vk_bytes.json +32 -0
- package/cortex-v3/proving-assets.json +64 -0
- package/cortex-v3/zk/BUILD-CONTRACT.md +87 -0
- package/cortex-v3/zk/action-transition-vk.json +119 -0
- package/cortex-v3/zk/alias-adversarial.test.mjs +220 -0
- package/cortex-v3/zk/groth16-verify-child.mjs +17 -0
- package/cortex-v3/zk/intent-witness.mjs +365 -0
- package/cortex-v3/zk/intent-witness.test.mjs +485 -0
- package/cortex-v3/zk/proving-assets.mjs +203 -0
- package/cortex-v3/zk/sale-witness.mjs +783 -0
- package/cortex-v3/zk/sale-witness.test.mjs +784 -0
- package/cortex-v3/zk/sealed-sale-release-vk.json +119 -0
- package/cortex-v3/zk/settlement-evidence.mjs +722 -0
- package/cortex-v3/zk/setup-intent.mjs +688 -0
- package/cortex-v3/zk/setup-sale.mjs +666 -0
- package/cortex-v3/zk/setup.mjs +594 -0
- package/cortex-v3/zk/witness.mjs +184 -0
- package/cortex-v3/zk/zk-codec.mjs +232 -0
- package/cortex-v3/zk/zk-codec.test.mjs +293 -0
- package/cortex-v3/zk/zk-settle.mjs +370 -0
- package/cortex-v3/zk/zk-tree.mjs +256 -0
- package/cortex-v3/zk/zk-tree.test.mjs +419 -0
- package/deploy/docker-compose.local-production-simulation.yml +36 -0
- package/docs/browser-extension-install.md +8 -6
- package/docs/client-connectors.md +15 -11
- package/docs/developer-ecosystem.md +15 -13
- package/docs/enigma-memory-ready-conformance.md +11 -9
- package/docs/install-anywhere.md +61 -28
- package/docs/installers-and-desktop.md +8 -7
- package/docs/novelty-invention-candidates.md +161 -161
- package/docs/proof-network-claim-boundaries.md +320 -318
- package/examples/01-quickstart-agent/index.mjs +49 -0
- package/examples/01_agent_memory_quickstart.mjs +57 -0
- package/examples/02-multi-agent-swarm/index.mjs +57 -0
- package/examples/02_cross_model_passport.mjs +64 -0
- package/examples/03-langchain-memory/index.mjs +41 -0
- package/examples/03_poseidon_commitment_verification.mjs +71 -0
- package/examples/04-python-trading-agent/trader.py +49 -0
- package/examples/README.md +27 -0
- package/examples/ci/github-actions.yml +7 -2
- package/package.json +142 -11
- package/packages/adapters/PACKAGE_CONTRACT.md +1 -1
- package/packages/connectors/src/index.js +196 -4
- package/packages/connectors/swarm-router.mjs +168 -0
- package/packages/core/src/index.js +248 -1
- package/packages/core/src/version.mjs +7 -0
- package/packages/dev-tools/package.json +19 -0
- package/packages/dev-tools/src/index.js +4 -0
- package/packages/dev-tools/src/memory-benchmark-suite.js +112 -0
- package/packages/dev-tools/src/swarm-simulator.js +101 -0
- package/packages/dev-tools/src/vault-inspector.js +114 -0
- package/packages/dev-tools/src/vector-benchmark.js +100 -0
- package/packages/developer-platform/src/access-credentials.js +341 -0
- package/packages/developer-platform/src/http.js +132 -0
- package/packages/developer-platform/src/index.js +4 -0
- package/packages/developer-platform/src/usage-http.js +60 -0
- package/packages/developer-platform/src/usage.js +295 -0
- package/packages/enclave-runtime/attestation.mjs +159 -0
- package/packages/enclave-runtime/index.mjs +47 -0
- package/packages/enclave-runtime/session-manager.mjs +253 -0
- package/packages/enclave-runtime/zeroization-proof.mjs +227 -0
- package/packages/enigma-reflex/package.json +14 -0
- package/packages/enigma-reflex/src/index.js +204 -0
- package/packages/enigma-reflex/training/generate-dataset.mjs +40 -0
- package/packages/enigma-reflex/training/requirements.txt +8 -0
- package/packages/enigma-reflex/training/train.py +314 -0
- package/packages/enigma-weave/LICENSE +22 -0
- package/packages/enigma-weave/UPSTREAM.json +21 -0
- package/packages/enigma-weave/package.json +14 -0
- package/packages/enigma-weave/src/index.js +286 -0
- package/packages/hosted-cloud/src/index.js +80 -5
- package/packages/importers/src/index.js +432 -0
- package/packages/inference-runtime/src/browser.js +401 -0
- package/packages/inference-runtime/src/chat.js +265 -0
- package/packages/inference-runtime/src/code.js +407 -0
- package/packages/inference-runtime/src/contracts.js +162 -0
- package/packages/inference-runtime/src/http.js +232 -0
- package/packages/inference-runtime/src/image.js +186 -0
- package/packages/inference-runtime/src/index.js +10 -0
- package/packages/inference-runtime/src/model-router.js +320 -0
- package/packages/inference-runtime/src/platform.js +125 -0
- package/packages/inference-runtime/src/privacy.js +400 -0
- package/packages/inference-runtime/src/video.js +253 -0
- package/packages/mcp-server/README.md +22 -6
- package/packages/mcp-server/bin/enigma-mcp.mjs +2 -1
- package/packages/mcp-server/src/index.js +1418 -105
- package/packages/mcp-server/src/oauth.js +561 -0
- package/packages/mcp-server/src/private-handoff.js +84 -0
- package/packages/mcp-server/src/remote-http.js +273 -0
- package/packages/mcp-server/src/remote-policy.js +72 -0
- package/packages/mcp-server/swarm-bridge.mjs +361 -0
- package/packages/mesh/index.d.ts +283 -0
- package/packages/mesh/package.json +23 -0
- package/packages/mesh/src/crypto.js +189 -0
- package/packages/mesh/src/federation-packets.js +353 -0
- package/packages/mesh/src/gossip.js +311 -0
- package/packages/mesh/src/index.js +6 -0
- package/packages/mesh/src/protocol.js +255 -0
- package/packages/mesh/src/router.js +279 -0
- package/packages/mesh/src/transport.js +306 -0
- package/packages/passport/src/index.js +426 -1
- package/packages/private-economy/src/credits-http.js +100 -0
- package/packages/private-economy/src/credits.js +447 -0
- package/packages/private-economy/src/index.js +5 -0
- package/packages/private-economy/src/payments-http.js +120 -0
- package/packages/private-economy/src/payments.js +509 -0
- package/packages/private-economy/src/x402.js +346 -0
- package/packages/proof-network/PACKAGE_CONTRACT.md +21 -0
- package/packages/rag/index.d.ts +182 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/THIRD_PARTY_LICENSES.txt +207 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/config.json +25 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/onnx/model_quantized.onnx +0 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/sha256-manifest.json +28 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/tokenizer.json +30686 -0
- package/packages/rag/models/Xenova/all-MiniLM-L6-v2/tokenizer_config.json +15 -0
- package/packages/rag/package.json +27 -0
- package/packages/rag/src/blinded-search.js +109 -0
- package/packages/rag/src/bm25.js +169 -0
- package/packages/rag/src/embeddings.js +459 -0
- package/packages/rag/src/hybrid.js +76 -0
- package/packages/rag/src/index.js +38 -0
- package/packages/rag/src/reranker.js +61 -0
- package/packages/rag/src/research.js +107 -0
- package/packages/rag/src/vector-store.js +430 -0
- package/packages/rag/src/verify-model-artifacts.mjs +4 -0
- package/packages/sdk/index.d.ts +760 -0
- package/packages/sdk/package.json +33 -0
- package/packages/sdk/python/README.md +24 -0
- package/packages/sdk/python/enigma_sdk.py +250 -0
- package/packages/sdk/python/pyproject.toml +34 -0
- package/packages/sdk/python/requirements.txt +1 -0
- package/packages/sdk/python/setup.py +20 -0
- package/packages/sdk/src/federation/capability-grant.js +389 -0
- package/packages/sdk/src/federation/federation-router.js +360 -0
- package/packages/sdk/src/federation/ghostmesh-bridge.js +497 -0
- package/packages/sdk/src/federation/index.js +3 -0
- package/packages/sdk/src/index.js +1796 -0
- package/packages/sdk/src/intelligence/contradiction.js +337 -0
- package/packages/sdk/src/intelligence/decision-engine.js +155 -0
- package/packages/sdk/src/intelligence/index.js +4 -0
- package/packages/sdk/src/intelligence/ontology.js +122 -0
- package/packages/sdk/src/intelligence/temporal.js +123 -0
- package/packages/sdk/src/market-client.js +142 -0
- package/packages/sdk/src/mesh-client.js +110 -0
- package/packages/sdk/src/middleware/index.js +3 -0
- package/packages/sdk/src/middleware/langchain.js +159 -0
- package/packages/sdk/src/middleware/llamaindex.js +101 -0
- package/packages/sdk/src/middleware/vercel-ai.js +112 -0
- package/packages/sdk/src/rag-client.js +85 -0
- package/packages/sdk/src/swarm-orchestrator.js +260 -0
- package/packages/settlement/PACKAGE_CONTRACT.md +1 -1
- package/packages/snapcompact/THIRD_PARTY_LICENSES.txt +40 -0
- package/packages/snapcompact/assets/8x13-latin1.bdf +3837 -0
- package/packages/snapcompact/index.d.ts +284 -0
- package/packages/snapcompact/package.json +25 -0
- package/packages/snapcompact/src/index.js +716 -0
- package/packages/storage/PACKAGE_CONTRACT.md +1 -1
- package/packages/terminal-console/animations.mjs +240 -0
- package/packages/terminal-console/auto-anchor.mjs +220 -0
- package/packages/terminal-console/banner.mjs +91 -0
- package/packages/terminal-console/commands.mjs +459 -0
- package/packages/terminal-console/delegation.mjs +152 -0
- package/packages/terminal-console/index.mjs +5 -0
- package/packages/terminal-console/outbox.mjs +143 -0
- package/packages/terminal-console/phantom-bridge.mjs +637 -0
- package/packages/terminal-console/repl.mjs +136 -0
- package/packages/terminal-console/signer-store.mjs +130 -0
- package/packages/terminal-console/solana-rpc.mjs +214 -0
- package/packages/terminal-console/solana-transport.mjs +189 -0
- package/packages/terminal-tui/dashboard.mjs +214 -0
- package/packages/terminal-tui/index.mjs +28 -0
- package/packages/terminal-tui/merkle-tree-renderer.mjs +268 -0
- package/packages/terminal-tui/telemetry-hud.mjs +137 -0
- package/packages/vault/index.d.ts +449 -0
- package/packages/vault/package.json +27 -0
- package/packages/vault/src/e2ee.mjs +393 -0
- package/packages/vault/src/enclave.js +481 -0
- package/packages/vault/src/erasure.js +207 -0
- package/packages/vault/src/index.js +1018 -155
- package/packages/vault/src/persistence.js +307 -0
- package/packages/vault/src/poseidon.js +354 -0
- package/packages/vault/src/receipt.js +459 -0
- package/scripts/benchmark-optical-context.mjs +166 -0
- package/scripts/bootstrap-enigma.mjs +502 -0
- package/scripts/build-edge-backend-workers.mjs +20 -5
- package/scripts/build-goal-completion-audit.mjs +72 -25
- package/scripts/build-hosted-api-key-lifecycle.mjs +26 -8
- package/scripts/build-hosted-customer-lifecycle.mjs +20 -3
- package/scripts/build-hosted-probe-worker.mjs +19 -4
- package/scripts/build-installer-assets.mjs +41 -21
- package/scripts/build-operator-evidence-starter.mjs +59 -1
- package/scripts/build-production-backend-env-kit.mjs +2 -0
- package/scripts/build-production-unblocker.mjs +3 -0
- package/scripts/check.mjs +17 -3
- package/scripts/collect-hosted-backend-live-evidence.mjs +49 -12
- package/scripts/install-enigma-local.mjs +18 -5
- package/scripts/release-audit.mjs +65 -109
- package/scripts/release-provenance.mjs +6 -0
- package/scripts/run-backend-readiness-smoke.mjs +112 -10
- package/scripts/scan-secrets.mjs +1 -0
- package/scripts/simulate-production-env.mjs +7 -2
- package/scripts/validate-hosted-backend-live.mjs +112 -1
- package/specs/antibody-pack-v1.schema.json +95 -0
- package/specs/antigen-envelope-v1.schema.json +81 -0
- package/specs/boundary-manifest-v1.schema.json +35 -35
- package/specs/capsule-v1.schema.json +55 -55
- package/specs/claim-boundary-manifest-v1.schema.json +22 -22
- package/specs/claim-ledger-v1.schema.json +291 -0
- package/specs/context-passport-v1.schema.json +59 -0
- package/specs/deletion-tombstone-v1.schema.json +26 -26
- package/specs/evidence-packet-v1.schema.json +177 -0
- package/specs/hosted-backend-live-evidence-v1.schema.json +72 -3
- package/specs/immune-scan-report-v1.schema.json +112 -0
- package/specs/lifecycle-receipt-log-v1.schema.json +67 -0
- package/specs/memory-atom-v1.schema.json +59 -0
- package/specs/memory-event-v1.schema.json +42 -42
- package/specs/passport-v1.schema.json +50 -50
- package/specs/proof-of-non-use-v1.schema.json +65 -0
- package/specs/quarantine-record-v1.schema.json +126 -0
- package/specs/receipt-v1.schema.json +61 -61
- package/specs/state-checkpoint-v1.schema.json +37 -37
- package/specs/trust-bundle-v1.schema.json +56 -56
- package/specs/trust-card-v1.schema.json +119 -0
- package/docs/proof-network-launch-plan.md +0 -421
- package/packages/metering/PACKAGE_CONTRACT.md +0 -20
- package/scripts/build-ai-orchestration-plan.mjs +0 -248
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
3
|
+
import { open, mkdir, readFile, rename, stat, unlink, utimes } from 'node:fs/promises';
|
|
4
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
5
|
+
|
|
6
|
+
const DEFAULT_LOCK_TIMEOUT_MS = 10_000;
|
|
7
|
+
const DEFAULT_STALE_LOCK_MS = 30_000;
|
|
8
|
+
const HEAD_SCHEMA = 'enigma.vault_monotonic_head.v1';
|
|
9
|
+
const lockContext = new AsyncLocalStorage();
|
|
10
|
+
|
|
11
|
+
function sha256(value) {
|
|
12
|
+
return `sha256:${createHash('sha256').update(value).digest('hex')}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function sleep(milliseconds) {
|
|
16
|
+
return new Promise((resolveSleep) => setTimeout(resolveSleep, milliseconds));
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async function lockSnapshot(lockPath) {
|
|
20
|
+
try {
|
|
21
|
+
const [raw, info] = await Promise.all([readFile(lockPath, 'utf8'), stat(lockPath)]);
|
|
22
|
+
const value = JSON.parse(raw);
|
|
23
|
+
return { token: value?.token, pid: value?.pid, mtimeMs: info.mtimeMs };
|
|
24
|
+
} catch (error) {
|
|
25
|
+
if (error?.code === 'ENOENT') return null;
|
|
26
|
+
if (error instanceof SyntaxError) return { token: null, pid: null, mtimeMs: 0 };
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function processIsAlive(pid) {
|
|
31
|
+
if (!Number.isInteger(pid) || pid <= 0) return false;
|
|
32
|
+
try {
|
|
33
|
+
process.kill(pid, 0);
|
|
34
|
+
return true;
|
|
35
|
+
} catch (error) {
|
|
36
|
+
return error?.code === 'EPERM';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
async function removeIfStale(lockPath, staleLockMs) {
|
|
42
|
+
const first = await lockSnapshot(lockPath);
|
|
43
|
+
if (!first || Date.now() - first.mtimeMs <= staleLockMs) return first === null;
|
|
44
|
+
if (processIsAlive(first.pid)) return false;
|
|
45
|
+
await sleep(Math.min(25, Math.max(5, Math.floor(staleLockMs / 20))));
|
|
46
|
+
const second = await lockSnapshot(lockPath);
|
|
47
|
+
if (!second) return true;
|
|
48
|
+
if (second.token !== first.token || second.pid !== first.pid || second.mtimeMs !== first.mtimeMs || Date.now() - second.mtimeMs <= staleLockMs) return false;
|
|
49
|
+
if (processIsAlive(second.pid)) return false;
|
|
50
|
+
await unlink(lockPath);
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function assertLockOwner(lock) {
|
|
55
|
+
const snapshot = await lockSnapshot(lock.lockPath);
|
|
56
|
+
if (!snapshot || snapshot.token !== lock.token) {
|
|
57
|
+
const error = new Error(`Vault lock ownership changed: ${lock.lockPath}`);
|
|
58
|
+
error.code = 'ENIGMA_VAULT_LOCK_LOST';
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async function acquireBundleLock(path, options = {}) {
|
|
64
|
+
const lockPath = `${path}.lock`;
|
|
65
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_LOCK_TIMEOUT_MS;
|
|
66
|
+
const staleLockMs = options.staleLockMs ?? DEFAULT_STALE_LOCK_MS;
|
|
67
|
+
if (!Number.isFinite(staleLockMs) || staleLockMs < 100) throw new Error('staleLockMs must be at least 100');
|
|
68
|
+
const started = Date.now();
|
|
69
|
+
const token = randomUUID();
|
|
70
|
+
await mkdir(dirname(path), { recursive: true });
|
|
71
|
+
while (true) {
|
|
72
|
+
try {
|
|
73
|
+
const handle = await open(lockPath, 'wx', 0o600);
|
|
74
|
+
try {
|
|
75
|
+
await handle.writeFile(JSON.stringify({ token, pid: process.pid, acquired_at: new Date().toISOString() }), 'utf8');
|
|
76
|
+
await handle.sync();
|
|
77
|
+
} finally {
|
|
78
|
+
await handle.close();
|
|
79
|
+
}
|
|
80
|
+
const lock = { lockPath, token, staleLockMs, heartbeatError: null, heartbeat: null };
|
|
81
|
+
const intervalMs = Math.max(50, Math.floor(staleLockMs / 3));
|
|
82
|
+
lock.heartbeat = setInterval(() => {
|
|
83
|
+
const now = new Date();
|
|
84
|
+
utimes(lockPath, now, now).catch((error) => { lock.heartbeatError = error; });
|
|
85
|
+
}, intervalMs);
|
|
86
|
+
lock.heartbeat.unref?.();
|
|
87
|
+
return lock;
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (error?.code !== 'EEXIST') throw error;
|
|
90
|
+
if (await removeIfStale(lockPath, staleLockMs)) continue;
|
|
91
|
+
if (Date.now() - started >= timeoutMs) throw new Error(`Timed out acquiring vault lock: ${lockPath}`);
|
|
92
|
+
await sleep(15 + Math.floor(Math.random() * 35));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
async function releaseBundleLock(lock) {
|
|
98
|
+
clearInterval(lock.heartbeat);
|
|
99
|
+
try {
|
|
100
|
+
await assertLockOwner(lock);
|
|
101
|
+
await unlink(lock.lockPath);
|
|
102
|
+
} catch (error) {
|
|
103
|
+
if (error?.code !== 'ENOENT') throw error;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function canonicalPath(path) {
|
|
108
|
+
return resolve(String(path));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export async function withBundleFileLock(path, operation, options = {}) {
|
|
112
|
+
if (typeof operation !== 'function') throw new TypeError('withBundleFileLock requires an operation function');
|
|
113
|
+
const target = canonicalPath(path);
|
|
114
|
+
const inherited = lockContext.getStore();
|
|
115
|
+
if (inherited?.has(target)) return operation();
|
|
116
|
+
const lock = await acquireBundleLock(target, options);
|
|
117
|
+
const store = new Map(inherited ?? []);
|
|
118
|
+
store.set(target, lock);
|
|
119
|
+
try {
|
|
120
|
+
return await lockContext.run(store, operation);
|
|
121
|
+
} finally {
|
|
122
|
+
await releaseBundleLock(lock);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function monotonicHeadPath(path) {
|
|
127
|
+
return `${canonicalPath(path)}.head`;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
async function readHead(path) {
|
|
131
|
+
try {
|
|
132
|
+
const head = JSON.parse(await readFile(monotonicHeadPath(path), 'utf8'));
|
|
133
|
+
if (head?.schema !== HEAD_SCHEMA || !Number.isInteger(head.sequence) || head.sequence < 0) {
|
|
134
|
+
throw new Error('Vault monotonic head is invalid');
|
|
135
|
+
}
|
|
136
|
+
return head;
|
|
137
|
+
} catch (error) {
|
|
138
|
+
if (error?.code === 'ENOENT') return null;
|
|
139
|
+
throw error;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function bundleHead(value, revision) {
|
|
144
|
+
if (value?.schema !== 'enigma.vault_bundle.v1') return null;
|
|
145
|
+
const sequence = value.vault?.sequence;
|
|
146
|
+
if (!Number.isInteger(sequence) || sequence < 0) throw new Error('Vault bundle sequence is invalid');
|
|
147
|
+
const lastReceipt = Array.isArray(value.receipts) ? value.receipts.at(-1) : undefined;
|
|
148
|
+
return {
|
|
149
|
+
schema: HEAD_SCHEMA,
|
|
150
|
+
vault_id: value.vault?.vault_id,
|
|
151
|
+
trust_domain: 'same_user_local_file_not_rollback_resistant',
|
|
152
|
+
sequence,
|
|
153
|
+
bundle_revision: revision,
|
|
154
|
+
receipt_hash: lastReceipt ? sha256(JSON.stringify(lastReceipt)) : null,
|
|
155
|
+
updated_at: new Date().toISOString(),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function assertMonotonic(value, revision, head, options = {}) {
|
|
160
|
+
const candidate = bundleHead(value, revision);
|
|
161
|
+
if (!candidate) return;
|
|
162
|
+
if (options.minimumSequence !== undefined && candidate.sequence < options.minimumSequence) {
|
|
163
|
+
const error = new Error('Vault bundle sequence is below the caller monotonic head');
|
|
164
|
+
error.code = 'ENIGMA_VAULT_ROLLBACK';
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
167
|
+
if (!head) {
|
|
168
|
+
if (options.requireMonotonicHead === true) throw new Error('Vault monotonic head is required');
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
if (candidate.vault_id !== head.vault_id || candidate.sequence < head.sequence) {
|
|
172
|
+
const error = new Error('Vault bundle rollback or vault substitution detected');
|
|
173
|
+
error.code = 'ENIGMA_VAULT_ROLLBACK';
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
if (candidate.sequence === head.sequence && candidate.bundle_revision !== head.bundle_revision) {
|
|
177
|
+
const error = new Error('Vault bundle revision conflicts with the monotonic head');
|
|
178
|
+
error.code = 'ENIGMA_VAULT_ROLLBACK';
|
|
179
|
+
throw error;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function checkpointProvider(options = {}) {
|
|
184
|
+
const provider = options.checkpointProvider;
|
|
185
|
+
if (provider === undefined || provider === null) {
|
|
186
|
+
if (options.requireExternalCheckpoint === true) throw new Error('An external monotonic checkpoint provider is required');
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
if (typeof provider?.load !== 'function' || typeof provider?.advance !== 'function') {
|
|
190
|
+
throw new TypeError('checkpointProvider requires async load and advance functions');
|
|
191
|
+
}
|
|
192
|
+
return provider;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async function loadExternalCheckpoint(path, value, options = {}) {
|
|
196
|
+
const provider = checkpointProvider(options);
|
|
197
|
+
if (!provider) return null;
|
|
198
|
+
const head = await provider.load({ path: canonicalPath(path), vault_id: value?.vault?.vault_id });
|
|
199
|
+
if (head === null || head === undefined) return null;
|
|
200
|
+
if (!Number.isInteger(head.sequence) || head.sequence < 0 || typeof head.bundle_revision !== 'string') {
|
|
201
|
+
throw new Error('External vault monotonic checkpoint is invalid');
|
|
202
|
+
}
|
|
203
|
+
return head;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export async function readJsonFileWithRevision(path, options = {}) {
|
|
207
|
+
const raw = await readFile(path, 'utf8');
|
|
208
|
+
const value = JSON.parse(raw);
|
|
209
|
+
const revision = sha256(raw);
|
|
210
|
+
const localHead = await readHead(path);
|
|
211
|
+
assertMonotonic(value, revision, localHead, options);
|
|
212
|
+
const externalHead = await loadExternalCheckpoint(path, value, options);
|
|
213
|
+
assertMonotonic(value, revision, externalHead, options);
|
|
214
|
+
return { value, revision, raw, localHead, externalHead };
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async function currentRevision(path) {
|
|
218
|
+
try {
|
|
219
|
+
return sha256(await readFile(path));
|
|
220
|
+
} catch (error) {
|
|
221
|
+
if (error?.code === 'ENOENT') return null;
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async function syncDirectory(path) {
|
|
227
|
+
let handle;
|
|
228
|
+
try {
|
|
229
|
+
handle = await open(path, 'r');
|
|
230
|
+
await handle.sync();
|
|
231
|
+
} catch (error) {
|
|
232
|
+
if (!['EACCES', 'EISDIR', 'EINVAL', 'ENOTSUP', 'EPERM'].includes(error?.code)) throw error;
|
|
233
|
+
} finally {
|
|
234
|
+
await handle?.close();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async function atomicReplace(path, serialized, beforeRename) {
|
|
239
|
+
const tempPath = join(dirname(path), `.${basename(path)}.${process.pid}.${randomUUID()}.tmp`);
|
|
240
|
+
let handle;
|
|
241
|
+
try {
|
|
242
|
+
handle = await open(tempPath, 'wx', 0o600);
|
|
243
|
+
await handle.writeFile(serialized, 'utf8');
|
|
244
|
+
await handle.sync();
|
|
245
|
+
await handle.close();
|
|
246
|
+
handle = undefined;
|
|
247
|
+
await beforeRename?.();
|
|
248
|
+
await rename(tempPath, path);
|
|
249
|
+
await syncDirectory(dirname(path));
|
|
250
|
+
} catch (error) {
|
|
251
|
+
await handle?.close().catch(() => undefined);
|
|
252
|
+
await unlink(tempPath).catch(() => undefined);
|
|
253
|
+
throw error;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export async function readFileRevision(path) {
|
|
258
|
+
const raw = await readFile(path);
|
|
259
|
+
return { revision: sha256(raw), raw };
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export async function writeJsonFileAtomic(path, value, options = {}) {
|
|
263
|
+
const target = canonicalPath(path);
|
|
264
|
+
const heldLock = lockContext.getStore()?.get(target);
|
|
265
|
+
if (!heldLock) {
|
|
266
|
+
return withBundleFileLock(target, () => writeJsonFileAtomic(target, value, options), options.lockOptions);
|
|
267
|
+
}
|
|
268
|
+
await assertLockOwner(heldLock);
|
|
269
|
+
await mkdir(dirname(target), { recursive: true });
|
|
270
|
+
if (Object.prototype.hasOwnProperty.call(options, 'expectedRevision')) {
|
|
271
|
+
const actual = await currentRevision(target);
|
|
272
|
+
if (actual !== options.expectedRevision) {
|
|
273
|
+
const error = new Error(`Vault bundle changed concurrently: expected ${options.expectedRevision ?? '<missing>'}, found ${actual ?? '<missing>'}`);
|
|
274
|
+
error.code = 'ENIGMA_VAULT_CAS_MISMATCH';
|
|
275
|
+
throw error;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const serialized = `${JSON.stringify(value, null, 2)}\n`;
|
|
280
|
+
const revision = sha256(serialized);
|
|
281
|
+
const priorHead = options.resetMonotonicHead === true ? null : await readHead(target);
|
|
282
|
+
const externalHead = await loadExternalCheckpoint(target, value, options);
|
|
283
|
+
assertMonotonic(value, revision, externalHead, options);
|
|
284
|
+
assertMonotonic(value, revision, priorHead, options);
|
|
285
|
+
await assertLockOwner(heldLock);
|
|
286
|
+
await atomicReplace(target, serialized, () => assertLockOwner(heldLock));
|
|
287
|
+
const nextHead = bundleHead(value, revision);
|
|
288
|
+
if (nextHead) {
|
|
289
|
+
await atomicReplace(monotonicHeadPath(target), `${JSON.stringify(nextHead, null, 2)}\n`, () => assertLockOwner(heldLock));
|
|
290
|
+
} else if (options.resetMonotonicHead === true) {
|
|
291
|
+
await unlink(monotonicHeadPath(target)).catch((error) => { if (error?.code !== 'ENOENT') throw error; });
|
|
292
|
+
}
|
|
293
|
+
const provider = checkpointProvider(options);
|
|
294
|
+
if (provider && nextHead) {
|
|
295
|
+
const advanced = await provider.advance({
|
|
296
|
+
path: target,
|
|
297
|
+
previous: externalHead,
|
|
298
|
+
next: { ...nextHead, trust_domain: 'external_checkpoint_provider' },
|
|
299
|
+
});
|
|
300
|
+
if (advanced === false) {
|
|
301
|
+
const error = new Error('External vault monotonic checkpoint rejected advancement');
|
|
302
|
+
error.code = 'ENIGMA_VAULT_ROLLBACK';
|
|
303
|
+
throw error;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return { revision, bytes: Buffer.byteLength(serialized), head: nextHead };
|
|
307
|
+
}
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
import { createHash, randomBytes } from 'node:crypto';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Canonical Circomlib / Noir compatible Poseidon Hash over BN254 Fr scalar field
|
|
5
|
+
* Exact parameters for t=3 (2 inputs + 1 capacity element):
|
|
6
|
+
* - Prime p: 21888242871839275222246405745257275088548364400416034343698204186575808495617
|
|
7
|
+
* - S-box: x^5 mod p
|
|
8
|
+
* - R_F: 8 full rounds (4 front + 4 back)
|
|
9
|
+
* - R_P: 57 partial rounds (S-box on state[0] only)
|
|
10
|
+
* - Round constants C (195 constants) from canonical iden3/circomlib specification
|
|
11
|
+
* - MDS Matrix M (3x3) from canonical iden3/circomlib specification
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export const SNARK_SCALAR_FIELD = 21888242871839275222246405745257275088548364400416034343698204186575808495617n;
|
|
15
|
+
const P = SNARK_SCALAR_FIELD;
|
|
16
|
+
|
|
17
|
+
const POSEIDON_C_T3_HEX = [
|
|
18
|
+
"0x0ee9a592ba9a9518d05986d656f40c2114c4993c11bb29938d21d47304cd8e6e",
|
|
19
|
+
"0x00f1445235f2148c5986587169fc1bcd887b08d4d00868df5696fff40956e864",
|
|
20
|
+
"0x08dff3487e8ac99e1f29a058d0fa80b930c728730b7ab36ce879f3890ecf73f5",
|
|
21
|
+
"0x2f27be690fdaee46c3ce28f7532b13c856c35342c84bda6e20966310fadc01d0",
|
|
22
|
+
"0x2b2ae1acf68b7b8d2416bebf3d4f6234b763fe04b8043ee48b8327bebca16cf2",
|
|
23
|
+
"0x0319d062072bef7ecca5eac06f97d4d55952c175ab6b03eae64b44c7dbf11cfa",
|
|
24
|
+
"0x28813dcaebaeaa828a376df87af4a63bc8b7bf27ad49c6298ef7b387bf28526d",
|
|
25
|
+
"0x2727673b2ccbc903f181bf38e1c1d40d2033865200c352bc150928adddf9cb78",
|
|
26
|
+
"0x234ec45ca27727c2e74abd2b2a1494cd6efbd43e340587d6b8fb9e31e65cc632",
|
|
27
|
+
"0x15b52534031ae18f7f862cb2cf7cf760ab10a8150a337b1ccd99ff6e8797d428",
|
|
28
|
+
"0x0dc8fad6d9e4b35f5ed9a3d186b79ce38e0e8a8d1b58b132d701d4eecf68d1f6",
|
|
29
|
+
"0x1bcd95ffc211fbca600f705fad3fb567ea4eb378f62e1fec97805518a47e4d9c",
|
|
30
|
+
"0x10520b0ab721cadfe9eff81b016fc34dc76da36c2578937817cb978d069de559",
|
|
31
|
+
"0x1f6d48149b8e7f7d9b257d8ed5fbbaf42932498075fed0ace88a9eb81f5627f6",
|
|
32
|
+
"0x1d9655f652309014d29e00ef35a2089bfff8dc1c816f0dc9ca34bdb5460c8705",
|
|
33
|
+
"0x04df5a56ff95bcafb051f7b1cd43a99ba731ff67e47032058fe3d4185697cc7d",
|
|
34
|
+
"0x0672d995f8fff640151b3d290cedaf148690a10a8c8424a7f6ec282b6e4be828",
|
|
35
|
+
"0x099952b414884454b21200d7ffafdd5f0c9a9dcc06f2708e9fc1d8209b5c75b9",
|
|
36
|
+
"0x052cba2255dfd00c7c483143ba8d469448e43586a9b4cd9183fd0e843a6b9fa6",
|
|
37
|
+
"0x0b8badee690adb8eb0bd74712b7999af82de55707251ad7716077cb93c464ddc",
|
|
38
|
+
"0x119b1590f13307af5a1ee651020c07c749c15d60683a8050b963d0a8e4b2bdd1",
|
|
39
|
+
"0x03150b7cd6d5d17b2529d36be0f67b832c4acfc884ef4ee5ce15be0bfb4a8d09",
|
|
40
|
+
"0x2cc6182c5e14546e3cf1951f173912355374efb83d80898abe69cb317c9ea565",
|
|
41
|
+
"0x005032551e6378c450cfe129a404b3764218cadedac14e2b92d2cd73111bf0f9",
|
|
42
|
+
"0x233237e3289baa34bb147e972ebcb9516469c399fcc069fb88f9da2cc28276b5",
|
|
43
|
+
"0x05c8f4f4ebd4a6e3c980d31674bfbe6323037f21b34ae5a4e80c2d4c24d60280",
|
|
44
|
+
"0x0a7b1db13042d396ba05d818a319f25252bcf35ef3aeed91ee1f09b2590fc65b",
|
|
45
|
+
"0x2a73b71f9b210cf5b14296572c9d32dbf156e2b086ff47dc5df542365a404ec0",
|
|
46
|
+
"0x1ac9b0417abcc9a1935107e9ffc91dc3ec18f2c4dbe7f22976a760bb5c50c460",
|
|
47
|
+
"0x12c0339ae08374823fabb076707ef479269f3e4d6cb104349015ee046dc93fc0",
|
|
48
|
+
"0x0b7475b102a165ad7f5b18db4e1e704f52900aa3253baac68246682e56e9a28e",
|
|
49
|
+
"0x037c2849e191ca3edb1c5e49f6e8b8917c843e379366f2ea32ab3aa88d7f8448",
|
|
50
|
+
"0x05a6811f8556f014e92674661e217e9bd5206c5c93a07dc145fdb176a716346f",
|
|
51
|
+
"0x29a795e7d98028946e947b75d54e9f044076e87a7b2883b47b675ef5f38bd66e",
|
|
52
|
+
"0x20439a0c84b322eb45a3857afc18f5826e8c7382c8a1585c507be199981fd22f",
|
|
53
|
+
"0x2e0ba8d94d9ecf4a94ec2050c7371ff1bb50f27799a84b6d4a2a6f2a0982c887",
|
|
54
|
+
"0x143fd115ce08fb27ca38eb7cce822b4517822cd2109048d2e6d0ddcca17d71c8",
|
|
55
|
+
"0x0c64cbecb1c734b857968dbbdcf813cdf8611659323dbcbfc84323623be9caf1",
|
|
56
|
+
"0x028a305847c683f646fca925c163ff5ae74f348d62c2b670f1426cef9403da53",
|
|
57
|
+
"0x2e4ef510ff0b6fda5fa940ab4c4380f26a6bcb64d89427b824d6755b5db9e30c",
|
|
58
|
+
"0x0081c95bc43384e663d79270c956ce3b8925b4f6d033b078b96384f50579400e",
|
|
59
|
+
"0x2ed5f0c91cbd9749187e2fade687e05ee2491b349c039a0bba8a9f4023a0bb38",
|
|
60
|
+
"0x30509991f88da3504bbf374ed5aae2f03448a22c76234c8c990f01f33a735206",
|
|
61
|
+
"0x1c3f20fd55409a53221b7c4d49a356b9f0a1119fb2067b41a7529094424ec6ad",
|
|
62
|
+
"0x10b4e7f3ab5df003049514459b6e18eec46bb2213e8e131e170887b47ddcb96c",
|
|
63
|
+
"0x2a1982979c3ff7f43ddd543d891c2abddd80f804c077d775039aa3502e43adef",
|
|
64
|
+
"0x1c74ee64f15e1db6feddbead56d6d55dba431ebc396c9af95cad0f1315bd5c91",
|
|
65
|
+
"0x07533ec850ba7f98eab9303cace01b4b9e4f2e8b82708cfa9c2fe45a0ae146a0",
|
|
66
|
+
"0x21576b438e500449a151e4eeaf17b154285c68f42d42c1808a11abf3764c0750",
|
|
67
|
+
"0x2f17c0559b8fe79608ad5ca193d62f10bce8384c815f0906743d6930836d4a9e",
|
|
68
|
+
"0x2d477e3862d07708a79e8aae946170bc9775a4201318474ae665b0b1b7e2730e",
|
|
69
|
+
"0x162f5243967064c390e095577984f291afba2266c38f5abcd89be0f5b2747eab",
|
|
70
|
+
"0x2b4cb233ede9ba48264ecd2c8ae50d1ad7a8596a87f29f8a7777a70092393311",
|
|
71
|
+
"0x2c8fbcb2dd8573dc1dbaf8f4622854776db2eece6d85c4cf4254e7c35e03b07a",
|
|
72
|
+
"0x1d6f347725e4816af2ff453f0cd56b199e1b61e9f601e9ade5e88db870949da9",
|
|
73
|
+
"0x204b0c397f4ebe71ebc2d8b3df5b913df9e6ac02b68d31324cd49af5c4565529",
|
|
74
|
+
"0x0c4cb9dc3c4fd8174f1149b3c63c3c2f9ecb827cd7dc25534ff8fb75bc79c502",
|
|
75
|
+
"0x174ad61a1448c899a25416474f4930301e5c49475279e0639a616ddc45bc7b54",
|
|
76
|
+
"0x1a96177bcf4d8d89f759df4ec2f3cde2eaaa28c177cc0fa13a9816d49a38d2ef",
|
|
77
|
+
"0x066d04b24331d71cd0ef8054bc60c4ff05202c126a233c1a8242ace360b8a30a",
|
|
78
|
+
"0x2a4c4fc6ec0b0cf52195782871c6dd3b381cc65f72e02ad527037a62aa1bd804",
|
|
79
|
+
"0x13ab2d136ccf37d447e9f2e14a7cedc95e727f8446f6d9d7e55afc01219fd649",
|
|
80
|
+
"0x1121552fca26061619d24d843dc82769c1b04fcec26f55194c2e3e869acc6a9a",
|
|
81
|
+
"0x00ef653322b13d6c889bc81715c37d77a6cd267d595c4a8909a5546c7c97cff1",
|
|
82
|
+
"0x0e25483e45a665208b261d8ba74051e6400c776d652595d9845aca35d8a397d3",
|
|
83
|
+
"0x29f536dcb9dd7682245264659e15d88e395ac3d4dde92d8c46448db979eeba89",
|
|
84
|
+
"0x2a56ef9f2c53febadfda33575dbdbd885a124e2780bbea170e456baace0fa5be",
|
|
85
|
+
"0x1c8361c78eb5cf5decfb7a2d17b5c409f2ae2999a46762e8ee416240a8cb9af1",
|
|
86
|
+
"0x151aff5f38b20a0fc0473089aaf0206b83e8e68a764507bfd3d0ab4be74319c5",
|
|
87
|
+
"0x04c6187e41ed881dc1b239c88f7f9d43a9f52fc8c8b6cdd1e76e47615b51f100",
|
|
88
|
+
"0x13b37bd80f4d27fb10d84331f6fb6d534b81c61ed15776449e801b7ddc9c2967",
|
|
89
|
+
"0x01a5c536273c2d9df578bfbd32c17b7a2ce3664c2a52032c9321ceb1c4e8a8e4",
|
|
90
|
+
"0x2ab3561834ca73835ad05f5d7acb950b4a9a2c666b9726da832239065b7c3b02",
|
|
91
|
+
"0x1d4d8ec291e720db200fe6d686c0d613acaf6af4e95d3bf69f7ed516a597b646",
|
|
92
|
+
"0x041294d2cc484d228f5784fe7919fd2bb925351240a04b711514c9c80b65af1d",
|
|
93
|
+
"0x154ac98e01708c611c4fa715991f004898f57939d126e392042971dd90e81fc6",
|
|
94
|
+
"0x0b339d8acca7d4f83eedd84093aef51050b3684c88f8b0b04524563bc6ea4da4",
|
|
95
|
+
"0x0955e49e6610c94254a4f84cfbab344598f0e71eaff4a7dd81ed95b50839c82e",
|
|
96
|
+
"0x06746a6156eba54426b9e22206f15abca9a6f41e6f535c6f3525401ea0654626",
|
|
97
|
+
"0x0f18f5a0ecd1423c496f3820c549c27838e5790e2bd0a196ac917c7ff32077fb",
|
|
98
|
+
"0x04f6eeca1751f7308ac59eff5beb261e4bb563583ede7bc92a738223d6f76e13",
|
|
99
|
+
"0x2b56973364c4c4f5c1a3ec4da3cdce038811eb116fb3e45bc1768d26fc0b3758",
|
|
100
|
+
"0x123769dd49d5b054dcd76b89804b1bcb8e1392b385716a5d83feb65d437f29ef",
|
|
101
|
+
"0x2147b424fc48c80a88ee52b91169aacea989f6446471150994257b2fb01c63e9",
|
|
102
|
+
"0x0fdc1f58548b85701a6c5505ea332a29647e6f34ad4243c2ea54ad897cebe54d",
|
|
103
|
+
"0x12373a8251fea004df68abcf0f7786d4bceff28c5dbbe0c3944f685cc0a0b1f2",
|
|
104
|
+
"0x21e4f4ea5f35f85bad7ea52ff742c9e8a642756b6af44203dd8a1f35c1a90035",
|
|
105
|
+
"0x16243916d69d2ca3dfb4722224d4c462b57366492f45e90d8a81934f1bc3b147",
|
|
106
|
+
"0x1efbe46dd7a578b4f66f9adbc88b4378abc21566e1a0453ca13a4159cac04ac2",
|
|
107
|
+
"0x07ea5e8537cf5dd08886020e23a7f387d468d5525be66f853b672cc96a88969a",
|
|
108
|
+
"0x05a8c4f9968b8aa3b7b478a30f9a5b63650f19a75e7ce11ca9fe16c0b76c00bc",
|
|
109
|
+
"0x20f057712cc21654fbfe59bd345e8dac3f7818c701b9c7882d9d57b72a32e83f",
|
|
110
|
+
"0x04a12ededa9dfd689672f8c67fee31636dcd8e88d01d49019bd90b33eb33db69",
|
|
111
|
+
"0x27e88d8c15f37dcee44f1e5425a51decbd136ce5091a6767e49ec9544ccd101a",
|
|
112
|
+
"0x2feed17b84285ed9b8a5c8c5e95a41f66e096619a7703223176c41ee433de4d1",
|
|
113
|
+
"0x1ed7cc76edf45c7c404241420f729cf394e5942911312a0d6972b8bd53aff2b8",
|
|
114
|
+
"0x15742e99b9bfa323157ff8c586f5660eac6783476144cdcadf2874be45466b1a",
|
|
115
|
+
"0x1aac285387f65e82c895fc6887ddf40577107454c6ec0317284f033f27d0c785",
|
|
116
|
+
"0x25851c3c845d4790f9ddadbdb6057357832e2e7a49775f71ec75a96554d67c77",
|
|
117
|
+
"0x15a5821565cc2ec2ce78457db197edf353b7ebba2c5523370ddccc3d9f146a67",
|
|
118
|
+
"0x2411d57a4813b9980efa7e31a1db5966dcf64f36044277502f15485f28c71727",
|
|
119
|
+
"0x002e6f8d6520cd4713e335b8c0b6d2e647e9a98e12f4cd2558828b5ef6cb4c9b",
|
|
120
|
+
"0x2ff7bc8f4380cde997da00b616b0fcd1af8f0e91e2fe1ed7398834609e0315d2",
|
|
121
|
+
"0x00b9831b948525595ee02724471bcd182e9521f6b7bb68f1e93be4febb0d3cbe",
|
|
122
|
+
"0x0a2f53768b8ebf6a86913b0e57c04e011ca408648a4743a87d77adbf0c9c3512",
|
|
123
|
+
"0x00248156142fd0373a479f91ff239e960f599ff7e94be69b7f2a290305e1198d",
|
|
124
|
+
"0x171d5620b87bfb1328cf8c02ab3f0c9a397196aa6a542c2350eb512a2b2bcda9",
|
|
125
|
+
"0x170a4f55536f7dc970087c7c10d6fad760c952172dd54dd99d1045e4ec34a808",
|
|
126
|
+
"0x29aba33f799fe66c2ef3134aea04336ecc37e38c1cd211ba482eca17e2dbfae1",
|
|
127
|
+
"0x1e9bc179a4fdd758fdd1bb1945088d47e70d114a03f6a0e8b5ba650369e64973",
|
|
128
|
+
"0x1dd269799b660fad58f7f4892dfb0b5afeaad869a9c4b44f9c9e1c43bdaf8f09",
|
|
129
|
+
"0x22cdbc8b70117ad1401181d02e15459e7ccd426fe869c7c95d1dd2cb0f24af38",
|
|
130
|
+
"0x0ef042e454771c533a9f57a55c503fcefd3150f52ed94a7cd5ba93b9c7dacefd",
|
|
131
|
+
"0x11609e06ad6c8fe2f287f3036037e8851318e8b08a0359a03b304ffca62e8284",
|
|
132
|
+
"0x1166d9e554616dba9e753eea427c17b7fecd58c076dfe42708b08f5b783aa9af",
|
|
133
|
+
"0x2de52989431a859593413026354413db177fbf4cd2ac0b56f855a888357ee466",
|
|
134
|
+
"0x3006eb4ffc7a85819a6da492f3a8ac1df51aee5b17b8e89d74bf01cf5f71e9ad",
|
|
135
|
+
"0x2af41fbb61ba8a80fdcf6fff9e3f6f422993fe8f0a4639f962344c8225145086",
|
|
136
|
+
"0x119e684de476155fe5a6b41a8ebc85db8718ab27889e85e781b214bace4827c3",
|
|
137
|
+
"0x1835b786e2e8925e188bea59ae363537b51248c23828f047cff784b97b3fd800",
|
|
138
|
+
"0x28201a34c594dfa34d794996c6433a20d152bac2a7905c926c40e285ab32eeb6",
|
|
139
|
+
"0x083efd7a27d1751094e80fefaf78b000864c82eb571187724a761f88c22cc4e7",
|
|
140
|
+
"0x0b6f88a3577199526158e61ceea27be811c16df7774dd8519e079564f61fd13b",
|
|
141
|
+
"0x0ec868e6d15e51d9644f66e1d6471a94589511ca00d29e1014390e6ee4254f5b",
|
|
142
|
+
"0x2af33e3f866771271ac0c9b3ed2e1142ecd3e74b939cd40d00d937ab84c98591",
|
|
143
|
+
"0x0b520211f904b5e7d09b5d961c6ace7734568c547dd6858b364ce5e47951f178",
|
|
144
|
+
"0x0b2d722d0919a1aad8db58f10062a92ea0c56ac4270e822cca228620188a1d40",
|
|
145
|
+
"0x1f790d4d7f8cf094d980ceb37c2453e957b54a9991ca38bbe0061d1ed6e562d4",
|
|
146
|
+
"0x0171eb95dfbf7d1eaea97cd385f780150885c16235a2a6a8da92ceb01e504233",
|
|
147
|
+
"0x0c2d0e3b5fd57549329bf6885da66b9b790b40defd2c8650762305381b168873",
|
|
148
|
+
"0x1162fb28689c27154e5a8228b4e72b377cbcafa589e283c35d3803054407a18d",
|
|
149
|
+
"0x2f1459b65dee441b64ad386a91e8310f282c5a92a89e19921623ef8249711bc0",
|
|
150
|
+
"0x1e6ff3216b688c3d996d74367d5cd4c1bc489d46754eb712c243f70d1b53cfbb",
|
|
151
|
+
"0x01ca8be73832b8d0681487d27d157802d741a6f36cdc2a0576881f9326478875",
|
|
152
|
+
"0x1f7735706ffe9fc586f976d5bdf223dc680286080b10cea00b9b5de315f9650e",
|
|
153
|
+
"0x2522b60f4ea3307640a0c2dce041fba921ac10a3d5f096ef4745ca838285f019",
|
|
154
|
+
"0x23f0bee001b1029d5255075ddc957f833418cad4f52b6c3f8ce16c235572575b",
|
|
155
|
+
"0x2bc1ae8b8ddbb81fcaac2d44555ed5685d142633e9df905f66d9401093082d59",
|
|
156
|
+
"0x0f9406b8296564a37304507b8dba3ed162371273a07b1fc98011fcd6ad72205f",
|
|
157
|
+
"0x2360a8eb0cc7defa67b72998de90714e17e75b174a52ee4acb126c8cd995f0a8",
|
|
158
|
+
"0x15871a5cddead976804c803cbaef255eb4815a5e96df8b006dcbbc2767f88948",
|
|
159
|
+
"0x193a56766998ee9e0a8652dd2f3b1da0362f4f54f72379544f957ccdeefb420f",
|
|
160
|
+
"0x2a394a43934f86982f9be56ff4fab1703b2e63c8ad334834e4309805e777ae0f",
|
|
161
|
+
"0x1859954cfeb8695f3e8b635dcb345192892cd11223443ba7b4166e8876c0d142",
|
|
162
|
+
"0x04e1181763050e58013444dbcb99f1902b11bc25d90bbdca408d3819f4fed32b",
|
|
163
|
+
"0x0fdb253dee83869d40c335ea64de8c5bb10eb82db08b5e8b1f5e5552bfd05f23",
|
|
164
|
+
"0x058cbe8a9a5027bdaa4efb623adead6275f08686f1c08984a9d7c5bae9b4f1c0",
|
|
165
|
+
"0x1382edce9971e186497eadb1aeb1f52b23b4b83bef023ab0d15228b4cceca59a",
|
|
166
|
+
"0x03464990f045c6ee0819ca51fd11b0be7f61b8eb99f14b77e1e6634601d9e8b5",
|
|
167
|
+
"0x23f7bfc8720dc296fff33b41f98ff83c6fcab4605db2eb5aaa5bc137aeb70a58",
|
|
168
|
+
"0x0a59a158e3eec2117e6e94e7f0e9decf18c3ffd5e1531a9219636158bbaf62f2",
|
|
169
|
+
"0x06ec54c80381c052b58bf23b312ffd3ce2c4eba065420af8f4c23ed0075fd07b",
|
|
170
|
+
"0x118872dc832e0eb5476b56648e867ec8b09340f7a7bcb1b4962f0ff9ed1f9d01",
|
|
171
|
+
"0x13d69fa127d834165ad5c7cba7ad59ed52e0b0f0e42d7fea95e1906b520921b1",
|
|
172
|
+
"0x169a177f63ea681270b1c6877a73d21bde143942fb71dc55fd8a49f19f10c77b",
|
|
173
|
+
"0x04ef51591c6ead97ef42f287adce40d93abeb032b922f66ffb7e9a5a7450544d",
|
|
174
|
+
"0x256e175a1dc079390ecd7ca703fb2e3b19ec61805d4f03ced5f45ee6dd0f69ec",
|
|
175
|
+
"0x30102d28636abd5fe5f2af412ff6004f75cc360d3205dd2da002813d3e2ceeb2",
|
|
176
|
+
"0x10998e42dfcd3bbf1c0714bc73eb1bf40443a3fa99bef4a31fd31be182fcc792",
|
|
177
|
+
"0x193edd8e9fcf3d7625fa7d24b598a1d89f3362eaf4d582efecad76f879e36860",
|
|
178
|
+
"0x18168afd34f2d915d0368ce80b7b3347d1c7a561ce611425f2664d7aa51f0b5d",
|
|
179
|
+
"0x29383c01ebd3b6ab0c017656ebe658b6a328ec77bc33626e29e2e95b33ea6111",
|
|
180
|
+
"0x10646d2f2603de39a1f4ae5e7771a64a702db6e86fb76ab600bf573f9010c711",
|
|
181
|
+
"0x0beb5e07d1b27145f575f1395a55bf132f90c25b40da7b3864d0242dcb1117fb",
|
|
182
|
+
"0x16d685252078c133dc0d3ecad62b5c8830f95bb2e54b59abdffbf018d96fa336",
|
|
183
|
+
"0x0a6abd1d833938f33c74154e0404b4b40a555bbbec21ddfafd672dd62047f01a",
|
|
184
|
+
"0x1a679f5d36eb7b5c8ea12a4c2dedc8feb12dffeec450317270a6f19b34cf1860",
|
|
185
|
+
"0x0980fb233bd456c23974d50e0ebfde4726a423eada4e8f6ffbc7592e3f1b93d6",
|
|
186
|
+
"0x161b42232e61b84cbf1810af93a38fc0cece3d5628c9282003ebacb5c312c72b",
|
|
187
|
+
"0x0ada10a90c7f0520950f7d47a60d5e6a493f09787f1564e5d09203db47de1a0b",
|
|
188
|
+
"0x1a730d372310ba82320345a29ac4238ed3f07a8a2b4e121bb50ddb9af407f451",
|
|
189
|
+
"0x2c8120f268ef054f817064c369dda7ea908377feaba5c4dffbda10ef58e8c556",
|
|
190
|
+
"0x1c7c8824f758753fa57c00789c684217b930e95313bcb73e6e7b8649a4968f70",
|
|
191
|
+
"0x2cd9ed31f5f8691c8e39e4077a74faa0f400ad8b491eb3f7b47b27fa3fd1cf77",
|
|
192
|
+
"0x23ff4f9d46813457cf60d92f57618399a5e022ac321ca550854ae23918a22eea",
|
|
193
|
+
"0x09945a5d147a4f66ceece6405dddd9d0af5a2c5103529407dff1ea58f180426d",
|
|
194
|
+
"0x188d9c528025d4c2b67660c6b771b90f7c7da6eaa29d3f268a6dd223ec6fc630",
|
|
195
|
+
"0x3050e37996596b7f81f68311431d8734dba7d926d3633595e0c0d8ddf4f0f47f",
|
|
196
|
+
"0x15af1169396830a91600ca8102c35c426ceae5461e3f95d89d829518d30afd78",
|
|
197
|
+
"0x1da6d09885432ea9a06d9f37f873d985dae933e351466b2904284da3320d8acc",
|
|
198
|
+
"0x2796ea90d269af29f5f8acf33921124e4e4fad3dbe658945e546ee411ddaa9cb",
|
|
199
|
+
"0x202d7dd1da0f6b4b0325c8b3307742f01e15612ec8e9304a7cb0319e01d32d60",
|
|
200
|
+
"0x096d6790d05bb759156a952ba263d672a2d7f9c788f4c831a29dace4c0f8be5f",
|
|
201
|
+
"0x054efa1f65b0fce283808965275d877b438da23ce5b13e1963798cb1447d25a4",
|
|
202
|
+
"0x1b162f83d917e93edb3308c29802deb9d8aa690113b2e14864ccf6e18e4165f1",
|
|
203
|
+
"0x21e5241e12564dd6fd9f1cdd2a0de39eedfefc1466cc568ec5ceb745a0506edc",
|
|
204
|
+
"0x1cfb5662e8cf5ac9226a80ee17b36abecb73ab5f87e161927b4349e10e4bdf08",
|
|
205
|
+
"0x0f21177e302a771bbae6d8d1ecb373b62c99af346220ac0129c53f666eb24100",
|
|
206
|
+
"0x1671522374606992affb0dd7f71b12bec4236aede6290546bcef7e1f515c2320",
|
|
207
|
+
"0x0fa3ec5b9488259c2eb4cf24501bfad9be2ec9e42c5cc8ccd419d2a692cad870",
|
|
208
|
+
"0x193c0e04e0bd298357cb266c1506080ed36edce85c648cc085e8c57b1ab54bba",
|
|
209
|
+
"0x102adf8ef74735a27e9128306dcbc3c99f6f7291cd406578ce14ea2adaba68f8",
|
|
210
|
+
"0x0fe0af7858e49859e2a54d6f1ad945b1316aa24bfbdd23ae40a6d0cb70c3eab1",
|
|
211
|
+
"0x216f6717bbc7dedb08536a2220843f4e2da5f1daa9ebdefde8a5ea7344798d22",
|
|
212
|
+
"0x1da55cc900f0d21f4a3e694391918a1b3c23b2ac773c6b3ef88e2e4228325161"
|
|
213
|
+
];
|
|
214
|
+
|
|
215
|
+
const POSEIDON_M_T3_HEX = [
|
|
216
|
+
[
|
|
217
|
+
"0x109b7f411ba0e4c9b2b70caf5c36a7b194be7c11ad24378bfedb68592ba8118b",
|
|
218
|
+
"0x16ed41e13bb9c0c66ae119424fddbcbc9314dc9fdbdeea55d6c64543dc4903e0",
|
|
219
|
+
"0x2b90bba00fca0589f617e7dcbfe82e0df706ab640ceb247b791a93b74e36736d"
|
|
220
|
+
],
|
|
221
|
+
[
|
|
222
|
+
"0x2969f27eed31a480b9c36c764379dbca2cc8fdd1415c3dded62940bcde0bd771",
|
|
223
|
+
"0x2e2419f9ec02ec394c9871c832963dc1b89d743c8c7b964029b2311687b1fe23",
|
|
224
|
+
"0x101071f0032379b697315876690f053d148d4e109f5fb065c8aacc55a0f89bfa"
|
|
225
|
+
],
|
|
226
|
+
[
|
|
227
|
+
"0x143021ec686a3f330d5f9e654638065ce6cd79e28c5b3753326244ee65a1b1a7",
|
|
228
|
+
"0x176cc029695ad02582a70eff08a6fd99d057e12e58e7d7b6b16cdfabc8ee2911",
|
|
229
|
+
"0x19a3fc0a56702bf417ba7fee3802593fa644470307043f7773279cd71d25d5e0"
|
|
230
|
+
]
|
|
231
|
+
];
|
|
232
|
+
const C = POSEIDON_C_T3_HEX.map((hex) => BigInt(hex));
|
|
233
|
+
const M = POSEIDON_M_T3_HEX.map((row) => row.map((hex) => BigInt(hex)));
|
|
234
|
+
const N_ROUNDS_F = 8;
|
|
235
|
+
const N_ROUNDS_P = 57;
|
|
236
|
+
|
|
237
|
+
function sbox(x) {
|
|
238
|
+
const x2 = (x * x) % P;
|
|
239
|
+
const x4 = (x2 * x2) % P;
|
|
240
|
+
return (x4 * x) % P;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
function mix(state, mds) {
|
|
244
|
+
const out = [0n, 0n, 0n];
|
|
245
|
+
for (let i = 0; i < 3; i++) {
|
|
246
|
+
let sum = 0n;
|
|
247
|
+
for (let j = 0; j < 3; j++) {
|
|
248
|
+
sum = (sum + mds[i][j] * state[j]) % P;
|
|
249
|
+
}
|
|
250
|
+
out[i] = sum;
|
|
251
|
+
}
|
|
252
|
+
return out;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Standard Circomlib / Noir compatible Poseidon Hash for 2 inputs (t=3)
|
|
257
|
+
* @param {Array<bigint|string|Buffer|number>} inputs
|
|
258
|
+
* @returns {bigint} Output field element in Fr
|
|
259
|
+
*/
|
|
260
|
+
export function poseidon(inputs) {
|
|
261
|
+
if (!Array.isArray(inputs) || inputs.length !== 2) {
|
|
262
|
+
throw new Error('Poseidon t=3 requires exactly 2 inputs');
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
const toFr = (val) => {
|
|
266
|
+
if (typeof val === 'bigint') return ((val % P) + P) % P;
|
|
267
|
+
if (typeof val === 'number') return BigInt(val) % P;
|
|
268
|
+
if (Buffer.isBuffer(val)) return BigInt(`0x${val.toString('hex')}`) % P;
|
|
269
|
+
if (typeof val === 'string') {
|
|
270
|
+
const clean = val.startsWith('0x') ? val.slice(2) : val;
|
|
271
|
+
if (/^[0-9a-fA-F]+$/.test(clean)) {
|
|
272
|
+
return BigInt(`0x${clean}`) % P;
|
|
273
|
+
}
|
|
274
|
+
return BigInt(`0x${createHash('sha256').update(val).digest('hex')}`) % P;
|
|
275
|
+
}
|
|
276
|
+
throw new TypeError(`Invalid field element type: ${typeof val}`);
|
|
277
|
+
};
|
|
278
|
+
|
|
279
|
+
let state = [0n, toFr(inputs[0]), toFr(inputs[1])];
|
|
280
|
+
|
|
281
|
+
for (let r = 0; r < N_ROUNDS_F + N_ROUNDS_P; r++) {
|
|
282
|
+
for (let i = 0; i < 3; i++) {
|
|
283
|
+
state[i] = (state[i] + C[r * 3 + i]) % P;
|
|
284
|
+
}
|
|
285
|
+
if (r < N_ROUNDS_F / 2 || r >= N_ROUNDS_F / 2 + N_ROUNDS_P) {
|
|
286
|
+
state[0] = sbox(state[0]);
|
|
287
|
+
state[1] = sbox(state[1]);
|
|
288
|
+
state[2] = sbox(state[2]);
|
|
289
|
+
} else {
|
|
290
|
+
state[0] = sbox(state[0]);
|
|
291
|
+
}
|
|
292
|
+
state = mix(state, M);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
return state[0];
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Hard Assertions against canonical Circomlib test vectors (including Poseidon([1, 2]))
|
|
300
|
+
*/
|
|
301
|
+
export const CANONICAL_CIRCOMLIB_TEST_VECTORS = Object.freeze({
|
|
302
|
+
VECTOR_1_2: {
|
|
303
|
+
inputs: [1, 2],
|
|
304
|
+
expectedBigInt: 7853200120776062878684798364095072458815029376092732009249414926327459813530n,
|
|
305
|
+
expectedHex: '115cc0f5e7d690413df64c6b9662e9cf2a3617f2743245519e19607a4417189a',
|
|
306
|
+
},
|
|
307
|
+
VECTOR_0_0: {
|
|
308
|
+
inputs: [0, 0],
|
|
309
|
+
expectedHex: '2098f5fb9e239eab3ceac3f27b81e481dc3124d55ffed523a839ee8446b64864',
|
|
310
|
+
},
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
// Self-check canonical vector on module load
|
|
314
|
+
const _testOutput = poseidon(CANONICAL_CIRCOMLIB_TEST_VECTORS.VECTOR_1_2.inputs);
|
|
315
|
+
if (_testOutput !== CANONICAL_CIRCOMLIB_TEST_VECTORS.VECTOR_1_2.expectedBigInt) {
|
|
316
|
+
throw new Error(
|
|
317
|
+
`CRITICAL_CRYPTOGRAPHIC_MISMATCH: Poseidon([1,2]) did not match canonical Circomlib vector. Expected ${CANONICAL_CIRCOMLIB_TEST_VECTORS.VECTOR_1_2.expectedHex}, got ${_testOutput.toString(16)}`
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* Creates an algebraic Poseidon commitment: C = Poseidon([Key, Salt])
|
|
323
|
+
* Uses crypto.randomBytes(32) for secure cryptographic salt generation.
|
|
324
|
+
* @param {Buffer|string|bigint} key
|
|
325
|
+
* @param {Buffer|string|bigint} [salt]
|
|
326
|
+
* @returns {{ commitment: string, commitmentFr: bigint, salt: string }}
|
|
327
|
+
*/
|
|
328
|
+
export function createPoseidonCommitment(key, salt = null) {
|
|
329
|
+
const saltBuf = salt
|
|
330
|
+
? (Buffer.isBuffer(salt) ? salt : (typeof salt === 'string' && salt.startsWith('0x') ? Buffer.from(salt.slice(2), 'hex') : Buffer.from(salt, 'hex')))
|
|
331
|
+
: randomBytes(32); // Cryptographically secure 32-byte salt
|
|
332
|
+
|
|
333
|
+
const keyBuf = Buffer.isBuffer(key)
|
|
334
|
+
? key
|
|
335
|
+
: (typeof key === 'string' && key.startsWith('0x') ? Buffer.from(key.slice(2), 'hex') : Buffer.from(key, 'hex'));
|
|
336
|
+
|
|
337
|
+
const hashBigInt = poseidon([keyBuf, saltBuf]);
|
|
338
|
+
const hex32 = hashBigInt.toString(16).padStart(64, '0');
|
|
339
|
+
|
|
340
|
+
return {
|
|
341
|
+
commitment: `0x${hex32}`,
|
|
342
|
+
commitmentFr: hashBigInt,
|
|
343
|
+
salt: saltBuf.toString('hex'),
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* Verifies a commitment against a key and salt
|
|
349
|
+
*/
|
|
350
|
+
export function verifyPoseidonCommitment(commitment, key, salt) {
|
|
351
|
+
const computed = createPoseidonCommitment(key, salt);
|
|
352
|
+
const normalized = commitment.startsWith('0x') ? commitment.toLowerCase() : `0x${commitment.toLowerCase()}`;
|
|
353
|
+
return computed.commitment.toLowerCase() === normalized;
|
|
354
|
+
}
|