28 Commits
v2.1.0 ... main

Author SHA1 Message Date
Daniel Tehrani
4bf236a1a5 Merge pull request #45 from 0xisk/main
refactor: minor enhancements on the lib package
2023-12-05 14:12:43 -08:00
Daniel Tehrani
ede2b29cac fix: use tsconfig.build.json so vscode can annotate test files as well 2023-12-02 08:45:37 +09:00
0xisk
cb273002c0 refactor: destructure params, update package metadata, enhance file naming and structure. 2023-11-29 20:41:48 +01:00
Daniel Tehrani
a08876d1ff Merge pull request #44 from 0xisk/main
chore: refactor lib package exports to named for clarity
2023-11-25 13:42:03 +09:00
isk
8b0529f868 chore: refactor lib exports to named for clarity 2023-11-24 11:40:18 +01:00
Daniel Tehrani
3827e5de67 v2.3.1 2023-10-11 16:33:48 +09:00
Daniel Tehrani
53049c8cbe fix: this lead to the unintentional breaking change 2023-10-11 16:32:19 +09:00
Daniel Tehrani
2fab170a15 Merge pull request #41 from AtHeartEngineer/patch-1
Update package.json
2023-10-11 11:27:15 +09:00
Daniel Tehrani
82518aabc3 Remove unused snarkjs installations 2023-10-11 11:22:57 +09:00
Daniel Tehrani
e8c95a975b Update yarn.lock 2023-10-11 11:10:44 +09:00
AtHeartEngineer
4cf4b36efd Update package.json
Bump snarkjs version to get rid of vulnerability warning, even though it doesn't effect this project since spartan-ecdsa is only using the witness generation
2023-10-10 21:18:56 -04:00
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
Daniel Tehrani
86338b7d4d v2.1.2 2023-05-05 13:28:48 +02:00
Daniel Tehrani
4b8acc430d feat: use lazy_static to load the constants 2023-05-05 12:49:40 +02:00
Daniel Tehrani
4d72a30b63 feat: only allow two inputs 2023-05-05 12:48:59 +02:00
Dan Tehrani
ebf2b5f6cc Update README.md 2023-04-30 11:02:21 +02:00
Daniel Tehrani
9da3bb96ab v2.1.1 2023-04-24 11:01:47 +02:00
Daniel Tehrani
84a54098b5 Fix the javascript wasm compile 2023-04-24 11:01:29 +02:00
36 changed files with 2126 additions and 582 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"]

6
.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
@@ -26,6 +23,7 @@ circom_witness.wtns
*.ptau
build/
dist/
*.r1cs
*.sym
@@ -36,7 +34,7 @@ packages/prover/test_circuit/test_circuit_js/
packages/prover/test_circuit/*.json
wasm_bytes.ts
wasmBytes.ts
**/sage/*.sage.py
packages/lib/src/circuits/

1398
Cargo.lock generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -53,7 +53,17 @@ yarn add @personaelabs/spartan-ecdsa
v18 or later
### Install dependencies & Build all packages
### Build
1. Install Circom with secq256k1 support
```
git clone https://github.com/DanTehrani/circom-secq
cd circom-secq && cargo build --release && cargo install --path circom
```
2. Install [wasm-pack](https://rustwasm.github.io/wasm-pack/installer/)
4. Install dependencies & Build all packages
```jsx
yarn && yarn build

View File

@@ -16,8 +16,7 @@
"eslint-plugin-react": "7.32.1",
"eslint-plugin-react-hooks": "4.6.0",
"eslint-plugin-security": "1.7.0",
"lerna": "^6.4.0",
"snarkjs": "^0.5.0"
"lerna": "^6.4.0"
},
"workspaces": [
"packages/lib",

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",
@@ -17,8 +17,7 @@
"next": "13.0.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"readline": "^1.3.0",
"snarkjs": "^0.5.0"
"readline": "^1.3.0"
},
"devDependencies": {
"@types/node": "18.11.7",

View File

@@ -12,7 +12,7 @@ const embedWasmBytes = async () => {
export const wasmBytes = new Uint8Array([${bytes.toString()}]);
`;
fs.writeFileSync("./src/wasm/wasm_bytes.ts", file);
fs.writeFileSync("./src/wasm/wasmBytes.ts", file);
};
embedWasmBytes();

View File

@@ -3,7 +3,10 @@ module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
transform: {
"^.+\\.js?$": "ts-jest"
"^.+\\.(ts|js)?$": "ts-jest"
},
moduleNameMapper: {
"@src/(.*)$": "<rootDir>/src/$1",
},
testTimeout: 600000,
};

View File

@@ -1,17 +1,32 @@
{
"name": "@personaelabs/spartan-ecdsa",
"version": "2.1.0",
"main": "./build/lib.js",
"types": "./build/lib.d.ts",
"version": "2.3.1",
"description": "Spartan-ecdsa (which to our knowledge) is the fastest open-source method to verify ECDSA (secp256k1) signatures in zero-knowledge.",
"keywords": [
"spartan",
"spartan-ecdsa",
"zk",
"efficient-ecdsa"
],
"author": "Personae Labs",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"license": "MIT",
"bugs": {
"url": "https://github.com/personaelabs/spartan-ecdsa/issues/new"
},
"homepage": "https://github.com/personaelabs/spartan-ecdsa",
"publishConfig": {
"access": "public"
},
"files": [
"build/**/*"
"dist/**/*"
],
"scripts": {
"build": "rm -rf ./build && yarn embedWasmBytes && tsc",
"build": "rm -rf ./dist && yarn embedWasmBytes && tsc --project tsconfig.build.json",
"prepublishOnly": "yarn build",
"prepare": "yarn embedWasmBytes",
"embedWasmBytes": "ts-node ./embed_wasm_bytes.ts",
"embedWasmBytes": "ts-node ./embedWasmBytes.ts",
"test": "jest"
},
"devDependencies": {
@@ -25,6 +40,6 @@
"@ethereumjs/util": "^8.0.3",
"@zk-kit/incremental-merkle-tree": "^1.0.0",
"elliptic": "^6.5.4",
"snarkjs": "^0.5.0"
"snarkjs": "^0.7.1"
}
}
}

View File

@@ -1,25 +0,0 @@
import { ProverConfig, VerifyConfig } from "./types";
// Default configs for pubkey membership proving/verifying
export const defaultPubkeyMembershipPConfig: ProverConfig = {
witnessGenWasm:
"https://storage.googleapis.com/personae-proving-keys/membership/pubkey_membership.wasm",
circuit:
"https://storage.googleapis.com/personae-proving-keys/membership/pubkey_membership.circuit"
};
export const defaultPubkeyMembershipVConfig: VerifyConfig = {
circuit: defaultPubkeyMembershipPConfig.circuit
};
// Default configs for address membership proving/verifyign
export const defaultAddressMembershipPConfig: ProverConfig = {
witnessGenWasm:
"https://storage.googleapis.com/personae-proving-keys/membership/addr_membership.wasm",
circuit:
"https://storage.googleapis.com/personae-proving-keys/membership/addr_membership.circuit"
};
export const defaultAddressMembershipVConfig: VerifyConfig = {
circuit: defaultAddressMembershipPConfig.circuit
};

View File

@@ -0,0 +1,25 @@
import { ProverConfig, VerifyConfig } from "@src/types";
// Default configs for pubkey membership proving/verifying
export const defaultPubkeyProverConfig: ProverConfig = {
witnessGenWasm:
"https://storage.googleapis.com/personae-proving-keys/membership/pubkey_membership.wasm",
circuit:
"https://storage.googleapis.com/personae-proving-keys/membership/pubkey_membership.circuit"
};
export const defaultPubkeyVerifierConfig: VerifyConfig = {
circuit: defaultPubkeyProverConfig.circuit
};
// Default configs for address membership proving/verifyign
export const defaultAddressProverConfig: ProverConfig = {
witnessGenWasm:
"https://storage.googleapis.com/personae-proving-keys/membership/addr_membership.wasm",
circuit:
"https://storage.googleapis.com/personae-proving-keys/membership/addr_membership.circuit"
};
export const defaultAddressVerifierConfig: VerifyConfig = {
circuit: defaultAddressProverConfig.circuit
};

View File

