@bolyra/sdk 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/NOTICE +63 -0
- package/README.md +2 -2
- package/dist/delegation.d.ts +64 -16
- package/dist/delegation.d.ts.map +1 -1
- package/dist/delegation.js +200 -17
- package/dist/delegation.js.map +1 -1
- package/dist/errors.d.ts +12 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +32 -1
- package/dist/errors.js.map +1 -1
- package/dist/handshake.d.ts +2 -0
- package/dist/handshake.d.ts.map +1 -1
- package/dist/handshake.js +55 -13
- package/dist/handshake.js.map +1 -1
- package/dist/identity.d.ts +24 -0
- package/dist/identity.d.ts.map +1 -1
- package/dist/identity.js +46 -0
- package/dist/identity.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +26 -3
- package/dist/index.js.map +1 -1
- package/dist/model-binding.d.ts +113 -0
- package/dist/model-binding.d.ts.map +1 -0
- package/dist/model-binding.js +195 -0
- package/dist/model-binding.js.map +1 -0
- package/dist/offchain.d.ts +89 -0
- package/dist/offchain.d.ts.map +1 -0
- package/dist/offchain.js +300 -0
- package/dist/offchain.js.map +1 -0
- package/dist/prover.d.ts +21 -0
- package/dist/prover.d.ts.map +1 -0
- package/dist/prover.js +171 -0
- package/dist/prover.js.map +1 -0
- package/dist/types.d.ts +29 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +4 -0
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +14 -0
- package/dist/utils.js.map +1 -1
- package/package.json +5 -3
- package/src/delegation.ts +268 -30
- package/src/errors.ts +46 -0
- package/src/handshake.ts +69 -20
- package/src/identity.ts +55 -1
- package/src/index.ts +29 -2
- package/src/offchain.ts +344 -0
- package/src/prover.ts +178 -0
- package/src/types.ts +32 -0
- package/src/utils.ts +23 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// sdk/src/model-binding.ts
|
|
3
|
+
//
|
|
4
|
+
// C7 — ModelInstanceBinding SDK glue.
|
|
5
|
+
//
|
|
6
|
+
// Generates a ZK proof that a tool-call message is cryptographically bound to
|
|
7
|
+
// a specific (model, operator, permission, message) tuple AND that the
|
|
8
|
+
// operator was authorized by an enrolled provider key. See
|
|
9
|
+
// circuits/src/ModelInstanceBinding.circom and spec §5.1 for full semantics.
|
|
10
|
+
//
|
|
11
|
+
// Interim status: the circuit ships as Groth16 (pot16-compatible). PLONK is
|
|
12
|
+
// the long-term target once pot17.ptau is fetched (see circuits/CEREMONY.md).
|
|
13
|
+
// The SDK API stays stable across that migration.
|
|
14
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
17
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
18
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
19
|
+
}
|
|
20
|
+
Object.defineProperty(o, k2, desc);
|
|
21
|
+
}) : (function(o, m, k, k2) {
|
|
22
|
+
if (k2 === undefined) k2 = k;
|
|
23
|
+
o[k2] = m[k];
|
|
24
|
+
}));
|
|
25
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
26
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
27
|
+
}) : function(o, v) {
|
|
28
|
+
o["default"] = v;
|
|
29
|
+
});
|
|
30
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
31
|
+
var ownKeys = function(o) {
|
|
32
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
33
|
+
var ar = [];
|
|
34
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
35
|
+
return ar;
|
|
36
|
+
};
|
|
37
|
+
return ownKeys(o);
|
|
38
|
+
};
|
|
39
|
+
return function (mod) {
|
|
40
|
+
if (mod && mod.__esModule) return mod;
|
|
41
|
+
var result = {};
|
|
42
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
43
|
+
__setModuleDefault(result, mod);
|
|
44
|
+
return result;
|
|
45
|
+
};
|
|
46
|
+
})();
|
|
47
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48
|
+
exports.bindModelInstance = bindModelInstance;
|
|
49
|
+
exports.verifyModelInstanceBinding = verifyModelInstanceBinding;
|
|
50
|
+
const path = __importStar(require("path"));
|
|
51
|
+
const fs = __importStar(require("fs"));
|
|
52
|
+
const snarkjs = __importStar(require("snarkjs"));
|
|
53
|
+
const errors_1 = require("./errors");
|
|
54
|
+
const prover_1 = require("./prover");
|
|
55
|
+
// BOLYRA_CIRCUITS_DIR env override — see handshake.ts for rationale.
|
|
56
|
+
const DEFAULT_CIRCUIT_DIR = process.env.BOLYRA_CIRCUITS_DIR ?? path.join(__dirname, '../../circuits/build');
|
|
57
|
+
const AGENT_TREE_DEPTH = 20;
|
|
58
|
+
const PROVIDER_TREE_DEPTH = 8;
|
|
59
|
+
function padSiblings(siblings, depth) {
|
|
60
|
+
if (siblings.length > depth) {
|
|
61
|
+
throw new errors_1.VerificationError(`Merkle proof has ${siblings.length} siblings but depth is ${depth}`);
|
|
62
|
+
}
|
|
63
|
+
const out = siblings.map((s) => s.toString());
|
|
64
|
+
while (out.length < depth)
|
|
65
|
+
out.push('0');
|
|
66
|
+
return out;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Generate a ModelInstanceBinding ZK proof.
|
|
70
|
+
*
|
|
71
|
+
* The proof attests (in zero knowledge):
|
|
72
|
+
* - The agent credential is enrolled in the on-chain agent tree.
|
|
73
|
+
* - An enrolled provider signed the FULL `credentialCommitment`
|
|
74
|
+
* (= Poseidon5(modelHash, opPkAx, opPkAy, permissionBitmask, expiry)),
|
|
75
|
+
* which binds permissions and expiry — not just (model, operator).
|
|
76
|
+
* - The operator signed the same `credentialCommitment`.
|
|
77
|
+
* - The credential satisfies `requiredScopeMask` and is unexpired.
|
|
78
|
+
* - The tool-call message digest is bound to this proof.
|
|
79
|
+
* - `publicOutputs.providerKeyCommitment` identifies WHICH enrolled provider
|
|
80
|
+
* signed (closes the provider-anonymity attack found in codex challenge).
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* const result = await bindModelInstance({
|
|
85
|
+
* credential,
|
|
86
|
+
* providerAttestation,
|
|
87
|
+
* providerMerkleProof,
|
|
88
|
+
* message: BigInt('0x' + sha256(payload).slice(0, 62)), // mod p
|
|
89
|
+
* sessionNonce: BigInt(Date.now()),
|
|
90
|
+
* requiredScopeMask: 0b101n, // READ_DATA | FINANCIAL_SMALL
|
|
91
|
+
* });
|
|
92
|
+
* // Submit result.proof to IdentityRegistry.verifyModelInstanceBinding(...)
|
|
93
|
+
* ```
|
|
94
|
+
*/
|
|
95
|
+
async function bindModelInstance(input) {
|
|
96
|
+
const { credential, providerAttestation, providerMerkleProof, message, sessionNonce, requiredScopeMask = 0n, currentTimestamp = BigInt(Math.floor(Date.now() / 1000)), config, backend = 'auto', } = input;
|
|
97
|
+
const circuitDir = config?.circuitDir ?? DEFAULT_CIRCUIT_DIR;
|
|
98
|
+
const wasm = path.join(circuitDir, 'ModelInstanceBinding_js/ModelInstanceBinding.wasm');
|
|
99
|
+
const zkey = path.join(circuitDir, 'ModelInstanceBinding_final.zkey');
|
|
100
|
+
if (!fs.existsSync(wasm))
|
|
101
|
+
throw new errors_1.CircuitArtifactNotFoundError(wasm, 'wasm');
|
|
102
|
+
if (!fs.existsSync(zkey))
|
|
103
|
+
throw new errors_1.CircuitArtifactNotFoundError(zkey, 'zkey');
|
|
104
|
+
// Default: single-leaf agent tree (depth 0).
|
|
105
|
+
const agentMerkleProof = input.agentMerkleProof ?? {
|
|
106
|
+
length: 0,
|
|
107
|
+
index: 0,
|
|
108
|
+
siblings: [],
|
|
109
|
+
};
|
|
110
|
+
const witnessInput = {
|
|
111
|
+
// Credential
|
|
112
|
+
modelHash: credential.modelHash.toString(),
|
|
113
|
+
operatorPubkeyAx: credential.operatorPublicKey.x.toString(),
|
|
114
|
+
operatorPubkeyAy: credential.operatorPublicKey.y.toString(),
|
|
115
|
+
permissionBitmask: credential.permissionBitmask.toString(),
|
|
116
|
+
expiryTimestamp: credential.expiryTimestamp.toString(),
|
|
117
|
+
// Operator signature
|
|
118
|
+
operatorSigR8x: credential.signature.R8.x.toString(),
|
|
119
|
+
operatorSigR8y: credential.signature.R8.y.toString(),
|
|
120
|
+
operatorSigS: credential.signature.S.toString(),
|
|
121
|
+
// Provider key + signature
|
|
122
|
+
providerPubkeyAx: providerAttestation.providerPublicKey.x.toString(),
|
|
123
|
+
providerPubkeyAy: providerAttestation.providerPublicKey.y.toString(),
|
|
124
|
+
providerSigR8x: providerAttestation.signature.R8.x.toString(),
|
|
125
|
+
providerSigR8y: providerAttestation.signature.R8.y.toString(),
|
|
126
|
+
providerSigS: providerAttestation.signature.S.toString(),
|
|
127
|
+
// Message
|
|
128
|
+
messagePlaintext: message.toString(),
|
|
129
|
+
// Agent Merkle proof
|
|
130
|
+
merkleProofLength: agentMerkleProof.length.toString(),
|
|
131
|
+
merkleProofIndex: agentMerkleProof.index.toString(),
|
|
132
|
+
merkleProofSiblings: padSiblings(agentMerkleProof.siblings, AGENT_TREE_DEPTH),
|
|
133
|
+
// Provider Merkle proof
|
|
134
|
+
providerMerkleProofLength: providerMerkleProof.length.toString(),
|
|
135
|
+
providerMerkleProofIndex: providerMerkleProof.index.toString(),
|
|
136
|
+
providerMerkleProofSiblings: padSiblings(providerMerkleProof.siblings, PROVIDER_TREE_DEPTH),
|
|
137
|
+
// Public inputs
|
|
138
|
+
requiredScopeMask: requiredScopeMask.toString(),
|
|
139
|
+
currentTimestamp: currentTimestamp.toString(),
|
|
140
|
+
sessionNonce: sessionNonce.toString(),
|
|
141
|
+
providerRegistryRoot: providerMerkleProof.root.toString(),
|
|
142
|
+
};
|
|
143
|
+
let proof;
|
|
144
|
+
try {
|
|
145
|
+
proof = await (0, prover_1.proveGroth16)(witnessInput, wasm, zkey, backend);
|
|
146
|
+
}
|
|
147
|
+
catch (err) {
|
|
148
|
+
throw new errors_1.ProofGenerationError('ModelInstanceBinding', err.message ?? String(err));
|
|
149
|
+
}
|
|
150
|
+
// Public signal layout (snarkjs emits outputs first, then public inputs in
|
|
151
|
+
// declaration order). 10 signals post Phase 2 hardening:
|
|
152
|
+
// 0: agentMerkleRoot
|
|
153
|
+
// 1: nullifierHash
|
|
154
|
+
// 2: scopeCommitment
|
|
155
|
+
// 3: messageHash
|
|
156
|
+
// 4: modelOperatorFingerprint
|
|
157
|
+
// 5: providerKeyCommitment ← which enrolled provider signed
|
|
158
|
+
// 6: requiredScopeMask
|
|
159
|
+
// 7: currentTimestamp
|
|
160
|
+
// 8: sessionNonce
|
|
161
|
+
// 9: providerRegistryRoot
|
|
162
|
+
if (proof.publicSignals.length !== 10) {
|
|
163
|
+
throw new errors_1.VerificationError(`Expected 10 public signals, got ${proof.publicSignals.length}. Verifier may be out of sync with circuit.`);
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
proof,
|
|
167
|
+
publicOutputs: {
|
|
168
|
+
agentMerkleRoot: BigInt(proof.publicSignals[0]),
|
|
169
|
+
nullifierHash: BigInt(proof.publicSignals[1]),
|
|
170
|
+
scopeCommitment: BigInt(proof.publicSignals[2]),
|
|
171
|
+
messageHash: BigInt(proof.publicSignals[3]),
|
|
172
|
+
modelOperatorFingerprint: BigInt(proof.publicSignals[4]),
|
|
173
|
+
providerKeyCommitment: BigInt(proof.publicSignals[5]),
|
|
174
|
+
requiredScopeMask: BigInt(proof.publicSignals[6]),
|
|
175
|
+
currentTimestamp: BigInt(proof.publicSignals[7]),
|
|
176
|
+
sessionNonce: BigInt(proof.publicSignals[8]),
|
|
177
|
+
providerRegistryRoot: BigInt(proof.publicSignals[9]),
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Verify a ModelInstanceBinding proof off-chain (snarkjs-side).
|
|
183
|
+
* For on-chain verification, submit the proof to
|
|
184
|
+
* IdentityRegistry.verifyModelInstanceBinding(...).
|
|
185
|
+
*/
|
|
186
|
+
async function verifyModelInstanceBinding(proof, config) {
|
|
187
|
+
const circuitDir = config?.circuitDir ?? DEFAULT_CIRCUIT_DIR;
|
|
188
|
+
const vkeyPath = path.join(circuitDir, 'ModelInstanceBinding_groth16_vkey.json');
|
|
189
|
+
if (!fs.existsSync(vkeyPath)) {
|
|
190
|
+
throw new errors_1.CircuitArtifactNotFoundError(vkeyPath, 'vkey');
|
|
191
|
+
}
|
|
192
|
+
const vkey = require(vkeyPath);
|
|
193
|
+
return await snarkjs.groth16.verify(vkey, proof.publicSignals, proof.proof);
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=model-binding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-binding.js","sourceRoot":"","sources":["../src/model-binding.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { ethers } from 'ethers';
|
|
2
|
+
import { Proof, BolyraConfig, HandshakeResult, OffchainVerificationResult, BatchCheckpoint } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* Verify a handshake off-chain using local snarkjs verification.
|
|
5
|
+
* Same interface as verifyHandshake but never touches the chain.
|
|
6
|
+
* Produces a HandshakeResult suitable for batching.
|
|
7
|
+
*
|
|
8
|
+
* Gas savings: 0 gas per verification (vs ~300k+ on-chain).
|
|
9
|
+
* The batch root is posted once for N verifications.
|
|
10
|
+
*/
|
|
11
|
+
export declare function verifyHandshakeOffchain(humanProof: Proof, agentProof: Proof, nonce: bigint, config?: BolyraConfig): Promise<HandshakeResult>;
|
|
12
|
+
/**
|
|
13
|
+
* Compute the session commitment for a HandshakeResult.
|
|
14
|
+
* sessionCommitment = Poseidon2(humanNullifier, Poseidon2(agentNullifier, sessionNonce))
|
|
15
|
+
* This binds all three fields into a single leaf for the batch Merkle tree.
|
|
16
|
+
*/
|
|
17
|
+
export declare function computeSessionCommitment(result: HandshakeResult): Promise<bigint>;
|
|
18
|
+
/**
|
|
19
|
+
* Accumulates verified handshake sessions and produces a Poseidon Merkle root.
|
|
20
|
+
* The root can be posted on-chain in a single transaction, amortizing gas
|
|
21
|
+
* across all sessions in the batch (target: ~100x reduction).
|
|
22
|
+
*
|
|
23
|
+
* Tree construction: binary Poseidon Merkle tree. If the number of leaves
|
|
24
|
+
* is not a power of 2, zero-padding is applied to the right.
|
|
25
|
+
*/
|
|
26
|
+
export declare class OffchainVerificationBatch {
|
|
27
|
+
private sessions;
|
|
28
|
+
private commitments;
|
|
29
|
+
private cachedRoot;
|
|
30
|
+
/** Number of sessions in the batch. */
|
|
31
|
+
get size(): number;
|
|
32
|
+
/**
|
|
33
|
+
* Add a verified handshake result to the batch.
|
|
34
|
+
* Resets the cached Merkle root (will be recomputed on next getMerkleRoot call).
|
|
35
|
+
*
|
|
36
|
+
* @returns The OffchainVerificationResult with batchIndex set.
|
|
37
|
+
*/
|
|
38
|
+
add(result: HandshakeResult): Promise<OffchainVerificationResult>;
|
|
39
|
+
/**
|
|
40
|
+
* Compute the Poseidon Merkle root of all session commitments.
|
|
41
|
+
* Uses a binary tree with zero-padding to the next power of 2.
|
|
42
|
+
* Result is cached until a new session is added.
|
|
43
|
+
*/
|
|
44
|
+
getMerkleRoot(): Promise<bigint>;
|
|
45
|
+
/**
|
|
46
|
+
* Get a Merkle inclusion proof for a specific session in the batch.
|
|
47
|
+
* Returns sibling hashes and path indices (0 = left, 1 = right) from leaf to root.
|
|
48
|
+
*
|
|
49
|
+
* @param sessionIndex - Index of the session (from OffchainVerificationResult.batchIndex)
|
|
50
|
+
* @returns Merkle proof (siblings + pathIndices) or throws if index is out of bounds.
|
|
51
|
+
*/
|
|
52
|
+
getProofOfInclusion(sessionIndex: number): Promise<{
|
|
53
|
+
siblings: bigint[];
|
|
54
|
+
pathIndices: number[];
|
|
55
|
+
}>;
|
|
56
|
+
/**
|
|
57
|
+
* Get the session commitment at a given index.
|
|
58
|
+
*/
|
|
59
|
+
getCommitment(index: number): bigint;
|
|
60
|
+
/**
|
|
61
|
+
* Get all session commitments (for external verification).
|
|
62
|
+
*/
|
|
63
|
+
getCommitments(): bigint[];
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Post a batch Merkle root on-chain. A single transaction checkpoints N sessions.
|
|
67
|
+
*
|
|
68
|
+
* Gas cost: ~50k-80k gas for a single storage write + event emission,
|
|
69
|
+
* regardless of how many sessions are in the batch.
|
|
70
|
+
* For 100 sessions: ~500 gas/session vs ~300k gas/session on-chain = ~600x reduction.
|
|
71
|
+
*
|
|
72
|
+
* @param batch - The batch to checkpoint
|
|
73
|
+
* @param signer - An ethers Signer (connected to the target chain)
|
|
74
|
+
* @param registryAddress - Address of the IdentityRegistry (or a BatchCheckpoint contract)
|
|
75
|
+
* @returns The BatchCheckpoint with on-chain timestamp
|
|
76
|
+
*/
|
|
77
|
+
export declare function postBatchRoot(batch: OffchainVerificationBatch, signer: ethers.Signer, registryAddress: string): Promise<BatchCheckpoint>;
|
|
78
|
+
/**
|
|
79
|
+
* Verify a Merkle inclusion proof against a known root.
|
|
80
|
+
* Useful for verifiers who receive a proof-of-inclusion from a session participant.
|
|
81
|
+
*
|
|
82
|
+
* @param leaf - The session commitment (leaf value)
|
|
83
|
+
* @param siblings - Sibling hashes from the proof
|
|
84
|
+
* @param pathIndices - Path indices (0 = left, 1 = right)
|
|
85
|
+
* @param expectedRoot - The expected Merkle root (from on-chain checkpoint)
|
|
86
|
+
* @returns true if the proof is valid
|
|
87
|
+
*/
|
|
88
|
+
export declare function verifyMerkleInclusion(leaf: bigint, siblings: bigint[], pathIndices: number[], expectedRoot: bigint): Promise<boolean>;
|
|
89
|
+
//# sourceMappingURL=offchain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"offchain.d.ts","sourceRoot":"","sources":["../src/offchain.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EACL,KAAK,EACL,YAAY,EACZ,eAAe,EACf,0BAA0B,EAC1B,eAAe,EAChB,MAAM,SAAS,CAAC;AAOjB;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAC3C,UAAU,EAAE,KAAK,EACjB,UAAU,EAAE,KAAK,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,YAAY,GACpB,OAAO,CAAC,eAAe,CAAC,CAyD1B;AAED;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAGvF;AAED;;;;;;;GAOG;AACH,qBAAa,yBAAyB;IACpC,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,WAAW,CAAgB;IACnC,OAAO,CAAC,UAAU,CAAuB;IAEzC,uCAAuC;IACvC,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED;;;;;OAKG;IACG,GAAG,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,0BAA0B,CAAC;IAoBvE;;;;OAIG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC;IAatC;;;;;;OAMG;IACG,mBAAmB,CACvB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAUzD;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IASpC;;OAEG;IACH,cAAc,IAAI,MAAM,EAAE;CAG3B;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,yBAAyB,EAChC,MAAM,EAAE,MAAM,CAAC,MAAM,EACrB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,eAAe,CAAC,CA2B1B;AAsED;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAAE,EAClB,WAAW,EAAE,MAAM,EAAE,EACrB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,OAAO,CAAC,CAelB"}
|
package/dist/offchain.js
ADDED
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.OffchainVerificationBatch = void 0;
|
|
37
|
+
exports.verifyHandshakeOffchain = verifyHandshakeOffchain;
|
|
38
|
+
exports.computeSessionCommitment = computeSessionCommitment;
|
|
39
|
+
exports.postBatchRoot = postBatchRoot;
|
|
40
|
+
exports.verifyMerkleInclusion = verifyMerkleInclusion;
|
|
41
|
+
const snarkjs = __importStar(require("snarkjs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const fs = __importStar(require("fs"));
|
|
44
|
+
const ethers_1 = require("ethers");
|
|
45
|
+
const errors_1 = require("./errors");
|
|
46
|
+
const utils_1 = require("./utils");
|
|
47
|
+
// Default paths to circuit artifacts (relative to package root)
|
|
48
|
+
const DEFAULT_CIRCUIT_DIR = path.join(__dirname, '../../circuits/build');
|
|
49
|
+
/**
|
|
50
|
+
* Verify a handshake off-chain using local snarkjs verification.
|
|
51
|
+
* Same interface as verifyHandshake but never touches the chain.
|
|
52
|
+
* Produces a HandshakeResult suitable for batching.
|
|
53
|
+
*
|
|
54
|
+
* Gas savings: 0 gas per verification (vs ~300k+ on-chain).
|
|
55
|
+
* The batch root is posted once for N verifications.
|
|
56
|
+
*/
|
|
57
|
+
async function verifyHandshakeOffchain(humanProof, agentProof, nonce, config) {
|
|
58
|
+
const circuitDir = config?.circuitDir ?? DEFAULT_CIRCUIT_DIR;
|
|
59
|
+
// Validate proof structure
|
|
60
|
+
if (!humanProof || !humanProof.proof || !Array.isArray(humanProof.publicSignals)) {
|
|
61
|
+
throw new errors_1.VerificationError('Invalid humanProof structure: expected { proof: object, publicSignals: string[] }.');
|
|
62
|
+
}
|
|
63
|
+
if (!agentProof || !agentProof.proof || !Array.isArray(agentProof.publicSignals)) {
|
|
64
|
+
throw new errors_1.VerificationError('Invalid agentProof structure: expected { proof: object, publicSignals: string[] }.');
|
|
65
|
+
}
|
|
66
|
+
if (humanProof.publicSignals.length < 2) {
|
|
67
|
+
throw new errors_1.VerificationError(`humanProof has ${humanProof.publicSignals.length} public signals, expected at least 2.`);
|
|
68
|
+
}
|
|
69
|
+
if (agentProof.publicSignals.length < 3) {
|
|
70
|
+
throw new errors_1.VerificationError(`agentProof has ${agentProof.publicSignals.length} public signals, expected at least 3.`);
|
|
71
|
+
}
|
|
72
|
+
// Load verification keys
|
|
73
|
+
const humanVkeyPath = path.join(circuitDir, 'HumanUniqueness_vkey.json');
|
|
74
|
+
if (!fs.existsSync(humanVkeyPath)) {
|
|
75
|
+
throw new errors_1.CircuitArtifactNotFoundError(humanVkeyPath, 'vkey');
|
|
76
|
+
}
|
|
77
|
+
const agentVkeyPath = path.join(circuitDir, 'AgentPolicy_groth16_vkey.json');
|
|
78
|
+
if (!fs.existsSync(agentVkeyPath)) {
|
|
79
|
+
throw new errors_1.CircuitArtifactNotFoundError(agentVkeyPath, 'vkey');
|
|
80
|
+
}
|
|
81
|
+
// Verify both proofs locally (no on-chain interaction)
|
|
82
|
+
const humanVkey = require(humanVkeyPath);
|
|
83
|
+
const humanValid = await snarkjs.groth16.verify(humanVkey, humanProof.publicSignals, humanProof.proof);
|
|
84
|
+
const agentVkey = require(agentVkeyPath);
|
|
85
|
+
const agentValid = await snarkjs.groth16.verify(agentVkey, agentProof.publicSignals, agentProof.proof);
|
|
86
|
+
return {
|
|
87
|
+
humanNullifier: BigInt(humanProof.publicSignals[1]),
|
|
88
|
+
agentNullifier: BigInt(agentProof.publicSignals[1]),
|
|
89
|
+
sessionNonce: nonce,
|
|
90
|
+
scopeCommitment: BigInt(agentProof.publicSignals[2]),
|
|
91
|
+
verified: humanValid && agentValid,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Compute the session commitment for a HandshakeResult.
|
|
96
|
+
* sessionCommitment = Poseidon2(humanNullifier, Poseidon2(agentNullifier, sessionNonce))
|
|
97
|
+
* This binds all three fields into a single leaf for the batch Merkle tree.
|
|
98
|
+
*/
|
|
99
|
+
async function computeSessionCommitment(result) {
|
|
100
|
+
const inner = await (0, utils_1.poseidon2)(result.agentNullifier, result.sessionNonce);
|
|
101
|
+
return (0, utils_1.poseidon2)(result.humanNullifier, inner);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Accumulates verified handshake sessions and produces a Poseidon Merkle root.
|
|
105
|
+
* The root can be posted on-chain in a single transaction, amortizing gas
|
|
106
|
+
* across all sessions in the batch (target: ~100x reduction).
|
|
107
|
+
*
|
|
108
|
+
* Tree construction: binary Poseidon Merkle tree. If the number of leaves
|
|
109
|
+
* is not a power of 2, zero-padding is applied to the right.
|
|
110
|
+
*/
|
|
111
|
+
class OffchainVerificationBatch {
|
|
112
|
+
sessions = [];
|
|
113
|
+
commitments = [];
|
|
114
|
+
cachedRoot = null;
|
|
115
|
+
/** Number of sessions in the batch. */
|
|
116
|
+
get size() {
|
|
117
|
+
return this.sessions.length;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Add a verified handshake result to the batch.
|
|
121
|
+
* Resets the cached Merkle root (will be recomputed on next getMerkleRoot call).
|
|
122
|
+
*
|
|
123
|
+
* @returns The OffchainVerificationResult with batchIndex set.
|
|
124
|
+
*/
|
|
125
|
+
async add(result) {
|
|
126
|
+
if (!result.verified) {
|
|
127
|
+
throw new errors_1.VerificationError('Cannot add unverified handshake to batch. Verify the handshake first.');
|
|
128
|
+
}
|
|
129
|
+
const batchIndex = this.sessions.length;
|
|
130
|
+
const commitment = await computeSessionCommitment(result);
|
|
131
|
+
this.sessions.push(result);
|
|
132
|
+
this.commitments.push(commitment);
|
|
133
|
+
this.cachedRoot = null; // invalidate cache
|
|
134
|
+
return {
|
|
135
|
+
...result,
|
|
136
|
+
batchIndex,
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Compute the Poseidon Merkle root of all session commitments.
|
|
141
|
+
* Uses a binary tree with zero-padding to the next power of 2.
|
|
142
|
+
* Result is cached until a new session is added.
|
|
143
|
+
*/
|
|
144
|
+
async getMerkleRoot() {
|
|
145
|
+
if (this.sessions.length === 0) {
|
|
146
|
+
return 0n;
|
|
147
|
+
}
|
|
148
|
+
if (this.cachedRoot !== null) {
|
|
149
|
+
return this.cachedRoot;
|
|
150
|
+
}
|
|
151
|
+
this.cachedRoot = await buildPoseidonMerkleRoot(this.commitments);
|
|
152
|
+
return this.cachedRoot;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Get a Merkle inclusion proof for a specific session in the batch.
|
|
156
|
+
* Returns sibling hashes and path indices (0 = left, 1 = right) from leaf to root.
|
|
157
|
+
*
|
|
158
|
+
* @param sessionIndex - Index of the session (from OffchainVerificationResult.batchIndex)
|
|
159
|
+
* @returns Merkle proof (siblings + pathIndices) or throws if index is out of bounds.
|
|
160
|
+
*/
|
|
161
|
+
async getProofOfInclusion(sessionIndex) {
|
|
162
|
+
if (sessionIndex < 0 || sessionIndex >= this.sessions.length) {
|
|
163
|
+
throw new errors_1.VerificationError(`Session index ${sessionIndex} out of bounds (batch has ${this.sessions.length} sessions).`);
|
|
164
|
+
}
|
|
165
|
+
return buildPoseidonMerkleProof(this.commitments, sessionIndex);
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Get the session commitment at a given index.
|
|
169
|
+
*/
|
|
170
|
+
getCommitment(index) {
|
|
171
|
+
if (index < 0 || index >= this.commitments.length) {
|
|
172
|
+
throw new errors_1.VerificationError(`Index ${index} out of bounds (batch has ${this.commitments.length} sessions).`);
|
|
173
|
+
}
|
|
174
|
+
return this.commitments[index];
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Get all session commitments (for external verification).
|
|
178
|
+
*/
|
|
179
|
+
getCommitments() {
|
|
180
|
+
return [...this.commitments];
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
exports.OffchainVerificationBatch = OffchainVerificationBatch;
|
|
184
|
+
/**
|
|
185
|
+
* Post a batch Merkle root on-chain. A single transaction checkpoints N sessions.
|
|
186
|
+
*
|
|
187
|
+
* Gas cost: ~50k-80k gas for a single storage write + event emission,
|
|
188
|
+
* regardless of how many sessions are in the batch.
|
|
189
|
+
* For 100 sessions: ~500 gas/session vs ~300k gas/session on-chain = ~600x reduction.
|
|
190
|
+
*
|
|
191
|
+
* @param batch - The batch to checkpoint
|
|
192
|
+
* @param signer - An ethers Signer (connected to the target chain)
|
|
193
|
+
* @param registryAddress - Address of the IdentityRegistry (or a BatchCheckpoint contract)
|
|
194
|
+
* @returns The BatchCheckpoint with on-chain timestamp
|
|
195
|
+
*/
|
|
196
|
+
async function postBatchRoot(batch, signer, registryAddress) {
|
|
197
|
+
if (batch.size === 0) {
|
|
198
|
+
throw new errors_1.VerificationError('Cannot post empty batch root on-chain.');
|
|
199
|
+
}
|
|
200
|
+
const root = await batch.getMerkleRoot();
|
|
201
|
+
// ABI for the postBatchRoot function on the BatchCheckpoint extension contract.
|
|
202
|
+
// function postBatchRoot(uint256 root, uint256 sessionCount) external
|
|
203
|
+
const abi = [
|
|
204
|
+
'function postBatchRoot(uint256 root, uint256 sessionCount) external',
|
|
205
|
+
'event BatchRootPosted(uint256 indexed root, uint256 sessionCount, uint256 timestamp)',
|
|
206
|
+
];
|
|
207
|
+
const contract = new ethers_1.ethers.Contract(registryAddress, abi, signer);
|
|
208
|
+
const tx = await contract.postBatchRoot(root, batch.size);
|
|
209
|
+
const receipt = await tx.wait();
|
|
210
|
+
const timestamp = receipt?.blockNumber
|
|
211
|
+
? (await signer.provider.getBlock(receipt.blockNumber))?.timestamp ?? Math.floor(Date.now() / 1000)
|
|
212
|
+
: Math.floor(Date.now() / 1000);
|
|
213
|
+
return {
|
|
214
|
+
root,
|
|
215
|
+
timestamp,
|
|
216
|
+
sessionCount: batch.size,
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
// ============ Internal Merkle Tree Helpers ============
|
|
220
|
+
/**
|
|
221
|
+
* Pad leaves array to the next power of 2 with zeros.
|
|
222
|
+
*/
|
|
223
|
+
function padToPowerOfTwo(leaves) {
|
|
224
|
+
if (leaves.length === 0)
|
|
225
|
+
return [0n];
|
|
226
|
+
let size = 1;
|
|
227
|
+
while (size < leaves.length) {
|
|
228
|
+
size *= 2;
|
|
229
|
+
}
|
|
230
|
+
const padded = [...leaves];
|
|
231
|
+
while (padded.length < size) {
|
|
232
|
+
padded.push(0n);
|
|
233
|
+
}
|
|
234
|
+
return padded;
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Build a Poseidon Merkle root from a list of leaf commitments.
|
|
238
|
+
* Binary tree, zero-padded to next power of 2.
|
|
239
|
+
*/
|
|
240
|
+
async function buildPoseidonMerkleRoot(leaves) {
|
|
241
|
+
let layer = padToPowerOfTwo(leaves);
|
|
242
|
+
while (layer.length > 1) {
|
|
243
|
+
const nextLayer = [];
|
|
244
|
+
for (let i = 0; i < layer.length; i += 2) {
|
|
245
|
+
nextLayer.push(await (0, utils_1.poseidon2)(layer[i], layer[i + 1]));
|
|
246
|
+
}
|
|
247
|
+
layer = nextLayer;
|
|
248
|
+
}
|
|
249
|
+
return layer[0];
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Build a Merkle inclusion proof for a specific leaf index.
|
|
253
|
+
* Returns siblings and path indices (0 = leaf is on the left, 1 = leaf is on the right).
|
|
254
|
+
*/
|
|
255
|
+
async function buildPoseidonMerkleProof(leaves, index) {
|
|
256
|
+
const padded = padToPowerOfTwo(leaves);
|
|
257
|
+
const siblings = [];
|
|
258
|
+
const pathIndices = [];
|
|
259
|
+
let layer = padded;
|
|
260
|
+
let currentIndex = index;
|
|
261
|
+
while (layer.length > 1) {
|
|
262
|
+
const siblingIndex = currentIndex % 2 === 0 ? currentIndex + 1 : currentIndex - 1;
|
|
263
|
+
siblings.push(layer[siblingIndex]);
|
|
264
|
+
pathIndices.push(currentIndex % 2); // 0 = left, 1 = right
|
|
265
|
+
// Build next layer
|
|
266
|
+
const nextLayer = [];
|
|
267
|
+
for (let i = 0; i < layer.length; i += 2) {
|
|
268
|
+
nextLayer.push(await (0, utils_1.poseidon2)(layer[i], layer[i + 1]));
|
|
269
|
+
}
|
|
270
|
+
layer = nextLayer;
|
|
271
|
+
currentIndex = Math.floor(currentIndex / 2);
|
|
272
|
+
}
|
|
273
|
+
return { siblings, pathIndices };
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Verify a Merkle inclusion proof against a known root.
|
|
277
|
+
* Useful for verifiers who receive a proof-of-inclusion from a session participant.
|
|
278
|
+
*
|
|
279
|
+
* @param leaf - The session commitment (leaf value)
|
|
280
|
+
* @param siblings - Sibling hashes from the proof
|
|
281
|
+
* @param pathIndices - Path indices (0 = left, 1 = right)
|
|
282
|
+
* @param expectedRoot - The expected Merkle root (from on-chain checkpoint)
|
|
283
|
+
* @returns true if the proof is valid
|
|
284
|
+
*/
|
|
285
|
+
async function verifyMerkleInclusion(leaf, siblings, pathIndices, expectedRoot) {
|
|
286
|
+
if (siblings.length !== pathIndices.length) {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
let current = leaf;
|
|
290
|
+
for (let i = 0; i < siblings.length; i++) {
|
|
291
|
+
if (pathIndices[i] === 0) {
|
|
292
|
+
current = await (0, utils_1.poseidon2)(current, siblings[i]);
|
|
293
|
+
}
|
|
294
|
+
else {
|
|
295
|
+
current = await (0, utils_1.poseidon2)(siblings[i], current);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return current === expectedRoot;
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=offchain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"offchain.js","sourceRoot":"","sources":["../src/offchain.ts"],"names":[],"mappings":"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"}
|
package/dist/prover.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Proof } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Prover backend selection.
|
|
4
|
+
* - 'auto' : use rapidsnark if available, else snarkjs
|
|
5
|
+
* - 'rapidsnark' : require rapidsnark, throw if missing
|
|
6
|
+
* - 'snarkjs' : always use snarkjs (slower, pure JS)
|
|
7
|
+
*/
|
|
8
|
+
export type ProverBackend = 'auto' | 'rapidsnark' | 'snarkjs';
|
|
9
|
+
/**
|
|
10
|
+
* Generate a Groth16 proof using the fastest available backend.
|
|
11
|
+
* rapidsnark is ~5x faster than snarkjs but requires the native binary.
|
|
12
|
+
*
|
|
13
|
+
* @param input - Circuit input (string-encoded bigints)
|
|
14
|
+
* @param wasmPath - Path to circuit_js/circuit.wasm (witness generator)
|
|
15
|
+
* @param zkeyPath - Path to circuit_final.zkey
|
|
16
|
+
* @param backend - 'auto' (default), 'rapidsnark', or 'snarkjs'
|
|
17
|
+
*/
|
|
18
|
+
export declare function proveGroth16(input: Record<string, unknown>, wasmPath: string, zkeyPath: string, backend?: ProverBackend): Promise<Proof>;
|
|
19
|
+
/** Returns the active backend that would be used (for diagnostics/logging). */
|
|
20
|
+
export declare function activeProverBackend(backend?: ProverBackend): 'rapidsnark' | 'snarkjs';
|
|
21
|
+
//# sourceMappingURL=prover.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prover.d.ts","sourceRoot":"","sources":["../src/prover.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAEhC;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,YAAY,GAAG,SAAS,CAAC;AAqH9D;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC9B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,GAAE,aAAsB,GAC9B,OAAO,CAAC,KAAK,CAAC,CAuBhB;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,aAAsB,GAAG,YAAY,GAAG,SAAS,CAI7F"}
|