├── .gitignore ├── circuits ├── test_circuits │ ├── encrypt_test.circom │ └── decrypt_test.circom ├── decrypt.circom └── encrypt.circom ├── .prettierrc ├── tsconfig.json ├── scripts ├── build-all-circuits.sh ├── ptau.sh └── build-circuit.sh ├── utils ├── babyjub-noble.ts ├── precompute.ts ├── decode.ts └── tools.ts ├── benchmark ├── decode.ts ├── noble.ts ├── README.md └── circuit.ts ├── package.json ├── README.md ├── src └── index.ts ├── test ├── elgamal.test.ts └── circuits.test.ts └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | circuits/artifacts 3 | lookupTables 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /circuits/test_circuits/encrypt_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.1.2; 2 | 3 | include "../encrypt.circom"; 4 | 5 | component main { public [ publicKey ] } = Encrypt(); -------------------------------------------------------------------------------- /circuits/test_circuits/decrypt_test.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.1.2; 2 | 3 | include "../decrypt.circom"; 4 | 5 | component main { public [ encryptedMessage ] } = Decrypt(); -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "all", 3 | "tabWidth": 4, 4 | "singleQuote": false, 5 | "printWidth": 100, 6 | "bracketSpacing": true, 7 | "semi": true 8 | } -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | 4 | "target": "es2022", 5 | "module": "commonjs", 6 | "forceConsistentCasingInFileNames": true, 7 | "strict": false, 8 | "noImplicitAny": false, 9 | "skipLibCheck": true, 10 | "allowJs": true 11 | 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /scripts/build-all-circuits.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Check if circom exists in node_modules 4 | if [ -d "./node_modules/circom" ]; then 5 | # If it exists, delete it and its contents -> deleting it removes the bug that prevents running this script 6 | rm -r "./node_modules/circom" 7 | fi 8 | 9 | # Iterate over files with .circom extension in the current directory 10 | for file in ./circuits/test_circuits/*.circom; do 11 | # Extract the base name without the extension 12 | circuit_name=$(basename "$file" .circom) 13 | # Run the build-circuit script with the circuit name as an argument 14 | ./scripts/build-circuit.sh $circuit_name 15 | done 16 | -------------------------------------------------------------------------------- /utils/babyjub-noble.ts: -------------------------------------------------------------------------------- 1 | import { twistedEdwards } from "@noble/curves/abstract/edwards"; 2 | import { Field } from "@noble/curves/abstract/modular"; 3 | import { sha512 } from "@noble/hashes/sha512"; 4 | import { randomBytes } from "@noble/hashes/utils"; 5 | 6 | const Fp = Field(21888242871839275222246405745257275088548364400416034343698204186575808495617n); 7 | export const babyJub = twistedEdwards({ 8 | a: Fp.create(168700n), 9 | d: Fp.create(168696n), 10 | Fp: Fp, 11 | n: 21888242871839275222246405745257275088614511777268538073601725287587578984328n, 12 | h: 8n, 13 | Gx: 5299619240641551281634865583518297030282874472190772894086521144482721001553n, 14 | Gy: 16950150798460657717958625567821834550301663161624707787222815936182638968203n, 15 | hash: sha512, 16 | randomBytes, 17 | } as const); 18 | -------------------------------------------------------------------------------- /benchmark/decode.ts: -------------------------------------------------------------------------------- 1 | import * as bench from 'micro-bmark'; 2 | import * as assert from 'assert' 3 | import { decode, encode } from '../utils/decode'; 4 | import { genRandomSalt, babyJub } from '../src'; 5 | import { pruneTo32Bits } from '../utils/tools'; 6 | const { compare, run } = bench; 7 | 8 | async function decode_noble(precomputeSize: number) { 9 | const salt = pruneTo32Bits(genRandomSalt()); 10 | const encoded = encode(salt); 11 | const decoded = decode(encoded, precomputeSize); 12 | assert(salt === decoded); 13 | 14 | return decoded 15 | } 16 | 17 | run(async () => { 18 | await compare('decode-noble', 25, { 19 | precomputed19: () => decode_noble(19), 20 | precomputed18: () => decode_noble(18), 21 | precomputed17: () => decode_noble(17), 22 | precomputed16: () => decode_noble(16), 23 | }); 24 | bench.utils.logMem(); // Log current RAM 25 | }); -------------------------------------------------------------------------------- /scripts/ptau.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env sh 2 | 3 | set -e 4 | 5 | # -------------------------------------------------------------------------------- 6 | # Phase 1 7 | # ... non-circuit-specific stuff 8 | 9 | # if circuits/artifacts does not exist, make folder 10 | [ -d ./circuits/artifacts ] || mkdir ./circuits/artifacts 11 | 12 | # Check if artifacts/ptau exists 13 | if [ -d ./circuits/artifacts/ptau ]; then 14 | # If it exists, delete it and its contents 15 | rm -r ./circuits/artifacts/ptau 16 | fi 17 | # Create a directory for the ptau file 18 | mkdir -p ./circuits/artifacts/ptau 19 | 20 | POWERS_OF_TAU=15 # circuit will support max 2^POWERS_OF_TAU constraints 21 | if [ ! -f ./ptau$POWERS_OF_TAU ]; then 22 | echo "Downloading powers of tau file" 23 | curl -L https://hermez.s3-eu-west-1.amazonaws.com/powersOfTau28_hez_final_$POWERS_OF_TAU.ptau --create-dirs -o ./circuits/artifacts/ptau/pot$POWERS_OF_TAU.ptau 24 | fi -------------------------------------------------------------------------------- /utils/precompute.ts: -------------------------------------------------------------------------------- 1 | import { babyJub } from "../src/index"; 2 | const fs = require("fs"); 3 | const ProgressBar = require("cli-progress"); 4 | 5 | const bar = new ProgressBar.SingleBar({ 6 | format: 7 | "Progress |" + 8 | "{bar}" + 9 | "| {percentage}% || {value}/{total} Chunks || Remaining time: {eta_formatted}", 10 | barCompleteChar: "\u2588", 11 | barIncompleteChar: "\u2591", 12 | hideCursor: true, 13 | }); 14 | 15 | /** 16 | * Build a lookup table to break discrete log for 32-bit scalars for decoding 17 | * @param precomputeSize the size of the lookup table to be used --> 2**pc_size 18 | * @returns an object that contains 2**pc_size of keys and values 19 | */ 20 | function precompute(precomputeSize: number) { 21 | const directoryName = "lookupTables"; 22 | // Check if the lookupTables directory exists 23 | if (!fs.existsSync(directoryName)) { 24 | // If it doesn't exist, create it 25 | fs.mkdirSync(directoryName); 26 | console.log(`Directory "${directoryName}" created.`); 27 | } 28 | const range = 32 - precomputeSize; 29 | const upperBound = BigInt(2) ** BigInt(precomputeSize); 30 | 31 | let lookupTable = {}; 32 | let key: string; 33 | 34 | bar.start(Number(upperBound), 0); 35 | 36 | for (let xhi = BigInt(0); xhi < upperBound; xhi++) { 37 | key = babyJub.BASE.multiplyUnsafe(xhi * BigInt(2) ** BigInt(range)) 38 | .toAffine() 39 | .x.toString(); 40 | lookupTable[key] = xhi.toString(16); 41 | bar.update(Number(xhi) + 1); 42 | } 43 | bar.stop(); 44 | 45 | fs.writeFileSync( 46 | `./lookupTables/x${precomputeSize}xlookupTable.json`, 47 | JSON.stringify(lookupTable), 48 | ); 49 | } 50 | 51 | precompute(Number(process.argv[2]) || 19); 52 | -------------------------------------------------------------------------------- /benchmark/noble.ts: -------------------------------------------------------------------------------- 1 | import * as bench from 'micro-bmark'; 2 | import { genRandomSalt, genRandomPoint } from '../src'; 3 | import { babyJub as CURVE} from "../utils/babyjub-noble"; 4 | import { toBigIntArray } from '../utils/tools'; 5 | 6 | 7 | const buildBabyjub = require("circomlibjs").buildBabyjub; 8 | const babyJub = CURVE.ExtendedPoint; 9 | 10 | function circomlib_baby_mul(babyjub: any, F: any) { 11 | const randomScalar = genRandomSalt(); 12 | const idenPoint = babyjub.mulPointEscalar(babyjub.Base8, randomScalar); 13 | return idenPoint.map((x) => F.toString(x)) 14 | } 15 | 16 | function noble_baby_mul() { 17 | const randomScalar = genRandomSalt(); 18 | const noblePoint = babyJub.BASE.multiply(randomScalar).toAffine(); 19 | return noblePoint 20 | } 21 | 22 | function circomlib_baby_add(babyjub: any, F: any) { 23 | const point1 = genRandomPoint(); 24 | const point2 = genRandomPoint(); 25 | const point1_e = toBigIntArray(point1).map(x => F.e(x)); 26 | const point2_e = toBigIntArray(point2).map(x => F.e(x)); 27 | const added = babyjub.addPoint(point1_e, point2_e).map(x => F.toString(x)); 28 | 29 | return added 30 | } 31 | 32 | function noble_baby_add() { 33 | const point1 = genRandomPoint(); 34 | const point2 = genRandomPoint(); 35 | const added = point1.add(point2).toAffine() 36 | 37 | return added 38 | } 39 | 40 | const { compare, run } = bench; 41 | run(async () => { 42 | const babyjub = await buildBabyjub(); 43 | const F = babyjub.F; 44 | 45 | await compare('BabyJub EC Multiplication', 1000, { 46 | circomlibjs: () => circomlib_baby_mul(babyjub, F), 47 | noble: () => noble_baby_mul(), 48 | }); 49 | 50 | await compare('BabyJub EC Addition', 10_000, { 51 | circomlibjs: () => circomlib_baby_add(babyjub, F), 52 | noble: () => noble_baby_add(), 53 | }); 54 | bench.utils.logMem(); // Log current RAM 55 | }); -------------------------------------------------------------------------------- /circuits/decrypt.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.1.2; 2 | 3 | include "../node_modules/circomlib/circuits/babyjub.circom"; 4 | include "../node_modules/circomlib/circuits/bitify.circom"; 5 | include "../node_modules/circomlib/circuits/escalarmulany.circom"; 6 | 7 | template Decrypt() { 8 | 9 | // sender's encrypted message 10 | signal input encryptedMessage[2]; 11 | // sender's ephemeral key 12 | signal input ephemeralKey[2]; 13 | // receiver's private key 14 | signal input privateKey; 15 | 16 | // decrypted message => [privateKey].ephemralKey - decryptedMessage 17 | signal output decryptedMessage[2]; 18 | 19 | component isOnCurve[2]; 20 | // assert the encrypted message is a point on curve 21 | isOnCurve[0] = BabyCheck(); 22 | isOnCurve[0].x <== encryptedMessage[0]; 23 | isOnCurve[0].y <== encryptedMessage[1]; 24 | // assert the ephemeral key is a point on curve 25 | isOnCurve[1] = BabyCheck(); 26 | isOnCurve[1].x <== ephemeralKey[0]; 27 | isOnCurve[1].y <== ephemeralKey[1]; 28 | 29 | 30 | component escalarMul = EscalarMulAny(253); 31 | 32 | escalarMul.p[0] <== ephemeralKey[0]; 33 | escalarMul.p[1] <== ephemeralKey[1]; 34 | 35 | var i; 36 | component privateKeyBits = Num2Bits(253); 37 | privateKey ==> privateKeyBits.in; 38 | for (i=0; i<253; i++) { 39 | privateKeyBits.out[i] ==> escalarMul.e[i]; 40 | } 41 | 42 | signal inversedMaskingKey[2]; 43 | inversedMaskingKey[0] <== - escalarMul.out[0]; 44 | inversedMaskingKey[1] <== escalarMul.out[1]; 45 | 46 | component add = BabyAdd(); 47 | 48 | add.x1 <== encryptedMessage[0]; 49 | add.y1 <== encryptedMessage[1]; 50 | add.x2 <== inversedMaskingKey[0]; 51 | add.y2 <== inversedMaskingKey[1]; 52 | 53 | decryptedMessage[0] <== add.xout; 54 | decryptedMessage[1] <== add.yout; 55 | } 56 | 57 | -------------------------------------------------------------------------------- /benchmark/README.md: -------------------------------------------------------------------------------- 1 | ### Break Baby Jubjub ECDL => 25 iterations 2 | 3 | | Decode | Ops/Sec | Avg Time/Op | Min Time | Max Time | 4 | |-----------------|---------|-------------|----------|----------| 5 | | precomputed19 | 1 | 782ms ±18.04%| 129ms | 1988ms | 6 | | precomputed18 | 0 | 1059ms ±26.57%| 123ms | 2862ms | 7 | | precomputed17 | 0 | 2922ms ±21.33%| 123ms | 5609ms | 8 | | precomputed16 | 0 | 5819ms ±19.81%| 352ms | 11s | 9 | 10 | 11 | 12 | ### Baby Jubjub EC Multiplication => 1000 iterations 13 | 14 | | Library | Ops/Sec | Avg Time/Op | Min Time | Max Time | 15 | |--------------|----------|--------------|----------|----------| 16 | | circomlibjs | 106 | 9ms | - | - | 17 | | noble | 6,206 | 161μs ±32.14%| 119μs | 26ms | 18 | 19 | ### Baby Jubjub EC Addition => 10_000 iterations 20 | | Library | Ops/Sec | Avg Time/Op | Min Time | Max Time | 21 | |--------------|----------|--------------|----------|----------| 22 | | circomlibjs | 3,116 | 320μs | - | - | 23 | | noble | 3,165 | 315μs | - | - | 24 | 25 | ### Circuit Constraints 26 | 27 | #### ElGamal Encryption 28 | | Property | Value | 29 | |------------------------|-----------| 30 | | Curve | bn-128 | 31 | | # of Wires | 3348 | 32 | | # of Constraints | 3347 | 33 | | # of Private Inputs | 3 | 34 | | # of Public Inputs | 2 | 35 | | # of Labels | 18273 | 36 | | # of Outputs | 4 | 37 | 38 | #### ElGamal Decryption 39 | 40 | | Property | Value | 41 | |------------------------|-----------| 42 | | Curve | bn-128 | 43 | | # of Wires | 2569 | 44 | | # of Constraints | 2566 | 45 | | # of Private Inputs | 3 | 46 | | # of Public Inputs | 2 | 47 | | # of Labels | 8156 | 48 | | # of Outputs | 2 | -------------------------------------------------------------------------------- /utils/decode.ts: -------------------------------------------------------------------------------- 1 | import { ExtPointType } from "@noble/curves/abstract/edwards"; 2 | import { babyJub } from "../src/index"; 3 | const fs = require("fs"); 4 | 5 | function fetch_table(precomputeSize: number) { 6 | return JSON.parse(fs.readFileSync(`./lookupTables/x${precomputeSize}xlookupTable.json`)); 7 | } 8 | 9 | let lookupTable; 10 | 11 | function decode(encoded: ExtPointType, precomputeSize: number): bigint { 12 | /* The first time decode is called, it will call fetch_table() and store the lookupTable variable. 13 | Subsequent calls to fetchTable() will use the table stored in the lookupTable variable, rather than calling functionA again. 14 | This will save the time from reading the lookupTable whenever decode is called again 15 | */ 16 | if (!lookupTable || Object.keys(lookupTable).length != 2 ** precomputeSize) { 17 | lookupTable = fetch_table(precomputeSize); 18 | } 19 | 20 | const range = 32 - precomputeSize; 21 | const rangeBound = BigInt(2) ** BigInt(range); 22 | 23 | for (let xlo = BigInt(0); xlo < rangeBound; xlo++) { 24 | let loBase = babyJub.BASE.multiplyUnsafe(xlo); 25 | let key = encoded.subtract(loBase).toAffine().x.toString(); 26 | 27 | if (lookupTable.hasOwnProperty(key)) { 28 | return xlo + rangeBound * BigInt("0x" + lookupTable[key]); 29 | } 30 | } 31 | throw new Error("Not Found!"); 32 | } 33 | 34 | function encode(plaintext: bigint): ExtPointType { 35 | if (plaintext <= BigInt(2) ** BigInt(32)) { 36 | return babyJub.BASE.multiplyUnsafe(plaintext); 37 | } else throw new Error("The input should be 32-bit bigint"); 38 | } 39 | 40 | // xlo and xhi merging verification 41 | function split64(x: bigint): [bigint, bigint] { 42 | function padBin(x: string) { 43 | return "0".repeat(64 - x.length) + x; 44 | } 45 | const limit = BigInt(2) ** BigInt(64n); 46 | 47 | if (x <= limit) { 48 | const bin64 = padBin(x.toString(2)); 49 | // the first 32 bits 50 | const xhi = "0b" + bin64.substring(0, 32); 51 | // the last 32 bits 52 | const xlo = "0b" + bin64.substring(32, 64); 53 | 54 | return [BigInt(xlo), BigInt(xhi)]; 55 | } else throw new Error("The input should be 64-bit bigint"); 56 | } 57 | 58 | export { decode, encode, split64 }; 59 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ec-elgamal-circuit", 3 | "version": "2.0.0", 4 | "description": "Circom2 Circuit of ElGamal Scheme over Baby Jubjub Curve", 5 | "main": "index.js", 6 | "scripts": { 7 | "ptau": "./scripts/ptau.sh", 8 | "build-circuits": "./scripts/build-all-circuits.sh", 9 | "test": "ts-mocha --timeout 500000 --require mocha-suppress-logs ./test/*.test.ts --exit", 10 | "test-circuits": "ts-mocha --timeout 5000000 --require mocha-suppress-logs ./test/circuits.test.ts --exit", 11 | "test-elgamal": "ts-mocha --timeout 500000000 ./test/elgamal.test.ts --exit", 12 | "delete-lookupTables": "rm ./lookupTables/*.json", 13 | "precompute-lookupTable": "yarn ts-node ./utils/precompute.ts", 14 | "r1cs-info-encrypt": "snarkjs ri ./circuits/artifacts/encrypt_test/encrypt.r1cs", 15 | "r1cs-info-decrypt": "snarkjs ri ./circuits/artifacts/decrypt_test/decrypt.r1cs", 16 | "r1cs-info-elgamal": "yarn r1cs-info-encrypt && yarn r1cs-info-decrypt", 17 | "r1cs-info": "yarn bench-negate && yarn benchmark-elgamal", 18 | "benchmark-babyjub": "yarn ts-node ./benchmark/noble.ts", 19 | "benchmark-circom_tester": "yarn ts-node ./benchmark/circuit.ts", 20 | "benchmark-decode": "yarn ts-node ./benchmark/decode.ts", 21 | "format": "yarn prettier --write \"src/**/*.{ts,js}\" \"test/**/*.{ts,js}\" \"utils/**/*.{ts,js}\" -w", 22 | "lint": "yarn prettier \"src/**/*{ts,js}\" --check" 23 | }, 24 | "keywords": [ 25 | "ZKP", 26 | "circom2", 27 | "elgamal", 28 | "homomorphic", 29 | "baby jubjub" 30 | ], 31 | "author": "Shigoto-dev19", 32 | "license": "ISC", 33 | "devDependencies": { 34 | "@types/chai": "^4.3.5", 35 | "@types/chai-as-promised": "^7.1.6", 36 | "@types/mocha": "^10.0.1", 37 | "@types/node": "^20.5.3", 38 | "chai": "^4.3.7", 39 | "chai-as-promised": "^7.1.1", 40 | "circom_tester": "^0.0.19", 41 | "cli-progress": "^3.11.2", 42 | "micro-bmark": "^0.3.1", 43 | "mocha": "^10.2.0", 44 | "mocha-suppress-logs": "^0.3.1", 45 | "prettier": "^3.0.3", 46 | "ts-mocha": "^10.0.0", 47 | "ts-node": "^10.9.1", 48 | "typescript": "^5.1.6" 49 | }, 50 | "dependencies": { 51 | "@noble/curves": "^1.2.0", 52 | "circomlib": "^2.0.5", 53 | "circomlibjs": "^0.1.7", 54 | "ffjavascript": "^0.2.60", 55 | "fs": "^0.0.1-security", 56 | "snarkjs": "^0.5.0" 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /benchmark/circuit.ts: -------------------------------------------------------------------------------- 1 | import * as bench from 'micro-bmark'; 2 | import { encrypt, genKeypair } from "../src/index"; 3 | import { getSignalByName, stringifyBigInts, toBigIntArray, toStringArray } from '../utils/tools'; 4 | 5 | const snarkjs = require("snarkjs"); 6 | const path = require("path"); 7 | const wasm_tester = require('circom_tester').wasm; 8 | 9 | const wasm_path_encrypt = "./circuits/artifacts/encrypt_test/encrypt.wasm"; 10 | const zkey_path_encrypt = "./circuits/artifacts/encrypt_test/encrypt.zkey"; 11 | 12 | const genCircuitInputs = () => { 13 | const keypair = genKeypair(); 14 | const encryption = encrypt(keypair.pubKey); 15 | const encrypted_message = toStringArray(encryption.encrypted_message); 16 | 17 | let input_encrypt = stringifyBigInts({ 18 | message: toBigIntArray(encryption.message), 19 | nonceKey: encryption.nonce, 20 | publicKey: toBigIntArray(keypair.pubKey), 21 | }); 22 | 23 | return { input_encrypt, encrypted_message } 24 | } 25 | 26 | async function test_snarkjs() { 27 | const { input_encrypt, encrypted_message } = genCircuitInputs(); 28 | 29 | const prove_encrypt = await snarkjs.groth16.fullProve( 30 | input_encrypt, 31 | wasm_path_encrypt, 32 | zkey_path_encrypt, 33 | ); 34 | const publicSignals_encrypt = prove_encrypt.publicSignals; 35 | 36 | const resX = (publicSignals_encrypt[2] == encrypted_message[0]); 37 | const resY = (publicSignals_encrypt[3] == encrypted_message[1]); 38 | 39 | return resX && resY 40 | } 41 | 42 | async function test_circom_tester(circuit) { 43 | 44 | const { input_encrypt, encrypted_message } = genCircuitInputs(); 45 | 46 | const witness = await circuit.calculateWitness(input_encrypt); 47 | await circuit.checkConstraints(witness); 48 | await circuit.loadSymbols(); 49 | 50 | 51 | const resX = (getSignalByName(circuit, witness, 'main.encryptedMessage[0]') == encrypted_message[0]); 52 | const resY = (getSignalByName(circuit, witness, 'main.encryptedMessage[1]') == encrypted_message[1]); 53 | return resX && resY 54 | } 55 | 56 | const { compare, run } = bench; 57 | run(async () => { 58 | 59 | const circuit = await wasm_tester(path.resolve("./circuits/test_circuits/encrypt_test.circom")); 60 | await compare('Testing Circom Circuits', 50, { 61 | snarkjs: async() => await test_snarkjs(), 62 | circom_tester: async() => await test_circom_tester(circuit), 63 | }); 64 | bench.utils.logMem(); // Log current RAM 65 | (globalThis as any).curve_bn128.terminate(); 66 | // console.log(bench.utils.getTime(), bench.utils.formatD(bench.utils.getTime())); // Get current time in nanoseconds 67 | }); 68 | 69 | -------------------------------------------------------------------------------- /scripts/build-circuit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # -------------------------------------------------------------------------------- 5 | # Phase 2 6 | # ... circuit-specific stuff 7 | 8 | # Check if artifacts/circuitName exists 9 | if [ -d "./circuits/artifacts/$1" ]; then 10 | # If it exists, delete it and its contents 11 | rm -r "./circuits/artifacts/$1" 12 | fi 13 | 14 | # Create a directory for the circuit 15 | mkdir -p "./circuits/artifacts/$1" 16 | 17 | 18 | # Compile circuit => $1 will refer to the full circuit name 19 | CIRCUIT_NAME="${1%%_*}" 20 | circom ./circuits/test_circuits/$1.circom -o ./circuits/artifacts/$1 --r1cs --wasm 21 | 22 | #Setup 23 | yarn snarkjs groth16 setup ./circuits/artifacts/$1/$1.r1cs ./circuits/artifacts/ptau/pot15.ptau ./circuits/artifacts/$1/$CIRCUIT_NAME.zkey 24 | 25 | # # Generate reference zkey 26 | yarn snarkjs zkey new ./circuits/artifacts/$1/$1.r1cs ./circuits/artifacts/ptau/pot15.ptau ./circuits/artifacts/$1/$1_0000.zkey 27 | 28 | # # Ceremony just like before but for zkey this time 29 | yarn snarkjs zkey contribute ./circuits/artifacts/$1/$1_0000.zkey ./circuits/artifacts/$1/$1_0001.zkey \ 30 | --name="First $1 contribution" -v -e="$(head -n 4096 /dev/urandom | openssl sha1)" 31 | 32 | yarn snarkjs zkey contribute ./circuits/artifacts/$1/$1_0001.zkey ./circuits/artifacts/$1/$1_0002.zkey \ 33 | --name="Second $1 contribution" -v -e="$(head -n 4096 /dev/urandom | openssl sha1)" 34 | 35 | yarn snarkjs zkey contribute ./circuits/artifacts/$1/$1_0002.zkey ./circuits/artifacts/$1/$1_0003.zkey \ 36 | --name="Third $1 contribution" -v -e="$(head -n 4096 /dev/urandom | openssl sha1)" 37 | 38 | # # Verify zkey 39 | yarn snarkjs zkey verify ./circuits/artifacts/$1/$1.r1cs ./circuits/artifacts/ptau/pot15.ptau ./circuits/artifacts/$1/$1_0003.zkey 40 | 41 | # # Apply random beacon as before 42 | yarn snarkjs zkey beacon ./circuits/artifacts/$1/$1_0003.zkey ./circuits/artifacts/$1/$CIRCUIT_NAME.zkey \ 43 | 0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f 10 -n="$1 FinalBeacon phase2" 44 | 45 | # # Optional: verify final zkey 46 | yarn snarkjs zkey verify ./circuits/artifacts/$1/$1.r1cs ./circuits/artifacts/ptau/pot15.ptau ./circuits/artifacts/$1/$CIRCUIT_NAME.zkey 47 | 48 | # # Export verification key 49 | yarn snarkjs zkey export verificationkey ./circuits/artifacts/$1/$CIRCUIT_NAME.zkey ./circuits/artifacts/$1/$CIRCUIT_NAME.vkey.json 50 | 51 | 52 | rm ./circuits/artifacts/$1/$1_000*.zkey 53 | mv ./circuits/artifacts/$1/$1_js/$1.wasm ./circuits/artifacts/$1 54 | rm -rf ./circuits/artifacts/$1/$1_js 55 | 56 | # Rename the wasm and r1cs output files 57 | mv ./circuits/artifacts/$1/$1.r1cs ./circuits/artifacts/$1/$CIRCUIT_NAME.r1cs 58 | mv ./circuits/artifacts/$1/$1.wasm ./circuits/artifacts/$1/$CIRCUIT_NAME.wasm 59 | -------------------------------------------------------------------------------- /circuits/encrypt.circom: -------------------------------------------------------------------------------- 1 | pragma circom 2.1.2; 2 | 3 | include "../node_modules/circomlib/circuits/babyjub.circom"; 4 | include "../node_modules/circomlib/circuits/bitify.circom"; 5 | include "../node_modules/circomlib/circuits/escalarmulany.circom"; 6 | include "../node_modules/circomlib/circuits/escalarmulfix.circom"; 7 | 8 | template Encode() { 9 | signal input plaintext; 10 | signal output out[2]; 11 | 12 | // baby jubjub curve base point 13 | var base[2] = [ 14 | 5299619240641551281634865583518297030282874472190772894086521144482721001553, 15 | 16950150798460657717958625567821834550301663161624707787222815936182638968203 16 | ]; 17 | 18 | component plaintextBits = Num2Bits(32); 19 | component escalarMulF = EscalarMulFix(32, base); 20 | 21 | var i; 22 | plaintext ==> plaintextBits.in; 23 | for (i=0; i<32; i++) { 24 | plaintextBits.out[i] ==> escalarMulF.e[i]; 25 | } 26 | 27 | escalarMulF.out ==> out; 28 | } 29 | 30 | template Encrypt() { 31 | 32 | // message encoded as a point on the curve: message = [plaintext].G, G: curve base point 33 | signal input message[2]; 34 | // secret key nonce 35 | signal input nonceKey; 36 | // public key generated by the receiver 37 | signal input publicKey[2]; 38 | 39 | // ephemeral key: [nonce].Base 40 | signal output ephemeralKey[2]; 41 | // encrypted message: encryptedMessage = message + [nonceKey].publicKey 42 | signal output encryptedMessage[2]; 43 | 44 | component isz = IsZero(); 45 | isz.in <== publicKey[0]; 46 | 47 | component ise = IsEqual(); 48 | ise.in[0] <== publicKey[1]; 49 | ise.in[1] <== 1; 50 | 51 | // protect against invalid curve attacks => Public Key shouldn't be the identity point 52 | isz.out + ise.out === 0; 53 | 54 | component isOnCurve[2]; 55 | 56 | // check the public key is point on curve 57 | isOnCurve[0] = BabyCheck(); 58 | isOnCurve[0].x <== publicKey[0]; 59 | isOnCurve[0].y <== publicKey[1]; 60 | 61 | // check the Message is a point on curve 62 | isOnCurve[1] = BabyCheck(); 63 | isOnCurve[1].x <== message[0]; 64 | isOnCurve[1].y <== message[1]; 65 | 66 | // baby jubjub curve base point 67 | var base[2] = [ 68 | 5299619240641551281634865583518297030282874472190772894086521144482721001553, 69 | 16950150798460657717958625567821834550301663161624707787222815936182638968203 70 | ]; 71 | 72 | component n2b[2]; 73 | // calculate the ephemeral key 74 | n2b[0] = Num2Bits(253); 75 | component escalarMulF = EscalarMulFix(253, base); 76 | 77 | var i; 78 | nonceKey ==> n2b[0].in; 79 | for (i=0; i<253; i++) { 80 | n2b[0].out[i] ==> escalarMulF.e[i]; 81 | } 82 | 83 | escalarMulF.out[0] ==> ephemeralKey[0]; 84 | escalarMulF.out[1] ==> ephemeralKey[1]; 85 | 86 | // calculate the second part of the encrypted message => [nonce].PublicKey 87 | n2b[1] = Num2Bits(253); 88 | component escalarMul = EscalarMulAny(253); 89 | 90 | escalarMul.p[0] <== publicKey[0]; 91 | escalarMul.p[1] <== publicKey[1]; 92 | 93 | var j; 94 | nonceKey ==> n2b[1].in; 95 | for (j=0; j<253; j++) { 96 | n2b[1].out[j] ==> escalarMul.e[j]; 97 | } 98 | 99 | component add = BabyAdd(); 100 | add.x1 <== escalarMul.out[0]; 101 | add.y1 <== escalarMul.out[1]; 102 | add.x2 <== message[0]; 103 | add.y2 <== message[1]; 104 | encryptedMessage[0] <== add.xout; 105 | encryptedMessage[1] <== add.yout; 106 | } 107 | -------------------------------------------------------------------------------- /utils/tools.ts: -------------------------------------------------------------------------------- 1 | const createBlakeHash = require("blake-hash"); 2 | const ff = require("ffjavascript"); 3 | 4 | const stringifyBigInts: (obj: object) => any = ff.utils.stringifyBigInts; 5 | const unstringifyBigInts: (obj: object) => any = ff.utils.unstringifyBigInts; 6 | 7 | import { Scalar } from "ffjavascript"; 8 | import { babyJub as CURVE } from "./babyjub-noble"; 9 | import { BabyJubAffinePoint, BabyJubExtPoint } from "../src"; 10 | const babyJub = CURVE.ExtendedPoint; 11 | 12 | // Taken from https://github.com/iden3/circomlibjs/blob/main/src/eddsa.js 13 | function pruneBuffer(buff) { 14 | buff[0] = buff[0] & 0xf8; 15 | buff[31] = buff[31] & 0x7f; 16 | buff[31] = buff[31] | 0x40; 17 | return buff; 18 | } 19 | 20 | // Taken from https://github.com/iden3/circomlibjs/blob/main/src/eddsa.js 21 | function prv2pub(prv) { 22 | const sBuff = pruneBuffer(createBlakeHash("blake512").update(Buffer.from(prv)).digest()); 23 | let s = Scalar.fromRprLE(sBuff, 0, 32); 24 | const A = babyJub.BASE.multiply(BigInt(Scalar.shr(s, 3))); 25 | return A; 26 | } 27 | 28 | /** 29 | * An internal function which formats a random private key to be compatible 30 | * with the BabyJub curve. This is the format which should be passed into the 31 | * PubKey and other circuits. 32 | */ 33 | function formatPrivKeyForBabyJub(privKey: bigint) { 34 | const sBuff = pruneBuffer( 35 | createBlakeHash("blake512").update(bigInt2Buffer(privKey)).digest().slice(0, 32), 36 | ); 37 | const s = ff.utils.leBuff2int(sBuff); 38 | return ff.Scalar.shr(s, 3); 39 | } 40 | 41 | /** 42 | * Convert a BigInt to a Buffer 43 | */ 44 | const bigInt2Buffer = (i: BigInt): Buffer => { 45 | return Buffer.from(i.toString(16), "hex"); 46 | }; 47 | 48 | /** 49 | * Convert an EC extended point into an array of two bigints 50 | */ 51 | function toBigIntArray(point: BabyJubExtPoint): Array { 52 | const point_affine = point.toAffine(); 53 | const x = point_affine.x; 54 | const y = point_affine.y; 55 | return [x, y]; 56 | } 57 | 58 | /** 59 | * Convert an EC extended point into an array of two strings 60 | */ 61 | function toStringArray(point: BabyJubExtPoint): Array { 62 | const point_affine = point.toAffine(); 63 | const x = point_affine.x.toString(); 64 | const y = point_affine.y.toString(); 65 | return [x, y]; 66 | } 67 | 68 | /** 69 | * Convert two strings x and y into an EC extended point 70 | */ 71 | function coordinatesToExtPoint(x: string, y: string): BabyJubExtPoint { 72 | const x_bigint = BigInt(x); 73 | const y_bigint = BigInt(y); 74 | const affine_point: BabyJubAffinePoint = { x: x_bigint, y: y_bigint }; 75 | 76 | return babyJub.fromAffine(affine_point); 77 | } 78 | 79 | function pruneTo64Bits(originalValue: bigint): bigint { 80 | return originalValue & BigInt("0xFFFFFFFFFFFFFFFF"); 81 | } 82 | 83 | // Prune the 253-bit BigInt to 32 bits 84 | function pruneTo32Bits(bigInt253Bit: bigint): bigint { 85 | // Create a mask for 32 bits (all bits set to 1) 86 | const mask32Bit = (1n << 32n) - 1n; 87 | 88 | // Prune to 32 bits using the mask 89 | const pruned32BitBigInt = bigInt253Bit & mask32Bit; 90 | 91 | return pruned32BitBigInt; 92 | } 93 | 94 | /** 95 | * - Returns a signal value similar to the "callGetSignalByName" function from the "circom-helper" package. 96 | * - This function depends on the "circom_tester" package. 97 | * 98 | * Example usage: 99 | * 100 | * ```typescript 101 | * const wasm_tester = require('circom_tester').wasm; 102 | * 103 | * /// the circuit is loaded only once and it is available for use across multiple test cases. 104 | * const circuit = await wasm_tester(path.resolve("./circuit/path")); 105 | * const witness = await circuit.calculateWitness(inputsObject); 106 | * await circuit.checkConstraints(witness); 107 | * await circuit.loadSymbols(); 108 | * 109 | * /// You can check signal names by printing "circuit.symbols". 110 | * /// You will mostly need circuit inputs and outputs. 111 | * const singalName = 'main.out' 112 | * const signalValue = getSignalByName(circuit, witness, SignalName) 113 | * ``` 114 | */ 115 | const getSignalByName = (circuit: any, witness: any, signalName: string) => { 116 | return witness[circuit.symbols[signalName].varIdx].toString(); 117 | }; 118 | 119 | export { 120 | pruneBuffer, 121 | prv2pub, 122 | bigInt2Buffer, 123 | getSignalByName, 124 | stringifyBigInts, 125 | unstringifyBigInts, 126 | toStringArray, 127 | toBigIntArray, 128 | formatPrivKeyForBabyJub, 129 | coordinatesToExtPoint, 130 | pruneTo64Bits, 131 | pruneTo32Bits, 132 | }; 133 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Description 3 | 4 | 5 | 6 | This repo contains circuits to build ElGamal scheme over the [Baby Jubjub](https://eips.ethereum.org/EIPS/eip-2494) curve. 7 | 8 | The code to conduct the general elliptic curve operations is a custiom twisted edwards curve from the [noble-curves]("https://github.com/paulmillr/noble-curves") package to prove compliant results to the field elements dependant circom-circuits. 9 | 10 | The protocol in general aims to realize zero knowledge encryption/decryption that offers linear homomorphic properties. 11 | 12 | - An encoding/decoding algorithm is crucial to preserve linear homomorphism. Many existing mapping, imbedding or encoding techniques are mostly utilized to map a plaintext to a curve point and the encoded point is in most cases undistinguishable when added to another point. 13 | 14 | - The decoding algorithm in this repo is inspired from [solana-zk-token]("https://github.com/solana-labs/solana/tree/master/zk-token-sdk/src") that uses baby-step/giant-step algorithm to break the discrete log of a 32-bit scalar multiplication to the base point. 15 | 16 | - Caching a lookuptable offers O(1) time comlexity that makes decoding faster. 17 | - Additionally, other optimizations were tried to make it even faster by implementing [Worker Threads]("https://nodejs.org/api/worker_threads.html#workergetenvironmentdatakey") to parallelize computation. 18 | - Unfortunately, it is not efficient enough to use native js concurrency and that is why the protocol will take advantage of Rust's ```Fearless Concurrency``` to break the 32-bit ECDL as fast as possible. 19 | 20 | 21 | 22 | ## Install 23 | 24 | 25 | 26 | `yarn install` to install the dependencies. 27 | 28 | 29 | 30 | ## Build 31 | 32 | 1. `yarn ptau` to download a [powerssOfTau]("https://hermezptau.blob.core.windows.net/ptau/powersOfTau28_hez_final_15.ptau") file directly for a direct and swift compilation to build circuits later. 33 | 34 | 2. `yarn build-circuits` to build deterministic development circuits. 35 | 36 | 3. `yarn precompute-lookupTable ` to precompute a lookupTable used to help break the discrete log of the base multiplied by a 32-bit scalar. 37 | 38 | - **Note:** Building a lookupTable of size=19 is crucial to run the tests! 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | ## Test 47 | 48 | 49 | 50 | `yarn test` to run different circuit tests for EC operations as well as ElGamal encryption and decryption. 51 | 52 | `yarn test-circuits` to run circuit tests only. 53 | 54 | `yarn test-elgamal` to run ElGamal Encrypt/Decrypt & Encode/Decode tests only. 55 | 56 | **Note:** What is meant by "*Testing compliance of Encrypt/Decrypt circuits*" is that getting the output of the *"encrypt"* circuit and using it as the input of the *"decrypt"* circuit result in a decrypted message that is identical to the original message used as an input in the *"encrypt"* circuit. 57 | 58 | 59 | ## Bechmarking 60 | 61 | **Note:** You can run the following commands individually or just read a summary of the benchmarks in the [benchmarks README](./benchmark/README.md) 62 | 63 | `yarn r1cs-info-elgamal` to log all important Encrypt/Decrypt circuit infos; 64 | 65 | `yarn benchmark-babyjub` to benchmark Baby Jubjub EC addition and multiplication between [noble](https://github.com/paulmillr/noble-curves) & [circomlibjs](https://github.com/iden3/circomlibjs/blob/main/src/babyjub.js) packages. 66 | 67 | `yarn benchmark-decode` to benchmark decoding speed using different lookup table sizes. 68 | `yarn benchmark-circom_tester` to benchmark the speed between [snarkjs](https://github.com/iden3/snarkjs/tree/master) and [circom_tester](https://github.com/iden3/circom_tester) for circuit testing purposes. 69 | 70 | 71 | 72 | 73 | 74 | 75 | ## Clean 76 | 77 | `yarn delete-lookupTables` to delete all the lookupTables. 78 | 79 | 80 | 81 | ## Scripts 82 | 83 | 84 | 85 | The ```ptau``` and ```build-all-circuits``` scripts make it much easier to compile all circuit and manage the derived files in an organized way by combining [Circom](https://github.com/iden3/circom) and [SnarkJS](https://github.com/iden3/snarkjs) workflow into a single command. 86 | 87 | 88 | 89 | By providing configuration containing your Phase 1 Powers of Tau and circuits, this plugin will: 90 | 91 | 92 | 93 | 1. Compile the circuits 94 | 95 | 2. Apply the final beacon 96 | 97 | 3. Output your `wasm` and `zkey` files 98 | 99 | ## Security Considerations 100 | 101 | - [ERC-2494](https://eips.ethereum.org/EIPS/eip-2494) points to a set of solid security considerations that prove that the Baby Jubjub elliptic curve is indeed resistant against ```weak curve attacks``. 102 | - The literature also states that the discrete logarithm problem remains difficult in the Baby Jubjub curve verifiying resistance againt the following known attacks: 103 | - ```Rho method``` 104 | - ```Additive and multiplicative transfers ``` 105 | - ```High discriminant``` 106 | - The package ```@noble/curves``` offers securtiy against ```time attacks``` for EC multiplication that is explicitly included in its API. 107 | - The public key in the encrypt circuit is checked to be a **point on curve** and **not an infinity point** as a counter for ```invalid curve attacks```(same logic applied for the ts code). 108 | - The ephemeralKey and encryptedMessage inputs are also checked to be points on curve inside the Decrypt circuit. 109 | - The nonces and big numbers are randomly generators by RNG functions imported from the [maci](https://github.com/privacy-scaling-explorations/maci/blob/master/crypto/ts/index.ts) package that depends on secure audited code. 110 | 111 | 112 | 113 | 114 | ## References 115 | 116 | 117 | 118 | If you want to learn about the details of ElGamal Scheme over Elliptic Curves, feel free to visit this [Notion Page](https://www.notion.so/BN254-ElGamal-Scheme-794db63513a04ff1bf76412fc91616ea). -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { AffinePoint } from "@noble/curves/abstract/curve"; 2 | import { babyJub as CURVE } from "../utils/babyjub-noble"; 3 | import { prv2pub, bigInt2Buffer, formatPrivKeyForBabyJub } from "../utils/tools"; 4 | import * as assert from "assert"; 5 | import * as crypto from "crypto"; 6 | import { ExtPointType } from "@noble/curves/abstract/edwards"; 7 | 8 | type SnarkBigInt = bigint; 9 | type PrivKey = bigint; 10 | type PubKey = ExtPointType; 11 | type BabyJubAffinePoint = AffinePoint; 12 | type BabyJubExtPoint = ExtPointType; 13 | 14 | /** 15 | * A private key and a public key 16 | */ 17 | interface Keypair { 18 | privKey: PrivKey; 19 | pubKey: PubKey; 20 | } 21 | 22 | // The BN254 group order p 23 | const SNARK_FIELD_SIZE: SnarkBigInt = BigInt( 24 | "21888242871839275222246405745257275088548364400416034343698204186575808495617", 25 | ); 26 | // Textbook Elgamal Encryption Scheme over Baby Jubjub curve without message encoding 27 | const babyJub = CURVE.ExtendedPoint; 28 | 29 | /** 30 | * Returns a BabyJub-compatible random value. We create it by first generating 31 | * a random value (initially 256 bits large) modulo the snark field size as 32 | * described in EIP197. This results in a key size of roughly 253 bits and no 33 | * more than 254 bits. To prevent modulo bias, we then use this efficient 34 | * algorithm: 35 | * http://cvsweb.openbsd.org/cgi-bin/cvsweb/~checkout~/src/lib/libc/crypt/arc4random_uniform.c 36 | * @return A BabyJub-compatible random value. 37 | * @see {@link https://github.com/privacy-scaling-explorations/maci/blob/master/crypto/ts/index.ts} 38 | */ 39 | function genRandomBabyJubValue(): bigint { 40 | // Prevent modulo bias 41 | //const lim = BigInt('0x10000000000000000000000000000000000000000000000000000000000000000') 42 | //const min = (lim - SNARK_FIELD_SIZE) % SNARK_FIELD_SIZE 43 | const min = BigInt( 44 | "6350874878119819312338956282401532410528162663560392320966563075034087161851", 45 | ); 46 | 47 | let rand; 48 | while (true) { 49 | rand = BigInt("0x" + crypto.randomBytes(32).toString("hex")); 50 | 51 | if (rand >= min) { 52 | break; 53 | } 54 | } 55 | 56 | const privKey: PrivKey = rand % SNARK_FIELD_SIZE; 57 | assert(privKey < SNARK_FIELD_SIZE); 58 | 59 | return privKey; 60 | } 61 | 62 | /** 63 | * @return A BabyJub-compatible private key. 64 | */ 65 | const genPrivKey = (): PrivKey => { 66 | return genRandomBabyJubValue(); 67 | }; 68 | 69 | /** 70 | * @return A BabyJub-compatible salt. 71 | */ 72 | const genRandomSalt = (): PrivKey => { 73 | return genRandomBabyJubValue(); 74 | }; 75 | 76 | /** 77 | * @param privKey A private key generated using genPrivKey() 78 | * @return A public key associated with the private key 79 | */ 80 | function genPubKey(privKey: PrivKey): PubKey { 81 | // Check whether privKey is a field element 82 | privKey = BigInt(privKey.toString()); 83 | assert(privKey < SNARK_FIELD_SIZE); 84 | return prv2pub(bigInt2Buffer(privKey)); 85 | } 86 | 87 | function genKeypair(): Keypair { 88 | const privKey = genPrivKey(); 89 | const pubKey = genPubKey(privKey); 90 | 91 | const Keypair: Keypair = { privKey, pubKey }; 92 | 93 | return Keypair; 94 | } 95 | 96 | function genRandomPoint(): BabyJubExtPoint { 97 | const salt = genRandomBabyJubValue(); 98 | return genPubKey(salt); 99 | } 100 | 101 | /** 102 | * Encrypts a plaintext such that only the owner of the specified public key 103 | * may decrypt it. 104 | * @param pubKey The recepient's public key 105 | * @param encodedMessage A plaintext encoded as a BabyJub curve point (optional) 106 | * @param randomVal A random value y used along with the private key to generate the ciphertext (optional) 107 | */ 108 | function encrypt(pubKey: PubKey, encodedMessage?: BabyJubExtPoint, randomVal?: bigint) { 109 | const message = encodedMessage ?? genRandomPoint(); 110 | 111 | // The sender chooses a secret key as a nonce 112 | const nonce: bigint = randomVal ?? formatPrivKeyForBabyJub(genRandomSalt()); 113 | 114 | // The sender calculates an ephemeral key => [nonce].Base 115 | const ephemeral_key = babyJub.BASE.multiply(nonce); 116 | const masking_key = pubKey.multiply(nonce); 117 | let encrypted_message: BabyJubExtPoint; 118 | // The sender encrypts the encodedMessage 119 | if (pubKey.assertValidity && !pubKey.equals(babyJub.ZERO)) { 120 | encrypted_message = message.add(masking_key); 121 | } else throw new Error("Invalid Public Key!"); 122 | 123 | return { message, ephemeral_key, encrypted_message, nonce }; 124 | } 125 | 126 | /** 127 | * Decrypts a ciphertext using a private key. 128 | * @param privKey The private key 129 | * @param ciphertext The ciphertext to decrypt 130 | */ 131 | function decrypt( 132 | privKey: PrivKey, 133 | ephemeral_key: BabyJubExtPoint, 134 | encrypted_message: BabyJubExtPoint, 135 | ): BabyJubExtPoint { 136 | // The receiver decrypts the message => encryptedMessage - [privKey].ephemeralKey 137 | const masking_key = ephemeral_key.multiply(formatPrivKeyForBabyJub(privKey)); 138 | const decrypted_message = encrypted_message.add(masking_key.negate()); 139 | 140 | return decrypted_message; 141 | } 142 | 143 | // ElGamal Scheme with specified inputs for testing purposes 144 | function encrypt_s(message: BabyJubExtPoint, public_key: PubKey, nonce?: bigint) { 145 | nonce = nonce ?? genRandomSalt(); 146 | 147 | const ephemeral_key = babyJub.BASE.multiply(nonce); 148 | const masking_key = public_key.multiply(nonce); 149 | const encrypted_message = masking_key.add(message); 150 | 151 | return { ephemeral_key, encrypted_message }; 152 | } 153 | /** 154 | * Randomize a ciphertext such that it is different from the original 155 | * ciphertext but can be decrypted by the same private key. 156 | * @param pubKey The same public key used to encrypt the original encodedMessage 157 | * @param ciphertext The ciphertext to re-randomize. 158 | * @param randomVal A random value z such that the re-randomized ciphertext could have been generated a random value y+z in the first 159 | * place (optional) 160 | */ 161 | function rerandomize( 162 | pubKey: PubKey, 163 | ephemeral_key: BabyJubExtPoint, 164 | encrypted_message: BabyJubExtPoint, 165 | randomVal?: bigint, 166 | ) { 167 | const nonce = randomVal ?? genRandomSalt(); 168 | const randomized_ephemeralKey = ephemeral_key.add(babyJub.BASE.multiply(nonce)); 169 | 170 | const randomized_encryptedMessage = encrypted_message.add(pubKey.multiply(nonce)); 171 | 172 | return { randomized_ephemeralKey, randomized_encryptedMessage }; 173 | } 174 | export { 175 | genRandomBabyJubValue, 176 | genRandomPoint, 177 | genRandomSalt, 178 | genPrivKey, 179 | genPubKey, 180 | genKeypair, 181 | encrypt, 182 | encrypt_s, 183 | decrypt, 184 | rerandomize, 185 | babyJub, 186 | BabyJubAffinePoint, 187 | BabyJubExtPoint, 188 | Keypair, 189 | }; 190 | -------------------------------------------------------------------------------- /test/elgamal.test.ts: -------------------------------------------------------------------------------- 1 | import { decode, encode, split64 } from "../utils/decode"; 2 | import { assert, expect } from "chai"; 3 | import { 4 | babyJub, 5 | genRandomPoint, 6 | genKeypair, 7 | genRandomSalt, 8 | encrypt, 9 | encrypt_s, 10 | decrypt, 11 | rerandomize, 12 | } from "../src"; 13 | 14 | import { pruneTo32Bits, pruneTo64Bits } from "../utils/tools"; 15 | 16 | const b32 = 4294967296n; 17 | 18 | describe("Testing ElGamal Scheme on EC points directly", () => { 19 | it("Check compliance of orignal and decrypted message as points", () => { 20 | const keypair = genKeypair(); 21 | const encryption = encrypt(keypair.pubKey); 22 | const decrypted_message = decrypt( 23 | keypair.privKey, 24 | encryption.ephemeral_key, 25 | encryption.encrypted_message, 26 | ); 27 | expect(encryption.message.toAffine(), "Decrypted message is different!").deep.equal( 28 | decrypted_message.toAffine(), 29 | ); 30 | }); 31 | 32 | it("Check unhappy compliance of orignal and decrypted message as points", () => { 33 | const keypair = genKeypair(); 34 | let encryption = encrypt(keypair.pubKey); 35 | // we just need to modify any of the inputs 36 | const { randomized_ephemeralKey } = rerandomize( 37 | keypair.pubKey, 38 | encryption.ephemeral_key, 39 | encryption.encrypted_message, 40 | ); 41 | const decrypted_message = decrypt( 42 | keypair.privKey, 43 | randomized_ephemeralKey, 44 | encryption.encrypted_message, 45 | ); 46 | 47 | expect(encryption.message.toAffine(), "Somehting went wrong!").to.not.deep.equal( 48 | decrypted_message.toAffine(), 49 | ); 50 | }); 51 | 52 | it("Check LOOPED compliance of orignal and decrypted message as points", () => { 53 | for (let i = 0; i < 100; i++) { 54 | let keypair = genKeypair(); 55 | let encryption = encrypt(keypair.pubKey); 56 | let decrypted_message = decrypt( 57 | keypair.privKey, 58 | encryption.ephemeral_key, 59 | encryption.encrypted_message, 60 | ); 61 | 62 | expect(encryption.message.toAffine(), "Decrypted message is different!").to.deep.equal( 63 | decrypted_message.toAffine(), 64 | ); 65 | } 66 | }); 67 | 68 | it("Check homomorphic properties of the Elgamal Scheme", () => { 69 | const keypair = genKeypair(); 70 | 71 | const encryption1 = encrypt(keypair.pubKey); 72 | const encryption2 = encrypt(keypair.pubKey); 73 | 74 | // We want to prove that message3 is equal to decrypted(encryptedMessage3) 75 | const message3 = encryption1.message.add(encryption2.message); 76 | const encrypted_message3 = encryption1.encrypted_message.add(encryption2.encrypted_message); 77 | const ephemeral_key3 = encryption1.ephemeral_key.add(encryption2.ephemeral_key); 78 | 79 | const decrypted_message3 = decrypt(keypair.privKey, ephemeral_key3, encrypted_message3); 80 | 81 | expect(decrypted_message3.toAffine(), "Invalid linear homomorphism!").to.deep.equal( 82 | message3.toAffine(), 83 | ); 84 | }); 85 | 86 | it("Check unhappy homomorphic properties for wrong inputs", () => { 87 | const keypair = genKeypair(); 88 | 89 | const encryption1 = encrypt(keypair.pubKey); 90 | const encryption2 = encrypt(keypair.pubKey); 91 | 92 | const message3 = encryption1.message.add(encryption2.message); 93 | const encrypted_message3 = encryption1.encrypted_message.add(encryption2.encrypted_message); 94 | // we only modifiy ephemeral_key3 in this example 95 | const ephemeral_key3 = encryption1.ephemeral_key.add(babyJub.BASE); 96 | 97 | const decrypted_message3 = decrypt(keypair.privKey, ephemeral_key3, encrypted_message3); 98 | 99 | expect(decrypted_message3.toAffine(), "Invalid linear homomorphism!").to.not.deep.equal( 100 | message3.toAffine(), 101 | ); 102 | }); 103 | }); 104 | 105 | describe("Testing Encoding/Decoding for ElGamal Scheme", async () => { 106 | it("Check encoding a plain text bigger than 32 bits returns error", () => { 107 | const plaintext = 4294967297n; 108 | let expected = Error; 109 | const exercise = () => encode(plaintext); 110 | assert.throws(exercise, expected); 111 | }); 112 | 113 | it("Check encoded value is a valid BabyJub point", () => { 114 | const plaintext = pruneTo32Bits(genRandomSalt()); 115 | const encoded = encode(plaintext); 116 | encoded.assertValidity(); 117 | }); 118 | 119 | it("Check compliance of orignal and decoded message as 32-bit numbers", async () => { 120 | const plaintext = pruneTo32Bits(genRandomSalt()); 121 | const encoded = encode(plaintext); 122 | const decoded = decode(encoded, 19); 123 | 124 | assert(plaintext === decoded, "Decoded number is different!"); 125 | }); 126 | 127 | it.skip("Check unhappy compliance of orignal and decoded message for a different random input", async () => { 128 | const plaintext = pruneTo32Bits(genRandomSalt()); 129 | const encoded = encode(plaintext); 130 | const rand = genRandomPoint(); 131 | const decoded = decode(encoded, 19); 132 | const decoded_rand = decode(rand, 19); 133 | 134 | assert(plaintext === decoded && decoded !== decoded_rand, "Something went different!"); 135 | }); 136 | 137 | it("Check LOOPED compliance of orignal and decoded message as 32-bit numbers", async () => { 138 | for (let i = 0; i < 15; i++) { 139 | let plaintext = pruneTo32Bits(genRandomSalt()); 140 | let encoded = encode(plaintext); 141 | let decoded = decode(encoded, 19); 142 | 143 | assert(plaintext === decoded, "Decoded number is different!"); 144 | } 145 | }); 146 | 147 | it("Check decoding preserves Elgamal linear homomorphism", async () => { 148 | // The input should be a 64-bit number 149 | const plaintext = pruneTo64Bits(genRandomSalt()); 150 | 151 | // the initial input is split into two 32-bit numbers for faster decoding 152 | const [xlo, xhi] = split64(plaintext); 153 | 154 | const M1 = encode(xlo); 155 | const M2 = encode(xhi); 156 | 157 | const keypair = genKeypair(); 158 | 159 | const encryption1 = encrypt_s(M1, keypair.pubKey); 160 | const encryption2 = encrypt_s(M2, keypair.pubKey); 161 | 162 | const decrypted_message1 = decrypt( 163 | keypair.privKey, 164 | encryption1.ephemeral_key, 165 | encryption1.encrypted_message, 166 | ); 167 | const decrypted_message2 = decrypt( 168 | keypair.privKey, 169 | encryption2.ephemeral_key, 170 | encryption2.encrypted_message, 171 | ); 172 | 173 | const dlo = decode(decrypted_message1, 19); 174 | const dhi = decode(decrypted_message2, 19); 175 | 176 | const decoded_input = dlo + b32 * dhi; 177 | 178 | assert(decoded_input === plaintext, "decoding led to different result!"); 179 | }); 180 | 181 | it("Check unhappy decoding breaks Elgamal linear homomorphism", async () => { 182 | // The input should be a 64-bit number 183 | const input = pruneTo64Bits(genRandomSalt()); 184 | 185 | // the initial input is split into two 32-bit numbers for faster decoding 186 | const [xlo, xhi] = split64(input); 187 | 188 | // we swap xlo and xhi to mess with the decoding 189 | const M1 = encode(xhi); 190 | const M2 = encode(xlo); 191 | 192 | const keypair = genKeypair(); 193 | 194 | const encryption1 = encrypt_s(M1, keypair.pubKey); 195 | const encryption2 = encrypt_s(M2, keypair.pubKey); 196 | 197 | const decrypted_message1 = decrypt( 198 | keypair.privKey, 199 | encryption1.ephemeral_key, 200 | encryption1.encrypted_message, 201 | ); 202 | const decrypted_message2 = decrypt( 203 | keypair.privKey, 204 | encryption2.ephemeral_key, 205 | encryption2.encrypted_message, 206 | ); 207 | 208 | const dlo = decode(decrypted_message1, 19); 209 | const dhi = decode(decrypted_message2, 19); 210 | 211 | const decoded_input = dlo + b32 * dhi; 212 | 213 | assert(decoded_input !== input, "decoding led to different result!"); 214 | }); 215 | 216 | it("Check LOOPED decoding preserves Elgamal linear homomorphism", async () => { 217 | for (let i = 0; i < 10; i++) { 218 | // The input should be a 64-bit number 219 | const input = pruneTo64Bits(genRandomSalt()); 220 | 221 | // the initial input is split into two 32-bit numbers for faster decoding 222 | let [xlo, xhi] = split64(input); 223 | 224 | let M1 = encode(xlo); 225 | let M2 = encode(xhi); 226 | 227 | let keypair = genKeypair(); 228 | 229 | const encryption1 = encrypt_s(M1, keypair.pubKey); 230 | const encryption2 = encrypt_s(M2, keypair.pubKey); 231 | 232 | const decrypted_message1 = decrypt( 233 | keypair.privKey, 234 | encryption1.ephemeral_key, 235 | encryption1.encrypted_message, 236 | ); 237 | const decrypted_message2 = decrypt( 238 | keypair.privKey, 239 | encryption2.ephemeral_key, 240 | encryption2.encrypted_message, 241 | ); 242 | 243 | const dlo = decode(decrypted_message1, 19); 244 | const dhi = decode(decrypted_message2, 19); 245 | 246 | const decoded_input = dlo + b32 * dhi; 247 | 248 | assert(decoded_input === input, "decoding led to different result!"); 249 | } 250 | }); 251 | }); 252 | -------------------------------------------------------------------------------- /test/circuits.test.ts: -------------------------------------------------------------------------------- 1 | const snarkjs = require("snarkjs"); 2 | const fs = require("fs"); 3 | const expect = require("chai").expect; 4 | const chai = require("chai"); 5 | const chaiAsPromised = require("chai-as-promised"); 6 | // Load chai-as-promised support 7 | chai.use(chaiAsPromised); 8 | 9 | import { ExtPointType } from "@noble/curves/abstract/edwards"; 10 | import { 11 | genKeypair, 12 | genRandomSalt, 13 | encrypt, 14 | decrypt, 15 | genRandomPoint, 16 | babyJub, 17 | Keypair, 18 | BabyJubExtPoint, 19 | } from "../src"; 20 | import { 21 | toStringArray, 22 | stringifyBigInts, 23 | toBigIntArray, 24 | formatPrivKeyForBabyJub, 25 | coordinatesToExtPoint, 26 | } from "../utils/tools"; 27 | 28 | type EncryptCircuitInputs = { 29 | message: string[]; 30 | nonceKey: string; 31 | publicKey: string[]; 32 | }; 33 | 34 | type DecryptCircuitInputs = { 35 | encryptedMessage: string[]; 36 | ephemeralKey: string[]; 37 | privateKey: string; 38 | }; 39 | 40 | const wasm_path_encrypt = "./circuits/artifacts/encrypt_test/encrypt.wasm"; 41 | const zkey_path_encrypt = "./circuits/artifacts/encrypt_test/encrypt.zkey"; 42 | 43 | const wasm_path_decrypt = "./circuits/artifacts/decrypt_test/decrypt.wasm"; 44 | const zkey_path_decrypt = "./circuits/artifacts/decrypt_test/decrypt.zkey"; 45 | 46 | const genCircuitInputs = ( 47 | keypair: Keypair, 48 | encodedMessage?: BabyJubExtPoint, 49 | ): { 50 | input_encrypt: EncryptCircuitInputs; 51 | ephemeral_key: string[]; 52 | encrypted_message: string[]; 53 | } => { 54 | const encryption = encrypt(keypair.pubKey, encodedMessage); 55 | 56 | let input_encrypt: EncryptCircuitInputs = stringifyBigInts({ 57 | message: toBigIntArray(encryption.message), 58 | nonceKey: encryption.nonce, 59 | publicKey: toBigIntArray(keypair.pubKey), 60 | }); 61 | 62 | const ephemeral_key = toStringArray(encryption.ephemeral_key); 63 | const encrypted_message = toStringArray(encryption.encrypted_message); 64 | return { input_encrypt, ephemeral_key, encrypted_message }; 65 | }; 66 | 67 | describe("Testing ElGamal Scheme Circuits\n", () => { 68 | context("Testing Encrypt Circuit", () => { 69 | let input_encrypt: EncryptCircuitInputs; 70 | let keypair: Keypair; 71 | let ephemeral_key: string[]; 72 | let encrypted_message: string[]; 73 | 74 | before(() => { 75 | keypair = genKeypair(); 76 | const object = genCircuitInputs(keypair); 77 | input_encrypt = object.input_encrypt; 78 | ephemeral_key = object.ephemeral_key; 79 | encrypted_message = object.encrypted_message; 80 | }); 81 | 82 | it("Verify Encrypt circuit", async () => { 83 | const { proof, publicSignals } = await snarkjs.groth16.fullProve( 84 | input_encrypt, 85 | wasm_path_encrypt, 86 | zkey_path_encrypt, 87 | ); 88 | const vKey = JSON.parse( 89 | fs.readFileSync("./circuits/artifacts/encrypt_test/encrypt.vkey.json"), 90 | ); 91 | 92 | const res = await snarkjs.groth16.verify(vKey, publicSignals, proof); 93 | expect(res).to.equal(true); 94 | }); 95 | 96 | it("Verify circuit is resistant to invalid curve attacks: Invalid Public Key: not on curve", async () => { 97 | const invalid_input = { 98 | message: input_encrypt.message, 99 | nonceKey: input_encrypt.nonceKey, 100 | publicKey: ["1", "0"], 101 | } 102 | try { 103 | await snarkjs.groth16.fullProve( 104 | invalid_input, 105 | wasm_path_encrypt, 106 | zkey_path_encrypt, 107 | ); 108 | throw new Error('Expected to throw an error'); 109 | } catch (error) { 110 | expect(error.message).to.contain("Error: Assert Failed. Error in template BabyCheck_2 line: 82\nError in template Encrypt_19 line: 59") 111 | } 112 | }); 113 | 114 | it("Verify circuit is resistant to invalid curve attacks: Invalid Public Key: identity", async () => { 115 | const invalid_input = { 116 | message: input_encrypt.message, 117 | nonceKey: input_encrypt.nonceKey, 118 | publicKey: ["0", "1"], 119 | } 120 | try { 121 | await snarkjs.groth16.fullProve( 122 | invalid_input, 123 | wasm_path_encrypt, 124 | zkey_path_encrypt, 125 | ); 126 | throw new Error('Expected to throw an error'); 127 | } catch (error) { 128 | expect(error.message).to.contain("Error: Assert Failed. Error in template Encrypt_19 line: 52") 129 | } 130 | }); 131 | 132 | it("Verify Message assertion to be a point on curve", async () => { 133 | const invalid_input = { 134 | message: ["1", "0"], 135 | nonceKey: input_encrypt.nonceKey, 136 | publicKey: input_encrypt.publicKey, 137 | } 138 | try { 139 | await snarkjs.groth16.fullProve( 140 | invalid_input, 141 | wasm_path_encrypt, 142 | zkey_path_encrypt, 143 | ); 144 | throw new Error('Expected to throw an error'); 145 | } catch (error) { 146 | expect(error.message).to.contain("Error: Assert Failed. Error in template BabyCheck_2 line: 82\nError in template Encrypt_19 line: 64") 147 | } 148 | }); 149 | 150 | it("Verify compliant encrypt output", async () => { 151 | const { publicSignals } = await snarkjs.groth16.fullProve( 152 | input_encrypt, 153 | wasm_path_encrypt, 154 | zkey_path_encrypt, 155 | ); 156 | // Verify compliant encryption output for the ephemeral key 157 | expect(publicSignals[0]).to.equals(ephemeral_key[0]); 158 | expect(publicSignals[1]).to.equals(ephemeral_key[1]); 159 | // Verify compliant encryption output for the encrypted message 160 | expect(publicSignals[2]).to.equals(encrypted_message[0]); 161 | expect(publicSignals[3]).to.equals(encrypted_message[1]); 162 | }); 163 | 164 | it("Verify false encrypt output is invalid", async () => { 165 | input_encrypt.nonceKey = formatPrivKeyForBabyJub(genRandomSalt()); 166 | const { publicSignals } = await snarkjs.groth16.fullProve( 167 | input_encrypt, 168 | wasm_path_encrypt, 169 | zkey_path_encrypt, 170 | ); 171 | 172 | // Verify compliant encryption output for the ephemeral key 173 | expect(publicSignals[0]).to.not.equals(ephemeral_key[0]); 174 | expect(publicSignals[1]).to.not.equals(ephemeral_key[1]); 175 | // Verify compliant encryption output for the encrypted message 176 | expect(publicSignals[2]).to.not.equals(encrypted_message[0]); 177 | expect(publicSignals[3]).to.not.equals(encrypted_message[1]); 178 | }); 179 | 180 | it("Looped: Verify compliant encrypt output for random inputs", async () => { 181 | for (let i = 0; i < 5; i++) { 182 | keypair = genKeypair(); 183 | let { input_encrypt, ephemeral_key, encrypted_message } = genCircuitInputs(keypair); 184 | const { publicSignals } = await snarkjs.groth16.fullProve( 185 | input_encrypt, 186 | wasm_path_encrypt, 187 | zkey_path_encrypt, 188 | ); 189 | // Verify compliant encryption output for the ephemeral key 190 | expect(publicSignals[0]).to.equals(ephemeral_key[0]); 191 | expect(publicSignals[1]).to.equals(ephemeral_key[1]); 192 | // Verify compliant encryption output for the encrypted message 193 | expect(publicSignals[2]).to.equals(encrypted_message[0]); 194 | expect(publicSignals[3]).to.equals(encrypted_message[1]); 195 | } 196 | }); 197 | }); 198 | 199 | context("Testing Decrypt Circuit", () => { 200 | let input_encrypt: EncryptCircuitInputs; 201 | let input_decrypt: DecryptCircuitInputs; 202 | let keypair: Keypair; 203 | let ephemeral_key: string[]; 204 | let encrypted_message: string[]; 205 | let decrypted_message: string[]; 206 | let message: string[]; 207 | let encodedMessage: ExtPointType; 208 | 209 | before(() => { 210 | keypair = genKeypair(); 211 | encodedMessage = genRandomPoint(); 212 | message = toStringArray(encodedMessage); 213 | 214 | const encryption = genCircuitInputs(keypair, encodedMessage); 215 | input_encrypt = encryption.input_encrypt; 216 | ephemeral_key = encryption.ephemeral_key; 217 | encrypted_message = encryption.encrypted_message; 218 | 219 | input_decrypt = { 220 | encryptedMessage: encrypted_message, 221 | ephemeralKey: ephemeral_key, 222 | privateKey: formatPrivKeyForBabyJub(keypair.privKey), 223 | }; 224 | }); 225 | 226 | it("Verify Decrypt circuit", async () => { 227 | const { proof, publicSignals } = await snarkjs.groth16.fullProve( 228 | input_decrypt, 229 | wasm_path_decrypt, 230 | zkey_path_decrypt, 231 | ); 232 | const vKey = JSON.parse( 233 | fs.readFileSync("./circuits/artifacts/decrypt_test/decrypt.vkey.json"), 234 | ); 235 | 236 | const res = await snarkjs.groth16.verify(vKey, publicSignals, proof); 237 | expect(res).to.equal(true); 238 | }); 239 | 240 | it("Verify encryptedMessage assertion to be a point on curve", async () => { 241 | const invalid_input = { 242 | encryptedMessage: ["1", "0"], 243 | ephemeralKey: input_decrypt.ephemeralKey, 244 | privateKey: input_decrypt.privateKey, 245 | } 246 | try { 247 | await snarkjs.groth16.fullProve( 248 | invalid_input, 249 | wasm_path_decrypt, 250 | zkey_path_decrypt, 251 | ); 252 | throw new Error('Expected to throw an error'); 253 | } catch (error) { 254 | expect(error.message).to.contain("Error: Assert Failed. Error in template BabyCheck_0 line: 82\nError in template Decrypt_13 line: 23") 255 | } 256 | }); 257 | 258 | it("Verify ephemeralKey assertion to be a point on curve", async () => { 259 | const invalid_input = { 260 | encryptedMessage: input_decrypt.encryptedMessage, 261 | ephemeralKey: ["1", "0"], 262 | privateKey: input_decrypt.privateKey, 263 | } 264 | try { 265 | await snarkjs.groth16.fullProve( 266 | invalid_input, 267 | wasm_path_decrypt, 268 | zkey_path_decrypt, 269 | ); 270 | throw new Error('Expected to throw an error'); 271 | } catch (error) { 272 | expect(error.message).to.contain("Error: Assert Failed. Error in template BabyCheck_0 line: 82\nError in template Decrypt_13 line: 27") 273 | } 274 | }); 275 | 276 | it("Verify compliant decrypt output", async () => { 277 | const { publicSignals } = await snarkjs.groth16.fullProve( 278 | input_decrypt, 279 | wasm_path_decrypt, 280 | zkey_path_decrypt, 281 | ); 282 | 283 | // Verify compliant decryption output of the decrypted message 284 | expect(publicSignals[0]).to.equals(message[0]); 285 | expect(publicSignals[1]).to.equals(message[1]); 286 | 287 | // Verify compliant decryption input for the encrypted message 288 | expect(publicSignals[2]).to.equals(encrypted_message[0]); 289 | expect(publicSignals[3]).to.equals(encrypted_message[1]); 290 | }); 291 | 292 | it("Verify false decrypt output is invalid", async () => { 293 | // only modify the private key 294 | input_decrypt.privateKey = formatPrivKeyForBabyJub(genRandomSalt()); 295 | const { publicSignals } = await snarkjs.groth16.fullProve( 296 | input_decrypt, 297 | wasm_path_decrypt, 298 | zkey_path_decrypt, 299 | ); 300 | 301 | // Verify compliant decryption output of the decrypted message 302 | expect(publicSignals[0]).to.not.equals(message[0]); 303 | expect(publicSignals[1]).to.not.equals(message[1]); 304 | 305 | // Verify compliant decryption input for the encrypted message 306 | expect(publicSignals[2]).to.equals(encrypted_message[0]); 307 | expect(publicSignals[3]).to.equals(encrypted_message[1]); 308 | }); 309 | 310 | it("Looped: Verify compliant decrypt output for random inputs", async () => { 311 | for (let i = 0; i < 5; i++) { 312 | keypair = genKeypair(); 313 | encodedMessage = genRandomPoint(); 314 | message = toStringArray(encodedMessage); 315 | 316 | const object = genCircuitInputs(keypair, encodedMessage); 317 | input_encrypt = object.input_encrypt; 318 | ephemeral_key = object.ephemeral_key; 319 | encrypted_message = object.encrypted_message; 320 | 321 | input_decrypt = { 322 | encryptedMessage: encrypted_message, 323 | ephemeralKey: ephemeral_key, 324 | privateKey: formatPrivKeyForBabyJub(keypair.privKey), 325 | }; 326 | 327 | const { publicSignals } = await snarkjs.groth16.fullProve( 328 | input_decrypt, 329 | wasm_path_decrypt, 330 | zkey_path_decrypt, 331 | ); 332 | 333 | // Verify compliant decryption output of the decrypted message 334 | expect(publicSignals[0]).to.equals(message[0]); 335 | expect(publicSignals[1]).to.equals(message[1]); 336 | 337 | // Verify compliant decryption input for the encrypted message 338 | expect(publicSignals[2]).to.equals(encrypted_message[0]); 339 | expect(publicSignals[3]).to.equals(encrypted_message[1]); 340 | } 341 | }); 342 | }); 343 | 344 | context("Testing compliance of Encrypt/Decrypt circuits: circuit to circuit", () => { 345 | let input_encrypt: EncryptCircuitInputs; 346 | let input_decrypt: DecryptCircuitInputs; 347 | let keypair: Keypair; 348 | let ephemeral_key: string[]; 349 | let encrypted_message: string[]; 350 | let decrypted_message: string[]; 351 | let message: string[]; 352 | let encodedMessage: ExtPointType; 353 | 354 | before(() => { 355 | keypair = genKeypair(); 356 | encodedMessage = genRandomPoint(); 357 | message = toStringArray(encodedMessage); 358 | 359 | let encryption = genCircuitInputs(keypair, encodedMessage); 360 | input_encrypt = encryption.input_encrypt; 361 | ephemeral_key = encryption.ephemeral_key; 362 | encrypted_message = encryption.encrypted_message; 363 | }); 364 | 365 | it("Verify the message input is the same as decrypted message", async () => { 366 | const prove_encrypt = await snarkjs.groth16.fullProve( 367 | input_encrypt, 368 | wasm_path_encrypt, 369 | zkey_path_encrypt, 370 | ); 371 | const publicSignals_encrypt = prove_encrypt.publicSignals; 372 | 373 | const input_decrypt = { 374 | encryptedMessage: [publicSignals_encrypt[2], publicSignals_encrypt[3]], 375 | ephemeralKey: [publicSignals_encrypt[0], publicSignals_encrypt[1]], 376 | privateKey: formatPrivKeyForBabyJub(keypair.privKey), 377 | }; 378 | 379 | const prove_decrypt = await snarkjs.groth16.fullProve( 380 | input_decrypt, 381 | wasm_path_decrypt, 382 | zkey_path_decrypt, 383 | ); 384 | const publicSignals_decrypt = prove_decrypt.publicSignals; 385 | 386 | expect(publicSignals_decrypt[0]).to.equals(message[0]); 387 | expect(publicSignals_decrypt[1]).to.equals(message[1]); 388 | }); 389 | 390 | it("Looped Verify the circuits given random inputs", async () => { 391 | for (let i = 0; i < 10; i++) { 392 | message = toStringArray(encodedMessage); 393 | keypair = genKeypair(); 394 | 395 | const object = genCircuitInputs(keypair, encodedMessage); 396 | input_encrypt = object.input_encrypt; 397 | ephemeral_key = object.ephemeral_key; 398 | encrypted_message = object.encrypted_message; 399 | 400 | const prove_encrypt = await snarkjs.groth16.fullProve( 401 | input_encrypt, 402 | wasm_path_encrypt, 403 | zkey_path_encrypt, 404 | ); 405 | const publicSignals_encrypt = prove_encrypt.publicSignals; 406 | 407 | // The input of the decrypt circuit is given by the output of the encrypt circuit 408 | let input_decrypt = { 409 | encryptedMessage: [publicSignals_encrypt[2], publicSignals_encrypt[3]], 410 | ephemeralKey: [publicSignals_encrypt[0], publicSignals_encrypt[1]], 411 | privateKey: formatPrivKeyForBabyJub(keypair.privKey), 412 | }; 413 | 414 | const prove_decrypt = await snarkjs.groth16.fullProve( 415 | input_decrypt, 416 | wasm_path_decrypt, 417 | zkey_path_decrypt, 418 | ); 419 | const publicSignals_decrypt = prove_decrypt.publicSignals; 420 | 421 | expect(publicSignals_decrypt[0]).to.equals(message[0]); 422 | expect(publicSignals_decrypt[1]).to.equals(message[1]); 423 | } 424 | }); 425 | 426 | it("Verify the ElGamal homomorphic property of two random messages", async () => { 427 | const keypair = genKeypair(); 428 | 429 | const encodedMessage1 = genRandomPoint(); 430 | const encryption1 = genCircuitInputs(keypair, encodedMessage1); 431 | const input_encrypt1 = encryption1.input_encrypt; 432 | 433 | const encodedMessage2 = genRandomPoint(); 434 | const encryption2 = genCircuitInputs(keypair, encodedMessage2); 435 | const input_encrypt2 = encryption2.input_encrypt; 436 | 437 | const prove_encrypt1 = await snarkjs.groth16.fullProve( 438 | input_encrypt1, 439 | wasm_path_encrypt, 440 | zkey_path_encrypt, 441 | ); 442 | const publicSignals_encrypt1 = prove_encrypt1.publicSignals; 443 | 444 | const prove_encrypt2 = await snarkjs.groth16.fullProve( 445 | input_encrypt2, 446 | wasm_path_encrypt, 447 | zkey_path_encrypt, 448 | ); 449 | const publicSignals_encrypt2 = prove_encrypt2.publicSignals; 450 | 451 | // Take the first encrypted message from the circuit output 452 | const encrypted_message1 = coordinatesToExtPoint( 453 | publicSignals_encrypt1[2], 454 | publicSignals_encrypt1[3], 455 | ); 456 | // Take the second encrypted message from the circuit output 457 | const encrypted_message2 = coordinatesToExtPoint( 458 | publicSignals_encrypt2[2], 459 | publicSignals_encrypt2[3], 460 | ); 461 | 462 | // Add both encrypted messages to verify the homomorphic property 463 | const encrypted_message3 = encrypted_message1.add(encrypted_message2); 464 | // Proving message is equal to the decrypted(encrypted_message3) => will prove the homomorphic property 465 | let message3 = encodedMessage1.add(encodedMessage2); 466 | 467 | // Take the first ephemeral key from the circuit output 468 | const ephemeral_key1 = coordinatesToExtPoint( 469 | publicSignals_encrypt1[0], 470 | publicSignals_encrypt1[1], 471 | ); 472 | // Take the second ephemeral key from the circuit output 473 | const ephemeral_key2 = coordinatesToExtPoint( 474 | publicSignals_encrypt2[0], 475 | publicSignals_encrypt2[1], 476 | ); 477 | 478 | // The ephemeral key for homomorphic decryption should be ephemeral_key1 + ephemeral_key2 479 | const ephemeral_key3 = ephemeral_key1.add(ephemeral_key2); 480 | 481 | // The input of the decrypt circuit is given by the added outputs of the encrypt circuit for message1 and message2 482 | const input_decrypt3: DecryptCircuitInputs = { 483 | encryptedMessage: toStringArray(encrypted_message3), 484 | ephemeralKey: toStringArray(ephemeral_key3), 485 | privateKey: formatPrivKeyForBabyJub(keypair.privKey), 486 | }; 487 | 488 | const prove_decrypt = await snarkjs.groth16.fullProve( 489 | input_decrypt3, 490 | wasm_path_decrypt, 491 | zkey_path_decrypt, 492 | ); 493 | const publicSignals_decrypt3 = prove_decrypt.publicSignals; 494 | 495 | expect(publicSignals_decrypt3[0]).to.equals(message3.toAffine().x.toString()); 496 | expect(publicSignals_decrypt3[1]).to.equals(message3.toAffine().y.toString()); 497 | }); 498 | }); 499 | }); 500 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@cspotcode/source-map-support@^0.8.0": 6 | version "0.8.1" 7 | resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" 8 | integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== 9 | dependencies: 10 | "@jridgewell/trace-mapping" "0.3.9" 11 | 12 | "@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.7.0": 13 | version "5.7.0" 14 | resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" 15 | integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== 16 | dependencies: 17 | "@ethersproject/address" "^5.7.0" 18 | "@ethersproject/bignumber" "^5.7.0" 19 | "@ethersproject/bytes" "^5.7.0" 20 | "@ethersproject/constants" "^5.7.0" 21 | "@ethersproject/hash" "^5.7.0" 22 | "@ethersproject/keccak256" "^5.7.0" 23 | "@ethersproject/logger" "^5.7.0" 24 | "@ethersproject/properties" "^5.7.0" 25 | "@ethersproject/strings" "^5.7.0" 26 | 27 | "@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.7.0": 28 | version "5.7.0" 29 | resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef" 30 | integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== 31 | dependencies: 32 | "@ethersproject/bignumber" "^5.7.0" 33 | "@ethersproject/bytes" "^5.7.0" 34 | "@ethersproject/logger" "^5.7.0" 35 | "@ethersproject/networks" "^5.7.0" 36 | "@ethersproject/properties" "^5.7.0" 37 | "@ethersproject/transactions" "^5.7.0" 38 | "@ethersproject/web" "^5.7.0" 39 | 40 | "@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.7.0": 41 | version "5.7.0" 42 | resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2" 43 | integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== 44 | dependencies: 45 | "@ethersproject/abstract-provider" "^5.7.0" 46 | "@ethersproject/bignumber" "^5.7.0" 47 | "@ethersproject/bytes" "^5.7.0" 48 | "@ethersproject/logger" "^5.7.0" 49 | "@ethersproject/properties" "^5.7.0" 50 | 51 | "@ethersproject/address@5.7.0", "@ethersproject/address@^5.7.0": 52 | version "5.7.0" 53 | resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" 54 | integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== 55 | dependencies: 56 | "@ethersproject/bignumber" "^5.7.0" 57 | "@ethersproject/bytes" "^5.7.0" 58 | "@ethersproject/keccak256" "^5.7.0" 59 | "@ethersproject/logger" "^5.7.0" 60 | "@ethersproject/rlp" "^5.7.0" 61 | 62 | "@ethersproject/base64@5.7.0", "@ethersproject/base64@^5.7.0": 63 | version "5.7.0" 64 | resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c" 65 | integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== 66 | dependencies: 67 | "@ethersproject/bytes" "^5.7.0" 68 | 69 | "@ethersproject/basex@5.7.0", "@ethersproject/basex@^5.7.0": 70 | version "5.7.0" 71 | resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.7.0.tgz#97034dc7e8938a8ca943ab20f8a5e492ece4020b" 72 | integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw== 73 | dependencies: 74 | "@ethersproject/bytes" "^5.7.0" 75 | "@ethersproject/properties" "^5.7.0" 76 | 77 | "@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.7.0": 78 | version "5.7.0" 79 | resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" 80 | integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== 81 | dependencies: 82 | "@ethersproject/bytes" "^5.7.0" 83 | "@ethersproject/logger" "^5.7.0" 84 | bn.js "^5.2.1" 85 | 86 | "@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.7.0": 87 | version "5.7.0" 88 | resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" 89 | integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== 90 | dependencies: 91 | "@ethersproject/logger" "^5.7.0" 92 | 93 | "@ethersproject/constants@5.7.0", "@ethersproject/constants@^5.7.0": 94 | version "5.7.0" 95 | resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e" 96 | integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== 97 | dependencies: 98 | "@ethersproject/bignumber" "^5.7.0" 99 | 100 | "@ethersproject/contracts@5.7.0": 101 | version "5.7.0" 102 | resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e" 103 | integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== 104 | dependencies: 105 | "@ethersproject/abi" "^5.7.0" 106 | "@ethersproject/abstract-provider" "^5.7.0" 107 | "@ethersproject/abstract-signer" "^5.7.0" 108 | "@ethersproject/address" "^5.7.0" 109 | "@ethersproject/bignumber" "^5.7.0" 110 | "@ethersproject/bytes" "^5.7.0" 111 | "@ethersproject/constants" "^5.7.0" 112 | "@ethersproject/logger" "^5.7.0" 113 | "@ethersproject/properties" "^5.7.0" 114 | "@ethersproject/transactions" "^5.7.0" 115 | 116 | "@ethersproject/hash@5.7.0", "@ethersproject/hash@^5.7.0": 117 | version "5.7.0" 118 | resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" 119 | integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== 120 | dependencies: 121 | "@ethersproject/abstract-signer" "^5.7.0" 122 | "@ethersproject/address" "^5.7.0" 123 | "@ethersproject/base64" "^5.7.0" 124 | "@ethersproject/bignumber" "^5.7.0" 125 | "@ethersproject/bytes" "^5.7.0" 126 | "@ethersproject/keccak256" "^5.7.0" 127 | "@ethersproject/logger" "^5.7.0" 128 | "@ethersproject/properties" "^5.7.0" 129 | "@ethersproject/strings" "^5.7.0" 130 | 131 | "@ethersproject/hdnode@5.7.0", "@ethersproject/hdnode@^5.7.0": 132 | version "5.7.0" 133 | resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.7.0.tgz#e627ddc6b466bc77aebf1a6b9e47405ca5aef9cf" 134 | integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== 135 | dependencies: 136 | "@ethersproject/abstract-signer" "^5.7.0" 137 | "@ethersproject/basex" "^5.7.0" 138 | "@ethersproject/bignumber" "^5.7.0" 139 | "@ethersproject/bytes" "^5.7.0" 140 | "@ethersproject/logger" "^5.7.0" 141 | "@ethersproject/pbkdf2" "^5.7.0" 142 | "@ethersproject/properties" "^5.7.0" 143 | "@ethersproject/sha2" "^5.7.0" 144 | "@ethersproject/signing-key" "^5.7.0" 145 | "@ethersproject/strings" "^5.7.0" 146 | "@ethersproject/transactions" "^5.7.0" 147 | "@ethersproject/wordlists" "^5.7.0" 148 | 149 | "@ethersproject/json-wallets@5.7.0", "@ethersproject/json-wallets@^5.7.0": 150 | version "5.7.0" 151 | resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz#5e3355287b548c32b368d91014919ebebddd5360" 152 | integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== 153 | dependencies: 154 | "@ethersproject/abstract-signer" "^5.7.0" 155 | "@ethersproject/address" "^5.7.0" 156 | "@ethersproject/bytes" "^5.7.0" 157 | "@ethersproject/hdnode" "^5.7.0" 158 | "@ethersproject/keccak256" "^5.7.0" 159 | "@ethersproject/logger" "^5.7.0" 160 | "@ethersproject/pbkdf2" "^5.7.0" 161 | "@ethersproject/properties" "^5.7.0" 162 | "@ethersproject/random" "^5.7.0" 163 | "@ethersproject/strings" "^5.7.0" 164 | "@ethersproject/transactions" "^5.7.0" 165 | aes-js "3.0.0" 166 | scrypt-js "3.0.1" 167 | 168 | "@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.7.0": 169 | version "5.7.0" 170 | resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" 171 | integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== 172 | dependencies: 173 | "@ethersproject/bytes" "^5.7.0" 174 | js-sha3 "0.8.0" 175 | 176 | "@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.7.0": 177 | version "5.7.0" 178 | resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" 179 | integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== 180 | 181 | "@ethersproject/networks@5.7.1", "@ethersproject/networks@^5.7.0": 182 | version "5.7.1" 183 | resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" 184 | integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== 185 | dependencies: 186 | "@ethersproject/logger" "^5.7.0" 187 | 188 | "@ethersproject/pbkdf2@5.7.0", "@ethersproject/pbkdf2@^5.7.0": 189 | version "5.7.0" 190 | resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz#d2267d0a1f6e123f3771007338c47cccd83d3102" 191 | integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== 192 | dependencies: 193 | "@ethersproject/bytes" "^5.7.0" 194 | "@ethersproject/sha2" "^5.7.0" 195 | 196 | "@ethersproject/properties@5.7.0", "@ethersproject/properties@^5.7.0": 197 | version "5.7.0" 198 | resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" 199 | integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== 200 | dependencies: 201 | "@ethersproject/logger" "^5.7.0" 202 | 203 | "@ethersproject/providers@5.7.2": 204 | version "5.7.2" 205 | resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" 206 | integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== 207 | dependencies: 208 | "@ethersproject/abstract-provider" "^5.7.0" 209 | "@ethersproject/abstract-signer" "^5.7.0" 210 | "@ethersproject/address" "^5.7.0" 211 | "@ethersproject/base64" "^5.7.0" 212 | "@ethersproject/basex" "^5.7.0" 213 | "@ethersproject/bignumber" "^5.7.0" 214 | "@ethersproject/bytes" "^5.7.0" 215 | "@ethersproject/constants" "^5.7.0" 216 | "@ethersproject/hash" "^5.7.0" 217 | "@ethersproject/logger" "^5.7.0" 218 | "@ethersproject/networks" "^5.7.0" 219 | "@ethersproject/properties" "^5.7.0" 220 | "@ethersproject/random" "^5.7.0" 221 | "@ethersproject/rlp" "^5.7.0" 222 | "@ethersproject/sha2" "^5.7.0" 223 | "@ethersproject/strings" "^5.7.0" 224 | "@ethersproject/transactions" "^5.7.0" 225 | "@ethersproject/web" "^5.7.0" 226 | bech32 "1.1.4" 227 | ws "7.4.6" 228 | 229 | "@ethersproject/random@5.7.0", "@ethersproject/random@^5.7.0": 230 | version "5.7.0" 231 | resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.7.0.tgz#af19dcbc2484aae078bb03656ec05df66253280c" 232 | integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== 233 | dependencies: 234 | "@ethersproject/bytes" "^5.7.0" 235 | "@ethersproject/logger" "^5.7.0" 236 | 237 | "@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.7.0": 238 | version "5.7.0" 239 | resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" 240 | integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== 241 | dependencies: 242 | "@ethersproject/bytes" "^5.7.0" 243 | "@ethersproject/logger" "^5.7.0" 244 | 245 | "@ethersproject/sha2@5.7.0", "@ethersproject/sha2@^5.7.0": 246 | version "5.7.0" 247 | resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb" 248 | integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw== 249 | dependencies: 250 | "@ethersproject/bytes" "^5.7.0" 251 | "@ethersproject/logger" "^5.7.0" 252 | hash.js "1.1.7" 253 | 254 | "@ethersproject/signing-key@5.7.0", "@ethersproject/signing-key@^5.7.0": 255 | version "5.7.0" 256 | resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3" 257 | integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== 258 | dependencies: 259 | "@ethersproject/bytes" "^5.7.0" 260 | "@ethersproject/logger" "^5.7.0" 261 | "@ethersproject/properties" "^5.7.0" 262 | bn.js "^5.2.1" 263 | elliptic "6.5.4" 264 | hash.js "1.1.7" 265 | 266 | "@ethersproject/solidity@5.7.0": 267 | version "5.7.0" 268 | resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8" 269 | integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA== 270 | dependencies: 271 | "@ethersproject/bignumber" "^5.7.0" 272 | "@ethersproject/bytes" "^5.7.0" 273 | "@ethersproject/keccak256" "^5.7.0" 274 | "@ethersproject/logger" "^5.7.0" 275 | "@ethersproject/sha2" "^5.7.0" 276 | "@ethersproject/strings" "^5.7.0" 277 | 278 | "@ethersproject/strings@5.7.0", "@ethersproject/strings@^5.7.0": 279 | version "5.7.0" 280 | resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" 281 | integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== 282 | dependencies: 283 | "@ethersproject/bytes" "^5.7.0" 284 | "@ethersproject/constants" "^5.7.0" 285 | "@ethersproject/logger" "^5.7.0" 286 | 287 | "@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.7.0": 288 | version "5.7.0" 289 | resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" 290 | integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== 291 | dependencies: 292 | "@ethersproject/address" "^5.7.0" 293 | "@ethersproject/bignumber" "^5.7.0" 294 | "@ethersproject/bytes" "^5.7.0" 295 | "@ethersproject/constants" "^5.7.0" 296 | "@ethersproject/keccak256" "^5.7.0" 297 | "@ethersproject/logger" "^5.7.0" 298 | "@ethersproject/properties" "^5.7.0" 299 | "@ethersproject/rlp" "^5.7.0" 300 | "@ethersproject/signing-key" "^5.7.0" 301 | 302 | "@ethersproject/units@5.7.0": 303 | version "5.7.0" 304 | resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.7.0.tgz#637b563d7e14f42deeee39245275d477aae1d8b1" 305 | integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== 306 | dependencies: 307 | "@ethersproject/bignumber" "^5.7.0" 308 | "@ethersproject/constants" "^5.7.0" 309 | "@ethersproject/logger" "^5.7.0" 310 | 311 | "@ethersproject/wallet@5.7.0": 312 | version "5.7.0" 313 | resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d" 314 | integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== 315 | dependencies: 316 | "@ethersproject/abstract-provider" "^5.7.0" 317 | "@ethersproject/abstract-signer" "^5.7.0" 318 | "@ethersproject/address" "^5.7.0" 319 | "@ethersproject/bignumber" "^5.7.0" 320 | "@ethersproject/bytes" "^5.7.0" 321 | "@ethersproject/hash" "^5.7.0" 322 | "@ethersproject/hdnode" "^5.7.0" 323 | "@ethersproject/json-wallets" "^5.7.0" 324 | "@ethersproject/keccak256" "^5.7.0" 325 | "@ethersproject/logger" "^5.7.0" 326 | "@ethersproject/properties" "^5.7.0" 327 | "@ethersproject/random" "^5.7.0" 328 | "@ethersproject/signing-key" "^5.7.0" 329 | "@ethersproject/transactions" "^5.7.0" 330 | "@ethersproject/wordlists" "^5.7.0" 331 | 332 | "@ethersproject/web@5.7.1", "@ethersproject/web@^5.7.0": 333 | version "5.7.1" 334 | resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" 335 | integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== 336 | dependencies: 337 | "@ethersproject/base64" "^5.7.0" 338 | "@ethersproject/bytes" "^5.7.0" 339 | "@ethersproject/logger" "^5.7.0" 340 | "@ethersproject/properties" "^5.7.0" 341 | "@ethersproject/strings" "^5.7.0" 342 | 343 | "@ethersproject/wordlists@5.7.0", "@ethersproject/wordlists@^5.7.0": 344 | version "5.7.0" 345 | resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.7.0.tgz#8fb2c07185d68c3e09eb3bfd6e779ba2774627f5" 346 | integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== 347 | dependencies: 348 | "@ethersproject/bytes" "^5.7.0" 349 | "@ethersproject/hash" "^5.7.0" 350 | "@ethersproject/logger" "^5.7.0" 351 | "@ethersproject/properties" "^5.7.0" 352 | "@ethersproject/strings" "^5.7.0" 353 | 354 | "@iden3/bigarray@0.0.2": 355 | version "0.0.2" 356 | resolved "https://registry.yarnpkg.com/@iden3/bigarray/-/bigarray-0.0.2.tgz#6fc4ba5be18daf8a26ee393f2fb62b80d98c05e9" 357 | integrity sha512-Xzdyxqm1bOFF6pdIsiHLLl3HkSLjbhqJHVyqaTxXt3RqXBEnmsUmEW47H7VOi/ak7TdkRpNkxjyK5Zbkm+y52g== 358 | 359 | "@iden3/binfileutils@0.0.11": 360 | version "0.0.11" 361 | resolved "https://registry.yarnpkg.com/@iden3/binfileutils/-/binfileutils-0.0.11.tgz#9ffbbcc1279f2b2182bb6dcff4eee8a5b2167911" 362 | integrity sha512-LylnJoZ0CTdgErnKY8OxohvW4K+p6UHD3sxt+3P9AmMyBQjYR4IpoqoYZZ+9aMj89cmCQ21UvdhndAx04er3NA== 363 | dependencies: 364 | fastfile "0.0.20" 365 | ffjavascript "^0.2.48" 366 | 367 | "@jridgewell/resolve-uri@^3.0.3": 368 | version "3.1.1" 369 | resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" 370 | integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== 371 | 372 | "@jridgewell/sourcemap-codec@^1.4.10": 373 | version "1.4.15" 374 | resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" 375 | integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== 376 | 377 | "@jridgewell/trace-mapping@0.3.9": 378 | version "0.3.9" 379 | resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" 380 | integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== 381 | dependencies: 382 | "@jridgewell/resolve-uri" "^3.0.3" 383 | "@jridgewell/sourcemap-codec" "^1.4.10" 384 | 385 | "@noble/curves@^1.2.0": 386 | version "1.2.0" 387 | resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.2.0.tgz#92d7e12e4e49b23105a2555c6984d41733d65c35" 388 | integrity sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw== 389 | dependencies: 390 | "@noble/hashes" "1.3.2" 391 | 392 | "@noble/hashes@1.3.2": 393 | version "1.3.2" 394 | resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" 395 | integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== 396 | 397 | "@tsconfig/node10@^1.0.7": 398 | version "1.0.9" 399 | resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" 400 | integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== 401 | 402 | "@tsconfig/node12@^1.0.7": 403 | version "1.0.11" 404 | resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" 405 | integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== 406 | 407 | "@tsconfig/node14@^1.0.0": 408 | version "1.0.3" 409 | resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" 410 | integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== 411 | 412 | "@tsconfig/node16@^1.0.2": 413 | version "1.0.4" 414 | resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" 415 | integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== 416 | 417 | "@types/chai-as-promised@^7.1.6": 418 | version "7.1.6" 419 | resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.6.tgz#3b08cbe1e7206567a480dc6538bade374b19e4e1" 420 | integrity sha512-cQLhk8fFarRVZAXUQV1xEnZgMoPxqKojBvRkqPCKPQCzEhpbbSKl1Uu75kDng7k5Ln6LQLUmNBjLlFthCgm1NA== 421 | dependencies: 422 | "@types/chai" "*" 423 | 424 | "@types/chai@*": 425 | version "4.3.6" 426 | resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.6.tgz#7b489e8baf393d5dd1266fb203ddd4ea941259e6" 427 | integrity sha512-VOVRLM1mBxIRxydiViqPcKn6MIxZytrbMpd6RJLIWKxUNr3zux8no0Oc7kJx0WAPIitgZ0gkrDS+btlqQpubpw== 428 | 429 | "@types/chai@^4.3.5": 430 | version "4.3.5" 431 | resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.5.tgz#ae69bcbb1bebb68c4ac0b11e9d8ed04526b3562b" 432 | integrity sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng== 433 | 434 | "@types/json5@^0.0.29": 435 | version "0.0.29" 436 | resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" 437 | integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== 438 | 439 | "@types/mocha@^10.0.1": 440 | version "10.0.1" 441 | resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b" 442 | integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== 443 | 444 | "@types/node@^20.5.3": 445 | version "20.5.3" 446 | resolved "https://registry.yarnpkg.com/@types/node/-/node-20.5.3.tgz#fa52c147f405d56b2f1dd8780d840aa87ddff629" 447 | integrity sha512-ITI7rbWczR8a/S6qjAW7DMqxqFMjjTo61qZVWJ1ubPvbIQsL5D/TvwjYEalM8Kthpe3hTzOGrF2TGbAu2uyqeA== 448 | 449 | acorn-walk@^8.1.1: 450 | version "8.2.0" 451 | resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" 452 | integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== 453 | 454 | acorn@^8.4.1: 455 | version "8.10.0" 456 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" 457 | integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== 458 | 459 | aes-js@3.0.0: 460 | version "3.0.0" 461 | resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" 462 | integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== 463 | 464 | ansi-colors@4.1.1: 465 | version "4.1.1" 466 | resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" 467 | integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== 468 | 469 | ansi-regex@^5.0.1: 470 | version "5.0.1" 471 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" 472 | integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== 473 | 474 | ansi-styles@^4.0.0, ansi-styles@^4.1.0: 475 | version "4.3.0" 476 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" 477 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== 478 | dependencies: 479 | color-convert "^2.0.1" 480 | 481 | anymatch@~3.1.2: 482 | version "3.1.3" 483 | resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" 484 | integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== 485 | dependencies: 486 | normalize-path "^3.0.0" 487 | picomatch "^2.0.4" 488 | 489 | arg@^4.1.0: 490 | version "4.1.3" 491 | resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" 492 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== 493 | 494 | argparse@^2.0.1: 495 | version "2.0.1" 496 | resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" 497 | integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 498 | 499 | arrify@^1.0.0: 500 | version "1.0.1" 501 | resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" 502 | integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== 503 | 504 | assertion-error@^1.1.0: 505 | version "1.1.0" 506 | resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" 507 | integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== 508 | 509 | async@^3.2.3: 510 | version "3.2.4" 511 | resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" 512 | integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== 513 | 514 | available-typed-arrays@^1.0.5: 515 | version "1.0.5" 516 | resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" 517 | integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== 518 | 519 | b4a@^1.0.1: 520 | version "1.6.4" 521 | resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.4.tgz#ef1c1422cae5ce6535ec191baeed7567443f36c9" 522 | integrity sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw== 523 | 524 | balanced-match@^1.0.0: 525 | version "1.0.2" 526 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" 527 | integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== 528 | 529 | bech32@1.1.4: 530 | version "1.1.4" 531 | resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" 532 | integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== 533 | 534 | bfj@^7.0.2: 535 | version "7.0.2" 536 | resolved "https://registry.yarnpkg.com/bfj/-/bfj-7.0.2.tgz#1988ce76f3add9ac2913fd8ba47aad9e651bfbb2" 537 | integrity sha512-+e/UqUzwmzJamNF50tBV6tZPTORow7gQ96iFow+8b562OdMpEK0BcJEq2OSPEDmAbSMBQ7PKZ87ubFkgxpYWgw== 538 | dependencies: 539 | bluebird "^3.5.5" 540 | check-types "^11.1.1" 541 | hoopy "^0.1.4" 542 | tryer "^1.0.1" 543 | 544 | binary-extensions@^2.0.0: 545 | version "2.2.0" 546 | resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" 547 | integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== 548 | 549 | blake-hash@^2.0.0: 550 | version "2.0.0" 551 | resolved "https://registry.yarnpkg.com/blake-hash/-/blake-hash-2.0.0.tgz#af184dce641951126d05b7d1c3de3224f538d66e" 552 | integrity sha512-Igj8YowDu1PRkRsxZA7NVkdFNxH5rKv5cpLxQ0CVXSIA77pVYwCPRQJ2sMew/oneUpfuYRyjG6r8SmmmnbZb1w== 553 | dependencies: 554 | node-addon-api "^3.0.0" 555 | node-gyp-build "^4.2.2" 556 | readable-stream "^3.6.0" 557 | 558 | blake2b-wasm@^2.4.0: 559 | version "2.4.0" 560 | resolved "https://registry.yarnpkg.com/blake2b-wasm/-/blake2b-wasm-2.4.0.tgz#9115649111edbbd87eb24ce7c04b427e4e2be5be" 561 | integrity sha512-S1kwmW2ZhZFFFOghcx73+ZajEfKBqhP82JMssxtLVMxlaPea1p9uoLiUZ5WYyHn0KddwbLc+0vh4wR0KBNoT5w== 562 | dependencies: 563 | b4a "^1.0.1" 564 | nanoassert "^2.0.0" 565 | 566 | blake2b@^2.1.3: 567 | version "2.1.4" 568 | resolved "https://registry.yarnpkg.com/blake2b/-/blake2b-2.1.4.tgz#817d278526ddb4cd673bfb1af16d1ad61e393ba3" 569 | integrity sha512-AyBuuJNI64gIvwx13qiICz6H6hpmjvYS5DGkG6jbXMOT8Z3WUJ3V1X0FlhIoT1b/5JtHE3ki+xjtMvu1nn+t9A== 570 | dependencies: 571 | blake2b-wasm "^2.4.0" 572 | nanoassert "^2.0.0" 573 | 574 | bluebird@^3.5.5: 575 | version "3.7.2" 576 | resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" 577 | integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== 578 | 579 | bn.js@^4.11.9: 580 | version "4.12.0" 581 | resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" 582 | integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== 583 | 584 | bn.js@^5.2.1: 585 | version "5.2.1" 586 | resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" 587 | integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== 588 | 589 | brace-expansion@^1.1.7: 590 | version "1.1.11" 591 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 592 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 593 | dependencies: 594 | balanced-match "^1.0.0" 595 | concat-map "0.0.1" 596 | 597 | brace-expansion@^2.0.1: 598 | version "2.0.1" 599 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" 600 | integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== 601 | dependencies: 602 | balanced-match "^1.0.0" 603 | 604 | braces@~3.0.2: 605 | version "3.0.2" 606 | resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" 607 | integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== 608 | dependencies: 609 | fill-range "^7.0.1" 610 | 611 | brorand@^1.1.0: 612 | version "1.1.0" 613 | resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" 614 | integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== 615 | 616 | browser-stdout@1.3.1: 617 | version "1.3.1" 618 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" 619 | integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== 620 | 621 | buffer-from@^1.0.0, buffer-from@^1.1.0: 622 | version "1.1.2" 623 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" 624 | integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== 625 | 626 | call-bind@^1.0.2: 627 | version "1.0.2" 628 | resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" 629 | integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== 630 | dependencies: 631 | function-bind "^1.1.1" 632 | get-intrinsic "^1.0.2" 633 | 634 | camelcase@^6.0.0: 635 | version "6.3.0" 636 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" 637 | integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== 638 | 639 | chai-as-promised@^7.1.1: 640 | version "7.1.1" 641 | resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" 642 | integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA== 643 | dependencies: 644 | check-error "^1.0.2" 645 | 646 | chai@^4.3.6, chai@^4.3.7: 647 | version "4.3.7" 648 | resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51" 649 | integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A== 650 | dependencies: 651 | assertion-error "^1.1.0" 652 | check-error "^1.0.2" 653 | deep-eql "^4.1.2" 654 | get-func-name "^2.0.0" 655 | loupe "^2.3.1" 656 | pathval "^1.1.1" 657 | type-detect "^4.0.5" 658 | 659 | chalk@^4.0.2, chalk@^4.1.0: 660 | version "4.1.2" 661 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" 662 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== 663 | dependencies: 664 | ansi-styles "^4.1.0" 665 | supports-color "^7.1.0" 666 | 667 | check-error@^1.0.2: 668 | version "1.0.2" 669 | resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" 670 | integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== 671 | 672 | check-types@^11.1.1: 673 | version "11.2.2" 674 | resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.2.2.tgz#7afc0b6a860d686885062f2dba888ba5710335b4" 675 | integrity sha512-HBiYvXvn9Z70Z88XKjz3AEKd4HJhBXsa3j7xFnITAzoS8+q6eIGi8qDB8FKPBAjtuxjI/zFpwuiCb8oDtKOYrA== 676 | 677 | child_process@^1.0.2: 678 | version "1.0.2" 679 | resolved "https://registry.yarnpkg.com/child_process/-/child_process-1.0.2.tgz#b1f7e7fc73d25e7fd1d455adc94e143830182b5a" 680 | integrity sha512-Wmza/JzL0SiWz7kl6MhIKT5ceIlnFPJX+lwUGj7Clhy5MMldsSoJR0+uvRzOS5Kv45Mq7t1PoE8TsOA9bzvb6g== 681 | 682 | chokidar@3.5.3: 683 | version "3.5.3" 684 | resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" 685 | integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== 686 | dependencies: 687 | anymatch "~3.1.2" 688 | braces "~3.0.2" 689 | glob-parent "~5.1.2" 690 | is-binary-path "~2.1.0" 691 | is-glob "~4.0.1" 692 | normalize-path "~3.0.0" 693 | readdirp "~3.6.0" 694 | optionalDependencies: 695 | fsevents "~2.3.2" 696 | 697 | circom_runtime@0.1.21: 698 | version "0.1.21" 699 | resolved "https://registry.yarnpkg.com/circom_runtime/-/circom_runtime-0.1.21.tgz#0ee93bb798b5afb8ecec30725ed14d94587a999b" 700 | integrity sha512-qTkud630B/GK8y76hnOaaS1aNuF6prfV0dTrkeRsiJKnlP1ryQbP2FWLgDOPqn6aKyaPlam+Z+DTbBhkEzh8dA== 701 | dependencies: 702 | ffjavascript "0.2.56" 703 | 704 | circom_tester@^0.0.19: 705 | version "0.0.19" 706 | resolved "https://registry.yarnpkg.com/circom_tester/-/circom_tester-0.0.19.tgz#e8bed494d080f8186bd0ac6571755d00ccec83bd" 707 | integrity sha512-SNHaBsGxcBH6XsVWfsRbRPA7NF8m8AMKJI9dtJJCFGUtOTT2+zsoIqAwi50z6XCnO4TtjyXq7AeXa1PLHqT0tw== 708 | dependencies: 709 | chai "^4.3.6" 710 | child_process "^1.0.2" 711 | ffjavascript "^0.2.56" 712 | fnv-plus "^1.3.1" 713 | r1csfile "^0.0.41" 714 | snarkjs "0.5.0" 715 | tmp-promise "^3.0.3" 716 | util "^0.12.4" 717 | 718 | circomlib@^2.0.5: 719 | version "2.0.5" 720 | resolved "https://registry.yarnpkg.com/circomlib/-/circomlib-2.0.5.tgz#183c703e53ed7d011811842dbeeeb9819f4cc1d6" 721 | integrity sha512-O7NQ8OS+J4eshBuoy36z/TwQU0YHw8W3zxZcs4hVwpEll3e4hDm3mgkIPqItN8FDeLEKZFK3YeT/+k8TiLF3/A== 722 | 723 | circomlibjs@^0.1.7: 724 | version "0.1.7" 725 | resolved "https://registry.yarnpkg.com/circomlibjs/-/circomlibjs-0.1.7.tgz#9f5a7d9a23323744b11ee456b05b0cd81f48b554" 726 | integrity sha512-GRAUoAlKAsiiTa+PA725G9RmEmJJRc8tRFxw/zKktUxlQISGznT4hH4ESvW8FNTsrGg/nNd06sGP/Wlx0LUHVg== 727 | dependencies: 728 | blake-hash "^2.0.0" 729 | blake2b "^2.1.3" 730 | ethers "^5.5.1" 731 | ffjavascript "^0.2.45" 732 | 733 | cli-progress@^3.11.2: 734 | version "3.12.0" 735 | resolved "https://registry.yarnpkg.com/cli-progress/-/cli-progress-3.12.0.tgz#807ee14b66bcc086258e444ad0f19e7d42577942" 736 | integrity sha512-tRkV3HJ1ASwm19THiiLIXLO7Im7wlTuKnvkYaTkyoAPefqjNg7W7DHKUlGRxy9vxDvbyCYQkQozvptuMkGCg8A== 737 | dependencies: 738 | string-width "^4.2.3" 739 | 740 | cliui@^7.0.2: 741 | version "7.0.4" 742 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" 743 | integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== 744 | dependencies: 745 | string-width "^4.2.0" 746 | strip-ansi "^6.0.0" 747 | wrap-ansi "^7.0.0" 748 | 749 | color-convert@^2.0.1: 750 | version "2.0.1" 751 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" 752 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== 753 | dependencies: 754 | color-name "~1.1.4" 755 | 756 | color-name@~1.1.4: 757 | version "1.1.4" 758 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" 759 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== 760 | 761 | concat-map@0.0.1: 762 | version "0.0.1" 763 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 764 | integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== 765 | 766 | create-require@^1.1.0: 767 | version "1.1.1" 768 | resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" 769 | integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== 770 | 771 | debug@4.3.4: 772 | version "4.3.4" 773 | resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" 774 | integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== 775 | dependencies: 776 | ms "2.1.2" 777 | 778 | decamelize@^4.0.0: 779 | version "4.0.0" 780 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" 781 | integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== 782 | 783 | deep-eql@^4.1.2: 784 | version "4.1.3" 785 | resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" 786 | integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== 787 | dependencies: 788 | type-detect "^4.0.0" 789 | 790 | diff@5.0.0: 791 | version "5.0.0" 792 | resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" 793 | integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== 794 | 795 | diff@^3.1.0: 796 | version "3.5.0" 797 | resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" 798 | integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== 799 | 800 | diff@^4.0.1: 801 | version "4.0.2" 802 | resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" 803 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 804 | 805 | ejs@^3.1.6: 806 | version "3.1.9" 807 | resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" 808 | integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== 809 | dependencies: 810 | jake "^10.8.5" 811 | 812 | elliptic@6.5.4: 813 | version "6.5.4" 814 | resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" 815 | integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== 816 | dependencies: 817 | bn.js "^4.11.9" 818 | brorand "^1.1.0" 819 | hash.js "^1.0.0" 820 | hmac-drbg "^1.0.1" 821 | inherits "^2.0.4" 822 | minimalistic-assert "^1.0.1" 823 | minimalistic-crypto-utils "^1.0.1" 824 | 825 | emoji-regex@^8.0.0: 826 | version "8.0.0" 827 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" 828 | integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== 829 | 830 | escalade@^3.1.1: 831 | version "3.1.1" 832 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" 833 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== 834 | 835 | escape-string-regexp@4.0.0: 836 | version "4.0.0" 837 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" 838 | integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== 839 | 840 | ethers@^5.5.1: 841 | version "5.7.2" 842 | resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" 843 | integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== 844 | dependencies: 845 | "@ethersproject/abi" "5.7.0" 846 | "@ethersproject/abstract-provider" "5.7.0" 847 | "@ethersproject/abstract-signer" "5.7.0" 848 | "@ethersproject/address" "5.7.0" 849 | "@ethersproject/base64" "5.7.0" 850 | "@ethersproject/basex" "5.7.0" 851 | "@ethersproject/bignumber" "5.7.0" 852 | "@ethersproject/bytes" "5.7.0" 853 | "@ethersproject/constants" "5.7.0" 854 | "@ethersproject/contracts" "5.7.0" 855 | "@ethersproject/hash" "5.7.0" 856 | "@ethersproject/hdnode" "5.7.0" 857 | "@ethersproject/json-wallets" "5.7.0" 858 | "@ethersproject/keccak256" "5.7.0" 859 | "@ethersproject/logger" "5.7.0" 860 | "@ethersproject/networks" "5.7.1" 861 | "@ethersproject/pbkdf2" "5.7.0" 862 | "@ethersproject/properties" "5.7.0" 863 | "@ethersproject/providers" "5.7.2" 864 | "@ethersproject/random" "5.7.0" 865 | "@ethersproject/rlp" "5.7.0" 866 | "@ethersproject/sha2" "5.7.0" 867 | "@ethersproject/signing-key" "5.7.0" 868 | "@ethersproject/solidity" "5.7.0" 869 | "@ethersproject/strings" "5.7.0" 870 | "@ethersproject/transactions" "5.7.0" 871 | "@ethersproject/units" "5.7.0" 872 | "@ethersproject/wallet" "5.7.0" 873 | "@ethersproject/web" "5.7.1" 874 | "@ethersproject/wordlists" "5.7.0" 875 | 876 | fastfile@0.0.20: 877 | version "0.0.20" 878 | resolved "https://registry.yarnpkg.com/fastfile/-/fastfile-0.0.20.tgz#794a143d58cfda2e24c298e5ef619c748c8a1879" 879 | integrity sha512-r5ZDbgImvVWCP0lA/cGNgQcZqR+aYdFx3u+CtJqUE510pBUVGMn4ulL/iRTI4tACTYsNJ736uzFxEBXesPAktA== 880 | 881 | ffjavascript@0.2.56: 882 | version "0.2.56" 883 | resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.2.56.tgz#3509f98fcbd3e44ea93cd23519071b76d6eae433" 884 | integrity sha512-em6G5Lrj7ucIqj4TYEgyoHs/j99Urwwqa4+YxEVY2hggnpRimVj+noX5pZQTxI1pvtiekZI4rG65JBf0xraXrg== 885 | dependencies: 886 | wasmbuilder "0.0.16" 887 | wasmcurves "0.2.0" 888 | web-worker "^1.2.0" 889 | 890 | ffjavascript@^0.2.45, ffjavascript@^0.2.48, ffjavascript@^0.2.56, ffjavascript@^0.2.60: 891 | version "0.2.60" 892 | resolved "https://registry.yarnpkg.com/ffjavascript/-/ffjavascript-0.2.60.tgz#4d8ae613d6bf4e98b3cc29ba10c626f5853854cf" 893 | integrity sha512-T/9bnEL5xAZRDbQoEMf+pM9nrhK+C3JyZNmqiWub26EQorW7Jt+jR54gpqDhceA4Nj0YctPQwYnl8xa52/A26A== 894 | dependencies: 895 | wasmbuilder "0.0.16" 896 | wasmcurves "0.2.2" 897 | web-worker "^1.2.0" 898 | 899 | filelist@^1.0.4: 900 | version "1.0.4" 901 | resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" 902 | integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== 903 | dependencies: 904 | minimatch "^5.0.1" 905 | 906 | fill-range@^7.0.1: 907 | version "7.0.1" 908 | resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" 909 | integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== 910 | dependencies: 911 | to-regex-range "^5.0.1" 912 | 913 | find-up@5.0.0: 914 | version "5.0.0" 915 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" 916 | integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== 917 | dependencies: 918 | locate-path "^6.0.0" 919 | path-exists "^4.0.0" 920 | 921 | flat@^5.0.2: 922 | version "5.0.2" 923 | resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" 924 | integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== 925 | 926 | fnv-plus@^1.3.1: 927 | version "1.3.1" 928 | resolved "https://registry.yarnpkg.com/fnv-plus/-/fnv-plus-1.3.1.tgz#c34cb4572565434acb08ba257e4044ce2b006d67" 929 | integrity sha512-Gz1EvfOneuFfk4yG458dJ3TLJ7gV19q3OM/vVvvHf7eT02Hm1DleB4edsia6ahbKgAYxO9gvyQ1ioWZR+a00Yw== 930 | 931 | for-each@^0.3.3: 932 | version "0.3.3" 933 | resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" 934 | integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== 935 | dependencies: 936 | is-callable "^1.1.3" 937 | 938 | fs.realpath@^1.0.0: 939 | version "1.0.0" 940 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 941 | integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== 942 | 943 | fs@^0.0.1-security: 944 | version "0.0.1-security" 945 | resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4" 946 | integrity sha512-3XY9e1pP0CVEUCdj5BmfIZxRBTSDycnbqhIOGec9QYtmVH2fbLpj86CFWkrNOkt/Fvty4KZG5lTglL9j/gJ87w== 947 | 948 | fsevents@~2.3.2: 949 | version "2.3.3" 950 | resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" 951 | integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== 952 | 953 | function-bind@^1.1.1: 954 | version "1.1.1" 955 | resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" 956 | integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== 957 | 958 | get-caller-file@^2.0.5: 959 | version "2.0.5" 960 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 961 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 962 | 963 | get-func-name@^2.0.0: 964 | version "2.0.0" 965 | resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" 966 | integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== 967 | 968 | get-intrinsic@^1.0.2, get-intrinsic@^1.1.3: 969 | version "1.2.1" 970 | resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" 971 | integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== 972 | dependencies: 973 | function-bind "^1.1.1" 974 | has "^1.0.3" 975 | has-proto "^1.0.1" 976 | has-symbols "^1.0.3" 977 | 978 | glob-parent@~5.1.2: 979 | version "5.1.2" 980 | resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" 981 | integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== 982 | dependencies: 983 | is-glob "^4.0.1" 984 | 985 | glob@7.2.0: 986 | version "7.2.0" 987 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" 988 | integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== 989 | dependencies: 990 | fs.realpath "^1.0.0" 991 | inflight "^1.0.4" 992 | inherits "2" 993 | minimatch "^3.0.4" 994 | once "^1.3.0" 995 | path-is-absolute "^1.0.0" 996 | 997 | glob@^7.1.3: 998 | version "7.2.3" 999 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" 1000 | integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== 1001 | dependencies: 1002 | fs.realpath "^1.0.0" 1003 | inflight "^1.0.4" 1004 | inherits "2" 1005 | minimatch "^3.1.1" 1006 | once "^1.3.0" 1007 | path-is-absolute "^1.0.0" 1008 | 1009 | gopd@^1.0.1: 1010 | version "1.0.1" 1011 | resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" 1012 | integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== 1013 | dependencies: 1014 | get-intrinsic "^1.1.3" 1015 | 1016 | has-flag@^4.0.0: 1017 | version "4.0.0" 1018 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" 1019 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== 1020 | 1021 | has-proto@^1.0.1: 1022 | version "1.0.1" 1023 | resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" 1024 | integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== 1025 | 1026 | has-symbols@^1.0.2, has-symbols@^1.0.3: 1027 | version "1.0.3" 1028 | resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" 1029 | integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== 1030 | 1031 | has-tostringtag@^1.0.0: 1032 | version "1.0.0" 1033 | resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" 1034 | integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== 1035 | dependencies: 1036 | has-symbols "^1.0.2" 1037 | 1038 | has@^1.0.3: 1039 | version "1.0.3" 1040 | resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" 1041 | integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== 1042 | dependencies: 1043 | function-bind "^1.1.1" 1044 | 1045 | hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: 1046 | version "1.1.7" 1047 | resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" 1048 | integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== 1049 | dependencies: 1050 | inherits "^2.0.3" 1051 | minimalistic-assert "^1.0.1" 1052 | 1053 | he@1.2.0: 1054 | version "1.2.0" 1055 | resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" 1056 | integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== 1057 | 1058 | hmac-drbg@^1.0.1: 1059 | version "1.0.1" 1060 | resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" 1061 | integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== 1062 | dependencies: 1063 | hash.js "^1.0.3" 1064 | minimalistic-assert "^1.0.0" 1065 | minimalistic-crypto-utils "^1.0.1" 1066 | 1067 | hoopy@^0.1.4: 1068 | version "0.1.4" 1069 | resolved "https://registry.yarnpkg.com/hoopy/-/hoopy-0.1.4.tgz#609207d661100033a9a9402ad3dea677381c1b1d" 1070 | integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== 1071 | 1072 | inflight@^1.0.4: 1073 | version "1.0.6" 1074 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 1075 | integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== 1076 | dependencies: 1077 | once "^1.3.0" 1078 | wrappy "1" 1079 | 1080 | inherits@2, inherits@^2.0.3, inherits@^2.0.4: 1081 | version "2.0.4" 1082 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 1083 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 1084 | 1085 | is-arguments@^1.0.4: 1086 | version "1.1.1" 1087 | resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" 1088 | integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== 1089 | dependencies: 1090 | call-bind "^1.0.2" 1091 | has-tostringtag "^1.0.0" 1092 | 1093 | is-binary-path@~2.1.0: 1094 | version "2.1.0" 1095 | resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" 1096 | integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== 1097 | dependencies: 1098 | binary-extensions "^2.0.0" 1099 | 1100 | is-callable@^1.1.3: 1101 | version "1.2.7" 1102 | resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" 1103 | integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== 1104 | 1105 | is-extglob@^2.1.1: 1106 | version "2.1.1" 1107 | resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" 1108 | integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== 1109 | 1110 | is-fullwidth-code-point@^3.0.0: 1111 | version "3.0.0" 1112 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" 1113 | integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== 1114 | 1115 | is-generator-function@^1.0.7: 1116 | version "1.0.10" 1117 | resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" 1118 | integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== 1119 | dependencies: 1120 | has-tostringtag "^1.0.0" 1121 | 1122 | is-glob@^4.0.1, is-glob@~4.0.1: 1123 | version "4.0.3" 1124 | resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" 1125 | integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== 1126 | dependencies: 1127 | is-extglob "^2.1.1" 1128 | 1129 | is-number@^7.0.0: 1130 | version "7.0.0" 1131 | resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" 1132 | integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== 1133 | 1134 | is-plain-obj@^2.1.0: 1135 | version "2.1.0" 1136 | resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" 1137 | integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== 1138 | 1139 | is-typed-array@^1.1.3: 1140 | version "1.1.12" 1141 | resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" 1142 | integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== 1143 | dependencies: 1144 | which-typed-array "^1.1.11" 1145 | 1146 | is-unicode-supported@^0.1.0: 1147 | version "0.1.0" 1148 | resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" 1149 | integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== 1150 | 1151 | jake@^10.8.5: 1152 | version "10.8.7" 1153 | resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" 1154 | integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== 1155 | dependencies: 1156 | async "^3.2.3" 1157 | chalk "^4.0.2" 1158 | filelist "^1.0.4" 1159 | minimatch "^3.1.2" 1160 | 1161 | js-sha3@0.8.0, js-sha3@^0.8.0: 1162 | version "0.8.0" 1163 | resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" 1164 | integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== 1165 | 1166 | js-yaml@4.1.0: 1167 | version "4.1.0" 1168 | resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" 1169 | integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== 1170 | dependencies: 1171 | argparse "^2.0.1" 1172 | 1173 | json5@^1.0.2: 1174 | version "1.0.2" 1175 | resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" 1176 | integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== 1177 | dependencies: 1178 | minimist "^1.2.0" 1179 | 1180 | locate-path@^6.0.0: 1181 | version "6.0.0" 1182 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" 1183 | integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== 1184 | dependencies: 1185 | p-locate "^5.0.0" 1186 | 1187 | log-symbols@4.1.0: 1188 | version "4.1.0" 1189 | resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" 1190 | integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== 1191 | dependencies: 1192 | chalk "^4.1.0" 1193 | is-unicode-supported "^0.1.0" 1194 | 1195 | logplease@^1.2.15: 1196 | version "1.2.15" 1197 | resolved "https://registry.yarnpkg.com/logplease/-/logplease-1.2.15.tgz#3da442e93751a5992cc19010a826b08d0293c48a" 1198 | integrity sha512-jLlHnlsPSJjpwUfcNyUxXCl33AYg2cHhIf9QhGL2T4iPT0XPB+xP1LRKFPgIg1M/sg9kAJvy94w9CzBNrfnstA== 1199 | 1200 | loupe@^2.3.1: 1201 | version "2.3.6" 1202 | resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53" 1203 | integrity sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA== 1204 | dependencies: 1205 | get-func-name "^2.0.0" 1206 | 1207 | make-error@^1.1.1: 1208 | version "1.3.6" 1209 | resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" 1210 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== 1211 | 1212 | micro-bmark@^0.3.1: 1213 | version "0.3.1" 1214 | resolved "https://registry.yarnpkg.com/micro-bmark/-/micro-bmark-0.3.1.tgz#1ba5289c01dd06ec06fb185ef1f859258d10e5ba" 1215 | integrity sha512-bNaKObD4yPAAPrpEqp5jO6LJ2sEFgLoFSmRjEY809mJ62+2AehI/K3+RlVpN3Oo92RHpgC2RQhj6b1Tb4dmo+w== 1216 | 1217 | minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: 1218 | version "1.0.1" 1219 | resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" 1220 | integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== 1221 | 1222 | minimalistic-crypto-utils@^1.0.1: 1223 | version "1.0.1" 1224 | resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" 1225 | integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== 1226 | 1227 | minimatch@5.0.1: 1228 | version "5.0.1" 1229 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" 1230 | integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== 1231 | dependencies: 1232 | brace-expansion "^2.0.1" 1233 | 1234 | minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: 1235 | version "3.1.2" 1236 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 1237 | integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== 1238 | dependencies: 1239 | brace-expansion "^1.1.7" 1240 | 1241 | minimatch@^5.0.1: 1242 | version "5.1.6" 1243 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" 1244 | integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== 1245 | dependencies: 1246 | brace-expansion "^2.0.1" 1247 | 1248 | minimist@^1.2.0, minimist@^1.2.6: 1249 | version "1.2.8" 1250 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" 1251 | integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== 1252 | 1253 | mkdirp@^0.5.1: 1254 | version "0.5.6" 1255 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" 1256 | integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== 1257 | dependencies: 1258 | minimist "^1.2.6" 1259 | 1260 | mocha-suppress-logs@^0.3.1: 1261 | version "0.3.1" 1262 | resolved "https://registry.yarnpkg.com/mocha-suppress-logs/-/mocha-suppress-logs-0.3.1.tgz#e0fb454daea9e65e4aced488c26e5000691ed598" 1263 | integrity sha512-Iu6jyTguAtFzmt7l4Agfnve0v+cQNbH92iMau1kjWwom7MNn18/Mzo1EaVhwDrH24cQ87RDKAMse2rDUkuXy8A== 1264 | 1265 | mocha@^10.2.0: 1266 | version "10.2.0" 1267 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" 1268 | integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== 1269 | dependencies: 1270 | ansi-colors "4.1.1" 1271 | browser-stdout "1.3.1" 1272 | chokidar "3.5.3" 1273 | debug "4.3.4" 1274 | diff "5.0.0" 1275 | escape-string-regexp "4.0.0" 1276 | find-up "5.0.0" 1277 | glob "7.2.0" 1278 | he "1.2.0" 1279 | js-yaml "4.1.0" 1280 | log-symbols "4.1.0" 1281 | minimatch "5.0.1" 1282 | ms "2.1.3" 1283 | nanoid "3.3.3" 1284 | serialize-javascript "6.0.0" 1285 | strip-json-comments "3.1.1" 1286 | supports-color "8.1.1" 1287 | workerpool "6.2.1" 1288 | yargs "16.2.0" 1289 | yargs-parser "20.2.4" 1290 | yargs-unparser "2.0.0" 1291 | 1292 | ms@2.1.2: 1293 | version "2.1.2" 1294 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" 1295 | integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== 1296 | 1297 | ms@2.1.3: 1298 | version "2.1.3" 1299 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 1300 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 1301 | 1302 | nanoassert@^2.0.0: 1303 | version "2.0.0" 1304 | resolved "https://registry.yarnpkg.com/nanoassert/-/nanoassert-2.0.0.tgz#a05f86de6c7a51618038a620f88878ed1e490c09" 1305 | integrity sha512-7vO7n28+aYO4J+8w96AzhmU8G+Y/xpPDJz/se19ICsqj/momRbb9mh9ZUtkoJ5X3nTnPdhEJyc0qnM6yAsHBaA== 1306 | 1307 | nanoid@3.3.3: 1308 | version "3.3.3" 1309 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" 1310 | integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== 1311 | 1312 | node-addon-api@^3.0.0: 1313 | version "3.2.1" 1314 | resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" 1315 | integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== 1316 | 1317 | node-gyp-build@^4.2.2: 1318 | version "4.6.0" 1319 | resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" 1320 | integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== 1321 | 1322 | normalize-path@^3.0.0, normalize-path@~3.0.0: 1323 | version "3.0.0" 1324 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 1325 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 1326 | 1327 | once@^1.3.0: 1328 | version "1.4.0" 1329 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 1330 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 1331 | dependencies: 1332 | wrappy "1" 1333 | 1334 | p-limit@^3.0.2: 1335 | version "3.1.0" 1336 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" 1337 | integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== 1338 | dependencies: 1339 | yocto-queue "^0.1.0" 1340 | 1341 | p-locate@^5.0.0: 1342 | version "5.0.0" 1343 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" 1344 | integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== 1345 | dependencies: 1346 | p-limit "^3.0.2" 1347 | 1348 | path-exists@^4.0.0: 1349 | version "4.0.0" 1350 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" 1351 | integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== 1352 | 1353 | path-is-absolute@^1.0.0: 1354 | version "1.0.1" 1355 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 1356 | integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== 1357 | 1358 | pathval@^1.1.1: 1359 | version "1.1.1" 1360 | resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" 1361 | integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== 1362 | 1363 | picomatch@^2.0.4, picomatch@^2.2.1: 1364 | version "2.3.1" 1365 | resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" 1366 | integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== 1367 | 1368 | prettier@^3.0.3: 1369 | version "3.0.3" 1370 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.3.tgz#432a51f7ba422d1469096c0fdc28e235db8f9643" 1371 | integrity sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg== 1372 | 1373 | r1csfile@0.0.41, r1csfile@^0.0.41: 1374 | version "0.0.41" 1375 | resolved "https://registry.yarnpkg.com/r1csfile/-/r1csfile-0.0.41.tgz#e3d2709d36923156dd1fc2db9858987b30c92948" 1376 | integrity sha512-Q1WDF3u1vYeAwjHo4YuddkA8Aq0TulbKjmGm99+Atn13Lf5fTsMZBnBV9T741w8iSyPFG6Uh6sapQby77sREqA== 1377 | dependencies: 1378 | "@iden3/bigarray" "0.0.2" 1379 | "@iden3/binfileutils" "0.0.11" 1380 | fastfile "0.0.20" 1381 | ffjavascript "0.2.56" 1382 | 1383 | randombytes@^2.1.0: 1384 | version "2.1.0" 1385 | resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" 1386 | integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== 1387 | dependencies: 1388 | safe-buffer "^5.1.0" 1389 | 1390 | readable-stream@^3.6.0: 1391 | version "3.6.2" 1392 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" 1393 | integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== 1394 | dependencies: 1395 | inherits "^2.0.3" 1396 | string_decoder "^1.1.1" 1397 | util-deprecate "^1.0.1" 1398 | 1399 | readdirp@~3.6.0: 1400 | version "3.6.0" 1401 | resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" 1402 | integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== 1403 | dependencies: 1404 | picomatch "^2.2.1" 1405 | 1406 | require-directory@^2.1.1: 1407 | version "2.1.1" 1408 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 1409 | integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== 1410 | 1411 | rimraf@^3.0.0: 1412 | version "3.0.2" 1413 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" 1414 | integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== 1415 | dependencies: 1416 | glob "^7.1.3" 1417 | 1418 | safe-buffer@^5.1.0, safe-buffer@~5.2.0: 1419 | version "5.2.1" 1420 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 1421 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 1422 | 1423 | scrypt-js@3.0.1: 1424 | version "3.0.1" 1425 | resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" 1426 | integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== 1427 | 1428 | serialize-javascript@6.0.0: 1429 | version "6.0.0" 1430 | resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" 1431 | integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== 1432 | dependencies: 1433 | randombytes "^2.1.0" 1434 | 1435 | snarkjs@0.5.0, snarkjs@^0.5.0: 1436 | version "0.5.0" 1437 | resolved "https://registry.yarnpkg.com/snarkjs/-/snarkjs-0.5.0.tgz#cf26bf1d3835eb16b4b330a438bad9824837d6b0" 1438 | integrity sha512-KWz8mZ2Y+6wvn6GGkQo6/ZlKwETdAGohd40Lzpwp5TUZCn6N6O4Az1SuX1rw/qREGL6Im+ycb19suCFE8/xaKA== 1439 | dependencies: 1440 | "@iden3/binfileutils" "0.0.11" 1441 | bfj "^7.0.2" 1442 | blake2b-wasm "^2.4.0" 1443 | circom_runtime "0.1.21" 1444 | ejs "^3.1.6" 1445 | fastfile "0.0.20" 1446 | ffjavascript "0.2.56" 1447 | js-sha3 "^0.8.0" 1448 | logplease "^1.2.15" 1449 | r1csfile "0.0.41" 1450 | 1451 | source-map-support@^0.5.6: 1452 | version "0.5.21" 1453 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" 1454 | integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== 1455 | dependencies: 1456 | buffer-from "^1.0.0" 1457 | source-map "^0.6.0" 1458 | 1459 | source-map@^0.6.0: 1460 | version "0.6.1" 1461 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 1462 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 1463 | 1464 | string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: 1465 | version "4.2.3" 1466 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" 1467 | integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== 1468 | dependencies: 1469 | emoji-regex "^8.0.0" 1470 | is-fullwidth-code-point "^3.0.0" 1471 | strip-ansi "^6.0.1" 1472 | 1473 | string_decoder@^1.1.1: 1474 | version "1.3.0" 1475 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 1476 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 1477 | dependencies: 1478 | safe-buffer "~5.2.0" 1479 | 1480 | strip-ansi@^6.0.0, strip-ansi@^6.0.1: 1481 | version "6.0.1" 1482 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" 1483 | integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== 1484 | dependencies: 1485 | ansi-regex "^5.0.1" 1486 | 1487 | strip-bom@^3.0.0: 1488 | version "3.0.0" 1489 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" 1490 | integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== 1491 | 1492 | strip-json-comments@3.1.1: 1493 | version "3.1.1" 1494 | resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" 1495 | integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== 1496 | 1497 | supports-color@8.1.1: 1498 | version "8.1.1" 1499 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" 1500 | integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== 1501 | dependencies: 1502 | has-flag "^4.0.0" 1503 | 1504 | supports-color@^7.1.0: 1505 | version "7.2.0" 1506 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" 1507 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== 1508 | dependencies: 1509 | has-flag "^4.0.0" 1510 | 1511 | tmp-promise@^3.0.3: 1512 | version "3.0.3" 1513 | resolved "https://registry.yarnpkg.com/tmp-promise/-/tmp-promise-3.0.3.tgz#60a1a1cc98c988674fcbfd23b6e3367bdeac4ce7" 1514 | integrity sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ== 1515 | dependencies: 1516 | tmp "^0.2.0" 1517 | 1518 | tmp@^0.2.0: 1519 | version "0.2.1" 1520 | resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" 1521 | integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== 1522 | dependencies: 1523 | rimraf "^3.0.0" 1524 | 1525 | to-regex-range@^5.0.1: 1526 | version "5.0.1" 1527 | resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" 1528 | integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== 1529 | dependencies: 1530 | is-number "^7.0.0" 1531 | 1532 | tryer@^1.0.1: 1533 | version "1.0.1" 1534 | resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" 1535 | integrity sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA== 1536 | 1537 | ts-mocha@^10.0.0: 1538 | version "10.0.0" 1539 | resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-10.0.0.tgz#41a8d099ac90dbbc64b06976c5025ffaebc53cb9" 1540 | integrity sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw== 1541 | dependencies: 1542 | ts-node "7.0.1" 1543 | optionalDependencies: 1544 | tsconfig-paths "^3.5.0" 1545 | 1546 | ts-node@7.0.1: 1547 | version "7.0.1" 1548 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" 1549 | integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== 1550 | dependencies: 1551 | arrify "^1.0.0" 1552 | buffer-from "^1.1.0" 1553 | diff "^3.1.0" 1554 | make-error "^1.1.1" 1555 | minimist "^1.2.0" 1556 | mkdirp "^0.5.1" 1557 | source-map-support "^0.5.6" 1558 | yn "^2.0.0" 1559 | 1560 | ts-node@^10.9.1: 1561 | version "10.9.1" 1562 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" 1563 | integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== 1564 | dependencies: 1565 | "@cspotcode/source-map-support" "^0.8.0" 1566 | "@tsconfig/node10" "^1.0.7" 1567 | "@tsconfig/node12" "^1.0.7" 1568 | "@tsconfig/node14" "^1.0.0" 1569 | "@tsconfig/node16" "^1.0.2" 1570 | acorn "^8.4.1" 1571 | acorn-walk "^8.1.1" 1572 | arg "^4.1.0" 1573 | create-require "^1.1.0" 1574 | diff "^4.0.1" 1575 | make-error "^1.1.1" 1576 | v8-compile-cache-lib "^3.0.1" 1577 | yn "3.1.1" 1578 | 1579 | tsconfig-paths@^3.5.0: 1580 | version "3.14.2" 1581 | resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" 1582 | integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== 1583 | dependencies: 1584 | "@types/json5" "^0.0.29" 1585 | json5 "^1.0.2" 1586 | minimist "^1.2.6" 1587 | strip-bom "^3.0.0" 1588 | 1589 | type-detect@^4.0.0, type-detect@^4.0.5: 1590 | version "4.0.8" 1591 | resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" 1592 | integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== 1593 | 1594 | typescript@^5.1.6: 1595 | version "5.1.6" 1596 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" 1597 | integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== 1598 | 1599 | util-deprecate@^1.0.1: 1600 | version "1.0.2" 1601 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 1602 | integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== 1603 | 1604 | util@^0.12.4: 1605 | version "0.12.5" 1606 | resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" 1607 | integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== 1608 | dependencies: 1609 | inherits "^2.0.3" 1610 | is-arguments "^1.0.4" 1611 | is-generator-function "^1.0.7" 1612 | is-typed-array "^1.1.3" 1613 | which-typed-array "^1.1.2" 1614 | 1615 | v8-compile-cache-lib@^3.0.1: 1616 | version "3.0.1" 1617 | resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" 1618 | integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== 1619 | 1620 | wasmbuilder@0.0.16: 1621 | version "0.0.16" 1622 | resolved "https://registry.yarnpkg.com/wasmbuilder/-/wasmbuilder-0.0.16.tgz#f34c1f2c047d2f6e1065cbfec5603988f16d8549" 1623 | integrity sha512-Qx3lEFqaVvp1cEYW7Bfi+ebRJrOiwz2Ieu7ZG2l7YyeSJIok/reEQCQCuicj/Y32ITIJuGIM9xZQppGx5LrQdA== 1624 | 1625 | wasmcurves@0.2.0: 1626 | version "0.2.0" 1627 | resolved "https://registry.yarnpkg.com/wasmcurves/-/wasmcurves-0.2.0.tgz#ccfc5a7d3778b6e0768b82a9336c80054f9bc0cf" 1628 | integrity sha512-3e2rbxdujOwaod657gxgmdhZNn+i1qKdHO3Y/bK+8E7bV8ttV/fu5FO4/WLBACF375cK0QDLOP+65Na63qYuWA== 1629 | dependencies: 1630 | wasmbuilder "0.0.16" 1631 | 1632 | wasmcurves@0.2.2: 1633 | version "0.2.2" 1634 | resolved "https://registry.yarnpkg.com/wasmcurves/-/wasmcurves-0.2.2.tgz#ca444f6a6f6e2a5cbe6629d98ff478a62b4ccb2b" 1635 | integrity sha512-JRY908NkmKjFl4ytnTu5ED6AwPD+8VJ9oc94kdq7h5bIwbj0L4TDJ69mG+2aLs2SoCmGfqIesMWTEJjtYsoQXQ== 1636 | dependencies: 1637 | wasmbuilder "0.0.16" 1638 | 1639 | web-worker@^1.2.0: 1640 | version "1.2.0" 1641 | resolved "https://registry.yarnpkg.com/web-worker/-/web-worker-1.2.0.tgz#5d85a04a7fbc1e7db58f66595d7a3ac7c9c180da" 1642 | integrity sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA== 1643 | 1644 | which-typed-array@^1.1.11, which-typed-array@^1.1.2: 1645 | version "1.1.11" 1646 | resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" 1647 | integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== 1648 | dependencies: 1649 | available-typed-arrays "^1.0.5" 1650 | call-bind "^1.0.2" 1651 | for-each "^0.3.3" 1652 | gopd "^1.0.1" 1653 | has-tostringtag "^1.0.0" 1654 | 1655 | workerpool@6.2.1: 1656 | version "6.2.1" 1657 | resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" 1658 | integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== 1659 | 1660 | wrap-ansi@^7.0.0: 1661 | version "7.0.0" 1662 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" 1663 | integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== 1664 | dependencies: 1665 | ansi-styles "^4.0.0" 1666 | string-width "^4.1.0" 1667 | strip-ansi "^6.0.0" 1668 | 1669 | wrappy@1: 1670 | version "1.0.2" 1671 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 1672 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 1673 | 1674 | ws@7.4.6: 1675 | version "7.4.6" 1676 | resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" 1677 | integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== 1678 | 1679 | y18n@^5.0.5: 1680 | version "5.0.8" 1681 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 1682 | integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 1683 | 1684 | yargs-parser@20.2.4: 1685 | version "20.2.4" 1686 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" 1687 | integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== 1688 | 1689 | yargs-parser@^20.2.2: 1690 | version "20.2.9" 1691 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" 1692 | integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== 1693 | 1694 | yargs-unparser@2.0.0: 1695 | version "2.0.0" 1696 | resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" 1697 | integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== 1698 | dependencies: 1699 | camelcase "^6.0.0" 1700 | decamelize "^4.0.0" 1701 | flat "^5.0.2" 1702 | is-plain-obj "^2.1.0" 1703 | 1704 | yargs@16.2.0: 1705 | version "16.2.0" 1706 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" 1707 | integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== 1708 | dependencies: 1709 | cliui "^7.0.2" 1710 | escalade "^3.1.1" 1711 | get-caller-file "^2.0.5" 1712 | require-directory "^2.1.1" 1713 | string-width "^4.2.0" 1714 | y18n "^5.0.5" 1715 | yargs-parser "^20.2.2" 1716 | 1717 | yn@3.1.1: 1718 | version "3.1.1" 1719 | resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" 1720 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== 1721 | 1722 | yn@^2.0.0: 1723 | version "2.0.0" 1724 | resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" 1725 | integrity sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ== 1726 | 1727 | yocto-queue@^0.1.0: 1728 | version "0.1.0" 1729 | resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" 1730 | integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 1731 | --------------------------------------------------------------------------------