@@ -1,16 +1,16 @@
import { Profiler } from "../helpers/profiler";
import { IProver, MerkleProof, NIZK, ProverConfig } from "../types";
import { loadCircuit, fromSig, snarkJsWitnessGen } from "../helpers/utils";
import { Profiler } from "@src/helpers/profiler";
import { IProver, MerkleProof, NIZK, ProveArgs, ProverConfig } from "@src/types";
import { loadCircuit, fromSig, snarkJsWitnessGen } from "@src/helpers/utils";
import {
PublicInput,
computeEffEcdsaPubInput,
CircuitPubInput
} from "../helpers/public_input";
import wasm, { init } from "../wasm";
} from "@src/helpers/publicInputs";
import { init, wasm } from "@src/wasm";
import {
defaultPubkeyMembershipPConfig,
defaultAddressMembershipPConfig
} from "../config";
defaultPubkeyProverConfig,
defaultAddressProverConfig
} from "@src/config";
/**
* ECDSA Membership Prover
@@ -18,16 +18,22 @@ import {
export class MembershipProver extends Profiler implements IProver {
circuit: string;
witnessGenWasm: string;
useRemoteCircuit: boolean;
constructor(options: ProverConfig) {
super({ enabled: options?.enableProfiler });
constructor({
enableProfiler,
circuit,
witnessGenWasm,
useRemoteCircuit
}: ProverConfig) {
super({ enabled: enableProfiler });
if (
options.circuit === defaultPubkeyMembershipPConfig.circuit ||
options.witnessGenWasm ===
defaultPubkeyMembershipPConfig.witnessGenWasm ||
options.circuit === defaultAddressMembershipPConfig.circuit ||
options.witnessGenWasm === defaultAddressMembershipPConfig.witnessGenWasm
circuit === defaultPubkeyProverConfig.circuit ||
witnessGenWasm ===
defaultPubkeyProverConfig.witnessGenWasm ||
circuit === defaultAddressProverConfig.circuit ||
witnessGenWasm === defaultAddressProverConfig.witnessGenWasm
) {
console.warn(`
Spartan-ecdsa default config warning:
@@ -37,33 +43,16 @@ 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.circuit = circuit;
this.witnessGenWasm = witnessGenWasm;
this.useRemoteCircuit = useRemoteCircuit ?? false;
}
async initWasm() {
await init();
}
// @ts-ignore
async prove(
sig: string,
msgHash: Buffer,
merkleProof: MerkleProof
): Promise<NIZK> {
async prove({ sig, msgHash, merkleProof }: ProveArgs): Promise<NIZK> {
const { r, s, v } = fromSig(sig);
const effEcdsaPubInput = computeEffEcdsaPubInput(r, v, msgHash);
@@ -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

@@ -1,25 +1,30 @@
import {
defaultAddressMembershipVConfig,
defaultPubkeyMembershipVConfig
} from "../config";
import { Profiler } from "../helpers/profiler";
import { loadCircuit } from "../helpers/utils";
import { IVerifier, VerifyConfig } from "../types";
import wasm, { init } from "../wasm";
import { PublicInput, verifyEffEcdsaPubInput } from "../helpers/public_input";
defaultAddressVerifierConfig,
defaultPubkeyVerifierConfig
} from "@src/config";
import { Profiler } from "@src/helpers/profiler";
import { loadCircuit } from "@src/helpers/utils";
import { IVerifier, VerifyArgs, VerifyConfig } from "@src/types";
import { init, wasm } from "@src/wasm";
import { PublicInput, verifyEffEcdsaPubInput } from "@src/helpers/publicInputs";
/**
* ECDSA Membership Verifier
*/
export class MembershipVerifier extends Profiler implements IVerifier {
circuit: string;
useRemoteCircuit: boolean;
constructor(options: VerifyConfig) {
super({ enabled: options?.enableProfiler });
constructor({
circuit,
enableProfiler,
useRemoteCircuit
}: VerifyConfig) {
super({ enabled: enableProfiler });
if (
options.circuit === defaultAddressMembershipVConfig.circuit ||
options.circuit === defaultPubkeyMembershipVConfig.circuit
circuit === defaultAddressVerifierConfig.circuit ||
circuit === defaultPubkeyVerifierConfig.circuit
) {
console.warn(`
Spartan-ecdsa default config warning:
@@ -29,19 +34,18 @@ export class MembershipVerifier extends Profiler implements IVerifier {
`);
}
this.circuit = options.circuit;
this.circuit = circuit;
this.useRemoteCircuit =
useRemoteCircuit || typeof window !== "undefined";
}
async initWasm() {
await init();
}
async verify(
proof: Uint8Array,
publicInputSer: Uint8Array
): Promise<boolean> {
async verify({ proof, publicInputSer }: VerifyArgs): 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,5 +1,5 @@
import { init, wasm } from "@src/wasm";
import { bigIntToLeBytes, bytesLeToBigInt } from "./utils";
import wasm, { init } from "../wasm";
export class Poseidon {
hash(inputs: bigint[]): bigint {

View File

@@ -1,8 +1,8 @@
var EC = require("elliptic").ec;
const BN = require("bn.js");
import { EffECDSAPubInput } from "@src/types";
import { bytesToBigInt, bigIntToBytes } from "./utils";
import { EffECDSAPubInput } from "../types";
const ec = new EC("secp256k1");
@@ -144,15 +144,18 @@ export const computeEffEcdsaPubInput = (
/**
* Verify the public values of the efficient ECDSA circuit
*/
export const verifyEffEcdsaPubInput = (pubInput: PublicInput): boolean => {
export const verifyEffEcdsaPubInput = ({
r,
rV,
msgHash,
circuitPubInput
}: PublicInput): boolean => {
const expectedCircuitInput = computeEffEcdsaPubInput(
pubInput.r,
pubInput.rV,
pubInput.msgHash
r,
rV,
msgHash
);
const circuitPubInput = pubInput.circuitPubInput;
const isValid =
expectedCircuitInput.Tx === circuitPubInput.Tx &&
expectedCircuitInput.Ty === circuitPubInput.Ty &&

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,11 @@ 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

@@ -0,0 +1,8 @@
export { MembershipProver } from "@src/core/prover";
export { MembershipVerifier } from "@src/core/verifier";
export { CircuitPubInput, PublicInput, computeEffEcdsaPubInput, verifyEffEcdsaPubInput } from "@src/helpers/publicInputs";
export { Tree } from "@src/helpers/tree";
export { Poseidon } from "@src/helpers/poseidon";
export { init, wasm } from "@src/wasm/index";
export { defaultPubkeyProverConfig as defaultPubkeyMembershipPConfig, defaultPubkeyVerifierConfig as defaultPubkeyMembershipVConfig, defaultAddressProverConfig as defaultAddressMembershipPConfig, defaultAddressVerifierConfig as defaultAddressMembershipVConfig } from "@src/config";
export type { MerkleProof, EffECDSAPubInput, NIZK, ProverConfig, VerifyConfig, IProver, IVerifier } from "@src/types";

View File

@@ -1,8 +0,0 @@
export * from "./types";
export * from "./helpers/public_input";
export * from "./core/membership_prover";
export * from "./core/membership_verifier";
export * from "./helpers/tree";
export * from "./helpers/poseidon";
export * from "./wasm/index";
export * from "./config";

View File

@@ -1,45 +0,0 @@
import { PublicInput } from "./helpers/public_input";
// The same structure as MerkleProof in @zk-kit/incremental-merkle-tree.
// Not directly using MerkleProof defined in @zk-kit/incremental-merkle-tree so
// library users can choose whatever merkle tree management method they want.
export interface MerkleProof {
root: bigint;
siblings: bigint[];
pathIndices: number[];
}
export interface EffECDSAPubInput {
Tx: bigint;
Ty: bigint;
Ux: bigint;
Uy: bigint;
}
export interface NIZK {
proof: Uint8Array;
publicInput: PublicInput;
}
export interface ProverConfig {
witnessGenWasm: string;
circuit: string;
enableProfiler?: boolean;
}
export interface VerifyConfig {
circuit: string; // Path to circuit file compiled by Nova-Scotia
enableProfiler?: boolean;
}
export interface IProver {
circuit: string; // Path to circuit file compiled by Nova-Scotia
witnessGenWasm: string; // Path to witness generator wasm file generated by Circom
prove(...args: any): Promise<NIZK>;
}
export interface IVerifier {
circuit: string; // Path to circuit file compiled by Nova-Scotia
verify(proof: Uint8Array, publicInput: Uint8Array): Promise<boolean>;
}

View File

@@ -0,0 +1,58 @@
import { PublicInput } from "@src/helpers/publicInputs";
// The same structure as MerkleProof in @zk-kit/incremental-merkle-tree.
// Not directly using MerkleProof defined in @zk-kit/incremental-merkle-tree so
// library users can choose whatever merkle tree management method they want.
export interface MerkleProof {
root: bigint;
siblings: [bigint][];
pathIndices: number[];
}
export interface EffECDSAPubInput {
Tx: bigint;
Ty: bigint;
Ux: bigint;
Uy: bigint;
}
export interface NIZK {
proof: Uint8Array;
publicInput: PublicInput;
}
export interface ProverConfig {
witnessGenWasm: string;
circuit: string;
enableProfiler?: boolean;
useRemoteCircuit?: boolean;
}
export interface ProveArgs {
sig: string;
msgHash: Buffer,
merkleProof: MerkleProof;
}
export interface VerifyArgs {
proof: Uint8Array,
publicInputSer: Uint8Array
}
export interface VerifyConfig {
circuit: string; // Path to circuit file compiled by Nova-Scotia
enableProfiler?: boolean;
useRemoteCircuit?: boolean;
}
export interface IProver {
circuit: string; // Path to circuit file compiled by Nova-Scotia
witnessGenWasm: string; // Path to witness generator wasm file generated by Circom
prove({ sig, msgHash, merkleProof }: ProveArgs): Promise<NIZK>;
}
export interface IVerifier {
circuit: string; // Path to circuit file compiled by Nova-Scotia
verify({ proof, publicInputSer }: VerifyArgs): Promise<boolean>;
}

View File

@@ -1,10 +1,10 @@
import * as wasm from "./wasm";
import { wasmBytes } from "./wasm_bytes";
import { wasmBytes } from "./wasmBytes";
export const init = async () => {
await wasm.initSync(wasmBytes.buffer);
wasm.init_panic_hook();
};
export default wasm;
export { wasm };

View File

@@ -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: () => 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.
@@ -61,4 +57,4 @@ export function initSync(module: SyncInitInput, maybe_memory?: WebAssembly.Memor
*
* @returns {Promise<InitOutput>}
*/
export default function init (module_or_path?: InitInput | Promise<InitInput>, maybe_memory?: WebAssembly.Memory): 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,19 +250,10 @@ async function load(module, imports) {
}
}
function getImports() {
function __wbg_get_imports() {
const imports = {};
imports.wbg = {};
imports.wbg.__wbg_randomFillSync_6894564c2c334c42 = function() { return handleError(function (arg0, arg1, arg2) {
getObject(arg0).randomFillSync(getArrayU8FromWasm0(arg1, arg2));
}, arguments) };
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
takeObject(arg0);
};
imports.wbg.__wbg_getRandomValues_805f1c3d65988a5a = function() { return handleError(function (arg0, arg1) {
getObject(arg0).getRandomValues(getObject(arg1));
}, arguments) };
imports.wbg.__wbg_crypto_e1d53a1d73fb10b8 = function(arg0) {
imports.wbg.__wbg_crypto_70a96de3b6b73dac = function(arg0) {
const ret = getObject(arg0).crypto;
return addHeapObject(ret);
};
@@ -265,15 +262,15 @@ function getImports() {
const ret = typeof(val) === 'object' && val !== null;
return ret;
};
imports.wbg.__wbg_process_038c26bf42b093f8 = function(arg0) {
imports.wbg.__wbg_process_dd1577445152112e = function(arg0) {
const ret = getObject(arg0).process;
return addHeapObject(ret);
};
imports.wbg.__wbg_versions_ab37218d2f0b24a8 = function(arg0) {
imports.wbg.__wbg_versions_58036bec3add9e6f = function(arg0) {
const ret = getObject(arg0).versions;
return addHeapObject(ret);
};
imports.wbg.__wbg_node_080f4b19d15bc1fe = function(arg0) {
imports.wbg.__wbg_node_6a9d28205ed5b0d8 = function(arg0) {
const ret = getObject(arg0).node;
return addHeapObject(ret);
};
@@ -281,11 +278,14 @@ function getImports() {
const ret = typeof(getObject(arg0)) === 'string';
return ret;
};
imports.wbg.__wbg_msCrypto_6e7d3e1f92610cbb = function(arg0) {
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);
};
imports.wbg.__wbg_require_78a3dcfbdba9cbce = function() { return handleError(function () {
imports.wbg.__wbg_require_f05d779769764e82 = function() { return handleError(function () {
const ret = module.require;
return addHeapObject(ret);
}, arguments) };
@@ -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_new_537b7341ce90bb31 = function(arg0) {
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_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_length_27a2afe8ab42b09f = function(arg0) {
const ret = getObject(arg0).length;
return ret;
};
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,57 +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;
}
async function initSync(module, maybe_memory) {
if (!wasm) {
const imports = getImports();
if (wasm !== undefined) return wasm;
initMemory(imports, maybe_memory);
/*
if (!(module instanceof WebAssembly.Module)) {
module = new WebAssembly.Module(module);
}
*/
const compiled = WebAssembly.compile(module);
const instance = await WebAssembly.instantiate(await compiled, imports);
return finalizeInit(instance, module);
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 = await WebAssembly.instantiate(await compiled, imports);
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

@@ -1,9 +1,10 @@
import { hashPersonalMessage } from "@ethereumjs/util";
import {
CircuitPubInput,
PublicInput,
verifyEffEcdsaPubInput
} from "../src/helpers/public_input";
import { hashPersonalMessage } from "@ethereumjs/util";
} from "../src/helpers/publicInputs";
describe("public_input", () => {
/**

View File

@@ -1,19 +1,20 @@
import {
MembershipProver,
MembershipVerifier,
Tree,
Poseidon,
NIZK
} from "../src/lib";
import {
hashPersonalMessage,
ecsign,
privateToAddress,
privateToPublic
} from "@ethereumjs/util";
var EC = require("elliptic").ec;
import * as path from "path";
import {
MembershipProver,
MembershipVerifier,
Tree,
Poseidon,
NIZK
} from "../src";
describe("membership prove and verify", () => {
// Init prover
const treeDepth = 20;
@@ -25,7 +26,6 @@ describe("membership prove and verify", () => {
// Sign (Use privKeys[0] for proving)
const proverIndex = 0;
const proverPrivKey = privKeys[proverIndex];
let proverAddress: bigint;
let msg = Buffer.from("harry potter");
const msgHash = hashPersonalMessage(msg);
@@ -84,11 +84,14 @@ describe("membership prove and verify", () => {
const index = pubKeyTree.indexOf(proverPubKeyHash as bigint);
const merkleProof = pubKeyTree.createProof(index);
nizk = await pubKeyMembershipProver.prove(sig, msgHash, merkleProof);
nizk = await pubKeyMembershipProver.prove({ sig, msgHash, merkleProof });
const { proof, publicInput } = nizk;
expect(
await pubKeyMembershipVerifier.verify(proof, publicInput.serialize())
await pubKeyMembershipVerifier.verify({
proof,
publicInputSer: publicInput.serialize()
})
).toBe(true);
});
@@ -97,17 +100,23 @@ describe("membership prove and verify", () => {
let proof = nizk.proof;
proof[0] = proof[0] += 1;
expect(
await pubKeyMembershipVerifier.verify(proof, publicInput.serialize())
await pubKeyMembershipVerifier.verify({
proof,
publicInputSer: publicInput.serialize()
})
).toBe(false);
});
it("should assert invalid public input", async () => {
const { proof } = nizk;
let publicInput = nizk.publicInput.serialize();
publicInput[0] = publicInput[0] += 1;
expect(await pubKeyMembershipVerifier.verify(proof, publicInput)).toBe(
false
);
let publicInputSer = nizk.publicInput.serialize();
publicInputSer[0] = publicInputSer[0] += 1;
expect(
await pubKeyMembershipVerifier.verify({
proof,
publicInputSer
})
).toBe(false);
});
});
@@ -154,14 +163,14 @@ describe("membership prove and verify", () => {
await addressMembershipProver.initWasm();
nizk = await addressMembershipProver.prove(sig, msgHash, merkleProof);
nizk = await addressMembershipProver.prove({ sig, msgHash, merkleProof });
await addressMembershipVerifier.initWasm();
expect(
await addressMembershipVerifier.verify(
nizk.proof,
nizk.publicInput.serialize()
)
await addressMembershipVerifier.verify({
proof: nizk.proof,
publicInputSer: nizk.publicInput.serialize()
})
).toBe(true);
});
@@ -170,17 +179,23 @@ describe("membership prove and verify", () => {
let proof = nizk.proof;
proof[0] = proof[0] += 1;
expect(
await addressMembershipVerifier.verify(proof, publicInput.serialize())
await addressMembershipVerifier.verify({
proof,
publicInputSer: publicInput.serialize()
})
).toBe(false);
});
it("should assert invalid public input", async () => {
const { proof } = nizk;
let publicInput = nizk.publicInput.serialize();
publicInput[0] = publicInput[0] += 1;
expect(await addressMembershipVerifier.verify(proof, publicInput)).toBe(
false
);
let publicInputSer = nizk.publicInput.serialize();
publicInputSer[0] = publicInputSer[0] += 1;
expect(
await addressMembershipVerifier.verify({
proof,
publicInputSer
})
).toBe(false);
});
});
});

View File

@@ -0,0 +1,31 @@
import { Tree, Poseidon } from "../src";
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

@@ -0,0 +1,6 @@
{
"extends": "./tsconfig.json",
"exclude": [
"./tests/**/*"
],
}

View File

@@ -1,25 +1,31 @@
{
"compilerOptions": {
"baseUrl": ".",
"rootDir": ".",
"outDir": "./dist",
"declaration": true,
"target": "ES6",
"module": "CommonJS",
"moduleResolution": "node",
"allowJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"paths": {
"@src/*": [
"src/*"
]
},
},
"include": [
"./src/**/*",
"./src/**/*.wasm",
"./tests/**/*"
],
"exclude": [
"./jest.config.js",
"./node_modules",
"./tests",
"./build"
"./dist"
],
"compilerOptions": {
"declaration": true,
"target": "ES6",
"module": "CommonJS",
"rootDir": "./src",
"moduleResolution": "node",
"allowJs": true,
"outDir": "./build",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}

View File

@@ -10,6 +10,7 @@ hex = "0.4.3"
hex-literal = "0.3.4"
secq256k1 = { path = "../secq256k1" }
getrandom = { version = "0.2.8", features = ["js"] }
lazy_static = "1.4.0"
#typenum = { version = "1.16.0", optional = true }
#neptune = { version = "8.1.0", optional = true }
#blstrs = { version = "0.6.0", optional = true }

View File

@@ -1,215 +1,224 @@
pub const NUM_FULL_ROUNDS: usize = 8;
pub const NUM_PARTIAL_ROUNDS: usize = 56;
use ff::PrimeField;
use lazy_static::lazy_static;
pub use secq256k1::field::field_secp::FieldElement;
pub static MDS_MATRIX: &'static [[&str; 3]; 3] = &[
[
"92469348809186613947252340883344274339611751744959319352506666082431267346705",
"100938028378191533449096235266991198229563815869344032449592738345766724371160",
"77486311749148948616988559783475694076613010381924638436641318334458515006661",
],
[
"110352262556914082363749654180080464794716701228558638957603951672835474954408",
"27607004873684391669404739690441550149894883072418944161048725383958774443141",
"29671705769502357195586268679831947082918094959101307962374709600277676341325",
],
[
"77762103796341032609398578911486222569419103128091016773380377798879650228751",
"1753012011204964731088925227042671869111026487299375073665493007998674391999",
"70274477372358662369456035572054501601454406272695978931839980644925236550307",
],
];
pub(crate) const NUM_FULL_ROUNDS: usize = 8;
pub(crate) const NUM_PARTIAL_ROUNDS: usize = 56;
pub static ROUND_CONSTANTS: &'static [&str; 192] = &[
"15180568604901803243989155929934437997245952775071395385994322939386074967328",
"98155933184944822056372510812105826951789406432246960633912199752807271851218",
"32585497418154084368870158853355239726261349829448673320273043226636389078017",
"66713968576806622579829258440960693099797917756640662361943757758980796487698",
"61296025743283504825054745787375839406507895949474930140819919915792438454216",
"64548089412749542282115556935384382035671782881737715696939837764375912217104",
"108421562972909537718478936575770973463273651828765393113349044862621092658552",
"93957623861448681916560847065407918286434708744548934125771289238599801659600",
"31886767595881910145119755249133120645312710313371225820300496900248094187131",
"36511615103248888903406040506250394762206798360602726106046630438239169384653",
"21193239787133737740669439860809806837993750509086389566475677877580362491125",
"15159189447883181997488877417695825734356570617827322308691834229181804753656",
"19272373877630561389686073945290625876718814210798194797601715657476609730306",
"23132197996397121955527964729507651432518694856862854469217474256539272053037",
"9869753235007825662020275771343858285582964429845049469800863115040150206544",
"36536341316285671890133896506951910369952562161551585116256678375995315827743",
"62582239167707347777855528698896708360409296899261565735324151945083720570858",
"96597358901965097853721114962031771931271685249979807653919643952343419105640",
"99475971754252188104003224702005940217163363685728394033034788135108600073953",
"52080483875928847502018688921126796935417602445765802481027972679966274137987",
"101922748752417217354391348649359865075718358385248454632698502400961567227929",
"26980595292132221181330746499613907829041623688147011560382352796984836870749",
"7059991836806083192408106370472821784612460308866802565871813230060135266390",
"19329812920723038526370491239817117039289784665617181727933894076969997926129",
"65570620823578601926240439251563587376966657231502120214692324496443514623818",
"58403733332589349613112270854204921427257113546270812628317365115158685715742",
"45021021211732634759643776743541935700591354899980928498981462362035961745443",
"313468157086800401026946312285365733155132234906935411743639256319782592571",
"101316949793045093761117346380310841944294663456931203380573537653884068660109",
"23683935571424619534194393788101669168630123784066421490798386323411538828592",
"45470730427236677197026094498490008082250264942279323465121581539984407294442",
"48141067373531800337373447278127981363951468257064369512416205750641258258193",
"42554919225040466028330117313396362347164995917041931400909482795914116747618",
"11551941832988244108260444347046942236051939264069344013774353630451796870907",
"60185799182545404739011626517355854847787627814101363386450657535504094743765",
"81823160578900678880708744457872721685515019032370491632046212317701226128393",
"7165646831054215773988859638722974820791178194871546344315162343128362695647",
"75289707601640398424243937567716657896680380639974371761136292031415717685949",
"7150842764562742184396161198129263121409208675362553300851082062734889620953",
"24380904705269761063866540342138412601132455197711667167747524315310027386226",
"9728986075621437350131504894128984146939551938810073671231633620616345344412",
"10579382052089733216628873394134968879891026686695240299956972154694558493896",
"8171994519466002143995890536756742287314780571933910736618431096190430536601",
"30420144259409274775063072923609924427757612539094840146996944760708902708570",
"63962155989812703023698320394024694856871261481871757094333286947755599007133",
"25280070391177856032024336895094721131222985610587247589336316615596140400436",
"15305872319988027006162258914083163651002306183917888172691618513722838997098",
"51545603291342006705870081001071419395633279951502747769141857387796043104608",
"91109680756552587805002537489407348773333405839144382221272597323798859182191",
"72175452855185658158184807496160149169667221240389196996344579971523681433202",
"30361989157454953234766224747536334157139256334148153290771332849307087761025",
"38169634499980959088614671703639492517637815232220682121652135514105493936992",
"49591153263237620796156788742811547511792615129981565620486914545749079774827",
"47403873018260745456113868791119169163627014766514972598212646481717066065016",
"93989849689047144228924801010853106857960399638657695410345207191739048300111",
"10590240512802509131776989274411792739339398409955259174829387591089799115255",
"29183703335869638067547208413224742887766212046438654772943025958628178245227",
"4131650227136944095885036960767735080970262672750406866066212532739784907379",
"43395510588213653537697670365796375057855260611965666448183946252832290017444",
"95246795133940226900907730059125298420936467652619708443128629427116119621152",
"6012209003558496814495903476753006089125143165365334812097313083703216071080",
"26183233284429251459198269925441295879550203824094631575778521083706115817955",
"26058994700533582730528567480051558438548299522338811756875396252016497202713",
"107240485663145290290374164860301805857261278222480421976433215167444496066511",
"84412820763898503096477800002865877536719992495674955119188074297975154406587",
"52386303852182662900790700046090769869460994629239741773176060026198900130384",
"95746062835936512160025091603469309809932540674474329021370075533568318932379",
"22711334660013961010382652754865456251782349529764119853461446587583972054666",
"16959835233095757670013367728627149851239789174357906293937455553277911805495",
"15116421110200928832147360650392633091242147433006813656250997138988179879750",
"107878787525302837370688492081178689950008165750500003692400517211520334656293",
"44210105558575948369921579518078229089923760124167628288943900602376706136436",
"90305995748749060889452130219544332384396626628663475498252761213618628372367",
"104941997925797907872686462815914481945432760720471803254797908465921520138024",
"100036855232527386145662094141100441220151775745916101660987264242446845728894",
"103285582836474146806606752170525767341430483568396209591447274936228630298052",
"82197692939371228160449741709034077803239992888716859217989995857278406253737",
"10040764964044995095453717286623030376397745892179877153575434454090155545240",
"27304226040425863042893623786832369758179176309230053449707879364285977952630",
"42627232144930751842910170221862679057276668485045156742021958050665662768084",
"76972394926916659428228833084621905890924612368412796262119501852346293848159",
"39796921406297542196667238133893946368231540421737718098283349901435707131075",
"14745047092916651495052563068083093689676472592445845983334785004125684263162",
"43421479365783318841667739359312715738029447177150400204380817518608837765863",
"107871536756946365977710326147511195471121248998432910212631960353348700694610",
"39505942243687894211614489736115535754716239859353578295470352855493707198619",
"59676442091621150164811367352362126934419932715789994860508056194143441226580",
"94470526851498636320865653968033227263836954414283116133326109455334870036212",
"15044796858044094866329855531761112645684343559112419720568996573556805975600",
"67157729293641241473980125231288476062565688273917759533572275886277269201651",
"72911083146182058225942884942982388217243826839805061121973109250798137784134",
"102973386186208530972563015865701244407271836208547629083437627219683649557477",
"57485522356347377122696081086816661784954498123948319434326439317393351620564",
"23112275556906805064863694321486306070917598599342299357379251070160695202292",
"107618884362423342584703700349292347754139538760798319916678240538294838342400",
"83961260400031958812820990908241261093246389047082613562825737834833753517337",
"42726953951733266282750892844947149703751388034177248277671157488506520215317",
"39379570934119946602507737250800178347029772561352879974941214627084076473292",
"72203650529122342092280763801468513707870760755235719535090090101623606334441",
"13389660788942842724553143053013919883368472759564135119390935439369513690496",
"101745263541280877725997503552978999350831489463993178838531539940805924817361",
"76849182334465191824607032600721023780793694103840553871800174717760598910761",
"53896256317996838683363773836826653859512780625932638736752563553878867538095",
"24688792501674999263943657175455335814404948006469220532686392550824320454904",
"69132683906595821927803530074656979217668636557563597358799899743174233903941",
"2861982085506615225917620192781928414994576134281371548401916333754363567986",
"37311353286221616083824584705974993449107063556724405440534160586561042968316",
"83718085796857523832195255218519255973031752296424117786202083986118546906913",
"103633177691684814414226251117070754499104739002759424774194851613917008856616",
"84968411062305024171594435878414659990735518025357685215223731503921265946461",
"41865099330909055069143724769818364262362915440371474104937435863183989905059",
"46156624920251322979270606388518884047396423747179340919303543598300663968593",
"64416327466854458915398302811825971539792429791049027619471115285308743811583",
"94942471312481523091911417289540395651121558150571128515230470225155209280585",
"109682618775735319282534546194470743032129102295907200313471041846112653687024",
"61531999191737540795124202104235799899980935519651613893518293245268304980543",
"17797352534596268622733030076742840951214734697361029060619245779495726996632",
"2323150752778983462106829021155031678603044899339819935981200101818542000989",
"16998018904363448507967526489917057882529252665835717172712095240271574074587",
"110634872413902251217040490777568744431854972018399530234679399294372694506842",
"31639545145649753705216327198217551838008233610574104460826956396569310697060",
"107845103764339268987018917144483935480716224058844669233389185480836000033760",
"46240297572174662698030819651333060930818959915797061274854448535534474175039",
"53065607123105696930220421963755520777674094852857308823370049733888025985616",
"16931881300947470270453776207625163368485560075525342751440832370220475352149",
"79254110800481916763656344422402393723573490114487681345184594841431920461089",
"42268569642639492314994307446626647824927989776691987788682655102426770655233",
"9749633319307409894058984489496091535125232227316143918000642155415596066903",
"57606597628648270579042266322415267200058617178318601782866227410456726724976",
"56082250485913115488341301630850455009935943641292622301678990296508134206571",
"17957245764842844288802777667800779232762688847417238921175068882796163705248",
"94356229516444419318132697346021621194464273500135725160277725602263001442644",
"52536631226748676066386651084538409050048707922045928887930261833545619358914",
"107794922118166328243581272159394479176678094739027519706768813902978100436849",
"92984368734102511759118281503078145182557799453616537383408606074187034371208",
"59652553897137603386525572460411404882917571255327541516871354737502335133690",
"49012645345644326995052653072578673750516379655033952006121214224119466671764",
"79025576845143484310735291619293962982804358365838961371044480386743856799994",
"5437377540613244374799729812489584777222423091155743557287567155811057717409",
"100687592213090267900708728796310211082532607828753010566886681655775031329660",
"99074462968857696481475128596339544396152341206708424767062829343406495063192",
"67476872698289965626550204192782761730653024363949045140720348870736942130242",
"103307125141718054130755829916960708430672826104789971350239945481960770107890",
"74087383014714668160537499936376991041273055222568604413015844459913259357334",
"40924049099780965904051946083599822761993164889139026432053420731164022206736",
"32594924940463736641240515015317856157169105212942308502676422036626316673214",
"98990663138035055774586216545398054668349058134877723031747421828753359974443",
"55821766022768786066770462759796825978667805772707620106340033118519147871694",
"4001942224536365489828915551180230767516454384395893814399938353050969198154",
"30136373426492646221252150708518703998248891683881870400906269276900707426865",
"34943205764464817266133164313915763122699935186597909347522822673832250079664",
"27737330737483170511275902246508559278973986181590368845166383812793468814968",
"96292398813565494438359802278723334615526914389306923046282571355958508916558",
"97147334956505986101750230325438660094766812949748276042292963837380833668274",
"24754519562402723848413674701792328284127274989440581643644298347747941238812",
"76111103490248669364580390783887028636436246028943665707064153006971943621186",
"33764090322658516047637223655525551979364055499647855895233821795694749902854",
"100536990630540359004783976190215234627391515555181073681294901127179838732969",
"55991997435987096996680289872758998763908676069536901375395297778729059185671",
"32860959903680178324832991459746631238726690317249285658471597044247794502256",
"70074816806976994707467706079200635184034023598764203123459335544110485476930",
"46213940675829172331116620705134022102338250410334045747023950259088879662946",
"77000624259024986585504351395777746568094934279771127334532438603183524642061",
"21719649576090832101273013788716623377603297433777804572370785470329817725170",
"29209622978540575483991966565508890231057362045066230397327380085945876837821",
"2445742484263083651472035320255578071935687960412507452207899496253120999364",
"86846812580007547526361109808384103509272544750564766849178767957571523649544",
"43025640639926253696325070988523609146060819319830735794100778654425057363895",
"108957662689228031021948854644435971168708642184764962508575441689859324862868",
"83891545396650121758556392255189778590486277180642660527000882403085396114823",
"42527013475786190604202451803064937203698027000671529418992521798122995373551",
"115180194520889678365425151865713593680657747284471744934804370945935167043862",
"28979598171177052880917135045920701144584888536299261666846302083645491369348",
"68351312608110279019109436395199010412431777911149851157132527077210966351650",
"61759623963943995967580147094342313397376358019837276043205235302342147116585",
"80714625408576660514217469096827255752431164791924432025682445176737446783085",
"33048555646676368266608424610100449208381357250300222636992099726804869416731",
"50682223610667325089810868083131721901859473966415125289975106060759036109476",
"4271213571706787092297985431667190050727614825584809797590204884727103716461",
"101314046722405990971733763321368296660561930294000591067108115987088407142646",
"55565500177602146197728150332647093173137211885612327122425918553270191254877",
"65556764608648687291293889343854786421750589271167654521933267288313526422497",
"66877533773422945979143954094644173219583178339199697252673545117318799706373",
"30511098623357801425494143655999121699575856091238269679669864984061501512835",
"95900192636363991637086954986559552472749485926252879461208179855482821976623",
"37879946127489462347049192209554168578320892231852882971030128420645686965013",
"80479504274334215471057938992198620419540634144266821121799003865782336406529",
"13326262422954139210095783388743602482455840337093117010479445267213907605425",
"16047106134611124637925332265703907202779549268127518502853950466090054176776",
"71499356105233640605079063493613576024353801558965221134519779175477723594865",
"28438981751956157476540225984733791304599172905715743025543841239013139121102",
"56066317647068426981453448715118237747130321302262827290362392918472904421147",
];
lazy_static! {
pub(crate) static ref MDS_MATRIX: [[FieldElement; 3]; 3] = [
[
"92469348809186613947252340883344274339611751744959319352506666082431267346705",
"100938028378191533449096235266991198229563815869344032449592738345766724371160",
"77486311749148948616988559783475694076613010381924638436641318334458515006661",
]
.map(|y| FieldElement::from_str_vartime(y).unwrap()),
[
"110352262556914082363749654180080464794716701228558638957603951672835474954408",
"27607004873684391669404739690441550149894883072418944161048725383958774443141",
"29671705769502357195586268679831947082918094959101307962374709600277676341325",
]
.map(|y| FieldElement::from_str_vartime(y).unwrap()),
[
"77762103796341032609398578911486222569419103128091016773380377798879650228751",
"1753012011204964731088925227042671869111026487299375073665493007998674391999",
"70274477372358662369456035572054501601454406272695978931839980644925236550307",
]
.map(|y| FieldElement::from_str_vartime(y).unwrap()),
];
pub(crate) static ref ROUND_CONSTANTS: [FieldElement; 192] = [
"15180568604901803243989155929934437997245952775071395385994322939386074967328",
"98155933184944822056372510812105826951789406432246960633912199752807271851218",
"32585497418154084368870158853355239726261349829448673320273043226636389078017",
"66713968576806622579829258440960693099797917756640662361943757758980796487698",
"61296025743283504825054745787375839406507895949474930140819919915792438454216",
"64548089412749542282115556935384382035671782881737715696939837764375912217104",
"108421562972909537718478936575770973463273651828765393113349044862621092658552",
"93957623861448681916560847065407918286434708744548934125771289238599801659600",
"31886767595881910145119755249133120645312710313371225820300496900248094187131",
"36511615103248888903406040506250394762206798360602726106046630438239169384653",
"21193239787133737740669439860809806837993750509086389566475677877580362491125",
"15159189447883181997488877417695825734356570617827322308691834229181804753656",
"19272373877630561389686073945290625876718814210798194797601715657476609730306",
"23132197996397121955527964729507651432518694856862854469217474256539272053037",
"9869753235007825662020275771343858285582964429845049469800863115040150206544",
"36536341316285671890133896506951910369952562161551585116256678375995315827743",
"62582239167707347777855528698896708360409296899261565735324151945083720570858",
"96597358901965097853721114962031771931271685249979807653919643952343419105640",
"99475971754252188104003224702005940217163363685728394033034788135108600073953",
"52080483875928847502018688921126796935417602445765802481027972679966274137987",
"101922748752417217354391348649359865075718358385248454632698502400961567227929",
"26980595292132221181330746499613907829041623688147011560382352796984836870749",
"7059991836806083192408106370472821784612460308866802565871813230060135266390",
"19329812920723038526370491239817117039289784665617181727933894076969997926129",
"65570620823578601926240439251563587376966657231502120214692324496443514623818",
"58403733332589349613112270854204921427257113546270812628317365115158685715742",
"45021021211732634759643776743541935700591354899980928498981462362035961745443",
"313468157086800401026946312285365733155132234906935411743639256319782592571",
"101316949793045093761117346380310841944294663456931203380573537653884068660109",
"23683935571424619534194393788101669168630123784066421490798386323411538828592",
"45470730427236677197026094498490008082250264942279323465121581539984407294442",
"48141067373531800337373447278127981363951468257064369512416205750641258258193",
"42554919225040466028330117313396362347164995917041931400909482795914116747618",
"11551941832988244108260444347046942236051939264069344013774353630451796870907",
"60185799182545404739011626517355854847787627814101363386450657535504094743765",
"81823160578900678880708744457872721685515019032370491632046212317701226128393",
"7165646831054215773988859638722974820791178194871546344315162343128362695647",
"75289707601640398424243937567716657896680380639974371761136292031415717685949",
"7150842764562742184396161198129263121409208675362553300851082062734889620953",
"24380904705269761063866540342138412601132455197711667167747524315310027386226",
"9728986075621437350131504894128984146939551938810073671231633620616345344412",
"10579382052089733216628873394134968879891026686695240299956972154694558493896",
"8171994519466002143995890536756742287314780571933910736618431096190430536601",
"30420144259409274775063072923609924427757612539094840146996944760708902708570",
"63962155989812703023698320394024694856871261481871757094333286947755599007133",
"25280070391177856032024336895094721131222985610587247589336316615596140400436",
"15305872319988027006162258914083163651002306183917888172691618513722838997098",
"51545603291342006705870081001071419395633279951502747769141857387796043104608",
"91109680756552587805002537489407348773333405839144382221272597323798859182191",
"72175452855185658158184807496160149169667221240389196996344579971523681433202",
"30361989157454953234766224747536334157139256334148153290771332849307087761025",
"38169634499980959088614671703639492517637815232220682121652135514105493936992",
"49591153263237620796156788742811547511792615129981565620486914545749079774827",
"47403873018260745456113868791119169163627014766514972598212646481717066065016",
"93989849689047144228924801010853106857960399638657695410345207191739048300111",
"10590240512802509131776989274411792739339398409955259174829387591089799115255",
"29183703335869638067547208413224742887766212046438654772943025958628178245227",
"4131650227136944095885036960767735080970262672750406866066212532739784907379",
"43395510588213653537697670365796375057855260611965666448183946252832290017444",
"95246795133940226900907730059125298420936467652619708443128629427116119621152",
"6012209003558496814495903476753006089125143165365334812097313083703216071080",
"26183233284429251459198269925441295879550203824094631575778521083706115817955",
"26058994700533582730528567480051558438548299522338811756875396252016497202713",
"107240485663145290290374164860301805857261278222480421976433215167444496066511",
"84412820763898503096477800002865877536719992495674955119188074297975154406587",
"52386303852182662900790700046090769869460994629239741773176060026198900130384",
"95746062835936512160025091603469309809932540674474329021370075533568318932379",
"22711334660013961010382652754865456251782349529764119853461446587583972054666",
"16959835233095757670013367728627149851239789174357906293937455553277911805495",
"15116421110200928832147360650392633091242147433006813656250997138988179879750",
"107878787525302837370688492081178689950008165750500003692400517211520334656293",
"44210105558575948369921579518078229089923760124167628288943900602376706136436",
"90305995748749060889452130219544332384396626628663475498252761213618628372367",
"104941997925797907872686462815914481945432760720471803254797908465921520138024",
"100036855232527386145662094141100441220151775745916101660987264242446845728894",
"103285582836474146806606752170525767341430483568396209591447274936228630298052",
"82197692939371228160449741709034077803239992888716859217989995857278406253737",
"10040764964044995095453717286623030376397745892179877153575434454090155545240",
"27304226040425863042893623786832369758179176309230053449707879364285977952630",
"42627232144930751842910170221862679057276668485045156742021958050665662768084",
"76972394926916659428228833084621905890924612368412796262119501852346293848159",
"39796921406297542196667238133893946368231540421737718098283349901435707131075",
"14745047092916651495052563068083093689676472592445845983334785004125684263162",
"43421479365783318841667739359312715738029447177150400204380817518608837765863",
"107871536756946365977710326147511195471121248998432910212631960353348700694610",
"39505942243687894211614489736115535754716239859353578295470352855493707198619",
"59676442091621150164811367352362126934419932715789994860508056194143441226580",
"94470526851498636320865653968033227263836954414283116133326109455334870036212",
"15044796858044094866329855531761112645684343559112419720568996573556805975600",
"67157729293641241473980125231288476062565688273917759533572275886277269201651",
"72911083146182058225942884942982388217243826839805061121973109250798137784134",
"102973386186208530972563015865701244407271836208547629083437627219683649557477",
"57485522356347377122696081086816661784954498123948319434326439317393351620564",
"23112275556906805064863694321486306070917598599342299357379251070160695202292",
"107618884362423342584703700349292347754139538760798319916678240538294838342400",
"83961260400031958812820990908241261093246389047082613562825737834833753517337",
"42726953951733266282750892844947149703751388034177248277671157488506520215317",
"39379570934119946602507737250800178347029772561352879974941214627084076473292",
"72203650529122342092280763801468513707870760755235719535090090101623606334441",
"13389660788942842724553143053013919883368472759564135119390935439369513690496",
"101745263541280877725997503552978999350831489463993178838531539940805924817361",
"76849182334465191824607032600721023780793694103840553871800174717760598910761",
"53896256317996838683363773836826653859512780625932638736752563553878867538095",
"24688792501674999263943657175455335814404948006469220532686392550824320454904",
"69132683906595821927803530074656979217668636557563597358799899743174233903941",
"2861982085506615225917620192781928414994576134281371548401916333754363567986",
"37311353286221616083824584705974993449107063556724405440534160586561042968316",
"83718085796857523832195255218519255973031752296424117786202083986118546906913",
"103633177691684814414226251117070754499104739002759424774194851613917008856616",
"84968411062305024171594435878414659990735518025357685215223731503921265946461",
"41865099330909055069143724769818364262362915440371474104937435863183989905059",
"46156624920251322979270606388518884047396423747179340919303543598300663968593",
"64416327466854458915398302811825971539792429791049027619471115285308743811583",
"94942471312481523091911417289540395651121558150571128515230470225155209280585",
"109682618775735319282534546194470743032129102295907200313471041846112653687024",
"61531999191737540795124202104235799899980935519651613893518293245268304980543",
"17797352534596268622733030076742840951214734697361029060619245779495726996632",
"2323150752778983462106829021155031678603044899339819935981200101818542000989",
"16998018904363448507967526489917057882529252665835717172712095240271574074587",
"110634872413902251217040490777568744431854972018399530234679399294372694506842",
"31639545145649753705216327198217551838008233610574104460826956396569310697060",
"107845103764339268987018917144483935480716224058844669233389185480836000033760",
"46240297572174662698030819651333060930818959915797061274854448535534474175039",
"53065607123105696930220421963755520777674094852857308823370049733888025985616",
"16931881300947470270453776207625163368485560075525342751440832370220475352149",
"79254110800481916763656344422402393723573490114487681345184594841431920461089",
"42268569642639492314994307446626647824927989776691987788682655102426770655233",
"9749633319307409894058984489496091535125232227316143918000642155415596066903",
"57606597628648270579042266322415267200058617178318601782866227410456726724976",
"56082250485913115488341301630850455009935943641292622301678990296508134206571",
"17957245764842844288802777667800779232762688847417238921175068882796163705248",
"94356229516444419318132697346021621194464273500135725160277725602263001442644",
"52536631226748676066386651084538409050048707922045928887930261833545619358914",
"107794922118166328243581272159394479176678094739027519706768813902978100436849",
"92984368734102511759118281503078145182557799453616537383408606074187034371208",
"59652553897137603386525572460411404882917571255327541516871354737502335133690",
"49012645345644326995052653072578673750516379655033952006121214224119466671764",
"79025576845143484310735291619293962982804358365838961371044480386743856799994",
"5437377540613244374799729812489584777222423091155743557287567155811057717409",
"100687592213090267900708728796310211082532607828753010566886681655775031329660",
"99074462968857696481475128596339544396152341206708424767062829343406495063192",
"67476872698289965626550204192782761730653024363949045140720348870736942130242",
"103307125141718054130755829916960708430672826104789971350239945481960770107890",
"74087383014714668160537499936376991041273055222568604413015844459913259357334",
"40924049099780965904051946083599822761993164889139026432053420731164022206736",
"32594924940463736641240515015317856157169105212942308502676422036626316673214",
"98990663138035055774586216545398054668349058134877723031747421828753359974443",
"55821766022768786066770462759796825978667805772707620106340033118519147871694",
"4001942224536365489828915551180230767516454384395893814399938353050969198154",
"30136373426492646221252150708518703998248891683881870400906269276900707426865",
"34943205764464817266133164313915763122699935186597909347522822673832250079664",
"27737330737483170511275902246508559278973986181590368845166383812793468814968",
"96292398813565494438359802278723334615526914389306923046282571355958508916558",
"97147334956505986101750230325438660094766812949748276042292963837380833668274",
"24754519562402723848413674701792328284127274989440581643644298347747941238812",
"76111103490248669364580390783887028636436246028943665707064153006971943621186",
"33764090322658516047637223655525551979364055499647855895233821795694749902854",
"100536990630540359004783976190215234627391515555181073681294901127179838732969",
"55991997435987096996680289872758998763908676069536901375395297778729059185671",
"32860959903680178324832991459746631238726690317249285658471597044247794502256",
"70074816806976994707467706079200635184034023598764203123459335544110485476930",
"46213940675829172331116620705134022102338250410334045747023950259088879662946",
"77000624259024986585504351395777746568094934279771127334532438603183524642061",
"21719649576090832101273013788716623377603297433777804572370785470329817725170",
"29209622978540575483991966565508890231057362045066230397327380085945876837821",
"2445742484263083651472035320255578071935687960412507452207899496253120999364",
"86846812580007547526361109808384103509272544750564766849178767957571523649544",
"43025640639926253696325070988523609146060819319830735794100778654425057363895",
"108957662689228031021948854644435971168708642184764962508575441689859324862868",
"83891545396650121758556392255189778590486277180642660527000882403085396114823",
"42527013475786190604202451803064937203698027000671529418992521798122995373551",
"115180194520889678365425151865713593680657747284471744934804370945935167043862",
"28979598171177052880917135045920701144584888536299261666846302083645491369348",
"68351312608110279019109436395199010412431777911149851157132527077210966351650",
"61759623963943995967580147094342313397376358019837276043205235302342147116585",
"80714625408576660514217469096827255752431164791924432025682445176737446783085",
"33048555646676368266608424610100449208381357250300222636992099726804869416731",
"50682223610667325089810868083131721901859473966415125289975106060759036109476",
"4271213571706787092297985431667190050727614825584809797590204884727103716461",
"101314046722405990971733763321368296660561930294000591067108115987088407142646",
"55565500177602146197728150332647093173137211885612327122425918553270191254877",
"65556764608648687291293889343854786421750589271167654521933267288313526422497",
"66877533773422945979143954094644173219583178339199697252673545117318799706373",
"30511098623357801425494143655999121699575856091238269679669864984061501512835",
"95900192636363991637086954986559552472749485926252879461208179855482821976623",
"37879946127489462347049192209554168578320892231852882971030128420645686965013",
"80479504274334215471057938992198620419540634144266821121799003865782336406529",
"13326262422954139210095783388743602482455840337093117010479445267213907605425",
"16047106134611124637925332265703907202779549268127518502853950466090054176776",
"71499356105233640605079063493613576024353801558965221134519779175477723594865",
"28438981751956157476540225984733791304599172905715743025543841239013139121102",
"56066317647068426981453448715118237747130321302262827290362392918472904421147",
]
.map(|y| FieldElement::from_str_vartime(y).unwrap());
}

View File

@@ -27,14 +27,14 @@ impl<F: PrimeField> PoseidonConstants<F> {
}
pub struct Poseidon<F: PrimeField> {
pub state: Vec<F>,
pub state: [F; 3],
pub constants: PoseidonConstants<F>,
pub pos: usize,
}
impl<F: PrimeField> Poseidon<F> {
pub fn new(constants: PoseidonConstants<F>) -> Self {
let state = vec![F::zero(); 3];
let state = [F::zero(); 3];
Self {
state,
constants,
@@ -42,12 +42,10 @@ impl<F: PrimeField> Poseidon<F> {
}
}
pub fn hash(&mut self, input: Vec<F>) -> F {
// add padding
let mut input = input.clone();
let domain_tag = 3; // 2^arity - 1
input.insert(0, F::from(domain_tag));
pub fn hash(&mut self, input: &[F; 2]) -> F {
// add the domain tag
let domain_tag = F::from(3); // 2^arity - 1
let input = [domain_tag, input[0], input[1]];
self.state = input;
@@ -80,14 +78,14 @@ impl<F: PrimeField> Poseidon<F> {
// MDS matrix multiplication
fn matrix_mul(&mut self) {
let mut result = Vec::new();
let mut result = [F::zero(); 3];
for val in self.constants.mds_matrix.iter() {
for (i, val) in self.constants.mds_matrix.iter().enumerate() {
let mut tmp = F::zero();
for (j, element) in self.state.iter().enumerate() {
tmp += val[j] * element
}
result.push(tmp)
result[i] = tmp;
}
self.state = result;
@@ -124,40 +122,30 @@ impl<F: PrimeField> Poseidon<F> {
#[cfg(test)]
mod tests {
use super::*;
use k256_consts::*;
use secq256k1::field::{field_secp, BaseField};
#[test]
fn test_k256() {
type Scalar = field_secp::FieldElement;
let input = vec![
let input = [
Scalar::from_str_vartime("1234567").unwrap(),
Scalar::from_str_vartime("109987").unwrap(),
];
let round_constants: Vec<Scalar> = k256_consts::ROUND_CONSTANTS
.iter()
.map(|x| Scalar::from_str_vartime(x).unwrap())
.collect();
let mds_matrix: Vec<Vec<Scalar>> = k256_consts::MDS_MATRIX
.iter()
.map(|x| {
x.iter()
.map(|y| Scalar::from_str_vartime(y).unwrap())
.collect::<Vec<Scalar>>()
})
.collect();
let constants = PoseidonConstants::<Scalar>::new(
round_constants,
mds_matrix,
k256_consts::NUM_FULL_ROUNDS,
k256_consts::NUM_PARTIAL_ROUNDS,
let constants = PoseidonConstants::<FieldElement>::new(
ROUND_CONSTANTS.to_vec(),
vec![
MDS_MATRIX[0].to_vec(),
MDS_MATRIX[1].to_vec(),
MDS_MATRIX[2].to_vec(),
],
NUM_FULL_ROUNDS,
NUM_PARTIAL_ROUNDS,
);
let mut poseidon = Poseidon::new(constants);
let digest = poseidon.hash(input);
let digest = poseidon.hash(&input);
assert_eq!(
digest,

View File

@@ -1,28 +1,18 @@
use crate::{k256_consts, Poseidon, PoseidonConstants};
use ff::PrimeField;
use crate::k256_consts::*;
use crate::{Poseidon, PoseidonConstants};
pub use secq256k1::field::field_secp::FieldElement;
#[allow(dead_code)]
pub fn hash(input: Vec<FieldElement>) -> FieldElement {
let round_constants: Vec<FieldElement> = k256_consts::ROUND_CONSTANTS
.iter()
.map(|x| FieldElement::from_str_vartime(x).unwrap())
.collect();
let mds_matrix: Vec<Vec<FieldElement>> = k256_consts::MDS_MATRIX
.iter()
.map(|x| {
x.iter()
.map(|y| FieldElement::from_str_vartime(y).unwrap())
.collect::<Vec<FieldElement>>()
})
.collect();
pub fn hash(input: &[FieldElement; 2]) -> FieldElement {
let constants = PoseidonConstants::<FieldElement>::new(
round_constants,
mds_matrix,
k256_consts::NUM_FULL_ROUNDS,
k256_consts::NUM_PARTIAL_ROUNDS,
ROUND_CONSTANTS.to_vec(),
vec![
MDS_MATRIX[0].to_vec(),
MDS_MATRIX[1].to_vec(),
MDS_MATRIX[2].to_vec(),
],
NUM_FULL_ROUNDS,
NUM_PARTIAL_ROUNDS,
);
let mut poseidon = Poseidon::new(constants);

View File

@@ -84,14 +84,14 @@ pub fn verify(circuit: &[u8], proof: &[u8], public_input: &[u8]) -> Result<bool,
#[wasm_bindgen]
pub fn poseidon(input_bytes: &[u8]) -> Result<Vec<u8>, JsValue> {
let mut input = Vec::new();
for i in 0..(input_bytes.len() / 32) {
let f: [u8; 32] = input_bytes[(i * 32)..(i + 1) * 32].try_into().unwrap();
let val = FieldElement::from_bytes(&f).unwrap();
input.push(FieldElement::from(val));
}
assert_eq!(input_bytes.len(), 64);
let result = hash(input);
let input = [
FieldElement::from_bytes(&input_bytes[0..32].try_into().unwrap()).unwrap(),
FieldElement::from_bytes(&input_bytes[32..64].try_into().unwrap()).unwrap(),
];
let result = hash(&input);
Ok(result.to_bytes().to_vec())
}

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.3.0"
dependencies:
"@ethereumjs/util" "^8.0.3"
"@zk-kit/incremental-merkle-tree" "^1.0.0"
elliptic "^6.5.4"
snarkjs "^0.7.1"
"@phenomnomnominal/tsquery@4.1.1":
version "4.1.1"
resolved "https://registry.npmjs.org/@phenomnomnominal/tsquery/-/tsquery-4.1.1.tgz"
@@ -3136,6 +3144,13 @@ circom_runtime@0.1.21:
dependencies:
ffjavascript "0.2.56"
circom_runtime@0.1.24:
version "0.1.24"
resolved "https://registry.yarnpkg.com/circom_runtime/-/circom_runtime-0.1.24.tgz#60ca8a31c3675802fbab5a0bcdeb02556e510733"
integrity sha512-H7/7I2J/cBmRnZm9docOCGhfxzS61BEm4TMCWcrZGsWNBQhePNfQq88Oj2XpUfzmBTCd8pRvRb3Mvazt3TMrJw==
dependencies:
ffjavascript "0.2.60"
circom_tester@^0.0.19:
version "0.0.19"
resolved "https://registry.npmjs.org/circom_tester/-/circom_tester-0.0.19.tgz"
@@ -4300,6 +4315,15 @@ ffjavascript@0.2.56:
wasmcurves "0.2.0"
web-worker "^1.2.0"
ffjavascript@0.2.60:
version "0.2.60"
resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.2.60.tgz#4d8ae613d6bf4e98b3cc29ba10c626f5853854cf"
integrity sha512-T/9bnEL5xAZRDbQoEMf+pM9nrhK+C3JyZNmqiWub26EQorW7Jt+jR54gpqDhceA4Nj0YctPQwYnl8xa52/A26A==
dependencies:
wasmbuilder "0.0.16"
wasmcurves "0.2.2"
web-worker "^1.2.0"
ffjavascript@^0.2.45, ffjavascript@^0.2.48, ffjavascript@^0.2.56, ffjavascript@^0.2.57:
version "0.2.57"
resolved "https://registry.npmjs.org/ffjavascript/-/ffjavascript-0.2.57.tgz"
@@ -7070,6 +7094,16 @@ r1csfile@0.0.41, r1csfile@^0.0.41:
fastfile "0.0.20"
ffjavascript "0.2.56"
r1csfile@0.0.47:
version "0.0.47"
resolved "https://registry.yarnpkg.com/r1csfile/-/r1csfile-0.0.47.tgz#ed95a0dc8e910e9c070253906f7a31bd8c5333c8"
integrity sha512-oI4mAwuh1WwuFg95eJDNDDL8hCaZkwnPuNZrQdLBWvDoRU7EG+L/MOHL7SwPW2Y+ZuYcTLpj3rBkgllBQZN/JA==
dependencies:
"@iden3/bigarray" "0.0.2"
"@iden3/binfileutils" "0.0.11"
fastfile "0.0.20"
ffjavascript "0.2.60"
react-dom@18.2.0:
version "18.2.0"
resolved "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz"
@@ -7446,7 +7480,7 @@ smart-buffer@^4.2.0:
resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz"
integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==
snarkjs@0.5.0, snarkjs@^0.5.0:
snarkjs@0.5.0:
version "0.5.0"
resolved "https://registry.npmjs.org/snarkjs/-/snarkjs-0.5.0.tgz"
integrity sha512-KWz8mZ2Y+6wvn6GGkQo6/ZlKwETdAGohd40Lzpwp5TUZCn6N6O4Az1SuX1rw/qREGL6Im+ycb19suCFE8/xaKA==
@@ -7462,6 +7496,22 @@ snarkjs@0.5.0, snarkjs@^0.5.0:
logplease "^1.2.15"
r1csfile "0.0.41"
snarkjs@^0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/snarkjs/-/snarkjs-0.7.1.tgz#c96ecaf4db8c2eb44d60b17ee02f37ed39c821bb"
integrity sha512-Qs1oxssa135WZkzfARgEp5SuKHKvKNtcspeJbE5je6MurUpBylD1rzcAzQSTGWA/EH/BV/TmUyTaTD64xScvbA==
dependencies:
"@iden3/binfileutils" "0.0.11"
bfj "^7.0.2"
blake2b-wasm "^2.4.0"
circom_runtime "0.1.24"
ejs "^3.1.6"
fastfile "0.0.20"
ffjavascript "0.2.60"
js-sha3 "^0.8.0"
logplease "^1.2.15"
r1csfile "0.0.47"
socks-proxy-agent@^7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz"
@@ -8133,6 +8183,13 @@ wasmcurves@0.2.0:
dependencies:
wasmbuilder "0.0.16"
wasmcurves@0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/wasmcurves/-/wasmcurves-0.2.2.tgz#ca444f6a6f6e2a5cbe6629d98ff478a62b4ccb2b"
integrity sha512-JRY908NkmKjFl4ytnTu5ED6AwPD+8VJ9oc94kdq7h5bIwbj0L4TDJ69mG+2aLs2SoCmGfqIesMWTEJjtYsoQXQ==
dependencies:
wasmbuilder "0.0.16"
wcwidth@^1.0.0, wcwidth@^1.0.1:
version "1.0.1"
resolved "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz"