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
|
@@ -1,13 +1,24 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { fork } from 'node:child_process';
|
|
3
|
+
import { createHash } from 'node:crypto';
|
|
4
|
+
import { createRequire } from 'node:module';
|
|
2
5
|
import { realpathSync } from 'node:fs';
|
|
3
6
|
import { readFile } from 'node:fs/promises';
|
|
4
|
-
import { pathToFileURL } from 'node:url';
|
|
7
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
5
8
|
import {
|
|
6
9
|
verifyReceipt,
|
|
7
10
|
verifyReceiptChain,
|
|
8
11
|
verifyCheckpoint,
|
|
9
12
|
} from '../../../packages/core/src/index.js';
|
|
10
|
-
|
|
13
|
+
import { verifyMemoryReceipt } from '../../../packages/vault/src/receipt.js';
|
|
14
|
+
import {
|
|
15
|
+
ZK_SETTLEMENT_EVIDENCE_SCHEMA,
|
|
16
|
+
ZK_VERIFICATION_KEY_PINS,
|
|
17
|
+
proofToSnarkjs,
|
|
18
|
+
validateZkSettlementEvidence,
|
|
19
|
+
validateZkSettlementEvidenceGraph,
|
|
20
|
+
verifyZkSettlementEvidence,
|
|
21
|
+
} from '../../../cortex-v3/zk/settlement-evidence.mjs';
|
|
11
22
|
function json(value) {
|
|
12
23
|
return JSON.stringify(value, null, 2);
|
|
13
24
|
}
|
|
@@ -123,12 +134,184 @@ function compareCommittedSequence(receipts, committed, errors) {
|
|
|
123
134
|
}));
|
|
124
135
|
}
|
|
125
136
|
}
|
|
137
|
+
function zkReceiptsFromBundle(bundle) {
|
|
138
|
+
return asArray(
|
|
139
|
+
bundle?.zk_receipts
|
|
140
|
+
?? bundle?.zkSettlementReceipts
|
|
141
|
+
?? bundle?.settlementReceipts
|
|
142
|
+
?? (bundle?.settlementReceipt ? [bundle.settlementReceipt] : []),
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// A bundle is an offline artifact, not a streaming proof service. Capping it at
|
|
147
|
+
// 64 receipts bounds CPU time, child-process lifetime, replay state, and parsed
|
|
148
|
+
// verification-key retention while remaining well above normal lifecycle size.
|
|
149
|
+
export const MAX_ZK_SETTLEMENT_RECEIPTS = 64;
|
|
150
|
+
|
|
151
|
+
const GROTH16_PROOF_EVENTS = new Set(['action.append', 'action.revoke', 'sale.list']);
|
|
152
|
+
const verificationKeyCache = new Map();
|
|
153
|
+
const MAX_VERIFICATION_KEY_CACHE_ITEMS = 16;
|
|
154
|
+
const GROTH16_WORKER_ARG = '--enigma-groth16-worker';
|
|
155
|
+
const IS_GROTH16_WORKER = process.argv[2] === GROTH16_WORKER_ARG;
|
|
156
|
+
|
|
157
|
+
function emitInstrumentation(options, event, details = {}) {
|
|
158
|
+
const callback = options?.instrumentation?.[event];
|
|
159
|
+
if (typeof callback === 'function') callback(details);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async function loadVerificationKey(circuit, expectedHash, options) {
|
|
163
|
+
const pin = ZK_VERIFICATION_KEY_PINS[circuit];
|
|
164
|
+
if (!pin) throw new Error(`no pinned verification key for circuit ${circuit}`);
|
|
165
|
+
const path = options.verificationKeyPaths?.[circuit] ?? pin.path;
|
|
166
|
+
const cacheKey = `${circuit}\0${String(path)}`;
|
|
167
|
+
let pending = verificationKeyCache.get(cacheKey);
|
|
168
|
+
if (!pending) {
|
|
169
|
+
pending = (async () => {
|
|
170
|
+
emitInstrumentation(options, 'verificationKeyLoad', { circuit, path: String(path) });
|
|
171
|
+
const raw = await readFile(path);
|
|
172
|
+
const actualHash = createHash('sha256').update(raw).digest('hex');
|
|
173
|
+
if (actualHash !== pin.sha256) {
|
|
174
|
+
throw new Error(`verification key hash mismatch for ${circuit}: expected sha256:${pin.sha256}, got sha256:${actualHash}`);
|
|
175
|
+
}
|
|
176
|
+
const key = JSON.parse(raw.toString('utf8'));
|
|
177
|
+
if (key.protocol !== 'groth16' || key.curve !== 'bn128' || key.nPublic !== 6) {
|
|
178
|
+
throw new Error(`pinned verification key for ${circuit} has an invalid Groth16 contract`);
|
|
179
|
+
}
|
|
180
|
+
return key;
|
|
181
|
+
})();
|
|
182
|
+
if (verificationKeyCache.size >= MAX_VERIFICATION_KEY_CACHE_ITEMS) {
|
|
183
|
+
verificationKeyCache.delete(verificationKeyCache.keys().next().value);
|
|
184
|
+
}
|
|
185
|
+
verificationKeyCache.set(cacheKey, pending);
|
|
186
|
+
pending.catch(() => {
|
|
187
|
+
if (verificationKeyCache.get(cacheKey) === pending) verificationKeyCache.delete(cacheKey);
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
const key = await pending;
|
|
191
|
+
if (expectedHash !== `sha256:${pin.sha256}`) {
|
|
192
|
+
throw new Error(`verification key pin mismatch for ${circuit}`);
|
|
193
|
+
}
|
|
194
|
+
return key;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
class Groth16VerifierWorker {
|
|
198
|
+
constructor(options) {
|
|
199
|
+
this.options = options;
|
|
200
|
+
this.child = null;
|
|
201
|
+
this.pending = null;
|
|
202
|
+
this.nextRequestId = 1;
|
|
203
|
+
this.closed = false;
|
|
204
|
+
}
|
|
126
205
|
|
|
206
|
+
ensureChild() {
|
|
207
|
+
if (this.closed) throw new Error('Groth16 verifier worker is closed');
|
|
208
|
+
if (this.child) return;
|
|
209
|
+
const child = fork(fileURLToPath(import.meta.url), [GROTH16_WORKER_ARG], {
|
|
210
|
+
stdio: ['ignore', 'ignore', 'ignore', 'ipc'],
|
|
211
|
+
});
|
|
212
|
+
this.child = child;
|
|
213
|
+
emitInstrumentation(this.options, 'workerSpawn', {});
|
|
214
|
+
child.on('message', (message) => {
|
|
215
|
+
if (!this.pending || message?.id !== this.pending.id) return;
|
|
216
|
+
if (message.error) this.finishPending(new Error(message.error));
|
|
217
|
+
else this.finishPending(null, message.verified === true);
|
|
218
|
+
});
|
|
219
|
+
child.on('error', (error) => this.failChild(error));
|
|
220
|
+
child.on('exit', (code, signal) => {
|
|
221
|
+
if (this.child === child) this.child = null;
|
|
222
|
+
if (this.pending) {
|
|
223
|
+
this.finishPending(new Error(`snarkjs verifier child exited before returning a verdict (code ${code}, signal ${signal ?? 'none'})`));
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
finishPending(error, result) {
|
|
229
|
+
const pending = this.pending;
|
|
230
|
+
if (!pending) return;
|
|
231
|
+
this.pending = null;
|
|
232
|
+
clearTimeout(pending.timer);
|
|
233
|
+
if (error) pending.reject(error);
|
|
234
|
+
else pending.resolve(result);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
failChild(error) {
|
|
238
|
+
const child = this.child;
|
|
239
|
+
this.child = null;
|
|
240
|
+
if (child && !child.killed) child.kill('SIGKILL');
|
|
241
|
+
this.finishPending(error);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async verify(request, timeoutMs) {
|
|
245
|
+
if (this.pending) throw new Error('Groth16 verifier worker received overlapping requests');
|
|
246
|
+
this.ensureChild();
|
|
247
|
+
const id = this.nextRequestId++;
|
|
248
|
+
emitInstrumentation(this.options, 'proofCheck', { circuit: request.circuit, receiptRef: request.receiptRef });
|
|
249
|
+
return await new Promise((resolve, reject) => {
|
|
250
|
+
const timer = setTimeout(() => {
|
|
251
|
+
const error = new Error(`snarkjs verification exceeded ${timeoutMs}ms`);
|
|
252
|
+
this.failChild(error);
|
|
253
|
+
}, timeoutMs);
|
|
254
|
+
this.pending = { id, timer, resolve, reject };
|
|
255
|
+
this.child.send({
|
|
256
|
+
id,
|
|
257
|
+
verificationKey: request.verificationKey,
|
|
258
|
+
publicSignals: request.publicSignals,
|
|
259
|
+
proof: request.proof,
|
|
260
|
+
}, (error) => {
|
|
261
|
+
if (error) this.failChild(error);
|
|
262
|
+
});
|
|
263
|
+
});
|
|
264
|
+
}
|
|
127
265
|
|
|
266
|
+
async close() {
|
|
267
|
+
this.closed = true;
|
|
268
|
+
const child = this.child;
|
|
269
|
+
this.child = null;
|
|
270
|
+
if (!child) return;
|
|
271
|
+
if (this.pending) this.finishPending(new Error('Groth16 verifier worker closed with a pending request'));
|
|
272
|
+
await new Promise((resolve) => {
|
|
273
|
+
let settled = false;
|
|
274
|
+
let forceTimer;
|
|
275
|
+
const finish = () => {
|
|
276
|
+
if (settled) return;
|
|
277
|
+
settled = true;
|
|
278
|
+
clearTimeout(forceTimer);
|
|
279
|
+
resolve();
|
|
280
|
+
};
|
|
281
|
+
forceTimer = setTimeout(() => {
|
|
282
|
+
try { child.kill('SIGKILL'); } catch {}
|
|
283
|
+
finish();
|
|
284
|
+
}, 1_000);
|
|
285
|
+
child.once('exit', finish);
|
|
286
|
+
child.kill();
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
}
|
|
128
290
|
|
|
291
|
+
function startGroth16Worker() {
|
|
292
|
+
const require = createRequire(import.meta.url);
|
|
293
|
+
const snarkjs = require('snarkjs');
|
|
294
|
+
let queue = Promise.resolve();
|
|
295
|
+
process.on('message', (request) => {
|
|
296
|
+
queue = queue.then(async () => {
|
|
297
|
+
try {
|
|
298
|
+
const verified = await snarkjs.groth16.verify(
|
|
299
|
+
request.verificationKey,
|
|
300
|
+
request.publicSignals,
|
|
301
|
+
request.proof,
|
|
302
|
+
);
|
|
303
|
+
process.send?.({ id: request.id, verified });
|
|
304
|
+
} catch (error) {
|
|
305
|
+
process.send?.({ id: request.id, error: error.message });
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
process.once('disconnect', () => process.exit(0));
|
|
310
|
+
}
|
|
129
311
|
|
|
130
|
-
export function verifyBundle(bundle) {
|
|
312
|
+
export function verifyBundle(bundle, options = {}) {
|
|
131
313
|
const receipts = asArray(bundle?.receipts);
|
|
314
|
+
const zkReceipts = zkReceiptsFromBundle(bundle);
|
|
132
315
|
const checkpoints = asArray(bundle?.checkpoints ?? bundle?.passport?.checkpoints);
|
|
133
316
|
const publicKey = publicKeyFromBundle(bundle);
|
|
134
317
|
const errors = [];
|
|
@@ -138,10 +321,10 @@ export function verifyBundle(bundle) {
|
|
|
138
321
|
if (!bundle || typeof bundle !== 'object') {
|
|
139
322
|
return { ok: false, errors: [makeError('BUNDLE_INVALID', 'Bundle must be a JSON object.')] };
|
|
140
323
|
}
|
|
141
|
-
if (receipts.length === 0) {
|
|
142
|
-
errors.push(makeError('RECEIPTS_MISSING', 'Bundle does not contain receipts.'));
|
|
324
|
+
if (receipts.length === 0 && zkReceipts.length === 0) {
|
|
325
|
+
errors.push(makeError('RECEIPTS_MISSING', 'Bundle does not contain memory or ZK settlement receipts.'));
|
|
143
326
|
}
|
|
144
|
-
if (!publicKey) {
|
|
327
|
+
if (receipts.length > 0 && !publicKey) {
|
|
145
328
|
errors.push(makeError('PUBLIC_KEY_MISSING', 'Bundle does not contain an offline verifier public key.'));
|
|
146
329
|
}
|
|
147
330
|
|
|
@@ -172,8 +355,14 @@ export function verifyBundle(bundle) {
|
|
|
172
355
|
}
|
|
173
356
|
}
|
|
174
357
|
|
|
175
|
-
|
|
358
|
+
if (zkReceipts.length > 0 && options.skipZk !== true) {
|
|
359
|
+
errors.push(makeError(
|
|
360
|
+
'ZK_ASYNC_VERIFICATION_REQUIRED',
|
|
361
|
+
'ZK settlement receipts require verifyBundleWithZk() or the enigma-verify CLI so snarkjs can verify Groth16 proofs.',
|
|
362
|
+
));
|
|
363
|
+
}
|
|
176
364
|
|
|
365
|
+
compareCommittedSequence(receipts, committed, errors);
|
|
177
366
|
if (receipts.length > 0 && checkpoints.length > 0 && publicKey) {
|
|
178
367
|
const lastReceipt = receipts.at(-1);
|
|
179
368
|
const lastCheckpoint = checkpoints.at(-1);
|
|
@@ -202,6 +391,84 @@ export function verifyBundle(bundle) {
|
|
|
202
391
|
checked_at: new Date().toISOString(),
|
|
203
392
|
receipt_count: receipts.length,
|
|
204
393
|
checkpoint_count: checkpoints.length,
|
|
394
|
+
zk_receipt_count: zkReceipts.length,
|
|
395
|
+
errors,
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
export async function verifyBundleWithZk(bundle, options = {}) {
|
|
400
|
+
const report = verifyBundle(bundle, { skipZk: true });
|
|
401
|
+
const receipts = zkReceiptsFromBundle(bundle);
|
|
402
|
+
const errors = [...report.errors];
|
|
403
|
+
const hasProofBearingReceipts = receipts.some((receipt) => GROTH16_PROOF_EVENTS.has(receipt?.event));
|
|
404
|
+
if (receipts.length > MAX_ZK_SETTLEMENT_RECEIPTS) {
|
|
405
|
+
errors.push(makeError(
|
|
406
|
+
'ZK_SETTLEMENT_RECEIPT_LIMIT',
|
|
407
|
+
`Bundle contains ${receipts.length} ZK settlement receipts; the safe maximum is ${MAX_ZK_SETTLEMENT_RECEIPTS}.`,
|
|
408
|
+
));
|
|
409
|
+
return { ...report, ok: false, proof_valid: null, settlement_verified: false, errors };
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const graphVerdict = validateZkSettlementEvidenceGraph(receipts);
|
|
413
|
+
if (!graphVerdict.ok) errors.push(...graphVerdict.errors.map((error) => verifierError(
|
|
414
|
+
error,
|
|
415
|
+
'ZK_SETTLEMENT_GRAPH_INVALID',
|
|
416
|
+
'ZK settlement receipt graph did not verify.',
|
|
417
|
+
)));
|
|
418
|
+
|
|
419
|
+
for (const receipt of receipts) {
|
|
420
|
+
const verdict = validateZkSettlementEvidence(receipt, options);
|
|
421
|
+
if (!verdict.ok) {
|
|
422
|
+
errors.push(...verdict.errors.map((error) => verifierError(
|
|
423
|
+
error,
|
|
424
|
+
'ZK_SETTLEMENT_EVIDENCE_INVALID',
|
|
425
|
+
`ZK settlement receipt ${receipt?.receipt_ref ?? '<unknown>'} did not verify.`,
|
|
426
|
+
)));
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
// No Groth16 work is launched unless every cheap bundle, trust, signature,
|
|
431
|
+
// state-transition, lineage, transaction, and replay check has succeeded.
|
|
432
|
+
if (errors.length > 0) {
|
|
433
|
+
return { ...report, ok: false, proof_valid: null, settlement_verified: false, errors };
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
const worker = new Groth16VerifierWorker(options);
|
|
437
|
+
const timeoutMs = Number.isSafeInteger(options.groth16TimeoutMs) && options.groth16TimeoutMs > 0
|
|
438
|
+
? options.groth16TimeoutMs
|
|
439
|
+
: 30_000;
|
|
440
|
+
try {
|
|
441
|
+
for (const receipt of receipts) {
|
|
442
|
+
if (!GROTH16_PROOF_EVENTS.has(receipt.event)) continue;
|
|
443
|
+
try {
|
|
444
|
+
const verificationKey = await loadVerificationKey(
|
|
445
|
+
receipt.circuit,
|
|
446
|
+
receipt.proof.verification_key?.sha256,
|
|
447
|
+
options,
|
|
448
|
+
);
|
|
449
|
+
const verified = await worker.verify({
|
|
450
|
+
circuit: receipt.circuit,
|
|
451
|
+
receiptRef: receipt.receipt_ref,
|
|
452
|
+
verificationKey,
|
|
453
|
+
publicSignals: receipt.proof.public_inputs.map((value) => BigInt(`0x${value}`).toString(10)),
|
|
454
|
+
proof: proofToSnarkjs(receipt.proof),
|
|
455
|
+
}, timeoutMs);
|
|
456
|
+
if (!verified) {
|
|
457
|
+
errors.push(makeError('ZK_EVIDENCE_GROTH16_INVALID', 'snarkjs rejected the Groth16 proof against the pinned verification key.'));
|
|
458
|
+
}
|
|
459
|
+
} catch (error) {
|
|
460
|
+
errors.push(makeError('ZK_EVIDENCE_GROTH16_INVALID', `Offline Groth16 verification failed closed: ${error.message}`));
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
} finally {
|
|
464
|
+
await worker.close();
|
|
465
|
+
}
|
|
466
|
+
const ok = errors.length === 0;
|
|
467
|
+
return {
|
|
468
|
+
...report,
|
|
469
|
+
ok,
|
|
470
|
+
proof_valid: hasProofBearingReceipts ? ok : null,
|
|
471
|
+
settlement_verified: ok,
|
|
205
472
|
errors,
|
|
206
473
|
};
|
|
207
474
|
}
|
|
@@ -210,14 +477,61 @@ export async function readBundle(path) {
|
|
|
210
477
|
return JSON.parse(await readFile(path, 'utf8'));
|
|
211
478
|
}
|
|
212
479
|
|
|
480
|
+
function optionValue(argv, name) {
|
|
481
|
+
const index = argv.indexOf(name);
|
|
482
|
+
return index >= 0 ? argv[index + 1] : null;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
async function loadZkTrustOptions(argv) {
|
|
486
|
+
const trustPath = optionValue(argv, '--trust');
|
|
487
|
+
if (!trustPath) {
|
|
488
|
+
throw new Error('ZK settlement verification requires --trust <trust-registry.json>.');
|
|
489
|
+
}
|
|
490
|
+
const trust = await readBundle(trustPath);
|
|
491
|
+
if (
|
|
492
|
+
!trust
|
|
493
|
+
|| !Array.isArray(trust.trusted_signers)
|
|
494
|
+
|| trust.trusted_signers.length === 0
|
|
495
|
+
|| typeof trust.program_id !== 'string'
|
|
496
|
+
|| !trust.program_id
|
|
497
|
+
|| typeof trust.cluster !== 'string'
|
|
498
|
+
|| !trust.cluster
|
|
499
|
+
|| !Array.isArray(trust.finalized_checkpoints)
|
|
500
|
+
|| trust.finalized_checkpoints.length === 0
|
|
501
|
+
) {
|
|
502
|
+
throw new Error('trust registry must contain non-empty trusted_signers, program_id, cluster, and finalized_checkpoints');
|
|
503
|
+
}
|
|
504
|
+
return {
|
|
505
|
+
trustedSigners: trust.trusted_signers,
|
|
506
|
+
expectedProgramId: trust.program_id,
|
|
507
|
+
expectedCluster: trust.cluster,
|
|
508
|
+
finalizedCheckpoints: trust.finalized_checkpoints,
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
|
|
213
512
|
export async function main(argv = process.argv.slice(2), io = { stdout: process.stdout, stderr: process.stderr }) {
|
|
214
|
-
const file = argv.find((arg) => !arg.startsWith('-'));
|
|
513
|
+
const file = argv.find((arg, index) => !arg.startsWith('-') && argv[index - 1] !== '--trust');
|
|
215
514
|
if (!file || argv.includes('--help') || argv.includes('-h')) {
|
|
216
|
-
io.stdout.write(`${json({ usage: 'enigma-verify <
|
|
515
|
+
io.stdout.write(`${json({ usage: 'enigma-verify <bundle-or-receipt.json> [--trust zk-trust-registry.json]', zk_trust_registry: { trusted_signers: ['base64-public-key or key-id'], program_id: 'expected program', cluster: 'expected cluster', finalized_checkpoints: ['receipt-bound finalized checkpoint objects'] }, output: 'JSON verification report' })}\n`);
|
|
217
516
|
return 0;
|
|
218
517
|
}
|
|
219
518
|
try {
|
|
220
|
-
const
|
|
519
|
+
const data = await readBundle(file);
|
|
520
|
+
if (data?.schema === ZK_SETTLEMENT_EVIDENCE_SCHEMA) {
|
|
521
|
+
const trustOptions = await loadZkTrustOptions(argv);
|
|
522
|
+
const report = await verifyZkSettlementEvidence(data, { ...trustOptions, seenRefs: new Set() });
|
|
523
|
+
io.stdout.write(`${json({ ...report, schema: 'enigma.zk_settlement_verification_report.v1' })}\n`);
|
|
524
|
+
return report.ok ? 0 : 1;
|
|
525
|
+
}
|
|
526
|
+
if (data && (data.schema === 'enigma.memory_receipt.v2' || (data.commitment && data.agent_pubkey && data.signature))) {
|
|
527
|
+
const report = verifyMemoryReceipt(data);
|
|
528
|
+
io.stdout.write(`${json({ ok: report.ok, verified: report.verified, schema: 'enigma.receipt_verification_report.v2', report })}\n`);
|
|
529
|
+
return report.ok ? 0 : 1;
|
|
530
|
+
}
|
|
531
|
+
const hasZkReceipts = zkReceiptsFromBundle(data).length > 0;
|
|
532
|
+
const report = hasZkReceipts
|
|
533
|
+
? await verifyBundleWithZk(data, await loadZkTrustOptions(argv))
|
|
534
|
+
: verifyBundle(data);
|
|
221
535
|
io.stdout.write(`${json(report)}\n`);
|
|
222
536
|
return report.ok ? 0 : 1;
|
|
223
537
|
} catch (error) {
|
|
@@ -235,6 +549,8 @@ function isMainModule(metaUrl) {
|
|
|
235
549
|
}
|
|
236
550
|
|
|
237
551
|
|
|
238
|
-
if (
|
|
552
|
+
if (IS_GROTH16_WORKER) {
|
|
553
|
+
startGroth16Worker();
|
|
554
|
+
} else if (isMainModule(import.meta.url)) {
|
|
239
555
|
process.exitCode = await main();
|
|
240
556
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "raw-be-hex-v1",
|
|
3
|
+
"curve": "bn128",
|
|
4
|
+
"g2LimbOrder": "c1c0",
|
|
5
|
+
"proofNote": "pi_a is raw — the on-chain program negates A",
|
|
6
|
+
"circuit": "intent_attestation",
|
|
7
|
+
"circuitVersion": 2,
|
|
8
|
+
"numPublicInputs": 4,
|
|
9
|
+
"icCount": 5,
|
|
10
|
+
"icPaddedTo": 7,
|
|
11
|
+
"alphaG1": "2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e214bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d1926",
|
|
12
|
+
"betaG2": "0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a71739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec8",
|
|
13
|
+
"gammaG2": "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa",
|
|
14
|
+
"deltaG2": "2c80382a4d2011a8047aa6712fb7998f63aaac9d904fe46fda37c705453f5d55011153e8b44da8dea7ff23cfc54402bd8dda85b6fd5b6e8c311ac04a24be81961ec087bc02f5a629cdad62683f7fd085693d8d9efd4331f680454072b55e3c120ed38191e3494aff5760cbb6f6a69296dcdbfca684dabc15f877e3dba3d92e46",
|
|
15
|
+
"ic": [
|
|
16
|
+
"24f95d74e34ded414c3e53f386722cf7635e3cb9dc3120b3bbc8110608b11d35283eed3710f3680588265308925d58ac23935f90f1448de5d2c76d8b7812778f",
|
|
17
|
+
"0daa93c2b8773b1b45a73d1032cecbc39dd38b4b726f0e6816f0cdc9eb64b59a277174ab8f322ece1e035389d0f486880ca9d656e087eb1b946582691e42b138",
|
|
18
|
+
"0d6d39d085f4470bdb472f8c2abcdfc8de0520b1f9a5632f3dd504e93f6fe9ee1a19eb6ed785a5fb2236d89c260be061a84645fe1eab6cc958d78d1ba63706e4",
|
|
19
|
+
"1f91d72d148fcd918eb093681b0b62ddb8afa8763fd99e97c208c22650c703c7202a4f5cee6f9a2e0103c08eb21cf7f49568de0f4b4c004efe763dfa8de2130f",
|
|
20
|
+
"2a37257d7820013d370539ad680c98346801a569015c545c61a818e8cd77326620723e84dc1c6a34d830001605339f25993e7990e41ad2b0219cc67dc70f4509",
|
|
21
|
+
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
|
22
|
+
"00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"
|
|
23
|
+
],
|
|
24
|
+
"ceremony": "development single-party",
|
|
25
|
+
"ceremonyDetail": {
|
|
26
|
+
"ptau": "reused repo-local file (no download)",
|
|
27
|
+
"ptauBytes": 302072984,
|
|
28
|
+
"ptauPower": 18,
|
|
29
|
+
"r1csSha256": "c485c9bb702d9db158ffeffa023ca24dd425764cdc876fadfbc63da5d8efef5d",
|
|
30
|
+
"constraintCount": 22702,
|
|
31
|
+
"contribution": "enigma-intent-dev-1 (random entropy) + random beacon (10 iterations)"
|
|
32
|
+
},
|
|
33
|
+
"source": "intent_verification_key.json",
|
|
34
|
+
"createdAt": "2026-08-23T07:05:55.037Z"
|
|
35
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "raw-be-hex-v1",
|
|
3
|
+
"curve": "bn128",
|
|
4
|
+
"g2LimbOrder": "c1c0",
|
|
5
|
+
"proofNote": "pi_a is raw — the on-chain program negates A",
|
|
6
|
+
"circuit": "sealed_sale_release",
|
|
7
|
+
"circuitVersion": 3,
|
|
8
|
+
"numPublicInputs": 6,
|
|
9
|
+
"icCount": 7,
|
|
10
|
+
"icPaddedTo": 7,
|
|
11
|
+
"alphaG1": "2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e214bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d1926",
|
|
12
|
+
"betaG2": "0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a71739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec8",
|
|
13
|
+
"gammaG2": "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa",
|
|
14
|
+
"deltaG2": "01cfc0c27e91936f3bbb83ecd7fda692ef101106289c5c2910e586a061ccdb8315d7e50fb73168a797d4e963a5058f077dc4fef911e3523d29b55ca9b1ee164d2d629f03e5937dd21c883966c212cf1de3cdc79da0d2a5e0bf8fe5041942536a17e1d560c080c3346087cb5d9aafdd7703c875a11bf7f2cdd44b64f83be65fe4",
|
|
15
|
+
"ic": [
|
|
16
|
+
"01ad96b8d94557fb0e599d74d6efacf2aa4b79eb95154bee16ecc2bb341300df0f2883242d52531e840e8b036d967118e46c7ae3b404771bc1f69a6744615f64",
|
|
17
|
+
"1eb5ce743d6e739b818dd89359c5f17de32a271a09a1f3ba83597e00621ed59f12f55c4b6d18bd4b42f1cd723045f238df1bca7852dba436b71cf0f21b1e2b6e",
|
|
18
|
+
"0440cfcbe09c27825d061222b7638c00d5696cd668ea597ab4a15674206b9b9e22f77b706aa53bf12a78e862e98ed83083787797acb28c52322b066964bf5ab4",
|
|
19
|
+
"22fdb5a3d9234f4440b8d8cbb8a9117348d0618139e2f1d5df3d9c6238d4eab62dff5fa539ee290fb5bdf76dd82817cdd034693023e775dad4688ab035088120",
|
|
20
|
+
"2eb22cc64a4848f0107b9bfc4b108d2a04fdf220fd4a42c0ea5d6f2cc9c9e24e1785dee6079cf7ec0b7f1963c98d3608b8f81900b96b061c036e23660adb1f85",
|
|
21
|
+
"0a4be75124046bca09901816bbb38a7815816ef4ea531057ebce60ee839cb72e20201653d9ebca2e691206c18611111280a17a0f6fab835d35ffd6b723ff3c37",
|
|
22
|
+
"009c32b9067eb596b86320cdeb35e459313b19b0505ec7aac01c57944dd648df151b97fbacf6a664070a10794502aaac1c5211e07a83d465194b5cbe90b016a9"
|
|
23
|
+
],
|
|
24
|
+
"ceremony": "development single-party",
|
|
25
|
+
"ceremonyDetail": {
|
|
26
|
+
"ptau": "reused repo-local file (no download)",
|
|
27
|
+
"ptauBytes": 302072984,
|
|
28
|
+
"ptauPower": 18,
|
|
29
|
+
"r1csSha256": "46e3d6846000005db1a11559604dcf5efbcefa263eed78b0aef7702de91b6830",
|
|
30
|
+
"constraintCount": 87422,
|
|
31
|
+
"contribution": "enigma-sale-dev-1 (random entropy) + random beacon (10 iterations)"
|
|
32
|
+
},
|
|
33
|
+
"source": "sale_verification_key.json",
|
|
34
|
+
"createdAt": "2026-08-23T07:06:19.059Z"
|
|
35
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"format": "raw-be-hex-v1",
|
|
3
|
+
"curve": "bn128",
|
|
4
|
+
"g2LimbOrder": "c1c0",
|
|
5
|
+
"proofNote": "pi_a is raw — the on-chain program negates A",
|
|
6
|
+
"numPublicInputs": 6,
|
|
7
|
+
"icCount": 7,
|
|
8
|
+
"alphaG1": "2d4d9aa7e302d9df41749d5507949d05dbea33fbb16c643b22f599a2be6df2e214bedd503c37ceb061d8ec60209fe345ce89830a19230301f076caff004d1926",
|
|
9
|
+
"betaG2": "0967032fcbf776d1afc985f88877f182d38480a653f2decaa9794cbc3bf3060c0e187847ad4c798374d0d6732bf501847dd68bc0e071241e0213bc7fc13db7ab304cfbd1e08a704a99f5e847d93f8c3caafddec46b7a0d379da69a4d112346a71739c1b1a457a8c7313123d24d2f9192f896b7c63eea05a9d57f06547ad0cec8",
|
|
10
|
+
"gammaG2": "198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa",
|
|
11
|
+
"deltaG2": "091a85f20ac1f736ee31f97959685e8bd82ce0339ccfe72019b5966a1403f2991e5f3dcb18f308d4d546cfb0dcff42243a1b86329133565ea25c6f40a8adfe0620fbbb95e8fc21ae9c782ddb84189c406ba096b31e148fc8764690bf9288022a1b812a8b2155480b2e69b506eabb0c4f340ada0473ea711a0299abdb47da907e",
|
|
12
|
+
"ic": [
|
|
13
|
+
"2634587402f69103e89eab1748090987058ee27f71a2edfd2d7f5176aa81ac0805e814cb2ceb8751885f2860ca8f011b05a5db7f157b83662020d6d3be103698",
|
|
14
|
+
"06155bbf16ad4f3d5f57dc918444386a096c845bceef38336e7372225bc1b37b245257b11f5a3a7ac5b8400505cf29a0e68c7a2d50a2c9e60c2ba67ecad098f8",
|
|
15
|
+
"22582647eedd69991be9f13e3da959f9c39e209c8f173ea8c9a68b8d585415032ba3bbf4fdf5de4241231954c4632f484cea61b1b0471f078a22145ce8403914",
|
|
16
|
+
"2e3fb4f50e18ffcd44a1f469482338430d966156f08e63f2ead4c882be8f437704f308855af1ae4d41ff894f949c4b622f9ba7ebae461384f1514d9c9afa78df",
|
|
17
|
+
"2ab15cd0f9ff27527b9a5d405cc34ae38dbb3173819a867d5c924fd92d91288c2b283f34ca1cff31b47c684bb2002ca9361fc8d1e69902d9cf8ca4109652c547",
|
|
18
|
+
"06a396bcc77f20e5309a81c49dd3fc1bb458c377500319c80149a7c7e06f0e6d18f0871baaa62a63e2c4628c3e0584ce2d0610dbb77c72a7d3a8068dd6041281",
|
|
19
|
+
"084973788eda5f9a243f990e9429380d7869c680ef49e3986f1132470080388f046a01cf1d208c633c2102df3b5a2da26abb9e82b0b705e5f9150e6749bc7f90"
|
|
20
|
+
],
|
|
21
|
+
"ceremony": {
|
|
22
|
+
"type": "single-party local (DEVELOPMENT ONLY — production needs a multi-party ceremony)",
|
|
23
|
+
"ptau": "reused existing file",
|
|
24
|
+
"ptauBytes": 302072984,
|
|
25
|
+
"r1csSha256": "558b99519e36fe94a0c7ffaed2cd5bb7865fc7387de42895e70dabba434c9656",
|
|
26
|
+
"constraintCount": 90897,
|
|
27
|
+
"powerOfTau": 18,
|
|
28
|
+
"contribution": "enigma-dev-1 (random entropy) + random beacon (10 iterations)"
|
|
29
|
+
},
|
|
30
|
+
"source": "verification_key.json",
|
|
31
|
+
"createdAt": "2026-08-23T07:05:43.317Z"
|
|
32
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 1,
|
|
3
|
+
"ceremony": "single-party development ceremony (2026-08-23) \u2014 production requires MPC",
|
|
4
|
+
"releaseBase": "https://github.com/Enigma-Memory/enigma-cortex-enterprise/releases/download/zk-assets-v1",
|
|
5
|
+
"circuits": {
|
|
6
|
+
"action_transition": {
|
|
7
|
+
"circuitVersion": 1,
|
|
8
|
+
"wasm": {
|
|
9
|
+
"file": "action_transition.wasm",
|
|
10
|
+
"sha256": "0e7abc6e4dcdf5869ccbc60f977e73bb24551a5004283ea6e96b22a43c9b6225",
|
|
11
|
+
"bytes": 2608957
|
|
12
|
+
},
|
|
13
|
+
"zkey": {
|
|
14
|
+
"file": "action_transition.zkey",
|
|
15
|
+
"sha256": "1b54596df69450c3b69128b10103188ccc9061a869fd7018cc939c68d7c1080c",
|
|
16
|
+
"bytes": 41534018
|
|
17
|
+
},
|
|
18
|
+
"r1csSha256": "558b99519e36fe94a0c7ffaed2cd5bb7865fc7387de42895e70dabba434c9656",
|
|
19
|
+
"vkBytes": {
|
|
20
|
+
"file": "vk_bytes.json",
|
|
21
|
+
"sha256": "e84987d4b4a0645214ef8b2cc91a883a922cdda7df9b9d435b745a3e0dce441c",
|
|
22
|
+
"bytes": 2595
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"intent_attestation": {
|
|
26
|
+
"circuitVersion": 2,
|
|
27
|
+
"wasm": {
|
|
28
|
+
"file": "intent_attestation.wasm",
|
|
29
|
+
"sha256": "2c680fdf5c9503825612cb5ef8629e7a9316881cb83705dbf3b37cd05e5ea233",
|
|
30
|
+
"bytes": 4039469
|
|
31
|
+
},
|
|
32
|
+
"zkey": {
|
|
33
|
+
"file": "intent_attestation.zkey",
|
|
34
|
+
"sha256": "53927073b2b41bae6f817929779758cbe5869e6a6a455aab6a5f1e7475e019dd",
|
|
35
|
+
"bytes": 10335105
|
|
36
|
+
},
|
|
37
|
+
"r1csSha256": "c485c9bb702d9db158ffeffa023ca24dd425764cdc876fadfbc63da5d8efef5d",
|
|
38
|
+
"vkBytes": {
|
|
39
|
+
"file": "intent_vk_bytes.json",
|
|
40
|
+
"sha256": "851f6d898e8b1877ff3081dcbfab61ca76ad72d2747e9d7648f6d9e4a06420d4",
|
|
41
|
+
"bytes": 2652
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"sealed_sale_release": {
|
|
45
|
+
"circuitVersion": 3,
|
|
46
|
+
"wasm": {
|
|
47
|
+
"file": "sealed_sale_release.wasm",
|
|
48
|
+
"sha256": "98c204a8fb9ab507d84962331c9c01b37f53d454699dcfd1e063f157962e9d79",
|
|
49
|
+
"bytes": 5568152
|
|
50
|
+
},
|
|
51
|
+
"zkey": {
|
|
52
|
+
"file": "sealed_sale_release.zkey",
|
|
53
|
+
"sha256": "8c577a3dfaa64477440397ace1ed61f817a3d533307d236abbe4251c76666ff2",
|
|
54
|
+
"bytes": 41163791
|
|
55
|
+
},
|
|
56
|
+
"r1csSha256": "46e3d6846000005db1a11559604dcf5efbcefa263eed78b0aef7702de91b6830",
|
|
57
|
+
"vkBytes": {
|
|
58
|
+
"file": "sale_vk_bytes.json",
|
|
59
|
+
"sha256": "a746456055c2f9521bb6cc2b3b569eea5ff2170662b73643bb3954fc774dfbe2",
|
|
60
|
+
"bytes": 2649
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Enigma ZK End-to-End Build Contract v3 (binding; supersedes v2)
|
|
2
|
+
|
|
3
|
+
## Architecture: sovereign per-action ZK proofs (single layer)
|
|
4
|
+
Every shared-state transition is a client-generated Groth16 proof. User secrets
|
|
5
|
+
(ownerKey, rho, payload openings, Merkle paths) NEVER leave the client — no
|
|
6
|
+
sequencer/relayer ever sees a witness. Relayers submit only proof + public inputs.
|
|
7
|
+
On-chain Poseidon does not exist, so BOTH appends and revocations are proven.
|
|
8
|
+
|
|
9
|
+
Design note (recorded decision): a two-layer admission(PendingAction)+epoch-batch
|
|
10
|
+
split was evaluated and rejected — binding admitted nullifiers into an epoch proof
|
|
11
|
+
requires either on-chain Poseidon (unavailable) or in-circuit SHA-256 (~400k extra
|
|
12
|
+
constraints). Client-side proving of the full IMT transition is 5-15s WASM —
|
|
13
|
+
affordable — so the single-layer design preserves sovereignty without the binding
|
|
14
|
+
hole. Batch/recursive aggregation remains a documented future optimization.
|
|
15
|
+
|
|
16
|
+
## On-chain contract (main agent implementing; DO NOT touch program source)
|
|
17
|
+
- SharedState PDA [b"shared_state"]: authority, note_root, null_root,
|
|
18
|
+
note_count u64, null_count u64, created_at.
|
|
19
|
+
- initialize_shared_state(genesis_note_root, genesis_null_root) — governance
|
|
20
|
+
(live upgrade-authority check). Genesis values from the JS zero-chain/IMT genesis.
|
|
21
|
+
- settle_action(proof{a[64],b[128],c[64]} raw BE — program negates A internally,
|
|
22
|
+
public_inputs[[u8;32];6]) — permissionless (relayer-friendly; any payer).
|
|
23
|
+
Program: canonicality (< r) on all 6; continuity old roots == stored roots;
|
|
24
|
+
unpack packed = mode*2^60 + action_index; mode 0 (append): nullifier MUST be 0,
|
|
25
|
+
action_index == note_count → note_count++; mode 1 (revoke): action_index ==
|
|
26
|
+
null_count → null_count++; Groth16 verify vs pinned VK (IC len 7); store new roots;
|
|
27
|
+
emit ActionSettled. Stale roots → tx fails → client regenerates within ~2 slots
|
|
28
|
+
(documented contention model, ~70-85 settles/block/account CU ceiling).
|
|
29
|
+
- KEEP: initialize_registry, register_commitment, record_revocation (non-ZK
|
|
30
|
+
owner-signed path), initialize_circuit_verifying_key (IC len now 7).
|
|
31
|
+
- REMOVE: RootIndex/RootShard/register_zk_root/verify_zk_memory_proof (wave-1 dead).
|
|
32
|
+
|
|
33
|
+
## 6 public inputs, exact order (canonical BE < r = 0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001)
|
|
34
|
+
[0] oldNoteRoot [1] newNoteRoot [2] oldNullRoot [3] newNullRoot
|
|
35
|
+
[4] nullifier (0 for append; nf for revoke)
|
|
36
|
+
[5] packed = mode * 2^60 + actionIndex (mode ∈ {0,1}; actionIndex < 2^60)
|
|
37
|
+
|
|
38
|
+
## Circuit: cortex-v3/circuits/action_transition.circom — ActionTransition(D=20)
|
|
39
|
+
Poseidon (circomlib), BN254. Public signal names/order exactly as above.
|
|
40
|
+
Private: isAppend (boolean-constrained), note, ownerKey, rho, payloadCommit,
|
|
41
|
+
notePathElements[D], notePathIndices[D] (LSB-first bits),
|
|
42
|
+
noteMemPathElements[D], noteMemPathIndices[D],
|
|
43
|
+
predValue, predNextIndex, predNextValue, predPathElements[D], predPathIndices[D],
|
|
44
|
+
appendPathElements[D], appendPathIndices[D].
|
|
45
|
+
|
|
46
|
+
### APPEND mode (isAppend=1; packed mode=0)
|
|
47
|
+
- zeros[0]=0, zeros[i+1]=Poseidon(zeros[i],zeros[i]) in-circuit.
|
|
48
|
+
- Verify zero-leaf (zeros[D]) path at actionIndex against oldNoteRoot.
|
|
49
|
+
- newNoteRoot = root with leaf=note inserted at actionIndex.
|
|
50
|
+
- Constrain newNullRoot == oldNullRoot; nullifier === 0.
|
|
51
|
+
- Note well-formedness in BOTH modes: note === Poseidon([ownerKey, rho, payloadCommit])
|
|
52
|
+
so an appended note is always bound to its owner's key.
|
|
53
|
+
|
|
54
|
+
### REVOKE mode (isAppend=0)
|
|
55
|
+
- Membership: note path vs oldNoteRoot. newNoteRoot == oldNoteRoot.
|
|
56
|
+
- nf = Poseidon([DOMAIN_REVOCATION, ownerKey, rho]); nullifier === nf.
|
|
57
|
+
DOMAIN_REVOCATION = 0x656e69676d615f7265766f6b65 ("enigma_revoke") field constant.
|
|
58
|
+
- IMT (Aztec-style): leaf hash = Poseidon([value, nextIndex, nextValue]); genesis
|
|
59
|
+
index 0 = {0, 0, r-1}; prove predecessor path vs oldNullRoot; strict
|
|
60
|
+
predValue < nf < predNextValue (bit-decomposition comparisons); updated predecessor
|
|
61
|
+
= {predValue, actionIndex, nf} → intermediate root; append new leaf
|
|
62
|
+
{nf, predNextIndex, predNextValue} at actionIndex (zero-leaf path vs intermediate
|
|
63
|
+
root) → newNullRoot.
|
|
64
|
+
|
|
65
|
+
Constraint target 60-120k → ptau 2^18 (powersOfTau28_hez_final_18.ptau).
|
|
66
|
+
|
|
67
|
+
## Toolchain
|
|
68
|
+
- circom: iden3/circom release binary → cargo install --locked fallback → WSL.
|
|
69
|
+
- snarkjs, circomlib, circomlibjs via npm -D in cortex-v3.
|
|
70
|
+
- Setup: single-party DEV ceremony (groth16 setup + contribute + beacon) — docs MUST
|
|
71
|
+
state production needs multi-party ceremony.
|
|
72
|
+
|
|
73
|
+
## File ownership
|
|
74
|
+
- Main agent: programs/enigma_nullifier/**, idl/**, tests/enigma_nullifier.ts,
|
|
75
|
+
scripts/test-governance-localnet.mjs, this contract.
|
|
76
|
+
- CircuitBuild: circuits/** (+ circomlib devDep).
|
|
77
|
+
- CodecSetup: zk/zk-codec.mjs, zk/zk-codec.test.mjs, zk/setup.mjs, ptau/**,
|
|
78
|
+
circuits/build/** outputs (verification_key.json + vk_bytes.json COMMITTABLE;
|
|
79
|
+
gitignore ptau/, *.zkey, *.r1cs, wasm). IC length MUST be 7.
|
|
80
|
+
- TreeWitness: zk/zk-tree.mjs, zk/witness.mjs (buildActionWitness), zk/zk-tree.test.mjs
|
|
81
|
+
(+ circomlibjs devDep).
|
|
82
|
+
|
|
83
|
+
## Claim boundaries (hard)
|
|
84
|
+
- Dev ceremony ≠ production trusted setup. Nullifiers = protocol non-use, never
|
|
85
|
+
deletion. No "first on Solana" until publicly reproducible end-to-end.
|
|
86
|
+
- Sovereignty invariant: no private witness material in ANY network-facing payload;
|
|
87
|
+
test-zk-e2e MUST assert the submitted tx contains only proof + public inputs.
|