@opaquecash/psr-prover 0.1.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/dist/defaultReputationArtifacts.d.ts +10 -0
- package/dist/defaultReputationArtifacts.d.ts.map +1 -0
- package/dist/defaultReputationArtifacts.js +12 -0
- package/dist/defaultReputationArtifacts.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/pipeline.d.ts +32 -0
- package/dist/pipeline.d.ts.map +1 -0
- package/dist/pipeline.js +20 -0
- package/dist/pipeline.js.map +1 -0
- package/dist/prove.d.ts +31 -0
- package/dist/prove.d.ts.map +1 -0
- package/dist/prove.js +47 -0
- package/dist/prove.js.map +1 -0
- package/dist/witness.d.ts +39 -0
- package/dist/witness.d.ts.map +1 -0
- package/dist/witness.js +86 -0
- package/dist/witness.js.map +1 -0
- package/package.json +30 -0
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ArtifactPaths } from "./prove.js";
|
|
2
|
+
/**
|
|
3
|
+
* Host for reputation Groth16 assets (same `/circuits/...` paths as the Opaque frontend).
|
|
4
|
+
*/
|
|
5
|
+
export declare const DEFAULT_REPUTATION_ARTIFACTS_ORIGIN = "https://www.opaque.cash";
|
|
6
|
+
/**
|
|
7
|
+
* Default wasm + zkey URLs for `generateReputationProof` when `artifacts` is omitted.
|
|
8
|
+
*/
|
|
9
|
+
export declare const DEFAULT_REPUTATION_ARTIFACT_PATHS: ArtifactPaths;
|
|
10
|
+
//# sourceMappingURL=defaultReputationArtifacts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultReputationArtifacts.d.ts","sourceRoot":"","sources":["../src/defaultReputationArtifacts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD;;GAEG;AACH,eAAO,MAAM,mCAAmC,4BAA4B,CAAC;AAE7E;;GAEG;AACH,eAAO,MAAM,iCAAiC,EAAE,aAG/C,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Host for reputation Groth16 assets (same `/circuits/...` paths as the Opaque frontend).
|
|
3
|
+
*/
|
|
4
|
+
export const DEFAULT_REPUTATION_ARTIFACTS_ORIGIN = "https://www.opaque.cash";
|
|
5
|
+
/**
|
|
6
|
+
* Default wasm + zkey URLs for `generateReputationProof` when `artifacts` is omitted.
|
|
7
|
+
*/
|
|
8
|
+
export const DEFAULT_REPUTATION_ARTIFACT_PATHS = {
|
|
9
|
+
wasmPath: `${DEFAULT_REPUTATION_ARTIFACTS_ORIGIN}/circuits/stealth_attestation_js/stealth_attestation.wasm`,
|
|
10
|
+
zkeyPath: `${DEFAULT_REPUTATION_ARTIFACTS_ORIGIN}/circuits/sa_final.zkey`,
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=defaultReputationArtifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultReputationArtifacts.js","sourceRoot":"","sources":["../src/defaultReputationArtifacts.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAG,yBAAyB,CAAC;AAE7E;;GAEG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAkB;IAC9D,QAAQ,EAAE,GAAG,mCAAmC,2DAA2D;IAC3G,QAAQ,EAAE,GAAG,mCAAmC,yBAAyB;CAC1E,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@opaquecash/psr-prover` — witness construction and Groth16 proving for the stealth attestation circuit.
|
|
3
|
+
*
|
|
4
|
+
* Depends on `snarkjs` and `circomlibjs`; browser apps should polyfill `Buffer` (see {@link ensureBufferPolyfill}).
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
export type { CircuitWitness } from "./witness.js";
|
|
9
|
+
export { buildWitnessCircuitConsistent, buildWitnessFromWasm, ensureBufferPolyfill, } from "./witness.js";
|
|
10
|
+
export type { ArtifactPaths, ProofProgressCallback } from "./prove.js";
|
|
11
|
+
export { generateGroth16Proof, verifyProofLocally, } from "./prove.js";
|
|
12
|
+
export { DEFAULT_REPUTATION_ARTIFACT_PATHS, DEFAULT_REPUTATION_ARTIFACTS_ORIGIN, } from "./defaultReputationArtifacts.js";
|
|
13
|
+
export type { GenerateReputationProofParams } from "./pipeline.js";
|
|
14
|
+
export { generateReputationProof } from "./pipeline.js";
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EACL,6BAA6B,EAC7B,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,cAAc,CAAC;AAEtB,YAAY,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EACL,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,iCAAiC,EACjC,mCAAmC,GACpC,MAAM,iCAAiC,CAAC;AAEzC,YAAY,EAAE,6BAA6B,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@opaquecash/psr-prover` — witness construction and Groth16 proving for the stealth attestation circuit.
|
|
3
|
+
*
|
|
4
|
+
* Depends on `snarkjs` and `circomlibjs`; browser apps should polyfill `Buffer` (see {@link ensureBufferPolyfill}).
|
|
5
|
+
*
|
|
6
|
+
* @packageDocumentation
|
|
7
|
+
*/
|
|
8
|
+
export { buildWitnessCircuitConsistent, buildWitnessFromWasm, ensureBufferPolyfill, } from "./witness.js";
|
|
9
|
+
export { generateGroth16Proof, verifyProofLocally, } from "./prove.js";
|
|
10
|
+
export { DEFAULT_REPUTATION_ARTIFACT_PATHS, DEFAULT_REPUTATION_ARTIFACTS_ORIGIN, } from "./defaultReputationArtifacts.js";
|
|
11
|
+
export { generateReputationProof } from "./pipeline.js";
|
|
12
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EACL,6BAA6B,EAC7B,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,cAAc,CAAC;AAGtB,OAAO,EACL,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,iCAAiC,EACjC,mCAAmC,GACpC,MAAM,iCAAiC,CAAC;AAGzC,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { DiscoveredTrait, ProofData } from "@opaquecash/psr-core";
|
|
2
|
+
import type { StealthWasmModule } from "@opaquecash/stealth-wasm";
|
|
3
|
+
import type { ArtifactPaths, ProofProgressCallback } from "./prove.js";
|
|
4
|
+
/**
|
|
5
|
+
* High-level inputs for {@link generateReputationProof}.
|
|
6
|
+
*/
|
|
7
|
+
export interface GenerateReputationProofParams {
|
|
8
|
+
/** Initialized WASM module. */
|
|
9
|
+
wasm: StealthWasmModule;
|
|
10
|
+
/** Trait to prove (from scanner). */
|
|
11
|
+
trait: DiscoveredTrait;
|
|
12
|
+
/**
|
|
13
|
+
* When set, witness is built via Rust `generate_reputation_witness` using this JSON string.
|
|
14
|
+
* Otherwise {@link buildWitnessCircuitConsistent} is used (zero-hash tree dev mode).
|
|
15
|
+
*/
|
|
16
|
+
attestationsJson?: string;
|
|
17
|
+
/** 32-byte reconstructed one-time stealth private key for the trait output. */
|
|
18
|
+
stealthPrivKeyBytes: Uint8Array;
|
|
19
|
+
/** External nullifier as decimal string (see {@link externalNullifierFromScope} in `@opaquecash/psr-core`). */
|
|
20
|
+
externalNullifier: string;
|
|
21
|
+
/**
|
|
22
|
+
* Circom wasm + zkey paths/URLs.
|
|
23
|
+
* Defaults to {@link DEFAULT_REPUTATION_ARTIFACT_PATHS} (opaque.cash).
|
|
24
|
+
*/
|
|
25
|
+
artifacts?: ArtifactPaths;
|
|
26
|
+
onProgress?: ProofProgressCallback;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* End-to-end: build witness (WASM or circomlib placeholder tree) + Groth16 prove.
|
|
30
|
+
*/
|
|
31
|
+
export declare function generateReputationProof(params: GenerateReputationProofParams): Promise<ProofData>;
|
|
32
|
+
//# sourceMappingURL=pipeline.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.d.ts","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,KAAK,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAQvE;;GAEG;AACH,MAAM,WAAW,6BAA6B;IAC5C,+BAA+B;IAC/B,IAAI,EAAE,iBAAiB,CAAC;IACxB,qCAAqC;IACrC,KAAK,EAAE,eAAe,CAAC;IACvB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,+EAA+E;IAC/E,mBAAmB,EAAE,UAAU,CAAC;IAChC,+GAA+G;IAC/G,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B,UAAU,CAAC,EAAE,qBAAqB,CAAC;CACpC;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,6BAA6B,GACpC,OAAO,CAAC,SAAS,CAAC,CAyBpB"}
|
package/dist/pipeline.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DEFAULT_REPUTATION_ARTIFACT_PATHS } from "./defaultReputationArtifacts.js";
|
|
2
|
+
import { generateGroth16Proof } from "./prove.js";
|
|
3
|
+
import { buildWitnessCircuitConsistent, buildWitnessFromWasm, } from "./witness.js";
|
|
4
|
+
/**
|
|
5
|
+
* End-to-end: build witness (WASM or circomlib placeholder tree) + Groth16 prove.
|
|
6
|
+
*/
|
|
7
|
+
export async function generateReputationProof(params) {
|
|
8
|
+
params.onProgress?.("preparing-witness", 5);
|
|
9
|
+
let witness;
|
|
10
|
+
if (params.attestationsJson !== undefined) {
|
|
11
|
+
witness = buildWitnessFromWasm(params.wasm, params.attestationsJson, String(params.trait.attestationId), params.stealthPrivKeyBytes, params.externalNullifier);
|
|
12
|
+
params.onProgress?.("preparing-witness", 60);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
witness = await buildWitnessCircuitConsistent(params.trait.attestationId, params.stealthPrivKeyBytes, params.externalNullifier);
|
|
16
|
+
params.onProgress?.("preparing-witness", 60);
|
|
17
|
+
}
|
|
18
|
+
return generateGroth16Proof(witness, params.artifacts ?? DEFAULT_REPUTATION_ARTIFACT_PATHS, params.onProgress);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=pipeline.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iCAAiC,EAAE,MAAM,iCAAiC,CAAC;AAEpF,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EACL,6BAA6B,EAC7B,oBAAoB,GAErB,MAAM,cAAc,CAAC;AA2BtB;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,MAAqC;IAErC,MAAM,CAAC,UAAU,EAAE,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC;IAC5C,IAAI,OAAuB,CAAC;IAC5B,IAAI,MAAM,CAAC,gBAAgB,KAAK,SAAS,EAAE,CAAC;QAC1C,OAAO,GAAG,oBAAoB,CAC5B,MAAM,CAAC,IAAI,EACX,MAAM,CAAC,gBAAgB,EACvB,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,EAClC,MAAM,CAAC,mBAAmB,EAC1B,MAAM,CAAC,iBAAiB,CACzB,CAAC;QACF,MAAM,CAAC,UAAU,EAAE,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,MAAM,6BAA6B,CAC3C,MAAM,CAAC,KAAK,CAAC,aAAa,EAC1B,MAAM,CAAC,mBAAmB,EAC1B,MAAM,CAAC,iBAAiB,CACzB,CAAC;QACF,MAAM,CAAC,UAAU,EAAE,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,oBAAoB,CACzB,OAAO,EACP,MAAM,CAAC,SAAS,IAAI,iCAAiC,EACrD,MAAM,CAAC,UAAU,CAClB,CAAC;AACJ,CAAC"}
|
package/dist/prove.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ProofData } from "@opaquecash/psr-core";
|
|
2
|
+
import type { CircuitWitness } from "./witness.js";
|
|
3
|
+
/**
|
|
4
|
+
* Paths or URLs to Circom wasm + final zkey (Groth16).
|
|
5
|
+
*/
|
|
6
|
+
export interface ArtifactPaths {
|
|
7
|
+
/** Path/URL to `stealth_attestation.wasm`. */
|
|
8
|
+
wasmPath: string;
|
|
9
|
+
/** Path/URL to final `.zkey`. */
|
|
10
|
+
zkeyPath: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Progress callback for long-running prove steps.
|
|
14
|
+
*/
|
|
15
|
+
export type ProofProgressCallback = (stage: string, percent: number) => void;
|
|
16
|
+
/**
|
|
17
|
+
* Run `snarkjs.groth16.fullProve` on a prepared witness.
|
|
18
|
+
*
|
|
19
|
+
* @param witness - JSON object accepted by the Circom wasm.
|
|
20
|
+
* @param artifacts - Wasm + zkey locations (browser: serve static files; Node: file paths).
|
|
21
|
+
* @param onProgress - Optional UI hook.
|
|
22
|
+
*/
|
|
23
|
+
export declare function generateGroth16Proof(witness: CircuitWitness, artifacts: ArtifactPaths, onProgress?: ProofProgressCallback): Promise<ProofData>;
|
|
24
|
+
/**
|
|
25
|
+
* Verify a proof locally with snarkjs (development / diagnostics).
|
|
26
|
+
*
|
|
27
|
+
* @param proofData - Output of {@link generateGroth16Proof}.
|
|
28
|
+
* @param vkeyPath - Path/URL to verification key JSON from the trusted setup.
|
|
29
|
+
*/
|
|
30
|
+
export declare function verifyProofLocally(proofData: ProofData, vkeyPath: string): Promise<boolean>;
|
|
31
|
+
//# sourceMappingURL=prove.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prove.d.ts","sourceRoot":"","sources":["../src/prove.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAMnD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;AAE7E;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,cAAc,EACvB,SAAS,EAAE,aAAa,EACxB,UAAU,CAAC,EAAE,qBAAqB,GACjC,OAAO,CAAC,SAAS,CAAC,CAgCpB;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAOlB"}
|
package/dist/prove.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { ProofError } from "@opaquecash/psr-core";
|
|
2
|
+
/**
|
|
3
|
+
* Run `snarkjs.groth16.fullProve` on a prepared witness.
|
|
4
|
+
*
|
|
5
|
+
* @param witness - JSON object accepted by the Circom wasm.
|
|
6
|
+
* @param artifacts - Wasm + zkey locations (browser: serve static files; Node: file paths).
|
|
7
|
+
* @param onProgress - Optional UI hook.
|
|
8
|
+
*/
|
|
9
|
+
export async function generateGroth16Proof(witness, artifacts, onProgress) {
|
|
10
|
+
onProgress?.("generating-proof", 10);
|
|
11
|
+
const snarkjs = (await import("snarkjs")).groth16;
|
|
12
|
+
const { proof, publicSignals } = await snarkjs.fullProve(witness, artifacts.wasmPath, artifacts.zkeyPath);
|
|
13
|
+
onProgress?.("generating-proof", 90);
|
|
14
|
+
const nullifier = publicSignals[0];
|
|
15
|
+
const attestationIdFromProof = Number(publicSignals[3]);
|
|
16
|
+
const isValidSignal = String(publicSignals[1] ?? "0");
|
|
17
|
+
if (isValidSignal !== "1") {
|
|
18
|
+
throw new ProofError("Generated proof has is_valid≠1; witness does not satisfy the circuit.");
|
|
19
|
+
}
|
|
20
|
+
return {
|
|
21
|
+
proof: {
|
|
22
|
+
pi_a: proof.pi_a.slice(0, 2),
|
|
23
|
+
pi_b: proof.pi_b.slice(0, 2),
|
|
24
|
+
pi_c: proof.pi_c.slice(0, 2),
|
|
25
|
+
},
|
|
26
|
+
publicSignals,
|
|
27
|
+
nullifier,
|
|
28
|
+
attestationId: Number.isFinite(attestationIdFromProof)
|
|
29
|
+
? attestationIdFromProof
|
|
30
|
+
: Number(witness.attestation_id),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Verify a proof locally with snarkjs (development / diagnostics).
|
|
35
|
+
*
|
|
36
|
+
* @param proofData - Output of {@link generateGroth16Proof}.
|
|
37
|
+
* @param vkeyPath - Path/URL to verification key JSON from the trusted setup.
|
|
38
|
+
*/
|
|
39
|
+
export async function verifyProofLocally(proofData, vkeyPath) {
|
|
40
|
+
const snarkjs = (await import("snarkjs")).groth16;
|
|
41
|
+
return snarkjs.verify(vkeyPath, proofData.publicSignals, {
|
|
42
|
+
pi_a: proofData.proof.pi_a,
|
|
43
|
+
pi_b: proofData.proof.pi_b,
|
|
44
|
+
pi_c: proofData.proof.pi_c,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=prove.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prove.js","sourceRoot":"","sources":["../src/prove.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAsBlD;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,OAAuB,EACvB,SAAwB,EACxB,UAAkC;IAElC,UAAU,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAuB,CAAC;IAClE,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,MAAM,OAAO,CAAC,SAAS,CACtD,OAAO,EACP,SAAS,CAAC,QAAQ,EAClB,SAAS,CAAC,QAAQ,CACnB,CAAC;IACF,UAAU,EAAE,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;IAErC,MAAM,SAAS,GAAG,aAAa,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,sBAAsB,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IACxD,MAAM,aAAa,GAAG,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IAEtD,IAAI,aAAa,KAAK,GAAG,EAAE,CAAC;QAC1B,MAAM,IAAI,UAAU,CAClB,uEAAuE,CACxE,CAAC;IACJ,CAAC;IAED,OAAO;QACL,KAAK,EAAE;YACL,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5B,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5B,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SAC7B;QACD,aAAa;QACb,SAAS;QACT,aAAa,EAAE,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAC;YACpD,CAAC,CAAC,sBAAsB;YACxB,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC;KACnC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAoB,EACpB,QAAgB;IAEhB,MAAM,OAAO,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,OAAuB,CAAC;IAClE,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,aAAa,EAAE;QACvD,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI;QAC1B,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI;QAC1B,IAAI,EAAE,SAAS,CAAC,KAAK,CAAC,IAAI;KAC3B,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { StealthWasmModule } from "@opaquecash/stealth-wasm";
|
|
2
|
+
/**
|
|
3
|
+
* Ensure `Buffer` exists for `circomlibjs` in browser bundles.
|
|
4
|
+
*/
|
|
5
|
+
export declare function ensureBufferPolyfill(): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Circuit witness object matching `stealth_attestation` public/private input names (decimal string fields).
|
|
8
|
+
*/
|
|
9
|
+
export interface CircuitWitness {
|
|
10
|
+
merkle_root: string;
|
|
11
|
+
attestation_id: string;
|
|
12
|
+
external_nullifier: string;
|
|
13
|
+
stealth_private_key: string;
|
|
14
|
+
ephemeral_pubkey: [string, string];
|
|
15
|
+
announcement_attestation_id: string;
|
|
16
|
+
merkle_path_elements: string[];
|
|
17
|
+
merkle_path_indices: number[];
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build a **placeholder** Merkle witness using zero-hash siblings (matches Opaque wallet dev prover).
|
|
21
|
+
*
|
|
22
|
+
* For production you must align leaves with the same tree the verifier admin commits on-chain.
|
|
23
|
+
*
|
|
24
|
+
* @param traitAttestationId - Public attestation id to prove.
|
|
25
|
+
* @param stealthPrivKeyBytes - 32-byte reconstructed one-time stealth private key.
|
|
26
|
+
* @param externalNullifier - Decimal string or hex-compatible numeric string for the circuit scalar.
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildWitnessCircuitConsistent(traitAttestationId: number, stealthPrivKeyBytes: Uint8Array, externalNullifier: string): Promise<CircuitWitness>;
|
|
29
|
+
/**
|
|
30
|
+
* Delegate witness construction to Rust WASM (`generate_reputation_witness`) for full Merkle paths.
|
|
31
|
+
*
|
|
32
|
+
* @param wasm - Initialized `@opaquecash/stealth-wasm` module.
|
|
33
|
+
* @param attestationsJson - JSON array string from the scanner.
|
|
34
|
+
* @param targetTraitId - Decimal string attestation id to prove.
|
|
35
|
+
* @param stealthPrivkeyBytes - 32-byte one-time stealth private key.
|
|
36
|
+
* @param externalNullifier - Decimal string (must match {@link buildActionScope} encoding policy).
|
|
37
|
+
*/
|
|
38
|
+
export declare function buildWitnessFromWasm(wasm: StealthWasmModule, attestationsJson: string, targetTraitId: string, stealthPrivkeyBytes: Uint8Array, externalNullifier: string): CircuitWitness;
|
|
39
|
+
//# sourceMappingURL=witness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"witness.d.ts","sourceRoot":"","sources":["../src/witness.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAWlE;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CAK1D;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,gBAAgB,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,2BAA2B,EAAE,MAAM,CAAC;IACpC,oBAAoB,EAAE,MAAM,EAAE,CAAC;IAC/B,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED;;;;;;;;GAQG;AACH,wBAAsB,6BAA6B,CACjD,kBAAkB,EAAE,MAAM,EAC1B,mBAAmB,EAAE,UAAU,EAC/B,iBAAiB,EAAE,MAAM,GACxB,OAAO,CAAC,cAAc,CAAC,CA8DzB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,iBAAiB,EACvB,gBAAgB,EAAE,MAAM,EACxB,aAAa,EAAE,MAAM,EACrB,mBAAmB,EAAE,UAAU,EAC/B,iBAAiB,EAAE,MAAM,GACxB,cAAc,CAShB"}
|
package/dist/witness.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { Buffer } from "buffer";
|
|
2
|
+
import { generateReputationWitnessJson } from "@opaquecash/stealth-wasm";
|
|
3
|
+
const TREE_DEPTH = 20;
|
|
4
|
+
function bytesToBigInt(bytes) {
|
|
5
|
+
let result = 0n;
|
|
6
|
+
for (const b of bytes)
|
|
7
|
+
result = (result << 8n) + BigInt(b);
|
|
8
|
+
return result;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Ensure `Buffer` exists for `circomlibjs` in browser bundles.
|
|
12
|
+
*/
|
|
13
|
+
export async function ensureBufferPolyfill() {
|
|
14
|
+
if (typeof globalThis !== "undefined" && !("Buffer" in globalThis)) {
|
|
15
|
+
const g = globalThis;
|
|
16
|
+
g.Buffer = Buffer;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Build a **placeholder** Merkle witness using zero-hash siblings (matches Opaque wallet dev prover).
|
|
21
|
+
*
|
|
22
|
+
* For production you must align leaves with the same tree the verifier admin commits on-chain.
|
|
23
|
+
*
|
|
24
|
+
* @param traitAttestationId - Public attestation id to prove.
|
|
25
|
+
* @param stealthPrivKeyBytes - 32-byte reconstructed one-time stealth private key.
|
|
26
|
+
* @param externalNullifier - Decimal string or hex-compatible numeric string for the circuit scalar.
|
|
27
|
+
*/
|
|
28
|
+
export async function buildWitnessCircuitConsistent(traitAttestationId, stealthPrivKeyBytes, externalNullifier) {
|
|
29
|
+
await ensureBufferPolyfill();
|
|
30
|
+
const circomlib = await import("circomlibjs");
|
|
31
|
+
const poseidon = await circomlib.buildPoseidon();
|
|
32
|
+
const babyjub = await circomlib.buildBabyjub();
|
|
33
|
+
const F = poseidon.F;
|
|
34
|
+
const attestationId = BigInt(traitAttestationId);
|
|
35
|
+
const extNullifier = BigInt(externalNullifier);
|
|
36
|
+
const stealthPriv = F.toObject(F.e(bytesToBigInt(stealthPrivKeyBytes)));
|
|
37
|
+
const ephemeralPriv = F.toObject(F.e(stealthPriv + extNullifier + 1n));
|
|
38
|
+
const stealthPub = babyjub.mulPointEscalar(babyjub.Base8, stealthPriv);
|
|
39
|
+
const ephemeralPub = babyjub.mulPointEscalar(babyjub.Base8, ephemeralPriv);
|
|
40
|
+
const sharedSecret = babyjub.mulPointEscalar(ephemeralPub, stealthPriv);
|
|
41
|
+
const stealthPubX = F.toObject(stealthPub[0]);
|
|
42
|
+
const stealthPubY = F.toObject(stealthPub[1]);
|
|
43
|
+
const ephemeralPubX = F.toObject(ephemeralPub[0]);
|
|
44
|
+
const ephemeralPubY = F.toObject(ephemeralPub[1]);
|
|
45
|
+
const sharedX = F.toObject(sharedSecret[0]);
|
|
46
|
+
const sharedY = F.toObject(sharedSecret[1]);
|
|
47
|
+
const addressCommitment = F.toObject(poseidon([sharedX, sharedY, stealthPubX, stealthPubY]));
|
|
48
|
+
const leaf = F.toObject(poseidon([addressCommitment, attestationId]));
|
|
49
|
+
const zeroHashes = [];
|
|
50
|
+
zeroHashes.push(F.toObject(poseidon([0n, 0n])));
|
|
51
|
+
for (let i = 1; i < TREE_DEPTH; i++) {
|
|
52
|
+
zeroHashes.push(F.toObject(poseidon([zeroHashes[i - 1], zeroHashes[i - 1]])));
|
|
53
|
+
}
|
|
54
|
+
const merklePathElements = [];
|
|
55
|
+
const merklePathIndices = [];
|
|
56
|
+
let current = leaf;
|
|
57
|
+
for (let i = 0; i < TREE_DEPTH; i++) {
|
|
58
|
+
merklePathElements.push(zeroHashes[i].toString());
|
|
59
|
+
merklePathIndices.push(0);
|
|
60
|
+
current = F.toObject(poseidon([current, zeroHashes[i]]));
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
merkle_root: current.toString(),
|
|
64
|
+
attestation_id: attestationId.toString(),
|
|
65
|
+
external_nullifier: extNullifier.toString(),
|
|
66
|
+
stealth_private_key: stealthPriv.toString(),
|
|
67
|
+
ephemeral_pubkey: [ephemeralPubX.toString(), ephemeralPubY.toString()],
|
|
68
|
+
announcement_attestation_id: attestationId.toString(),
|
|
69
|
+
merkle_path_elements: merklePathElements,
|
|
70
|
+
merkle_path_indices: merklePathIndices,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Delegate witness construction to Rust WASM (`generate_reputation_witness`) for full Merkle paths.
|
|
75
|
+
*
|
|
76
|
+
* @param wasm - Initialized `@opaquecash/stealth-wasm` module.
|
|
77
|
+
* @param attestationsJson - JSON array string from the scanner.
|
|
78
|
+
* @param targetTraitId - Decimal string attestation id to prove.
|
|
79
|
+
* @param stealthPrivkeyBytes - 32-byte one-time stealth private key.
|
|
80
|
+
* @param externalNullifier - Decimal string (must match {@link buildActionScope} encoding policy).
|
|
81
|
+
*/
|
|
82
|
+
export function buildWitnessFromWasm(wasm, attestationsJson, targetTraitId, stealthPrivkeyBytes, externalNullifier) {
|
|
83
|
+
const json = generateReputationWitnessJson(wasm, attestationsJson, targetTraitId, stealthPrivkeyBytes, externalNullifier);
|
|
84
|
+
return JSON.parse(json);
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=witness.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"witness.js","sourceRoot":"","sources":["../src/witness.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@opaquecash/psr-prover",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Circom witness helpers and Groth16 proving (snarkjs) for PSR",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc -p tsconfig.json",
|
|
19
|
+
"clean": "rm -rf dist"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"@opaquecash/psr-core": "0.1.0",
|
|
23
|
+
"@opaquecash/stealth-wasm": "0.1.0",
|
|
24
|
+
"buffer": "^6.0.3",
|
|
25
|
+
"circomlibjs": "^0.1.7",
|
|
26
|
+
"snarkjs": "^0.7.5",
|
|
27
|
+
"viem": "^2.21.0"
|
|
28
|
+
},
|
|
29
|
+
"sideEffects": false
|
|
30
|
+
}
|