11 Commits

Author SHA1 Message Date
Daniel Tehrani
63f534a23a v2.3.0 2023-10-05 19:24:51 +09:00
Daniel Tehrani
4d7c3c73df feat: allow specifying using a remote circuit for the prover 2023-10-05 19:13:59 +09:00
Daniel Tehrani
baedc727fb v2.2.0 2023-09-21 14:58:58 +09:00
Daniel Tehrani
eeb704a7d1 feat: allow specifying using the remote circuit 2023-09-21 14:53:35 +09:00
Dan Tehrani
5dae5e1aa4 Update README.md 2023-06-24 00:34:04 +09:00
Daniel Tehrani
3386b30d9b v2.1.4 2023-05-29 12:17:16 +02:00
Daniel Tehrani
19e1ddd4ef Add method verifyProof to Tree 2023-05-29 12:14:23 +02:00
Daniel Tehrani
85fc788204 Remove multi threading config (not doing multi threading at this moment) 2023-05-26 16:01:57 +02:00
Daniel Tehrani
5fa21ec9c3 Commit lock file 2023-05-12 16:17:33 +02:00
Daniel Tehrani
f05b40e7f3 v2.1.3 2023-05-12 13:36:30 +02:00
Daniel Tehrani
adb73907fd Fix WebAssembly instantiation 2023-05-12 13:34:38 +02:00
16 changed files with 1578 additions and 172 deletions

View File

@@ -1,5 +1,5 @@
[target.wasm32-unknown-unknown]
rustflags = ["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals", "-C", "link-arg=--max-memory=4294967296"]
rustflags = ["-C", "link-arg=--max-memory=4294967296"]
[unstable]
build-std = ["panic_abort", "std"]

3
.gitignore vendored
View File

@@ -2,9 +2,6 @@
# will have compiled files and executables
/target/
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
Cargo.lock
# These are backup files generated by rustfmt
**/*.rs.bk

1398
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -61,7 +61,9 @@ git clone https://github.com/DanTehrani/circom-secq
cd circom-secq && cargo build --release && cargo install --path circom
```
2. Install dependencies & Build all packages
2. Install [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/)
4. Install dependencies & Build all packages
```jsx
yarn && yarn build

View File

@@ -8,7 +8,7 @@
},
"dependencies": {
"@ethereumjs/util": "^8.0.3",
"@personaelabs/spartan-ecdsa": "*"
"@personaelabs/spartan-ecdsa": "file:./../../lib"
},
"devDependencies": {
"ts-node": "^10.9.1",

View File

@@ -9,7 +9,7 @@
"lint": "next lint"
},
"dependencies": {
"@personaelabs/spartan-ecdsa": "*",
"@personaelabs/spartan-ecdsa": "file:./../../lib",
"@ethereumjs/util": "^8.0.3",
"comlink": "^4.3.1",
"elliptic": "^6.5.4",

View File

@@ -1,6 +1,6 @@
{
"name": "@personaelabs/spartan-ecdsa",
"version": "2.1.2",
"version": "2.3.0",
"main": "./build/lib.js",
"types": "./build/lib.d.ts",
"license": "MIT",

View File

@@ -18,6 +18,7 @@ import {
export class MembershipProver extends Profiler implements IProver {
circuit: string;
witnessGenWasm: string;
useRemoteCircuit: boolean;
constructor(options: ProverConfig) {
super({ enabled: options?.enableProfiler });
@@ -37,21 +38,9 @@ export class MembershipProver extends Profiler implements IProver {
`);
}
const isNode = typeof window === "undefined";
if (isNode) {
if (
options.circuit.includes("http") ||
options.witnessGenWasm.includes("http")
) {
throw new Error(
`An URL was given for circuit/witnessGenWasm in Node.js environment. Please specify a local path.
`
);
}
}
this.circuit = options.circuit;
this.witnessGenWasm = options.witnessGenWasm;
this.useRemoteCircuit = options.useRemoteCircuit ?? false;
}
async initWasm() {
@@ -90,7 +79,9 @@ export class MembershipProver extends Profiler implements IProver {
this.timeEnd("Generate witness");
this.time("Load circuit");
const circuitBin = await loadCircuit(this.circuit);
const useRemoteCircuit =
this.useRemoteCircuit ?? typeof window !== "undefined";
const circuitBin = await loadCircuit(this.circuit, useRemoteCircuit);
this.timeEnd("Load circuit");
// Get the public input in bytes

View File

@@ -13,6 +13,7 @@ import { PublicInput, verifyEffEcdsaPubInput } from "../helpers/public_input";
*/
export class MembershipVerifier extends Profiler implements IVerifier {
circuit: string;
useRemoteCircuit: boolean;
constructor(options: VerifyConfig) {
super({ enabled: options?.enableProfiler });
@@ -30,6 +31,8 @@ export class MembershipVerifier extends Profiler implements IVerifier {
}
this.circuit = options.circuit;
this.useRemoteCircuit =
options.useRemoteCircuit ?? typeof window !== "undefined";
}
async initWasm() {
@@ -41,7 +44,7 @@ export class MembershipVerifier extends Profiler implements IVerifier {
publicInputSer: Uint8Array
): Promise<boolean> {
this.time("Load circuit");
const circuitBin = await loadCircuit(this.circuit);
const circuitBin = await loadCircuit(this.circuit, this.useRemoteCircuit);
this.timeEnd("Load circuit");
this.time("Verify public input");

View File

@@ -1,7 +1,6 @@
import { IncrementalMerkleTree } from "@zk-kit/incremental-merkle-tree";
import { Poseidon } from "./poseidon";
import { MerkleProof } from "../types";
import { bytesToBigInt } from "./utils";
export class Tree {
depth: number;
@@ -38,17 +37,14 @@ export class Tree {
createProof(index: number): MerkleProof {
const proof = this.treeInner.createProof(index);
const siblings = proof.siblings.map(s =>
typeof s[0] === "bigint" ? s : bytesToBigInt(s[0])
);
return {
siblings,
siblings: proof.siblings,
pathIndices: proof.pathIndices,
root: proof.root
};
}
// TODO: Add more functions that expose the IncrementalMerkleTree API
verifyProof(proof: MerkleProof, leaf: bigint): boolean {
return this.treeInner.verifyProof({ ...proof, leaf });
}
}

View File

@@ -18,9 +18,8 @@ export const snarkJsWitnessGen = async (input: any, wasmFile: string) => {
/**
* Load a circuit from a file or URL
*/
export const loadCircuit = async (pathOrUrl: string): Promise<Uint8Array> => {
const isWeb = typeof window !== "undefined";
if (isWeb) {
export const loadCircuit = async (pathOrUrl: string, useRemoteCircuit: boolean): Promise<Uint8Array> => {
if (useRemoteCircuit) {
return await fetchCircuit(pathOrUrl);
} else {
return await readCircuitFromFs(pathOrUrl);

View File

@@ -5,7 +5,7 @@ import { PublicInput } from "./helpers/public_input";
// library users can choose whatever merkle tree management method they want.
export interface MerkleProof {
root: bigint;
siblings: bigint[];
siblings: [bigint][];
pathIndices: number[];
}
export interface EffECDSAPubInput {
@@ -24,11 +24,13 @@ export interface ProverConfig {
witnessGenWasm: string;
circuit: string;
enableProfiler?: boolean;
useRemoteCircuit?: boolean;
}
export interface VerifyConfig {
circuit: string; // Path to circuit file compiled by Nova-Scotia
enableProfiler?: boolean;
useRemoteCircuit?: boolean;
}
export interface IProver {

View File

@@ -1,99 +1,60 @@
/* tslint:disable */
/* eslint-disable */
/**
*/
*/
export function init_panic_hook(): void;
/**
* @param {Uint8Array} circuit
* @param {Uint8Array} vars
* @param {Uint8Array} public_inputs
* @returns {Uint8Array}
*/
export function prove(
circuit: Uint8Array,
vars: Uint8Array,
public_inputs: Uint8Array
): Uint8Array;
* @param {Uint8Array} circuit
* @param {Uint8Array} vars
* @param {Uint8Array} public_inputs
* @returns {Uint8Array}
*/
export function prove(circuit: Uint8Array, vars: Uint8Array, public_inputs: Uint8Array): Uint8Array;
/**
* @param {Uint8Array} circuit
* @param {Uint8Array} proof
* @param {Uint8Array} public_input
* @returns {boolean}
*/
export function verify(
circuit: Uint8Array,
proof: Uint8Array,
public_input: Uint8Array
): boolean;
* @param {Uint8Array} circuit
* @param {Uint8Array} proof
* @param {Uint8Array} public_input
* @returns {boolean}
*/
export function verify(circuit: Uint8Array, proof: Uint8Array, public_input: Uint8Array): boolean;
/**
* @param {Uint8Array} input_bytes
* @returns {Uint8Array}
*/
* @param {Uint8Array} input_bytes
* @returns {Uint8Array}
*/
export function poseidon(input_bytes: Uint8Array): Uint8Array;
export type InitInput =
| RequestInfo
| URL
| Response
| BufferSource
| WebAssembly.Module;
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
export interface InitOutput {
readonly prove: (
a: number,
b: number,
c: number,
d: number,
e: number,
f: number,
g: number
) => void;
readonly verify: (
a: number,
b: number,
c: number,
d: number,
e: number,
f: number,
g: number
) => void;
readonly memory: WebAssembly.Memory;
readonly prove: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
readonly verify: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
readonly poseidon: (a: number, b: number, c: number) => void;
readonly init_panic_hook: () => void;
readonly memory: WebAssembly.Memory;
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
readonly __wbindgen_malloc: (a: number) => number;
readonly __wbindgen_free: (a: number, b: number) => void;
readonly __wbindgen_exn_store: (a: number) => void;
readonly __wbindgen_realloc: (a: number, b: number, c: number) => number;
readonly __wbindgen_thread_destroy: (a: number, b: number) => void;
readonly __wbindgen_start: () => void;
}
export type SyncInitInput = BufferSource | WebAssembly.Module;
/**
* Instantiates the given `module`, which can either be bytes or
* a precompiled `WebAssembly.Module`.
*
* @param {SyncInitInput} module
* @param {WebAssembly.Memory} maybe_memory
*
* @returns {InitOutput}
*/
export function initSync(
module: SyncInitInput,
maybe_memory?: WebAssembly.Memory
): InitOutput;
* Instantiates the given `module`, which can either be bytes or
* a precompiled `WebAssembly.Module`.
*
* @param {SyncInitInput} module
*
* @returns {InitOutput}
*/
export function initSync(module: SyncInitInput): InitOutput;
/**
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
* for everything else, calls `WebAssembly.instantiate` directly.
*
* @param {InitInput | Promise<InitInput>} module_or_path
* @param {WebAssembly.Memory} maybe_memory
*
* @returns {Promise<InitOutput>}
*/
export default function init(
module_or_path?: InitInput | Promise<InitInput>,
maybe_memory?: WebAssembly.Memory
): Promise<InitOutput>;
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
* for everything else, calls `WebAssembly.instantiate` directly.
*
* @param {InitInput | Promise<InitInput>} module_or_path
* @param {WebAssembly.Memory} maybe_memory
*
* @returns {Promise<InitOutput>}
*/
export default function __wbg_init (module_or_path?: InitInput | Promise<InitInput>, maybe_memory?: WebAssembly.Memory): Promise<InitOutput>;

View File

@@ -20,21 +20,22 @@ function takeObject(idx) {
return ret;
}
const cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } );
cachedTextDecoder.decode();
if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); };
let cachedUint8Memory0 = null;
function getUint8Memory0() {
if (cachedUint8Memory0 === null || cachedUint8Memory0.buffer !== wasm.memory.buffer) {
if (cachedUint8Memory0 === null || cachedUint8Memory0.byteLength === 0) {
cachedUint8Memory0 = new Uint8Array(wasm.memory.buffer);
}
return cachedUint8Memory0;
}
function getStringFromWasm0(ptr, len) {
return cachedTextDecoder.decode(getUint8Memory0().slice(ptr, ptr + len));
ptr = ptr >>> 0;
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
}
function addHeapObject(obj) {
@@ -54,7 +55,7 @@ export function init_panic_hook() {
let WASM_VECTOR_LEN = 0;
function passArray8ToWasm0(arg, malloc) {
const ptr = malloc(arg.length * 1);
const ptr = malloc(arg.length * 1) >>> 0;
getUint8Memory0().set(arg, ptr / 1);
WASM_VECTOR_LEN = arg.length;
return ptr;
@@ -63,13 +64,14 @@ function passArray8ToWasm0(arg, malloc) {
let cachedInt32Memory0 = null;
function getInt32Memory0() {
if (cachedInt32Memory0 === null || cachedInt32Memory0.buffer !== wasm.memory.buffer) {
if (cachedInt32Memory0 === null || cachedInt32Memory0.byteLength === 0) {
cachedInt32Memory0 = new Int32Array(wasm.memory.buffer);
}
return cachedInt32Memory0;
}
function getArrayU8FromWasm0(ptr, len) {
ptr = ptr >>> 0;
return getUint8Memory0().subarray(ptr / 1, ptr / 1 + len);
}
/**
@@ -95,9 +97,9 @@ export function prove(circuit, vars, public_inputs) {
if (r3) {
throw takeObject(r2);
}
var v3 = getArrayU8FromWasm0(r0, r1).slice();
var v4 = getArrayU8FromWasm0(r0, r1).slice();
wasm.__wbindgen_free(r0, r1 * 1);
return v3;
return v4;
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
}
@@ -148,9 +150,9 @@ export function poseidon(input_bytes) {
if (r3) {
throw takeObject(r2);
}
var v1 = getArrayU8FromWasm0(r0, r1).slice();
var v2 = getArrayU8FromWasm0(r0, r1).slice();
wasm.__wbindgen_free(r0, r1 * 1);
return v1;
return v2;
} finally {
wasm.__wbindgen_add_to_stack_pointer(16);
}
@@ -164,29 +166,33 @@ function handleError(f, args) {
}
}
const cachedTextEncoder = new TextEncoder('utf-8');
const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } );
const encodeString = function (arg, view) {
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
? function (arg, view) {
return cachedTextEncoder.encodeInto(arg, view);
}
: function (arg, view) {
const buf = cachedTextEncoder.encode(arg);
view.set(buf);
return {
read: arg.length,
written: buf.length
};
};
});
function passStringToWasm0(arg, malloc, realloc) {
if (realloc === undefined) {
const buf = cachedTextEncoder.encode(arg);
const ptr = malloc(buf.length);
const ptr = malloc(buf.length) >>> 0;
getUint8Memory0().subarray(ptr, ptr + buf.length).set(buf);
WASM_VECTOR_LEN = buf.length;
return ptr;
}
let len = arg.length;
let ptr = malloc(len);
let ptr = malloc(len) >>> 0;
const mem = getUint8Memory0();
@@ -202,7 +208,7 @@ function passStringToWasm0(arg, malloc, realloc) {
if (offset !== 0) {
arg = arg.slice(offset);
}
ptr = realloc(ptr, len, len = offset + arg.length * 3);
ptr = realloc(ptr, len, len = offset + arg.length * 3) >>> 0;
const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
const ret = encodeString(arg, view);
@@ -213,7 +219,7 @@ function passStringToWasm0(arg, malloc, realloc) {
return ptr;
}
async function load(module, imports) {
async function __wbg_load(module, imports) {
if (typeof Response === 'function' && module instanceof Response) {
if (typeof WebAssembly.instantiateStreaming === 'function') {
try {
@@ -244,18 +250,9 @@ async function load(module, imports) {
}
}
function getImports() {
function __wbg_get_imports() {
const imports = {};
imports.wbg = {};
imports.wbg.__wbg_getRandomValues_3774744e221a22ad = function() { return handleError(function (arg0, arg1) {
getObject(arg0).getRandomValues(getObject(arg1));
}, arguments) };
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};
imports.wbg.__wbg_randomFillSync_e950366c42764a07 = function() { return handleError(function (arg0, arg1) {
getObject(arg0).randomFillSync(takeObject(arg1));
}, arguments) };
imports.wbg.__wbg_crypto_70a96de3b6b73dac = function(arg0) {
const ret = getObject(arg0).crypto;
return addHeapObject(ret);
@@ -281,6 +278,9 @@ function getImports() {
const ret = typeof(getObject(arg0)) === 'string';
return ret;
};
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};
imports.wbg.__wbg_msCrypto_adbc770ec9eca9c7 = function(arg0) {
const ret = getObject(arg0).msCrypto;
return addHeapObject(ret);
@@ -297,11 +297,17 @@ function getImports() {
const ret = getStringFromWasm0(arg0, arg1);
return addHeapObject(ret);
};
imports.wbg.__wbg_newnoargs_2b8b6bd7753c76ba = function(arg0, arg1) {
imports.wbg.__wbg_getRandomValues_3774744e221a22ad = function() { return handleError(function (arg0, arg1) {
getObject(arg0).getRandomValues(getObject(arg1));
}, arguments) };
imports.wbg.__wbg_randomFillSync_e950366c42764a07 = function() { return handleError(function (arg0, arg1) {
getObject(arg0).randomFillSync(takeObject(arg1));
}, arguments) };
imports.wbg.__wbg_newnoargs_e643855c6572a4a8 = function(arg0, arg1) {
const ret = new Function(getStringFromWasm0(arg0, arg1));
return addHeapObject(ret);
};
imports.wbg.__wbg_call_95d1ea488d03e4e8 = function() { return handleError(function (arg0, arg1) {
imports.wbg.__wbg_call_f96b398515635514 = function() { return handleError(function (arg0, arg1) {
const ret = getObject(arg0).call(getObject(arg1));
return addHeapObject(ret);
}, arguments) };
@@ -309,19 +315,19 @@ function getImports() {
const ret = getObject(arg0);
return addHeapObject(ret);
};
imports.wbg.__wbg_self_e7c1f827057f6584 = function() { return handleError(function () {
imports.wbg.__wbg_self_b9aad7f1c618bfaf = function() { return handleError(function () {
const ret = self.self;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_window_a09ec664e14b1b81 = function() { return handleError(function () {
imports.wbg.__wbg_window_55e469842c98b086 = function() { return handleError(function () {
const ret = window.window;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_globalThis_87cbb8506fecf3a9 = function() { return handleError(function () {
imports.wbg.__wbg_globalThis_d0957e302752547e = function() { return handleError(function () {
const ret = globalThis.globalThis;
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_global_c85a9259e621f3db = function() { return handleError(function () {
imports.wbg.__wbg_global_ae2f87312b8987fb = function() { return handleError(function () {
const ret = global.global;
return addHeapObject(ret);
}, arguments) };
@@ -329,30 +335,30 @@ function getImports() {
const ret = getObject(arg0) === undefined;
return ret;
};
imports.wbg.__wbg_call_9495de66fdbe016b = function() { return handleError(function (arg0, arg1, arg2) {
imports.wbg.__wbg_call_35782e9a1aa5e091 = function() { return handleError(function (arg0, arg1, arg2) {
const ret = getObject(arg0).call(getObject(arg1), getObject(arg2));
return addHeapObject(ret);
}, arguments) };
imports.wbg.__wbg_buffer_cf65c07de34b9a08 = function(arg0) {
imports.wbg.__wbg_buffer_fcbfb6d88b2732e9 = function(arg0) {
const ret = getObject(arg0).buffer;
return addHeapObject(ret);
};
imports.wbg.__wbg_newwithbyteoffsetandlength_9fb2f11355ecadf5 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_newwithbyteoffsetandlength_92c251989c485785 = function(arg0, arg1, arg2) {
const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
return addHeapObject(ret);
};
imports.wbg.__wbg_new_537b7341ce90bb31 = function(arg0) {
imports.wbg.__wbg_new_bc5d9aad3f9ac80e = function(arg0) {
const ret = new Uint8Array(getObject(arg0));
return addHeapObject(ret);
};
imports.wbg.__wbg_set_17499e8aa4003ebd = function(arg0, arg1, arg2) {
imports.wbg.__wbg_set_4b3aa8445ac1e91c = function(arg0, arg1, arg2) {
getObject(arg0).set(getObject(arg1), arg2 >>> 0);
};
imports.wbg.__wbg_newwithlength_b56c882b57805732 = function(arg0) {
imports.wbg.__wbg_newwithlength_89eca18f2603a999 = function(arg0) {
const ret = new Uint8Array(arg0 >>> 0);
return addHeapObject(ret);
};
imports.wbg.__wbg_subarray_7526649b91a252a6 = function(arg0, arg1, arg2) {
imports.wbg.__wbg_subarray_7649d027b2b141b3 = function(arg0, arg1, arg2) {
const ret = getObject(arg0).subarray(arg1 >>> 0, arg2 >>> 0);
return addHeapObject(ret);
};
@@ -362,16 +368,20 @@ function getImports() {
};
imports.wbg.__wbg_stack_658279fe44541cf6 = function(arg0, arg1) {
const ret = getObject(arg1).stack;
const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len0 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len0;
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
const len1 = WASM_VECTOR_LEN;
getInt32Memory0()[arg0 / 4 + 1] = len1;
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
};
imports.wbg.__wbg_error_f851667af71bcfc6 = function(arg0, arg1) {
let deferred0_0;
let deferred0_1;
try {
deferred0_0 = arg0;
deferred0_1 = arg1;
console.error(getStringFromWasm0(arg0, arg1));
} finally {
wasm.__wbindgen_free(arg0, arg1);
wasm.__wbindgen_free(deferred0_0, deferred0_1);
}
};
imports.wbg.__wbindgen_throw = function(arg0, arg1) {
@@ -385,52 +395,60 @@ function getImports() {
return imports;
}
function initMemory(imports, maybe_memory) {
imports.wbg.memory = maybe_memory || new WebAssembly.Memory({initial:18,maximum:65536,shared:true});
function __wbg_init_memory(imports, maybe_memory) {
}
function finalizeInit(instance, module) {
function __wbg_finalize_init(instance, module) {
wasm = instance.exports;
init.__wbindgen_wasm_module = module;
__wbg_init.__wbindgen_wasm_module = module;
cachedInt32Memory0 = null;
cachedUint8Memory0 = null;
wasm.__wbindgen_start();
return wasm;
}
function initSync(module, maybe_memory) {
const imports = getImports();
async function initSync(module, maybe_memory) {
if (wasm !== undefined) return wasm;
initMemory(imports, maybe_memory);
const imports = __wbg_get_imports();
__wbg_init_memory(imports, maybe_memory);
/*
if (!(module instanceof WebAssembly.Module)) {
module = new WebAssembly.Module(module);
}
*/
const compiled = WebAssembly.compile(module);
const instance = new WebAssembly.Instance(module, imports);
const instance = await WebAssembly.instantiate(await compiled, imports);
return finalizeInit(instance, module);
return __wbg_finalize_init(instance, module);
}
async function init(input, maybe_memory) {
async function __wbg_init(input, maybe_memory) {
if (wasm !== undefined) return wasm;
/*
if (typeof input === 'undefined') {
input = new URL('spartan_wasm_bg.wasm', import.meta.url);
}
*/
const imports = getImports();
const imports = __wbg_get_imports();
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
input = fetch(input);
}
initMemory(imports, maybe_memory);
__wbg_init_memory(imports, maybe_memory);
const { instance, module } = await load(await input, imports);
const { instance, module } = await __wbg_load(await input, imports);
return finalizeInit(instance, module);
return __wbg_finalize_init(instance, module);
}
export { initSync }
export default init;
export default __wbg_init;

View File

@@ -0,0 +1,31 @@
import { Tree, Poseidon } from "../src/lib";
describe("Merkle tree prove and verify", () => {
let poseidon: Poseidon;
let tree: Tree;
const members = new Array(10).fill(0).map((_, i) => BigInt(i));
beforeAll(async () => {
// Init Poseidon
poseidon = new Poseidon();
await poseidon.initWasm();
const treeDepth = 20;
tree = new Tree(treeDepth, poseidon);
for (const member of members) {
tree.insert(member);
}
});
it("should prove and verify a valid Merkle proof", async () => {
const proof = tree.createProof(0);
expect(tree.verifyProof(proof, members[0])).toBe(true);
});
it("should assert an invalid Merkle proof", async () => {
const proof = tree.createProof(0);
proof.siblings[0][0] = proof.siblings[0][0] += BigInt(1);
expect(tree.verifyProof(proof, members[0])).toBe(false);
proof.siblings[0][0] = proof.siblings[0][0] -= BigInt(1);
});
});

View File

@@ -2057,6 +2057,14 @@
node-addon-api "^3.2.1"
node-gyp-build "^4.3.0"
"@personaelabs/spartan-ecdsa@file:./packages/lib":
version "2.1.2"
dependencies:
"@ethereumjs/util" "^8.0.3"
"@zk-kit/incremental-merkle-tree" "^1.0.0"
elliptic "^6.5.4"
snarkjs "^0.5.0"
"@phenomnomnominal/tsquery@4.1.1":
version "4.1.1"
resolved "https://registry.npmjs.org/@phenomnomnominal/tsquery/-/tsquery-4.1.1.tgz"