mirror of
https://github.com/personaelabs/spartan-ecdsa.git
synced 2026-01-11 06:57:53 -05:00
Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3386b30d9b | ||
|
|
19e1ddd4ef | ||
|
|
85fc788204 |
@@ -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"]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@personaelabs/spartan-ecdsa",
|
||||
"version": "2.1.3",
|
||||
"version": "2.1.4",
|
||||
"main": "./build/lib.js",
|
||||
"types": "./build/lib.d.ts",
|
||||
"license": "MIT",
|
||||
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
8
packages/lib/src/wasm/wasm.d.ts
vendored
8
packages/lib/src/wasm/wasm.d.ts
vendored
@@ -26,18 +26,16 @@ export function poseidon(input_bytes: Uint8Array): Uint8Array;
|
||||
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||
|
||||
export interface InitOutput {
|
||||
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;
|
||||
@@ -46,12 +44,10 @@ export type SyncInitInput = BufferSource | WebAssembly.Module;
|
||||
* a precompiled `WebAssembly.Module`.
|
||||
*
|
||||
* @param {SyncInitInput} module
|
||||
* @param {WebAssembly.Memory} maybe_memory
|
||||
*
|
||||
* @returns {InitOutput}
|
||||
*/
|
||||
export function initSync(module: SyncInitInput, maybe_memory?: WebAssembly.Memory): 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.
|
||||
|
||||
@@ -27,7 +27,7 @@ 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;
|
||||
@@ -35,7 +35,7 @@ function getUint8Memory0() {
|
||||
|
||||
function getStringFromWasm0(ptr, len) {
|
||||
ptr = ptr >>> 0;
|
||||
return cachedTextDecoder.decode(getUint8Memory0().slice(ptr, ptr + len));
|
||||
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
||||
}
|
||||
|
||||
function addHeapObject(obj) {
|
||||
@@ -64,7 +64,7 @@ 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;
|
||||
@@ -168,14 +168,18 @@ function handleError(f, args) {
|
||||
|
||||
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) {
|
||||
|
||||
@@ -392,7 +396,7 @@ function __wbg_get_imports() {
|
||||
}
|
||||
|
||||
function __wbg_init_memory(imports, maybe_memory) {
|
||||
imports.wbg.memory = maybe_memory || new WebAssembly.Memory({initial:18,maximum:65536,shared:true});
|
||||
|
||||
}
|
||||
|
||||
function __wbg_finalize_init(instance, module) {
|
||||
@@ -401,7 +405,7 @@ function __wbg_finalize_init(instance, module) {
|
||||
cachedInt32Memory0 = null;
|
||||
cachedUint8Memory0 = null;
|
||||
|
||||
wasm.__wbindgen_start();
|
||||
|
||||
return wasm;
|
||||
}
|
||||
|
||||
|
||||
31
packages/lib/tests/tree.test.ts
Normal file
31
packages/lib/tests/tree.test.ts
Normal 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);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user