From 7090e13e4693a2fe69ffb53774ee75c4ff801397 Mon Sep 17 00:00:00 2001
From: GoodDaisy <90915921+GoodDaisy@users.noreply.github.com>
Date: Tue, 31 Oct 2023 08:08:32 +0800
Subject: [PATCH 1/8] chore: fix typo (#32)
---
halo2-lib-js/readme.md | 4 ++--
halo2-repl/components/TxNotification.tsx | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/halo2-lib-js/readme.md b/halo2-lib-js/readme.md
index 32f9023..40abedd 100644
--- a/halo2-lib-js/readme.md
+++ b/halo2-lib-js/readme.md
@@ -14,7 +14,7 @@ or use your favorite package manager (npm, yarn, etc.).
## Setting up the `CircuitScaffold`
-The `halo2-wasm` package already has an abstract `CircuitScaffold` that must implemented. Here is an example using `Halo2LibWasm` and `Halo2CircuitRunner`:
+The `halo2-wasm` package already has an abstract `CircuitScaffold` that must be implemented. Here is an example using `Halo2LibWasm` and `Halo2CircuitRunner`:
### Web
@@ -74,4 +74,4 @@ export class JsCircuitScaffold extends CircuitScaffold {
}
}
-```
\ No newline at end of file
+```
diff --git a/halo2-repl/components/TxNotification.tsx b/halo2-repl/components/TxNotification.tsx
index bc80979..78c1e5b 100644
--- a/halo2-repl/components/TxNotification.tsx
+++ b/halo2-repl/components/TxNotification.tsx
@@ -32,7 +32,7 @@ export default function Example(props: { title: string, link: string }) {
-
Succesfully sent {props.title}
+
Successfully sent {props.title}
View tx on Etherscan
From f4a6066fad65fdd1275a02bd7e5f1b6c4358b2e9 Mon Sep 17 00:00:00 2001
From: Roshan <19766713+rpalakkal@users.noreply.github.com>
Date: Tue, 31 Oct 2023 02:18:29 -0400
Subject: [PATCH 2/8] feat: add CircuitValue256 from axiom-sdk (#31)
Co-authored-by: Jonathan Wang <31040440+jonathanpwang@users.noreply.github.com>
---
halo2-lib-js/package.json | 2 +-
halo2-lib-js/readme.md | 2 +-
halo2-lib-js/src/halo2lib/CircuitValue.ts | 79 ++++++++++-------
halo2-lib-js/src/halo2lib/CircuitValue256.ts | 93 ++++++++++++++++++++
halo2-lib-js/src/halo2lib/index.ts | 1 +
halo2-wasm/readme.md | 42 +++++----
6 files changed, 170 insertions(+), 49 deletions(-)
create mode 100644 halo2-lib-js/src/halo2lib/CircuitValue256.ts
diff --git a/halo2-lib-js/package.json b/halo2-lib-js/package.json
index 73c11f2..5dc011a 100644
--- a/halo2-lib-js/package.json
+++ b/halo2-lib-js/package.json
@@ -1,6 +1,6 @@
{
"name": "@axiom-crypto/halo2-lib-js",
- "version": "0.2.1",
+ "version": "0.2.2",
"description": "Halo2 Javascript library",
"main": "index.js",
"scripts": {
diff --git a/halo2-lib-js/readme.md b/halo2-lib-js/readme.md
index 40abedd..155476c 100644
--- a/halo2-lib-js/readme.md
+++ b/halo2-lib-js/readme.md
@@ -4,7 +4,7 @@ This repository aims to streamline the process of writing circuits in Typescript
## Getting Started
-To build your own `halo2-wasm` module, see this [README](https://github.com/axiom-crypto/halo2-wasm).
+To build your own `halo2-wasm` module, see this [README](../halo2-wasm).
Install `halo2-js` in your own JS/TS project with
```
diff --git a/halo2-lib-js/src/halo2lib/CircuitValue.ts b/halo2-lib-js/src/halo2lib/CircuitValue.ts
index 7fe060d..7edd7ee 100644
--- a/halo2-lib-js/src/halo2lib/CircuitValue.ts
+++ b/halo2-lib-js/src/halo2lib/CircuitValue.ts
@@ -1,40 +1,59 @@
import { Halo2LibWasm } from "@axiom-crypto/halo2-wasm/web";
+import { CircuitValue256 } from "./CircuitValue256";
export class CircuitValue {
- private _value: bigint;
- private _cell: number;
- private _circuit: Halo2LibWasm;
+ private _value: bigint;
+ private _cell: number;
+ private _circuit: Halo2LibWasm;
- constructor(circuit: Halo2LibWasm, { value, cell }: { value?: bigint | number | string, cell?: number}) {
- this._circuit = circuit;
- if (value !== undefined) {
- this._value = BigInt(value);
- this._cell = this._circuit.constant(value.toString());
- }
- else if(cell !== undefined) {
- this._cell = cell;
- const val = BigInt(circuit.value(cell));
- this._value = val;
- }
- else {
- throw new Error("Invalid input");
- }
+ constructor(
+ circuit: Halo2LibWasm,
+ { value, cell }: { value?: bigint | number | string; cell?: number }
+ ) {
+ this._circuit = circuit;
+ if (value !== undefined) {
+ this._value = BigInt(value);
+ this._cell = this._circuit.constant(value.toString());
+ } else if (cell !== undefined) {
+ this._cell = cell;
+ const val = BigInt(circuit.value(cell));
+ this._value = val;
+ } else {
+ throw new Error("Invalid input");
}
+ }
- cell(){
- return this._cell;
- }
+ cell() {
+ return this._cell;
+ }
- value(){
- return this._value;
- }
+ value() {
+ return this._value;
+ }
- number(){
- return Number(this._value);
- }
+ number() {
+ return Number(this._value);
+ }
- address(){
- return "0x" + this._value.toString(16).padStart(40, '0');
- }
+ address() {
+ return "0x" + this._value.toString(16).padStart(40, "0");
+ }
-}
\ No newline at end of file
+ toCircuitValue256() {
+ const b = 2n ** 128n;
+ const lookupBits = this._circuit.lookup_bits();
+ let paddedNumBits = Math.floor(253 / lookupBits) * lookupBits - 1;
+ const [hi, lo] = this._circuit.div_mod(
+ this._cell,
+ b.toString(),
+ paddedNumBits.toString()
+ );
+ const hi128CircuitValue = new CircuitValue(this._circuit, { cell: hi });
+ const lo128CircuitValue = new CircuitValue(this._circuit, { cell: lo });
+ const halo2LibValue256 = new CircuitValue256(this._circuit, {
+ hi: hi128CircuitValue,
+ lo: lo128CircuitValue,
+ });
+ return halo2LibValue256;
+ }
+}
diff --git a/halo2-lib-js/src/halo2lib/CircuitValue256.ts b/halo2-lib-js/src/halo2lib/CircuitValue256.ts
new file mode 100644
index 0000000..ced6893
--- /dev/null
+++ b/halo2-lib-js/src/halo2lib/CircuitValue256.ts
@@ -0,0 +1,93 @@
+import { Halo2LibWasm } from "@axiom-crypto/halo2-wasm/web";
+import { CircuitValue } from "./CircuitValue";
+import { convertInput } from "../shared/utils";
+
+export class CircuitValue256 {
+ private _value: bigint;
+ private _circuitValue: [CircuitValue, CircuitValue];
+ private _halo2Lib: Halo2LibWasm;
+
+ constructor(
+ _halo2Lib: Halo2LibWasm,
+ {
+ value,
+ hi,
+ lo,
+ }: {
+ value?: bigint | string | number;
+ hi?: CircuitValue;
+ lo?: CircuitValue;
+ }
+ ) {
+ this._halo2Lib = _halo2Lib;
+ if (value !== undefined) {
+ if (BigInt(value) < 0n) {
+ throw new Error("Value cannot be negative.");
+ }
+ this._value = BigInt(value);
+ let input = BigInt(value)
+ .toString(16)
+ .padStart(64, "0");
+ let hi128 = input.slice(0, 32);
+ let lo128 = input.slice(32);
+
+ const hi128CircuitValue = new CircuitValue(_halo2Lib, {
+ cell: _halo2Lib.constant(convertInput("0x" + hi128)),
+ });
+ const lo128CircuitValue = new CircuitValue(_halo2Lib, {
+ cell: _halo2Lib.constant(convertInput("0x" + lo128)),
+ });
+ this._circuitValue = [hi128CircuitValue, lo128CircuitValue];
+ } else if (
+ hi !== undefined &&
+ hi instanceof CircuitValue &&
+ lo !== undefined &&
+ lo instanceof CircuitValue
+ ) {
+ this._circuitValue = [hi, lo];
+ const hiVal = BigInt(_halo2Lib.value(hi.cell()));
+ const loVal = BigInt(_halo2Lib.value(lo.cell()));
+ const value = hiVal * 2n ** 128n + loVal;
+ this._value = value;
+ } else {
+ throw new Error("Invalid input");
+ }
+ }
+
+ hi() {
+ return this._circuitValue[0];
+ }
+
+ lo() {
+ return this._circuitValue[1];
+ }
+
+ hex() {
+ return "0x" + this._value.toString(16).padStart(64, "0");
+ }
+
+ value() {
+ return this._value;
+ }
+
+ toCircuitValue() {
+ const b = BigInt(2) ** BigInt(128);
+ const bCell = this._halo2Lib.constant(b.toString());
+ const cell = this._halo2Lib.mul_add(
+ this.hi().cell(),
+ bCell,
+ this.lo().cell()
+ );
+ this._halo2Lib.range_check(this.hi().cell(), "125");
+ if (
+ this.hi()
+ .value()
+ .toString(2).length > 125
+ ) {
+ throw new Error(
+ "Cannot convert to CircuitValue (value is > 253 bits). Please use .hi()/.lo() instead."
+ );
+ }
+ return new CircuitValue(this._halo2Lib, { cell });
+ }
+}
diff --git a/halo2-lib-js/src/halo2lib/index.ts b/halo2-lib-js/src/halo2lib/index.ts
index b90e4bd..57e72e3 100644
--- a/halo2-lib-js/src/halo2lib/index.ts
+++ b/halo2-lib-js/src/halo2lib/index.ts
@@ -1,2 +1,3 @@
export * from './CircuitValue';
+export * from './CircuitValue256';
export * from './functions';
diff --git a/halo2-wasm/readme.md b/halo2-wasm/readme.md
index 0dfc7fe..0d5e51f 100644
--- a/halo2-wasm/readme.md
+++ b/halo2-wasm/readme.md
@@ -5,17 +5,21 @@ This repository aims to streamline the process of building WASM modules from zer
## Getting Started
For a brief overview on writing `halo2-lib` circuits, see this [doc](https://docs.axiom.xyz/zero-knowledge-proofs/getting-started-with-halo2). In addition to the `halo2-lib` setup, you will need `wasm-pack` installed:
+
```
curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
```
The [`template`](./template) folder includes everything you need to turn your circuit into a WASM bundle. In particular, [`template/src/lib.rs`](./template/src/lib.rs) is an example of a simple circuit that uses the context of a `Halo2Wasm` struct. You can then build your WASM bundle (from the `template` subdirectory) with:
+
```
-./build.sh
+./scripts/build.sh
```
+
where `` is either `nodejs` or `web`.
### Multithreading
+
Halo2 uses Rayon for multithreading, and we use `wasm-bindgen-rayon` to support this in the browser. It does not work outside the browser, however, so when `nodejs` is the compilation target, Rayon will be turned off (it is enabled using the `rayon` feature flag).
## Setting up the WASM module in JS
@@ -23,17 +27,22 @@ Halo2 uses Rayon for multithreading, and we use `wasm-bindgen-rayon` to support
### Web
```typescript
-import { init, initThreadPool, initPanicHook, Halo2Wasm, MyCircuit } from "";
+import {
+ init,
+ initThreadPool,
+ initPanicHook,
+ Halo2Wasm,
+ MyCircuit,
+} from "";
const main = async () => {
-
- //setup Halo2Wasm and MyCircuit
- await init();
- initPanicHook();
- await initThreadPool(numThreads);
- const halo2wasm = new Halo2Wasm();
- const myCircuit = new MyCircuit(halo2wasm);
-}
+ //setup Halo2Wasm and MyCircuit
+ await init();
+ initPanicHook();
+ await initThreadPool(numThreads);
+ const halo2wasm = new Halo2Wasm();
+ const myCircuit = new MyCircuit(halo2wasm);
+};
```
### Node.js
@@ -42,19 +51,18 @@ const main = async () => {
import { Halo2Wasm, initPanicHook, MyCircuit } from "";
const main = async () => {
-
- //setup Halo2Wasm and MyCircuit
- initPanicHook();
- const halo2wasm = new Halo2Wasm();
- const myCircuit = new MyCircuit(halo2wasm);
-}
+ //setup Halo2Wasm and MyCircuit
+ initPanicHook();
+ const halo2wasm = new Halo2Wasm();
+ const myCircuit = new MyCircuit(halo2wasm);
+};
```
You can now run `MyCircuit` witness generation with `myCircuit.run()` (following the example in the `template` subdirectory). You can then call any of the `Halo2Wasm` operations (`mock`, `keygen`, `prove`, etc.),
## halo2-js
-`halo2-js` is a Typescript wrapper for easily using the `halo2-wasm` module's functions (ie. proving, keygen, etc). Check out the [repo](https://github.com/axiom-crypto/halo2-js) for more info.
+`halo2-js` is a Typescript wrapper for easily using the `halo2-wasm` module's functions (ie. proving, keygen, etc). Check out the [repo](https://github.com/axiom-crypto/halo2-js) for more info.
## Benchmarks
From 14a97b315db5a20bd65e0377eb69a54713e440d7 Mon Sep 17 00:00:00 2001
From: Jonathan Wang <31040440+jonathanpwang@users.noreply.github.com>
Date: Tue, 31 Oct 2023 09:44:02 -0700
Subject: [PATCH 3/8] feat: ecc wrappers (#27)
Co-authored-by: anupsv
Co-authored-by: asv
Co-authored-by: Roshan <19766713+rpalakkal@users.noreply.github.com>
---
halo2-lib-js/package.json | 16 +-
halo2-lib-js/pnpm-lock.yaml | 1020 +++++++++----------
halo2-lib-js/src/halo2lib/ecc.ts | 21 +
halo2-lib-js/src/halo2lib/functions.ts | 155 ++-
halo2-lib-js/src/halo2lib/index.ts | 7 +-
halo2-lib-js/src/shared/docs/halo2Docs.d.ts | 134 ++-
halo2-lib-js/src/shared/docs/halo2Docs.ts | 2 +-
halo2-repl/app/page.tsx | 4 +-
halo2-repl/package.json | 6 +-
halo2-repl/pnpm-lock.yaml | 40 +-
halo2-wasm/Cargo.toml | 35 +-
halo2-wasm/js/js/index.ts | 8 +-
halo2-wasm/js/web/index.ts | 8 +-
halo2-wasm/package.json | 2 +-
halo2-wasm/pnpm-lock.yaml | 2 +-
halo2-wasm/scripts/build.sh | 2 +-
halo2-wasm/src/halo2lib.rs | 97 +-
halo2-wasm/src/halo2lib/ecc.rs | 510 ++++++++++
halo2-wasm/src/lib.rs | 71 +-
19 files changed, 1444 insertions(+), 696 deletions(-)
create mode 100644 halo2-lib-js/src/halo2lib/ecc.ts
create mode 100644 halo2-wasm/src/halo2lib/ecc.rs
diff --git a/halo2-lib-js/package.json b/halo2-lib-js/package.json
index 5dc011a..21e784a 100644
--- a/halo2-lib-js/package.json
+++ b/halo2-lib-js/package.json
@@ -1,6 +1,6 @@
{
"name": "@axiom-crypto/halo2-lib-js",
- "version": "0.2.2",
+ "version": "0.2.5",
"description": "Halo2 Javascript library",
"main": "index.js",
"scripts": {
@@ -18,22 +18,22 @@
"author": "Intrinsic Technologies",
"license": "ISC",
"devDependencies": {
- "@types/jest": "^29.5.4",
- "@types/node": "^20.5.6",
+ "@types/jest": "^29.5.7",
+ "@types/node": "^20.8.9",
"@types/prettier": "1.18.2",
- "dts-bundle-generator": "^8.0.1",
- "jest": "^29.6.4",
+ "dts-bundle-generator": "^8.1.2",
+ "jest": "^29.7.0",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"tslib": "^2.6.2",
"typescript": "^5.2.2"
},
"dependencies": {
- "@axiom-crypto/halo2-wasm": "0.2.3",
- "ethers": "^6.7.1",
+ "@axiom-crypto/halo2-wasm": "0.2.5",
+ "ethers": "^6.8.0",
"prettier": "1.18.2"
},
"publishConfig": {
"directory": "dist"
}
-}
\ No newline at end of file
+}
diff --git a/halo2-lib-js/pnpm-lock.yaml b/halo2-lib-js/pnpm-lock.yaml
index 039cbca..ee7e940 100644
--- a/halo2-lib-js/pnpm-lock.yaml
+++ b/halo2-lib-js/pnpm-lock.yaml
@@ -6,37 +6,37 @@ settings:
dependencies:
'@axiom-crypto/halo2-wasm':
- specifier: 0.2.3
- version: 0.2.3
+ specifier: 0.2.5
+ version: 0.2.5
ethers:
- specifier: ^6.7.1
- version: 6.7.1
+ specifier: ^6.8.0
+ version: 6.8.0
prettier:
specifier: 1.18.2
version: 1.18.2
devDependencies:
'@types/jest':
- specifier: ^29.5.4
- version: 29.5.4
+ specifier: ^29.5.7
+ version: 29.5.7
'@types/node':
- specifier: ^20.5.6
- version: 20.5.6
+ specifier: ^20.8.9
+ version: 20.8.9
'@types/prettier':
specifier: 1.18.2
version: 1.18.2
dts-bundle-generator:
- specifier: ^8.0.1
- version: 8.0.1
+ specifier: ^8.1.2
+ version: 8.1.2
jest:
- specifier: ^29.6.4
- version: 29.6.4(@types/node@20.5.6)(ts-node@10.9.1)
+ specifier: ^29.7.0
+ version: 29.7.0(@types/node@20.8.9)(ts-node@10.9.1)
ts-jest:
specifier: ^29.1.1
- version: 29.1.1(@babel/core@7.22.11)(jest@29.6.4)(typescript@5.2.2)
+ version: 29.1.1(@babel/core@7.23.2)(jest@29.7.0)(typescript@5.2.2)
ts-node:
specifier: ^10.9.1
- version: 10.9.1(@types/node@20.5.6)(typescript@5.2.2)
+ version: 10.9.1(@types/node@20.8.9)(typescript@5.2.2)
tslib:
specifier: ^2.6.2
version: 2.6.2
@@ -46,8 +46,8 @@ devDependencies:
packages:
- /@adraffy/ens-normalize@1.9.2:
- resolution: {integrity: sha512-0h+FrQDqe2Wn+IIGFkTCd4aAwTJ+7834Ek1COohCyV26AXhwQ7WQaz+4F/nLOeVl/3BtWHOHLPsq46V8YB46Eg==}
+ /@adraffy/ens-normalize@1.10.0:
+ resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==}
dev: false
/@ampproject/remapping@2.2.1:
@@ -55,21 +55,13 @@ packages:
engines: {node: '>=6.0.0'}
dependencies:
'@jridgewell/gen-mapping': 0.3.3
- '@jridgewell/trace-mapping': 0.3.19
+ '@jridgewell/trace-mapping': 0.3.20
dev: true
- /@axiom-crypto/halo2-wasm@0.2.3:
- resolution: {integrity: sha512-Yw5Nh825BiSF0tnvC0kZas4sezR8S6Z4ELJQsVKTaGiZin6416URFxBP5bQDj7u517QaFG8RTx50Do6xPIR8eg==}
+ /@axiom-crypto/halo2-wasm@0.2.5:
+ resolution: {integrity: sha512-89Nn9QOhKsVDMjMC35KLqsauVUWQ3K8/62mUjqDurc4hDg2MgAHUEM5DFQK198tJ7zNoEvDvhv+mWzLmDkUvzg==}
dev: false
- /@babel/code-frame@7.22.10:
- resolution: {integrity: sha512-/KKIMG4UEL35WmI9OlvMhurwtytjvXoFcGNrOvyG9zIzA8YmPjVtIZUf7b05+TPO7G7/GEmLHDaoCgACHl9hhA==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/highlight': 7.22.10
- chalk: 2.4.2
- dev: true
-
/@babel/code-frame@7.22.13:
resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==}
engines: {node: '>=6.9.0'}
@@ -78,26 +70,26 @@ packages:
chalk: 2.4.2
dev: true
- /@babel/compat-data@7.22.9:
- resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==}
+ /@babel/compat-data@7.23.2:
+ resolution: {integrity: sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ==}
engines: {node: '>=6.9.0'}
dev: true
- /@babel/core@7.22.11:
- resolution: {integrity: sha512-lh7RJrtPdhibbxndr6/xx0w8+CVlY5FJZiaSz908Fpy+G0xkBFTvwLcKJFF4PJxVfGhVWNebikpWGnOoC71juQ==}
+ /@babel/core@7.23.2:
+ resolution: {integrity: sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==}
engines: {node: '>=6.9.0'}
dependencies:
'@ampproject/remapping': 2.2.1
- '@babel/code-frame': 7.22.10
- '@babel/generator': 7.22.10
- '@babel/helper-compilation-targets': 7.22.10
- '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.11)
- '@babel/helpers': 7.22.11
- '@babel/parser': 7.22.11
- '@babel/template': 7.22.5
+ '@babel/code-frame': 7.22.13
+ '@babel/generator': 7.23.0
+ '@babel/helper-compilation-targets': 7.22.15
+ '@babel/helper-module-transforms': 7.23.0(@babel/core@7.23.2)
+ '@babel/helpers': 7.23.2
+ '@babel/parser': 7.23.0
+ '@babel/template': 7.22.15
'@babel/traverse': 7.23.2
- '@babel/types': 7.22.11
- convert-source-map: 1.9.0
+ '@babel/types': 7.23.0
+ convert-source-map: 2.0.0
debug: 4.3.4
gensync: 1.0.0-beta.2
json5: 2.2.3
@@ -106,33 +98,23 @@ packages:
- supports-color
dev: true
- /@babel/generator@7.22.10:
- resolution: {integrity: sha512-79KIf7YiWjjdZ81JnLujDRApWtl7BxTqWD88+FFdQEIOG8LJ0etDOM7CXuIgGJa55sGOwZVwuEsaLEm0PJ5/+A==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/types': 7.22.11
- '@jridgewell/gen-mapping': 0.3.3
- '@jridgewell/trace-mapping': 0.3.19
- jsesc: 2.5.2
- dev: true
-
/@babel/generator@7.23.0:
resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==}
engines: {node: '>=6.9.0'}
dependencies:
'@babel/types': 7.23.0
'@jridgewell/gen-mapping': 0.3.3
- '@jridgewell/trace-mapping': 0.3.19
+ '@jridgewell/trace-mapping': 0.3.20
jsesc: 2.5.2
dev: true
- /@babel/helper-compilation-targets@7.22.10:
- resolution: {integrity: sha512-JMSwHD4J7SLod0idLq5PKgI+6g/hLD/iuWBq08ZX49xE14VpVEojJ5rHWptpirV2j020MvypRLAXAO50igCJ5Q==}
+ /@babel/helper-compilation-targets@7.22.15:
+ resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/compat-data': 7.22.9
- '@babel/helper-validator-option': 7.22.5
- browserslist: 4.21.10
+ '@babel/compat-data': 7.23.2
+ '@babel/helper-validator-option': 7.22.15
+ browserslist: 4.22.1
lru-cache: 5.1.1
semver: 6.3.1
dev: true
@@ -142,11 +124,6 @@ packages:
engines: {node: '>=6.9.0'}
dev: true
- /@babel/helper-environment-visitor@7.22.5:
- resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==}
- engines: {node: '>=6.9.0'}
- dev: true
-
/@babel/helper-function-name@7.23.0:
resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==}
engines: {node: '>=6.9.0'}
@@ -162,25 +139,25 @@ packages:
'@babel/types': 7.23.0
dev: true
- /@babel/helper-module-imports@7.22.5:
- resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==}
+ /@babel/helper-module-imports@7.22.15:
+ resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.22.11
+ '@babel/types': 7.23.0
dev: true
- /@babel/helper-module-transforms@7.22.9(@babel/core@7.22.11):
- resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==}
+ /@babel/helper-module-transforms@7.23.0(@babel/core@7.23.2):
+ resolution: {integrity: sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.22.11
- '@babel/helper-environment-visitor': 7.22.5
- '@babel/helper-module-imports': 7.22.5
+ '@babel/core': 7.23.2
+ '@babel/helper-environment-visitor': 7.22.20
+ '@babel/helper-module-imports': 7.22.15
'@babel/helper-simple-access': 7.22.5
'@babel/helper-split-export-declaration': 7.22.6
- '@babel/helper-validator-identifier': 7.22.5
+ '@babel/helper-validator-identifier': 7.22.20
dev: true
/@babel/helper-plugin-utils@7.22.5:
@@ -192,7 +169,7 @@ packages:
resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/types': 7.22.11
+ '@babel/types': 7.23.0
dev: true
/@babel/helper-split-export-declaration@7.22.6:
@@ -212,36 +189,22 @@ packages:
engines: {node: '>=6.9.0'}
dev: true
- /@babel/helper-validator-identifier@7.22.5:
- resolution: {integrity: sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ==}
- engines: {node: '>=6.9.0'}
- dev: true
-
- /@babel/helper-validator-option@7.22.5:
- resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==}
+ /@babel/helper-validator-option@7.22.15:
+ resolution: {integrity: sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==}
engines: {node: '>=6.9.0'}
dev: true
- /@babel/helpers@7.22.11:
- resolution: {integrity: sha512-vyOXC8PBWaGc5h7GMsNx68OH33cypkEDJCHvYVVgVbbxJDROYVtexSk0gK5iCF1xNjRIN2s8ai7hwkWDq5szWg==}
+ /@babel/helpers@7.23.2:
+ resolution: {integrity: sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==}
engines: {node: '>=6.9.0'}
dependencies:
- '@babel/template': 7.22.5
+ '@babel/template': 7.22.15
'@babel/traverse': 7.23.2
- '@babel/types': 7.22.11
+ '@babel/types': 7.23.0
transitivePeerDependencies:
- supports-color
dev: true
- /@babel/highlight@7.22.10:
- resolution: {integrity: sha512-78aUtVcT7MUscr0K5mIEnkwxPE0MaxkR5RxRwuHaQ+JuU5AmTPhY+do2mdzVTnIJJpyBglql2pehuBIWHug+WQ==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/helper-validator-identifier': 7.22.5
- chalk: 2.4.2
- js-tokens: 4.0.0
- dev: true
-
/@babel/highlight@7.22.20:
resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==}
engines: {node: '>=6.9.0'}
@@ -251,14 +214,6 @@ packages:
js-tokens: 4.0.0
dev: true
- /@babel/parser@7.22.11:
- resolution: {integrity: sha512-R5zb8eJIBPJriQtbH/htEQy4k7E2dHWlD2Y2VT07JCzwYZHBxV5ZYtM0UhXSNMT74LyxuM+b1jdL7pSesXbC/g==}
- engines: {node: '>=6.0.0'}
- hasBin: true
- dependencies:
- '@babel/types': 7.22.11
- dev: true
-
/@babel/parser@7.23.0:
resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==}
engines: {node: '>=6.0.0'}
@@ -267,132 +222,132 @@ packages:
'@babel/types': 7.23.0
dev: true
- /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.11):
+ /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.23.2):
resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.22.11):
+ /@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.23.2):
resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.11):
+ /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.23.2):
resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.22.11):
+ /@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.23.2):
resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.11):
+ /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.23.2):
resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.11):
+ /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.11):
+ /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.23.2):
resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.11):
+ /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.23.2):
resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.11):
+ /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.23.2):
resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.11):
+ /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.23.2):
resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.11):
+ /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.23.2):
resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.11):
+ /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.23.2):
resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.11):
+ /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.23.2):
resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
- /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.22.11):
+ /@babel/plugin-syntax-typescript@7.22.5(@babel/core@7.23.2):
resolution: {integrity: sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ==}
engines: {node: '>=6.9.0'}
peerDependencies:
'@babel/core': ^7.0.0-0
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
'@babel/helper-plugin-utils': 7.22.5
dev: true
@@ -405,15 +360,6 @@ packages:
'@babel/types': 7.23.0
dev: true
- /@babel/template@7.22.5:
- resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/code-frame': 7.22.10
- '@babel/parser': 7.22.11
- '@babel/types': 7.22.11
- dev: true
-
/@babel/traverse@7.23.2:
resolution: {integrity: sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==}
engines: {node: '>=6.9.0'}
@@ -432,15 +378,6 @@ packages:
- supports-color
dev: true
- /@babel/types@7.22.11:
- resolution: {integrity: sha512-siazHiGuZRz9aB9NpHy9GOs9xiQPKnMzgdr493iI1M67vRXpnEq8ZOOKzezC5q7zwuQ6sDhdSp4SD9ixKSqKZg==}
- engines: {node: '>=6.9.0'}
- dependencies:
- '@babel/helper-string-parser': 7.22.5
- '@babel/helper-validator-identifier': 7.22.5
- to-fast-properties: 2.0.0
- dev: true
-
/@babel/types@7.23.0:
resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==}
engines: {node: '>=6.9.0'}
@@ -477,20 +414,20 @@ packages:
engines: {node: '>=8'}
dev: true
- /@jest/console@29.6.4:
- resolution: {integrity: sha512-wNK6gC0Ha9QeEPSkeJedQuTQqxZYnDPuDcDhVuVatRvMkL4D0VTvFVZj+Yuh6caG2aOfzkUZ36KtCmLNtR02hw==}
+ /@jest/console@29.7.0:
+ resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
- '@types/node': 20.5.6
+ '@types/node': 20.8.9
chalk: 4.1.2
- jest-message-util: 29.6.3
- jest-util: 29.6.3
+ jest-message-util: 29.7.0
+ jest-util: 29.7.0
slash: 3.0.0
dev: true
- /@jest/core@29.6.4(ts-node@10.9.1):
- resolution: {integrity: sha512-U/vq5ccNTSVgYH7mHnodHmCffGWHJnz/E1BEWlLuK5pM4FZmGfBn/nrJGLjUsSmyx3otCeqc1T31F4y08AMDLg==}
+ /@jest/core@29.7.0(ts-node@10.9.1):
+ resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
@@ -498,32 +435,32 @@ packages:
node-notifier:
optional: true
dependencies:
- '@jest/console': 29.6.4
- '@jest/reporters': 29.6.4
- '@jest/test-result': 29.6.4
- '@jest/transform': 29.6.4
+ '@jest/console': 29.7.0
+ '@jest/reporters': 29.7.0
+ '@jest/test-result': 29.7.0
+ '@jest/transform': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.5.6
+ '@types/node': 20.8.9
ansi-escapes: 4.3.2
chalk: 4.1.2
- ci-info: 3.8.0
+ ci-info: 3.9.0
exit: 0.1.2
graceful-fs: 4.2.11
- jest-changed-files: 29.6.3
- jest-config: 29.6.4(@types/node@20.5.6)(ts-node@10.9.1)
- jest-haste-map: 29.6.4
- jest-message-util: 29.6.3
+ jest-changed-files: 29.7.0
+ jest-config: 29.7.0(@types/node@20.8.9)(ts-node@10.9.1)
+ jest-haste-map: 29.7.0
+ jest-message-util: 29.7.0
jest-regex-util: 29.6.3
- jest-resolve: 29.6.4
- jest-resolve-dependencies: 29.6.4
- jest-runner: 29.6.4
- jest-runtime: 29.6.4
- jest-snapshot: 29.6.4
- jest-util: 29.6.3
- jest-validate: 29.6.3
- jest-watcher: 29.6.4
+ jest-resolve: 29.7.0
+ jest-resolve-dependencies: 29.7.0
+ jest-runner: 29.7.0
+ jest-runtime: 29.7.0
+ jest-snapshot: 29.7.0
+ jest-util: 29.7.0
+ jest-validate: 29.7.0
+ jest-watcher: 29.7.0
micromatch: 4.0.5
- pretty-format: 29.6.3
+ pretty-format: 29.7.0
slash: 3.0.0
strip-ansi: 6.0.1
transitivePeerDependencies:
@@ -532,59 +469,59 @@ packages:
- ts-node
dev: true
- /@jest/environment@29.6.4:
- resolution: {integrity: sha512-sQ0SULEjA1XUTHmkBRl7A1dyITM9yb1yb3ZNKPX3KlTd6IG7mWUe3e2yfExtC2Zz1Q+mMckOLHmL/qLiuQJrBQ==}
+ /@jest/environment@29.7.0:
+ resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@jest/fake-timers': 29.6.4
+ '@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.5.6
- jest-mock: 29.6.3
+ '@types/node': 20.8.9
+ jest-mock: 29.7.0
dev: true
- /@jest/expect-utils@29.6.4:
- resolution: {integrity: sha512-FEhkJhqtvBwgSpiTrocquJCdXPsyvNKcl/n7A3u7X4pVoF4bswm11c9d4AV+kfq2Gpv/mM8x7E7DsRvH+djkrg==}
+ /@jest/expect-utils@29.7.0:
+ resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
jest-get-type: 29.6.3
dev: true
- /@jest/expect@29.6.4:
- resolution: {integrity: sha512-Warhsa7d23+3X5bLbrbYvaehcgX5TLYhI03JKoedTiI8uJU4IhqYBWF7OSSgUyz4IgLpUYPkK0AehA5/fRclAA==}
+ /@jest/expect@29.7.0:
+ resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- expect: 29.6.4
- jest-snapshot: 29.6.4
+ expect: 29.7.0
+ jest-snapshot: 29.7.0
transitivePeerDependencies:
- supports-color
dev: true
- /@jest/fake-timers@29.6.4:
- resolution: {integrity: sha512-6UkCwzoBK60edXIIWb0/KWkuj7R7Qq91vVInOe3De6DSpaEiqjKcJw4F7XUet24Wupahj9J6PlR09JqJ5ySDHw==}
+ /@jest/fake-timers@29.7.0:
+ resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
'@sinonjs/fake-timers': 10.3.0
- '@types/node': 20.5.6
- jest-message-util: 29.6.3
- jest-mock: 29.6.3
- jest-util: 29.6.3
+ '@types/node': 20.8.9
+ jest-message-util: 29.7.0
+ jest-mock: 29.7.0
+ jest-util: 29.7.0
dev: true
- /@jest/globals@29.6.4:
- resolution: {integrity: sha512-wVIn5bdtjlChhXAzVXavcY/3PEjf4VqM174BM3eGL5kMxLiZD5CLnbmkEyA1Dwh9q8XjP6E8RwjBsY/iCWrWsA==}
+ /@jest/globals@29.7.0:
+ resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@jest/environment': 29.6.4
- '@jest/expect': 29.6.4
+ '@jest/environment': 29.7.0
+ '@jest/expect': 29.7.0
'@jest/types': 29.6.3
- jest-mock: 29.6.3
+ jest-mock: 29.7.0
transitivePeerDependencies:
- supports-color
dev: true
- /@jest/reporters@29.6.4:
- resolution: {integrity: sha512-sxUjWxm7QdchdrD3NfWKrL8FBsortZeibSJv4XLjESOOjSUOkjQcb0ZHJwfhEGIvBvTluTzfG2yZWZhkrXJu8g==}
+ /@jest/reporters@29.7.0:
+ resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0
@@ -593,29 +530,29 @@ packages:
optional: true
dependencies:
'@bcoe/v8-coverage': 0.2.3
- '@jest/console': 29.6.4
- '@jest/test-result': 29.6.4
- '@jest/transform': 29.6.4
+ '@jest/console': 29.7.0
+ '@jest/test-result': 29.7.0
+ '@jest/transform': 29.7.0
'@jest/types': 29.6.3
- '@jridgewell/trace-mapping': 0.3.19
- '@types/node': 20.5.6
+ '@jridgewell/trace-mapping': 0.3.20
+ '@types/node': 20.8.9
chalk: 4.1.2
collect-v8-coverage: 1.0.2
exit: 0.1.2
glob: 7.2.3
graceful-fs: 4.2.11
istanbul-lib-coverage: 3.2.0
- istanbul-lib-instrument: 6.0.0
+ istanbul-lib-instrument: 6.0.1
istanbul-lib-report: 3.0.1
istanbul-lib-source-maps: 4.0.1
istanbul-reports: 3.1.6
- jest-message-util: 29.6.3
- jest-util: 29.6.3
- jest-worker: 29.6.4
+ jest-message-util: 29.7.0
+ jest-util: 29.7.0
+ jest-worker: 29.7.0
slash: 3.0.0
string-length: 4.0.2
strip-ansi: 6.0.1
- v8-to-istanbul: 9.1.0
+ v8-to-istanbul: 9.1.3
transitivePeerDependencies:
- supports-color
dev: true
@@ -631,46 +568,46 @@ packages:
resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@jridgewell/trace-mapping': 0.3.19
+ '@jridgewell/trace-mapping': 0.3.20
callsites: 3.1.0
graceful-fs: 4.2.11
dev: true
- /@jest/test-result@29.6.4:
- resolution: {integrity: sha512-uQ1C0AUEN90/dsyEirgMLlouROgSY+Wc/JanVVk0OiUKa5UFh7sJpMEM3aoUBAz2BRNvUJ8j3d294WFuRxSyOQ==}
+ /@jest/test-result@29.7.0:
+ resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@jest/console': 29.6.4
+ '@jest/console': 29.7.0
'@jest/types': 29.6.3
- '@types/istanbul-lib-coverage': 2.0.4
+ '@types/istanbul-lib-coverage': 2.0.5
collect-v8-coverage: 1.0.2
dev: true
- /@jest/test-sequencer@29.6.4:
- resolution: {integrity: sha512-E84M6LbpcRq3fT4ckfKs9ryVanwkaIB0Ws9bw3/yP4seRLg/VaCZ/LgW0MCq5wwk4/iP/qnilD41aj2fsw2RMg==}
+ /@jest/test-sequencer@29.7.0:
+ resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@jest/test-result': 29.6.4
+ '@jest/test-result': 29.7.0
graceful-fs: 4.2.11
- jest-haste-map: 29.6.4
+ jest-haste-map: 29.7.0
slash: 3.0.0
dev: true
- /@jest/transform@29.6.4:
- resolution: {integrity: sha512-8thgRSiXUqtr/pPGY/OsyHuMjGyhVnWrFAwoxmIemlBuiMyU1WFs0tXoNxzcr4A4uErs/ABre76SGmrr5ab/AA==}
+ /@jest/transform@29.7.0:
+ resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
'@jest/types': 29.6.3
- '@jridgewell/trace-mapping': 0.3.19
+ '@jridgewell/trace-mapping': 0.3.20
babel-plugin-istanbul: 6.1.1
chalk: 4.1.2
convert-source-map: 2.0.0
fast-json-stable-stringify: 2.1.0
graceful-fs: 4.2.11
- jest-haste-map: 29.6.4
+ jest-haste-map: 29.7.0
jest-regex-util: 29.6.3
- jest-util: 29.6.3
+ jest-util: 29.7.0
micromatch: 4.0.5
pirates: 4.0.6
slash: 3.0.0
@@ -684,10 +621,10 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/schemas': 29.6.3
- '@types/istanbul-lib-coverage': 2.0.4
- '@types/istanbul-reports': 3.0.1
- '@types/node': 20.5.6
- '@types/yargs': 17.0.24
+ '@types/istanbul-lib-coverage': 2.0.5
+ '@types/istanbul-reports': 3.0.3
+ '@types/node': 20.8.9
+ '@types/yargs': 17.0.29
chalk: 4.1.2
dev: true
@@ -697,7 +634,7 @@ packages:
dependencies:
'@jridgewell/set-array': 1.1.2
'@jridgewell/sourcemap-codec': 1.4.15
- '@jridgewell/trace-mapping': 0.3.19
+ '@jridgewell/trace-mapping': 0.3.20
dev: true
/@jridgewell/resolve-uri@3.1.1:
@@ -714,8 +651,8 @@ packages:
resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==}
dev: true
- /@jridgewell/trace-mapping@0.3.19:
- resolution: {integrity: sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==}
+ /@jridgewell/trace-mapping@0.3.20:
+ resolution: {integrity: sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==}
dependencies:
'@jridgewell/resolve-uri': 3.1.1
'@jridgewell/sourcemap-codec': 1.4.15
@@ -728,12 +665,15 @@ packages:
'@jridgewell/sourcemap-codec': 1.4.15
dev: true
- /@noble/hashes@1.1.2:
- resolution: {integrity: sha512-KYRCASVTv6aeUi1tsF8/vpyR7zpfs3FUzy2Jqm+MU+LmUKhQ0y2FpfwqkCcxSg2ua4GALJd8k2R76WxwZGbQpA==}
+ /@noble/curves@1.2.0:
+ resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==}
+ dependencies:
+ '@noble/hashes': 1.3.2
dev: false
- /@noble/secp256k1@1.7.1:
- resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==}
+ /@noble/hashes@1.3.2:
+ resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==}
+ engines: {node: '>= 16'}
dev: false
/@sinclair/typebox@0.27.8:
@@ -768,97 +708,99 @@ packages:
resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==}
dev: true
- /@types/babel__core@7.20.1:
- resolution: {integrity: sha512-aACu/U/omhdk15O4Nfb+fHgH/z3QsfQzpnvRZhYhThms83ZnAOZz7zZAWO7mn2yyNQaA4xTO8GLK3uqFU4bYYw==}
+ /@types/babel__core@7.20.3:
+ resolution: {integrity: sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA==}
dependencies:
- '@babel/parser': 7.22.11
- '@babel/types': 7.22.11
- '@types/babel__generator': 7.6.4
- '@types/babel__template': 7.4.1
- '@types/babel__traverse': 7.20.1
+ '@babel/parser': 7.23.0
+ '@babel/types': 7.23.0
+ '@types/babel__generator': 7.6.6
+ '@types/babel__template': 7.4.3
+ '@types/babel__traverse': 7.20.3
dev: true
- /@types/babel__generator@7.6.4:
- resolution: {integrity: sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==}
+ /@types/babel__generator@7.6.6:
+ resolution: {integrity: sha512-66BXMKb/sUWbMdBNdMvajU7i/44RkrA3z/Yt1c7R5xejt8qh84iU54yUWCtm0QwGJlDcf/gg4zd/x4mpLAlb/w==}
dependencies:
- '@babel/types': 7.22.11
+ '@babel/types': 7.23.0
dev: true
- /@types/babel__template@7.4.1:
- resolution: {integrity: sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==}
+ /@types/babel__template@7.4.3:
+ resolution: {integrity: sha512-ciwyCLeuRfxboZ4isgdNZi/tkt06m8Tw6uGbBSBgWrnnZGNXiEyM27xc/PjXGQLqlZ6ylbgHMnm7ccF9tCkOeQ==}
dependencies:
- '@babel/parser': 7.22.11
- '@babel/types': 7.22.11
+ '@babel/parser': 7.23.0
+ '@babel/types': 7.23.0
dev: true
- /@types/babel__traverse@7.20.1:
- resolution: {integrity: sha512-MitHFXnhtgwsGZWtT68URpOvLN4EREih1u3QtQiN4VdAxWKRVvGCSvw/Qth0M0Qq3pJpnGOu5JaM/ydK7OGbqg==}
+ /@types/babel__traverse@7.20.3:
+ resolution: {integrity: sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw==}
dependencies:
- '@babel/types': 7.22.11
+ '@babel/types': 7.23.0
dev: true
- /@types/graceful-fs@4.1.6:
- resolution: {integrity: sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw==}
+ /@types/graceful-fs@4.1.8:
+ resolution: {integrity: sha512-NhRH7YzWq8WiNKVavKPBmtLYZHxNY19Hh+az28O/phfp68CF45pMFud+ZzJ8ewnxnC5smIdF3dqFeiSUQ5I+pw==}
dependencies:
- '@types/node': 20.5.6
+ '@types/node': 20.8.9
dev: true
- /@types/istanbul-lib-coverage@2.0.4:
- resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==}
+ /@types/istanbul-lib-coverage@2.0.5:
+ resolution: {integrity: sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ==}
dev: true
- /@types/istanbul-lib-report@3.0.0:
- resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==}
+ /@types/istanbul-lib-report@3.0.2:
+ resolution: {integrity: sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w==}
dependencies:
- '@types/istanbul-lib-coverage': 2.0.4
+ '@types/istanbul-lib-coverage': 2.0.5
dev: true
- /@types/istanbul-reports@3.0.1:
- resolution: {integrity: sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==}
+ /@types/istanbul-reports@3.0.3:
+ resolution: {integrity: sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg==}
dependencies:
- '@types/istanbul-lib-report': 3.0.0
+ '@types/istanbul-lib-report': 3.0.2
dev: true
- /@types/jest@29.5.4:
- resolution: {integrity: sha512-PhglGmhWeD46FYOVLt3X7TiWjzwuVGW9wG/4qocPevXMjCmrIc5b6db9WjeGE4QYVpUAWMDv3v0IiBwObY289A==}
+ /@types/jest@29.5.7:
+ resolution: {integrity: sha512-HLyetab6KVPSiF+7pFcUyMeLsx25LDNDemw9mGsJBkai/oouwrjTycocSDYopMEwFhN2Y4s9oPyOCZNofgSt2g==}
dependencies:
- expect: 29.6.4
- pretty-format: 29.6.3
+ expect: 29.7.0
+ pretty-format: 29.7.0
dev: true
/@types/node@18.15.13:
resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==}
dev: false
- /@types/node@20.5.6:
- resolution: {integrity: sha512-Gi5wRGPbbyOTX+4Y2iULQ27oUPrefaB0PxGQJnfyWN3kvEDGM3mIB5M/gQLmitZf7A9FmLeaqxD3L1CXpm3VKQ==}
+ /@types/node@20.8.9:
+ resolution: {integrity: sha512-UzykFsT3FhHb1h7yD4CA4YhBHq545JC0YnEz41xkipN88eKQtL6rSgocL5tbAP6Ola9Izm/Aw4Ora8He4x0BHg==}
+ dependencies:
+ undici-types: 5.26.5
dev: true
/@types/prettier@1.18.2:
resolution: {integrity: sha512-2JBasa5Qaj81Qsp/dxX2Njy+MdKC767WytHUDsRM7TYEfQvKPxsnGpnCBlBS1i2Aiv1YwCpmKSbQ6O6v8TpiKg==}
dev: true
- /@types/stack-utils@2.0.1:
- resolution: {integrity: sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==}
+ /@types/stack-utils@2.0.2:
+ resolution: {integrity: sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw==}
dev: true
- /@types/yargs-parser@21.0.0:
- resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==}
+ /@types/yargs-parser@21.0.2:
+ resolution: {integrity: sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw==}
dev: true
- /@types/yargs@17.0.24:
- resolution: {integrity: sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==}
+ /@types/yargs@17.0.29:
+ resolution: {integrity: sha512-nacjqA3ee9zRF/++a3FUY1suHTFKZeHba2n8WeDw9cCVdmzmHpIxyzOJBcpHvvEmS8E9KqWlSnWHUkOrkhWcvA==}
dependencies:
- '@types/yargs-parser': 21.0.0
+ '@types/yargs-parser': 21.0.2
dev: true
- /acorn-walk@8.2.0:
- resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==}
+ /acorn-walk@8.3.0:
+ resolution: {integrity: sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA==}
engines: {node: '>=0.4.0'}
dev: true
- /acorn@8.10.0:
- resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==}
+ /acorn@8.11.2:
+ resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==}
engines: {node: '>=0.4.0'}
hasBin: true
dev: true
@@ -916,17 +858,17 @@ packages:
sprintf-js: 1.0.3
dev: true
- /babel-jest@29.6.4(@babel/core@7.22.11):
- resolution: {integrity: sha512-meLj23UlSLddj6PC+YTOFRgDAtjnZom8w/ACsrx0gtPtv5cJZk0A5Unk5bV4wixD7XaPCN1fQvpww8czkZURmw==}
+ /babel-jest@29.7.0(@babel/core@7.23.2):
+ resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
'@babel/core': ^7.8.0
dependencies:
- '@babel/core': 7.22.11
- '@jest/transform': 29.6.4
- '@types/babel__core': 7.20.1
+ '@babel/core': 7.23.2
+ '@jest/transform': 29.7.0
+ '@types/babel__core': 7.20.3
babel-plugin-istanbul: 6.1.1
- babel-preset-jest: 29.6.3(@babel/core@7.22.11)
+ babel-preset-jest: 29.6.3(@babel/core@7.23.2)
chalk: 4.1.2
graceful-fs: 4.2.11
slash: 3.0.0
@@ -951,41 +893,41 @@ packages:
resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@babel/template': 7.22.5
- '@babel/types': 7.22.11
- '@types/babel__core': 7.20.1
- '@types/babel__traverse': 7.20.1
+ '@babel/template': 7.22.15
+ '@babel/types': 7.23.0
+ '@types/babel__core': 7.20.3
+ '@types/babel__traverse': 7.20.3
dev: true
- /babel-preset-current-node-syntax@1.0.1(@babel/core@7.22.11):
+ /babel-preset-current-node-syntax@1.0.1(@babel/core@7.23.2):
resolution: {integrity: sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.22.11
- '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.11)
- '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.22.11)
- '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.11)
- '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.22.11)
- '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.11)
- '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.11)
- '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.11)
- '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.11)
- '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.11)
- '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.11)
- '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.11)
- '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.11)
- dev: true
-
- /babel-preset-jest@29.6.3(@babel/core@7.22.11):
+ '@babel/core': 7.23.2
+ '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.23.2)
+ '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.23.2)
+ '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.23.2)
+ '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.23.2)
+ '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.23.2)
+ '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.23.2)
+ '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.23.2)
+ dev: true
+
+ /babel-preset-jest@29.6.3(@babel/core@7.23.2):
resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
'@babel/core': ^7.0.0
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
babel-plugin-jest-hoist: 29.6.3
- babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.11)
+ babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.2)
dev: true
/balanced-match@1.0.2:
@@ -1006,15 +948,15 @@ packages:
fill-range: 7.0.1
dev: true
- /browserslist@4.21.10:
- resolution: {integrity: sha512-bipEBdZfVH5/pwrvqc+Ub0kUPVfGUhlKxbvfD+z1BDnPEO/X98ruXGA1WP5ASpAFKan7Qr6j736IacbZQuAlKQ==}
+ /browserslist@4.22.1:
+ resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==}
engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
hasBin: true
dependencies:
- caniuse-lite: 1.0.30001523
- electron-to-chromium: 1.4.503
+ caniuse-lite: 1.0.30001559
+ electron-to-chromium: 1.4.571
node-releases: 2.0.13
- update-browserslist-db: 1.0.11(browserslist@4.21.10)
+ update-browserslist-db: 1.0.13(browserslist@4.22.1)
dev: true
/bs-logger@0.2.6:
@@ -1049,8 +991,8 @@ packages:
engines: {node: '>=10'}
dev: true
- /caniuse-lite@1.0.30001523:
- resolution: {integrity: sha512-I5q5cisATTPZ1mc588Z//pj/Ox80ERYDfR71YnvY7raS/NOk8xXlZcB0sF7JdqaV//kOaa6aus7lRfpdnt1eBA==}
+ /caniuse-lite@1.0.30001559:
+ resolution: {integrity: sha512-cPiMKZgqgkg5LY3/ntGeLFUpi6tzddBNS58A4tnTgQw1zON7u2sZMU7SzOeVH4tj20++9ggL+V6FDOFMTaFFYA==}
dev: true
/chalk@2.4.2:
@@ -1075,8 +1017,8 @@ packages:
engines: {node: '>=10'}
dev: true
- /ci-info@3.8.0:
- resolution: {integrity: sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw==}
+ /ci-info@3.9.0:
+ resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==}
engines: {node: '>=8'}
dev: true
@@ -1127,14 +1069,29 @@ packages:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
dev: true
- /convert-source-map@1.9.0:
- resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
- dev: true
-
/convert-source-map@2.0.0:
resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
dev: true
+ /create-jest@29.7.0(@types/node@20.8.9)(ts-node@10.9.1):
+ resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==}
+ engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
+ hasBin: true
+ dependencies:
+ '@jest/types': 29.6.3
+ chalk: 4.1.2
+ exit: 0.1.2
+ graceful-fs: 4.2.11
+ jest-config: 29.7.0(@types/node@20.8.9)(ts-node@10.9.1)
+ jest-util: 29.7.0
+ prompts: 2.4.2
+ transitivePeerDependencies:
+ - '@types/node'
+ - babel-plugin-macros
+ - supports-color
+ - ts-node
+ dev: true
+
/create-require@1.1.1:
resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==}
dev: true
@@ -1189,8 +1146,8 @@ packages:
engines: {node: '>=0.3.1'}
dev: true
- /dts-bundle-generator@8.0.1:
- resolution: {integrity: sha512-9JVw78/OXdKfq+RUrmpLm6WAUJp+aOUGEHimVqIlOEH2VugRt1I8CVIoQZlirWZko+/SVZkNgpWCyZubUuzzPA==}
+ /dts-bundle-generator@8.1.2:
+ resolution: {integrity: sha512-/yvy9Xw0cfFodA8n6jEq8/COZ/WXgJtPabnLBAzIfP/TfxWbD/0a0dvfqNHneNqswQrH0kUcaAfGJC9UNvH97w==}
engines: {node: '>=14.0.0'}
hasBin: true
dependencies:
@@ -1198,8 +1155,8 @@ packages:
yargs: 17.7.2
dev: true
- /electron-to-chromium@1.4.503:
- resolution: {integrity: sha512-LF2IQit4B0VrUHFeQkWhZm97KuJSGF2WJqq1InpY+ECpFRkXd8yTIaTtJxsO0OKDmiBYwWqcrNaXOurn2T2wiA==}
+ /electron-to-chromium@1.4.571:
+ resolution: {integrity: sha512-Sc+VtKwKCDj3f/kLBjdyjMpNzoZsU6WuL/wFb6EH8USmHEcebxRXcRrVpOpayxd52tuey4RUDpUsw5OS5LhJqg==}
dev: true
/emittery@0.13.1:
@@ -1238,13 +1195,13 @@ packages:
hasBin: true
dev: true
- /ethers@6.7.1:
- resolution: {integrity: sha512-qX5kxIFMfg1i+epfgb0xF4WM7IqapIIu50pOJ17aebkxxa4BacW5jFrQRmCJpDEg2ZK2oNtR5QjrQ1WDBF29dA==}
+ /ethers@6.8.0:
+ resolution: {integrity: sha512-zrFbmQRlraM+cU5mE4CZTLBurZTs2gdp2ld0nG/f3ecBK+x6lZ69KSxBqZ4NjclxwfTxl5LeNufcBbMsTdY53Q==}
engines: {node: '>=14.0.0'}
dependencies:
- '@adraffy/ens-normalize': 1.9.2
- '@noble/hashes': 1.1.2
- '@noble/secp256k1': 1.7.1
+ '@adraffy/ens-normalize': 1.10.0
+ '@noble/curves': 1.2.0
+ '@noble/hashes': 1.3.2
'@types/node': 18.15.13
aes-js: 4.0.0-beta.5
tslib: 2.4.0
@@ -1274,15 +1231,15 @@ packages:
engines: {node: '>= 0.8.0'}
dev: true
- /expect@29.6.4:
- resolution: {integrity: sha512-F2W2UyQ8XYyftHT57dtfg8Ue3X5qLgm2sSug0ivvLRH/VKNRL/pDxg/TH7zVzbQB0tu80clNFy6LU7OS/VSEKA==}
+ /expect@29.7.0:
+ resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@jest/expect-utils': 29.6.4
+ '@jest/expect-utils': 29.7.0
jest-get-type: 29.6.3
- jest-matcher-utils: 29.6.4
- jest-message-util: 29.6.3
- jest-util: 29.6.3
+ jest-matcher-utils: 29.7.0
+ jest-message-util: 29.7.0
+ jest-util: 29.7.0
dev: true
/fast-json-stable-stringify@2.1.0:
@@ -1322,8 +1279,8 @@ packages:
dev: true
optional: true
- /function-bind@1.1.1:
- resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
+ /function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
dev: true
/gensync@1.0.0-beta.2:
@@ -1376,11 +1333,11 @@ packages:
engines: {node: '>=8'}
dev: true
- /has@1.0.3:
- resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
- engines: {node: '>= 0.4.0'}
+ /hasown@2.0.0:
+ resolution: {integrity: sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==}
+ engines: {node: '>= 0.4'}
dependencies:
- function-bind: 1.1.1
+ function-bind: 1.1.2
dev: true
/html-escaper@2.0.2:
@@ -1421,10 +1378,10 @@ packages:
resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
dev: true
- /is-core-module@2.13.0:
- resolution: {integrity: sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ==}
+ /is-core-module@2.13.1:
+ resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==}
dependencies:
- has: 1.0.3
+ hasown: 2.0.0
dev: true
/is-fullwidth-code-point@3.0.0:
@@ -1460,8 +1417,8 @@ packages:
resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==}
engines: {node: '>=8'}
dependencies:
- '@babel/core': 7.22.11
- '@babel/parser': 7.22.11
+ '@babel/core': 7.23.2
+ '@babel/parser': 7.23.0
'@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.2.0
semver: 6.3.1
@@ -1469,12 +1426,12 @@ packages:
- supports-color
dev: true
- /istanbul-lib-instrument@6.0.0:
- resolution: {integrity: sha512-x58orMzEVfzPUKqlbLd1hXCnySCxKdDKa6Rjg97CwuLLRI4g3FHTdnExu1OqffVFay6zeMW+T6/DowFLndWnIw==}
+ /istanbul-lib-instrument@6.0.1:
+ resolution: {integrity: sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA==}
engines: {node: '>=10'}
dependencies:
- '@babel/core': 7.22.11
- '@babel/parser': 7.22.11
+ '@babel/core': 7.23.2
+ '@babel/parser': 7.23.0
'@istanbuljs/schema': 0.1.3
istanbul-lib-coverage: 3.2.0
semver: 7.5.4
@@ -1510,37 +1467,37 @@ packages:
istanbul-lib-report: 3.0.1
dev: true
- /jest-changed-files@29.6.3:
- resolution: {integrity: sha512-G5wDnElqLa4/c66ma5PG9eRjE342lIbF6SUnTJi26C3J28Fv2TVY2rOyKB9YGbSA5ogwevgmxc4j4aVjrEK6Yg==}
+ /jest-changed-files@29.7.0:
+ resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
execa: 5.1.1
- jest-util: 29.6.3
+ jest-util: 29.7.0
p-limit: 3.1.0
dev: true
- /jest-circus@29.6.4:
- resolution: {integrity: sha512-YXNrRyntVUgDfZbjXWBMPslX1mQ8MrSG0oM/Y06j9EYubODIyHWP8hMUbjbZ19M3M+zamqEur7O80HODwACoJw==}
+ /jest-circus@29.7.0:
+ resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@jest/environment': 29.6.4
- '@jest/expect': 29.6.4
- '@jest/test-result': 29.6.4
+ '@jest/environment': 29.7.0
+ '@jest/expect': 29.7.0
+ '@jest/test-result': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.5.6
+ '@types/node': 20.8.9
chalk: 4.1.2
co: 4.6.0
dedent: 1.5.1
is-generator-fn: 2.1.0
- jest-each: 29.6.3
- jest-matcher-utils: 29.6.4
- jest-message-util: 29.6.3
- jest-runtime: 29.6.4
- jest-snapshot: 29.6.4
- jest-util: 29.6.3
+ jest-each: 29.7.0
+ jest-matcher-utils: 29.7.0
+ jest-message-util: 29.7.0
+ jest-runtime: 29.7.0
+ jest-snapshot: 29.7.0
+ jest-util: 29.7.0
p-limit: 3.1.0
- pretty-format: 29.6.3
- pure-rand: 6.0.2
+ pretty-format: 29.7.0
+ pure-rand: 6.0.4
slash: 3.0.0
stack-utils: 2.0.6
transitivePeerDependencies:
@@ -1548,8 +1505,8 @@ packages:
- supports-color
dev: true
- /jest-cli@29.6.4(@types/node@20.5.6)(ts-node@10.9.1):
- resolution: {integrity: sha512-+uMCQ7oizMmh8ZwRfZzKIEszFY9ksjjEQnTEMTaL7fYiL3Kw4XhqT9bYh+A4DQKUb67hZn2KbtEnDuHvcgK4pQ==}
+ /jest-cli@29.7.0(@types/node@20.8.9)(ts-node@10.9.1):
+ resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
peerDependencies:
@@ -1558,17 +1515,16 @@ packages:
node-notifier:
optional: true
dependencies:
- '@jest/core': 29.6.4(ts-node@10.9.1)
- '@jest/test-result': 29.6.4
+ '@jest/core': 29.7.0(ts-node@10.9.1)
+ '@jest/test-result': 29.7.0
'@jest/types': 29.6.3
chalk: 4.1.2
+ create-jest: 29.7.0(@types/node@20.8.9)(ts-node@10.9.1)
exit: 0.1.2
- graceful-fs: 4.2.11
import-local: 3.1.0
- jest-config: 29.6.4(@types/node@20.5.6)(ts-node@10.9.1)
- jest-util: 29.6.3
- jest-validate: 29.6.3
- prompts: 2.4.2
+ jest-config: 29.7.0(@types/node@20.8.9)(ts-node@10.9.1)
+ jest-util: 29.7.0
+ jest-validate: 29.7.0
yargs: 17.7.2
transitivePeerDependencies:
- '@types/node'
@@ -1577,8 +1533,8 @@ packages:
- ts-node
dev: true
- /jest-config@29.6.4(@types/node@20.5.6)(ts-node@10.9.1):
- resolution: {integrity: sha512-JWohr3i9m2cVpBumQFv2akMEnFEPVOh+9L2xIBJhJ0zOaci2ZXuKJj0tgMKQCBZAKA09H049IR4HVS/43Qb19A==}
+ /jest-config@29.7.0(@types/node@20.8.9)(ts-node@10.9.1):
+ resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
peerDependencies:
'@types/node': '*'
@@ -1589,73 +1545,73 @@ packages:
ts-node:
optional: true
dependencies:
- '@babel/core': 7.22.11
- '@jest/test-sequencer': 29.6.4
+ '@babel/core': 7.23.2
+ '@jest/test-sequencer': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.5.6
- babel-jest: 29.6.4(@babel/core@7.22.11)
+ '@types/node': 20.8.9
+ babel-jest: 29.7.0(@babel/core@7.23.2)
chalk: 4.1.2
- ci-info: 3.8.0
+ ci-info: 3.9.0
deepmerge: 4.3.1
glob: 7.2.3
graceful-fs: 4.2.11
- jest-circus: 29.6.4
- jest-environment-node: 29.6.4
+ jest-circus: 29.7.0
+ jest-environment-node: 29.7.0
jest-get-type: 29.6.3
jest-regex-util: 29.6.3
- jest-resolve: 29.6.4
- jest-runner: 29.6.4
- jest-util: 29.6.3
- jest-validate: 29.6.3
+ jest-resolve: 29.7.0
+ jest-runner: 29.7.0
+ jest-util: 29.7.0
+ jest-validate: 29.7.0
micromatch: 4.0.5
parse-json: 5.2.0
- pretty-format: 29.6.3
+ pretty-format: 29.7.0
slash: 3.0.0
strip-json-comments: 3.1.1
- ts-node: 10.9.1(@types/node@20.5.6)(typescript@5.2.2)
+ ts-node: 10.9.1(@types/node@20.8.9)(typescript@5.2.2)
transitivePeerDependencies:
- babel-plugin-macros
- supports-color
dev: true
- /jest-diff@29.6.4:
- resolution: {integrity: sha512-9F48UxR9e4XOEZvoUXEHSWY4qC4zERJaOfrbBg9JpbJOO43R1vN76REt/aMGZoY6GD5g84nnJiBIVlscegefpw==}
+ /jest-diff@29.7.0:
+ resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
chalk: 4.1.2
diff-sequences: 29.6.3
jest-get-type: 29.6.3
- pretty-format: 29.6.3
+ pretty-format: 29.7.0
dev: true
- /jest-docblock@29.6.3:
- resolution: {integrity: sha512-2+H+GOTQBEm2+qFSQ7Ma+BvyV+waiIFxmZF5LdpBsAEjWX8QYjSCa4FrkIYtbfXUJJJnFCYrOtt6TZ+IAiTjBQ==}
+ /jest-docblock@29.7.0:
+ resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
detect-newline: 3.1.0
dev: true
- /jest-each@29.6.3:
- resolution: {integrity: sha512-KoXfJ42k8cqbkfshW7sSHcdfnv5agDdHCPA87ZBdmHP+zJstTJc0ttQaJ/x7zK6noAL76hOuTIJ6ZkQRS5dcyg==}
+ /jest-each@29.7.0:
+ resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
chalk: 4.1.2
jest-get-type: 29.6.3
- jest-util: 29.6.3
- pretty-format: 29.6.3
+ jest-util: 29.7.0
+ pretty-format: 29.7.0
dev: true
- /jest-environment-node@29.6.4:
- resolution: {integrity: sha512-i7SbpH2dEIFGNmxGCpSc2w9cA4qVD+wfvg2ZnfQ7XVrKL0NA5uDVBIiGH8SR4F0dKEv/0qI5r+aDomDf04DpEQ==}
+ /jest-environment-node@29.7.0:
+ resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@jest/environment': 29.6.4
- '@jest/fake-timers': 29.6.4
+ '@jest/environment': 29.7.0
+ '@jest/fake-timers': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.5.6
- jest-mock: 29.6.3
- jest-util: 29.6.3
+ '@types/node': 20.8.9
+ jest-mock: 29.7.0
+ jest-util: 29.7.0
dev: true
/jest-get-type@29.6.3:
@@ -1663,68 +1619,68 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dev: true
- /jest-haste-map@29.6.4:
- resolution: {integrity: sha512-12Ad+VNTDHxKf7k+M65sviyynRoZYuL1/GTuhEVb8RYsNSNln71nANRb/faSyWvx0j+gHcivChXHIoMJrGYjog==}
+ /jest-haste-map@29.7.0:
+ resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
- '@types/graceful-fs': 4.1.6
- '@types/node': 20.5.6
+ '@types/graceful-fs': 4.1.8
+ '@types/node': 20.8.9
anymatch: 3.1.3
fb-watchman: 2.0.2
graceful-fs: 4.2.11
jest-regex-util: 29.6.3
- jest-util: 29.6.3
- jest-worker: 29.6.4
+ jest-util: 29.7.0
+ jest-worker: 29.7.0
micromatch: 4.0.5
walker: 1.0.8
optionalDependencies:
fsevents: 2.3.3
dev: true
- /jest-leak-detector@29.6.3:
- resolution: {integrity: sha512-0kfbESIHXYdhAdpLsW7xdwmYhLf1BRu4AA118/OxFm0Ho1b2RcTmO4oF6aAMaxpxdxnJ3zve2rgwzNBD4Zbm7Q==}
+ /jest-leak-detector@29.7.0:
+ resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
jest-get-type: 29.6.3
- pretty-format: 29.6.3
+ pretty-format: 29.7.0
dev: true
- /jest-matcher-utils@29.6.4:
- resolution: {integrity: sha512-KSzwyzGvK4HcfnserYqJHYi7sZVqdREJ9DMPAKVbS98JsIAvumihaNUbjrWw0St7p9IY7A9UskCW5MYlGmBQFQ==}
+ /jest-matcher-utils@29.7.0:
+ resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
chalk: 4.1.2
- jest-diff: 29.6.4
+ jest-diff: 29.7.0
jest-get-type: 29.6.3
- pretty-format: 29.6.3
+ pretty-format: 29.7.0
dev: true
- /jest-message-util@29.6.3:
- resolution: {integrity: sha512-FtzaEEHzjDpQp51HX4UMkPZjy46ati4T5pEMyM6Ik48ztu4T9LQplZ6OsimHx7EuM9dfEh5HJa6D3trEftu3dA==}
+ /jest-message-util@29.7.0:
+ resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@babel/code-frame': 7.22.10
+ '@babel/code-frame': 7.22.13
'@jest/types': 29.6.3
- '@types/stack-utils': 2.0.1
+ '@types/stack-utils': 2.0.2
chalk: 4.1.2
graceful-fs: 4.2.11
micromatch: 4.0.5
- pretty-format: 29.6.3
+ pretty-format: 29.7.0
slash: 3.0.0
stack-utils: 2.0.6
dev: true
- /jest-mock@29.6.3:
- resolution: {integrity: sha512-Z7Gs/mOyTSR4yPsaZ72a/MtuK6RnC3JYqWONe48oLaoEcYwEDxqvbXz85G4SJrm2Z5Ar9zp6MiHF4AlFlRM4Pg==}
+ /jest-mock@29.7.0:
+ resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
- '@types/node': 20.5.6
- jest-util: 29.6.3
+ '@types/node': 20.8.9
+ jest-util: 29.7.0
dev: true
- /jest-pnp-resolver@1.2.3(jest-resolve@29.6.4):
+ /jest-pnp-resolver@1.2.3(jest-resolve@29.7.0):
resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==}
engines: {node: '>=6'}
peerDependencies:
@@ -1733,7 +1689,7 @@ packages:
jest-resolve:
optional: true
dependencies:
- jest-resolve: 29.6.4
+ jest-resolve: 29.7.0
dev: true
/jest-regex-util@29.6.3:
@@ -1741,132 +1697,132 @@ packages:
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dev: true
- /jest-resolve-dependencies@29.6.4:
- resolution: {integrity: sha512-7+6eAmr1ZBF3vOAJVsfLj1QdqeXG+WYhidfLHBRZqGN24MFRIiKG20ItpLw2qRAsW/D2ZUUmCNf6irUr/v6KHA==}
+ /jest-resolve-dependencies@29.7.0:
+ resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
jest-regex-util: 29.6.3
- jest-snapshot: 29.6.4
+ jest-snapshot: 29.7.0
transitivePeerDependencies:
- supports-color
dev: true
- /jest-resolve@29.6.4:
- resolution: {integrity: sha512-fPRq+0vcxsuGlG0O3gyoqGTAxasagOxEuyoxHeyxaZbc9QNek0AmJWSkhjlMG+mTsj+8knc/mWb3fXlRNVih7Q==}
+ /jest-resolve@29.7.0:
+ resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
chalk: 4.1.2
graceful-fs: 4.2.11
- jest-haste-map: 29.6.4
- jest-pnp-resolver: 1.2.3(jest-resolve@29.6.4)
- jest-util: 29.6.3
- jest-validate: 29.6.3
- resolve: 1.22.4
+ jest-haste-map: 29.7.0
+ jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0)
+ jest-util: 29.7.0
+ jest-validate: 29.7.0
+ resolve: 1.22.8
resolve.exports: 2.0.2
slash: 3.0.0
dev: true
- /jest-runner@29.6.4:
- resolution: {integrity: sha512-SDaLrMmtVlQYDuG0iSPYLycG8P9jLI+fRm8AF/xPKhYDB2g6xDWjXBrR5M8gEWsK6KVFlebpZ4QsrxdyIX1Jaw==}
+ /jest-runner@29.7.0:
+ resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@jest/console': 29.6.4
- '@jest/environment': 29.6.4
- '@jest/test-result': 29.6.4
- '@jest/transform': 29.6.4
+ '@jest/console': 29.7.0
+ '@jest/environment': 29.7.0
+ '@jest/test-result': 29.7.0
+ '@jest/transform': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.5.6
+ '@types/node': 20.8.9
chalk: 4.1.2
emittery: 0.13.1
graceful-fs: 4.2.11
- jest-docblock: 29.6.3
- jest-environment-node: 29.6.4
- jest-haste-map: 29.6.4
- jest-leak-detector: 29.6.3
- jest-message-util: 29.6.3
- jest-resolve: 29.6.4
- jest-runtime: 29.6.4
- jest-util: 29.6.3
- jest-watcher: 29.6.4
- jest-worker: 29.6.4
+ jest-docblock: 29.7.0
+ jest-environment-node: 29.7.0
+ jest-haste-map: 29.7.0
+ jest-leak-detector: 29.7.0
+ jest-message-util: 29.7.0
+ jest-resolve: 29.7.0
+ jest-runtime: 29.7.0
+ jest-util: 29.7.0
+ jest-watcher: 29.7.0
+ jest-worker: 29.7.0
p-limit: 3.1.0
source-map-support: 0.5.13
transitivePeerDependencies:
- supports-color
dev: true
- /jest-runtime@29.6.4:
- resolution: {integrity: sha512-s/QxMBLvmwLdchKEjcLfwzP7h+jsHvNEtxGP5P+Fl1FMaJX2jMiIqe4rJw4tFprzCwuSvVUo9bn0uj4gNRXsbA==}
+ /jest-runtime@29.7.0:
+ resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@jest/environment': 29.6.4
- '@jest/fake-timers': 29.6.4
- '@jest/globals': 29.6.4
+ '@jest/environment': 29.7.0
+ '@jest/fake-timers': 29.7.0
+ '@jest/globals': 29.7.0
'@jest/source-map': 29.6.3
- '@jest/test-result': 29.6.4
- '@jest/transform': 29.6.4
+ '@jest/test-result': 29.7.0
+ '@jest/transform': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.5.6
+ '@types/node': 20.8.9
chalk: 4.1.2
cjs-module-lexer: 1.2.3
collect-v8-coverage: 1.0.2
glob: 7.2.3
graceful-fs: 4.2.11
- jest-haste-map: 29.6.4
- jest-message-util: 29.6.3
- jest-mock: 29.6.3
+ jest-haste-map: 29.7.0
+ jest-message-util: 29.7.0
+ jest-mock: 29.7.0
jest-regex-util: 29.6.3
- jest-resolve: 29.6.4
- jest-snapshot: 29.6.4
- jest-util: 29.6.3
+ jest-resolve: 29.7.0
+ jest-snapshot: 29.7.0
+ jest-util: 29.7.0
slash: 3.0.0
strip-bom: 4.0.0
transitivePeerDependencies:
- supports-color
dev: true
- /jest-snapshot@29.6.4:
- resolution: {integrity: sha512-VC1N8ED7+4uboUKGIDsbvNAZb6LakgIPgAF4RSpF13dN6YaMokfRqO+BaqK4zIh6X3JffgwbzuGqDEjHm/MrvA==}
+ /jest-snapshot@29.7.0:
+ resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@babel/core': 7.22.11
- '@babel/generator': 7.22.10
- '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.11)
- '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.22.11)
- '@babel/types': 7.22.11
- '@jest/expect-utils': 29.6.4
- '@jest/transform': 29.6.4
+ '@babel/core': 7.23.2
+ '@babel/generator': 7.23.0
+ '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.23.2)
+ '@babel/plugin-syntax-typescript': 7.22.5(@babel/core@7.23.2)
+ '@babel/types': 7.23.0
+ '@jest/expect-utils': 29.7.0
+ '@jest/transform': 29.7.0
'@jest/types': 29.6.3
- babel-preset-current-node-syntax: 1.0.1(@babel/core@7.22.11)
+ babel-preset-current-node-syntax: 1.0.1(@babel/core@7.23.2)
chalk: 4.1.2
- expect: 29.6.4
+ expect: 29.7.0
graceful-fs: 4.2.11
- jest-diff: 29.6.4
+ jest-diff: 29.7.0
jest-get-type: 29.6.3
- jest-matcher-utils: 29.6.4
- jest-message-util: 29.6.3
- jest-util: 29.6.3
+ jest-matcher-utils: 29.7.0
+ jest-message-util: 29.7.0
+ jest-util: 29.7.0
natural-compare: 1.4.0
- pretty-format: 29.6.3
+ pretty-format: 29.7.0
semver: 7.5.4
transitivePeerDependencies:
- supports-color
dev: true
- /jest-util@29.6.3:
- resolution: {integrity: sha512-QUjna/xSy4B32fzcKTSz1w7YYzgiHrjjJjevdRf61HYk998R5vVMMNmrHESYZVDS5DSWs+1srPLPKxXPkeSDOA==}
+ /jest-util@29.7.0:
+ resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
- '@types/node': 20.5.6
+ '@types/node': 20.8.9
chalk: 4.1.2
- ci-info: 3.8.0
+ ci-info: 3.9.0
graceful-fs: 4.2.11
picomatch: 2.3.1
dev: true
- /jest-validate@29.6.3:
- resolution: {integrity: sha512-e7KWZcAIX+2W1o3cHfnqpGajdCs1jSM3DkXjGeLSNmCazv1EeI1ggTeK5wdZhF+7N+g44JI2Od3veojoaumlfg==}
+ /jest-validate@29.7.0:
+ resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/types': 29.6.3
@@ -1874,35 +1830,35 @@ packages:
chalk: 4.1.2
jest-get-type: 29.6.3
leven: 3.1.0
- pretty-format: 29.6.3
+ pretty-format: 29.7.0
dev: true
- /jest-watcher@29.6.4:
- resolution: {integrity: sha512-oqUWvx6+On04ShsT00Ir9T4/FvBeEh2M9PTubgITPxDa739p4hoQweWPRGyYeaojgT0xTpZKF0Y/rSY1UgMxvQ==}
+ /jest-watcher@29.7.0:
+ resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@jest/test-result': 29.6.4
+ '@jest/test-result': 29.7.0
'@jest/types': 29.6.3
- '@types/node': 20.5.6
+ '@types/node': 20.8.9
ansi-escapes: 4.3.2
chalk: 4.1.2
emittery: 0.13.1
- jest-util: 29.6.3
+ jest-util: 29.7.0
string-length: 4.0.2
dev: true
- /jest-worker@29.6.4:
- resolution: {integrity: sha512-6dpvFV4WjcWbDVGgHTWo/aupl8/LbBx2NSKfiwqf79xC/yeJjKHT1+StcKy/2KTmW16hE68ccKVOtXf+WZGz7Q==}
+ /jest-worker@29.7.0:
+ resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
- '@types/node': 20.5.6
- jest-util: 29.6.3
+ '@types/node': 20.8.9
+ jest-util: 29.7.0
merge-stream: 2.0.0
supports-color: 8.1.1
dev: true
- /jest@29.6.4(@types/node@20.5.6)(ts-node@10.9.1):
- resolution: {integrity: sha512-tEFhVQFF/bzoYV1YuGyzLPZ6vlPrdfvDmmAxudA1dLEuiztqg2Rkx20vkKY32xiDROcD2KXlgZ7Cu8RPeEHRKw==}
+ /jest@29.7.0(@types/node@20.8.9)(ts-node@10.9.1):
+ resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
peerDependencies:
@@ -1911,10 +1867,10 @@ packages:
node-notifier:
optional: true
dependencies:
- '@jest/core': 29.6.4(ts-node@10.9.1)
+ '@jest/core': 29.7.0(ts-node@10.9.1)
'@jest/types': 29.6.3
import-local: 3.1.0
- jest-cli: 29.6.4(@types/node@20.5.6)(ts-node@10.9.1)
+ jest-cli: 29.7.0(@types/node@20.8.9)(ts-node@10.9.1)
transitivePeerDependencies:
- '@types/node'
- babel-plugin-macros
@@ -2099,7 +2055,7 @@ packages:
resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
engines: {node: '>=8'}
dependencies:
- '@babel/code-frame': 7.22.10
+ '@babel/code-frame': 7.22.13
error-ex: 1.3.2
json-parse-even-better-errors: 2.3.1
lines-and-columns: 1.2.4
@@ -2151,8 +2107,8 @@ packages:
hasBin: true
dev: false
- /pretty-format@29.6.3:
- resolution: {integrity: sha512-ZsBgjVhFAj5KeK+nHfF1305/By3lechHQSMWCTl8iHSbfOm2TN5nHEtFc/+W7fAyUeCs2n5iow72gld4gW0xDw==}
+ /pretty-format@29.7.0:
+ resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
dependencies:
'@jest/schemas': 29.6.3
@@ -2168,8 +2124,8 @@ packages:
sisteransi: 1.0.5
dev: true
- /pure-rand@6.0.2:
- resolution: {integrity: sha512-6Yg0ekpKICSjPswYOuC5sku/TSWaRYlA0qsXqJgM/d/4pLPHPuTxK7Nbf7jFKzAeedUhR8C7K9Uv63FBsSo8xQ==}
+ /pure-rand@6.0.4:
+ resolution: {integrity: sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==}
dev: true
/react-is@18.2.0:
@@ -2198,11 +2154,11 @@ packages:
engines: {node: '>=10'}
dev: true
- /resolve@1.22.4:
- resolution: {integrity: sha512-PXNdCiPqDqeUou+w1C2eTQbNfxKSuMxqTCuvlmmMsk1NWHL5fRrhY6Pl0qEYYc6+QqGClco1Qj8XnjPego4wfg==}
+ /resolve@1.22.8:
+ resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
hasBin: true
dependencies:
- is-core-module: 2.13.0
+ is-core-module: 2.13.1
path-parse: 1.0.7
supports-preserve-symlinks-flag: 1.0.0
dev: true
@@ -2358,7 +2314,7 @@ packages:
is-number: 7.0.0
dev: true
- /ts-jest@29.1.1(@babel/core@7.22.11)(jest@29.6.4)(typescript@5.2.2):
+ /ts-jest@29.1.1(@babel/core@7.23.2)(jest@29.7.0)(typescript@5.2.2):
resolution: {integrity: sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA==}
engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
hasBin: true
@@ -2379,11 +2335,11 @@ packages:
esbuild:
optional: true
dependencies:
- '@babel/core': 7.22.11
+ '@babel/core': 7.23.2
bs-logger: 0.2.6
fast-json-stable-stringify: 2.1.0
- jest: 29.6.4(@types/node@20.5.6)(ts-node@10.9.1)
- jest-util: 29.6.3
+ jest: 29.7.0(@types/node@20.8.9)(ts-node@10.9.1)
+ jest-util: 29.7.0
json5: 2.2.3
lodash.memoize: 4.1.2
make-error: 1.3.6
@@ -2392,7 +2348,7 @@ packages:
yargs-parser: 21.1.1
dev: true
- /ts-node@10.9.1(@types/node@20.5.6)(typescript@5.2.2):
+ /ts-node@10.9.1(@types/node@20.8.9)(typescript@5.2.2):
resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
peerDependencies:
@@ -2411,9 +2367,9 @@ packages:
'@tsconfig/node12': 1.0.11
'@tsconfig/node14': 1.0.3
'@tsconfig/node16': 1.0.4
- '@types/node': 20.5.6
- acorn: 8.10.0
- acorn-walk: 8.2.0
+ '@types/node': 20.8.9
+ acorn: 8.11.2
+ acorn-walk: 8.3.0
arg: 4.1.3
create-require: 1.1.1
diff: 4.0.2
@@ -2447,13 +2403,17 @@ packages:
hasBin: true
dev: true
- /update-browserslist-db@1.0.11(browserslist@4.21.10):
- resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==}
+ /undici-types@5.26.5:
+ resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
+ dev: true
+
+ /update-browserslist-db@1.0.13(browserslist@4.22.1):
+ resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==}
hasBin: true
peerDependencies:
browserslist: '>= 4.21.0'
dependencies:
- browserslist: 4.21.10
+ browserslist: 4.22.1
escalade: 3.1.1
picocolors: 1.0.0
dev: true
@@ -2462,13 +2422,13 @@ packages:
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
dev: true
- /v8-to-istanbul@9.1.0:
- resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==}
+ /v8-to-istanbul@9.1.3:
+ resolution: {integrity: sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg==}
engines: {node: '>=10.12.0'}
dependencies:
- '@jridgewell/trace-mapping': 0.3.19
- '@types/istanbul-lib-coverage': 2.0.4
- convert-source-map: 1.9.0
+ '@jridgewell/trace-mapping': 0.3.20
+ '@types/istanbul-lib-coverage': 2.0.5
+ convert-source-map: 2.0.0
dev: true
/walker@1.0.8:
diff --git a/halo2-lib-js/src/halo2lib/ecc.ts b/halo2-lib-js/src/halo2lib/ecc.ts
new file mode 100644
index 0000000..5e6ccba
--- /dev/null
+++ b/halo2-lib-js/src/halo2lib/ecc.ts
@@ -0,0 +1,21 @@
+import { CircuitValue256 } from "./CircuitValue256";
+
+export interface CircuitBn254Fq2 {
+ c0: CircuitValue256;
+ c1: CircuitValue256;
+}
+
+export interface CircuitBn254G1Affine {
+ x: CircuitValue256;
+ y: CircuitValue256;
+}
+
+export interface CircuitBn254G2Affine {
+ x: CircuitBn254Fq2;
+ y: CircuitBn254Fq2;
+}
+
+export interface CircuitSecp256k1Affine {
+ x: CircuitValue256;
+ y: CircuitValue256;
+}
diff --git a/halo2-lib-js/src/halo2lib/functions.ts b/halo2-lib-js/src/halo2lib/functions.ts
index a5ef53d..75e08aa 100644
--- a/halo2-lib-js/src/halo2lib/functions.ts
+++ b/halo2-lib-js/src/halo2lib/functions.ts
@@ -2,6 +2,9 @@ import { Halo2LibWasm, Halo2Wasm } from "@axiom-crypto/halo2-wasm/web";
import { convertInput, joinArrays } from "../shared/utils";
import { CircuitValue } from "./CircuitValue";
import { RawCircuitInput } from "../shared/types";
+import {Bn254FqPoint, Bn254G1AffinePoint, Bn254G2AffinePoint, JsCircuitBn254Fq2, JsCircuitBn254G1Affine, JsCircuitBn254G2Affine, JsCircuitSecp256k1Affine, JsCircuitValue256, Secp256k1AffinePoint} from "@axiom-crypto/halo2-wasm/web/halo2_wasm";
+import { CircuitValue256 } from "./CircuitValue256";
+import { CircuitBn254Fq2, CircuitBn254G1Affine, CircuitBn254G2Affine, CircuitSecp256k1Affine } from "./ecc";
export class Halo2Lib {
@@ -305,12 +308,12 @@ export class Halo2Lib {
/**
* Divides two circuit values and returns the quotient.
- *
+ *
* @param a - The dividend circuit value.
* @param b - The divisor circuit value.
* @returns The quotient.
- *
- */
+ *
+ */
div = (a: CircuitValue, b: CircuitValue, c: string = this._MAX_BITS, d: string = this._MAX_BITS) => {
if (this._firstPass) {
b = this.constant(1);
@@ -321,12 +324,12 @@ export class Halo2Lib {
/**
* Divides two circuit values and returns the remainder.
- *
+ *
* @param a - The dividend circuit value.
* @param b - The divisor circuit value.
* @returns The remainder.
- *
- */
+ *
+ */
mod = (a: CircuitValue, b: CircuitValue, c: string = this._MAX_BITS, d: string = this._MAX_BITS) => {
const [_, remainder] = this. _halo2lib.div_mod_var(a.cell(), b.cell(), c, d)
return this.Cell(remainder);
@@ -387,4 +390,142 @@ export class Halo2Lib {
return this.Cell(res);
}
-}
\ No newline at end of file
+ /**
+ * Creates new `CircuitValue256` and range checks `hi, lo` to be `uint128`s.
+ * @param hi
+ * @param lo
+ * @returns
+ */
+ newCircuitValue256 = (hi: CircuitValue, lo: CircuitValue): CircuitValue256 => {
+ this.rangeCheck(hi, 128);
+ this.rangeCheck(lo, 128);
+ return new CircuitValue256(this._halo2lib, { hi, lo });
+ }
+ // ========== BN254 Elliptic Curve functions ============
+
+ /**
+ *
+ * @param val The field point to load, in hi-lo form. The hi, lo values must have been constrained to be `uint128`s.
+ * @returns `Bn254FqPoint` whose internals are opaque to the user.
+ */
+ loadBn254Fq = (val: CircuitValue256): Bn254FqPoint =>{
+ return this._halo2lib.load_bn254_fq(toJsCircuitValue256(val));
+ }
+
+ /**
+ *
+ * @param val
+ * @returns `val` in hi-lo form
+ */
+ convertBn254FqToCircuitValue256 = (val: Bn254FqPoint) => {
+ const _val = val.to_circuit_value_256(this._halo2lib);
+ return new CircuitValue256(this._halo2lib, { hi: this.Cell(_val.hi), lo: this.Cell(_val.lo) });
+ }
+
+ /**
+ * @param point The affine point to load, with coordinates `CircuitValue256`. The hi, lo values must have been constrained to be `uint128`s.
+ * @returns `Bn254G1AffinePoint`, which has been constrained to lie on the curve. Currently this point is not allowed to be identity (0, 0).
+ */
+ loadBn254G1 = (point: CircuitBn254G1Affine): Bn254G1AffinePoint => {
+ return this._halo2lib.load_bn254_g1(toJsCircuitBn254G1Affine(point));
+ }
+
+ /**
+ * Sums the values of the provided G1 affine points
+ *
+ * @param points - The array of `CircuitBn254G1Affine` points. All coordinates are in hi, lo form, and we assume they have been range checked to be `uint128`s.
+ * @returns The sum of all these points as `Bn254G1AffinePoint`.
+ */
+ bn254G1Sum = (points: Array): Bn254G1AffinePoint => {
+ const _points = points.map(toJsCircuitBn254G1Affine);
+ return this._halo2lib.bn254_g1_sum(_points);
+ };
+
+ /**
+ * Subtracts the 2 points and returns the value. Constrains that the points are not equal and also one is not the negative of the other (this would be a point doubling, which requires a different formula).
+ *
+ * @returns The subtraction of these points.
+ * @param g1Point1 - G1 point, x,y in hi lo format for each coordinate
+ * @param g1Point2 - G1 point, x,y in hi lo format for each coordinate
+ */
+
+ bn254G1SubUnequal = (g1Point1: CircuitBn254G1Affine, g1Point2: CircuitBn254G1Affine): Bn254G1AffinePoint => {
+ return this._halo2lib.bn254_g1_sub_unequal(toJsCircuitBn254G1Affine(g1Point1), toJsCircuitBn254G1Affine(g1Point2));
+ };
+
+ /**
+ * @param point The affine point to load, with coordinates `CircuitBn254Fq2`. The hi, lo values must have been constrained to be `uint128`s.
+ * @returns `Bn254G2AffinePoint`, which has been constrained to lie on the curve. Currently this point is not allowed to be identity (Fq2(0), Fq2(0)).
+ */
+ loadBn254G2 = (point: CircuitBn254G2Affine): Bn254G2AffinePoint => {
+ return this._halo2lib.load_bn254_g2(toJsCircuitBn254G2Affine(point));
+ }
+
+ /**
+ * Sums the values of the provided G2 affine points
+ *
+ * @param points - The array of `CircuitBn254G2Affine` points. All coordinates are `CircuitBn254Fq2`, whose coordinates are in hi, lo form, and we assume the hi, lo's have been range checked to be `uint128`s.
+ * @returns The sum of all these points as `Bn254G2AffinePoint`.
+ */
+ bn254G2Sum = (points: Array): Bn254G2AffinePoint => {
+ const _points = points.map(toJsCircuitBn254G2Affine);
+ return this._halo2lib.bn254_g2_sum(_points);
+ }
+
+ /**
+ * Verifies that e(lhsG1, lhsG2) = e(rhsG1, rhsG2) by checking e(lhsG1, lhsG2)*e(-rhsG1, rhsG2) === 1
+ * None of the points should be identity.
+ *
+ * @param lhsG1
+ * @param lhsG2
+ * @param rhsG1
+ * @param rhsG2
+ * @returns [CircuitValue] for the result as a boolean (1 if signature verification is successful).
+ */
+ bn254PairingCheck = (lhsG1: Bn254G1AffinePoint, lhsG2: Bn254G2AffinePoint, rhsG1: Bn254G1AffinePoint, rhsG2: Bn254G2AffinePoint): CircuitValue => {
+ return this.Cell(this._halo2lib.bn254_pairing_check(lhsG1, lhsG2, rhsG1, rhsG2));
+ }
+
+ /**
+ * @param pubkey The public key to load, in the form of an affine elliptic curve point `(x, y)` where `x, y` have type `CircuitValue256`. The hi, lo values of each `CircuitValue256` must have been constrained to be `uint128`s.
+ * @returns `Secp256k1AffinePoint`, the public key as a loaded elliptic curve point. This has been constrained to lie on the curve. The public key is constrained to not be the identity (0, 0).
+ */
+ loadSecp256k1Pubkey = (pubkey: CircuitSecp256k1Affine): Secp256k1AffinePoint => {
+ return this._halo2lib.load_secp256k1_pubkey(toJsCircuitSecp256k1Affine(pubkey));
+ }
+
+ /**
+ *
+ * Verifies the ECDSA signature `(r, s)` with message hash `msgHash` using the secp256k1 public key `pubkey`. Returns 1 if the signature is valid, 0 otherwise.
+ * @param pubkey
+ * @param r
+ * @param s
+ * @param msgHash
+ * @returns
+ */
+ verifySecp256k1ECDSASignature = (pubkey: Secp256k1AffinePoint, r: CircuitValue256, s: CircuitValue256, msgHash: CircuitValue256): CircuitValue => {
+ return this.Cell(this._halo2lib.verify_secp256k1_ecdsa_signature(pubkey, toJsCircuitValue256(r), toJsCircuitValue256(s), toJsCircuitValue256(msgHash)));
+ }
+}
+
+function toJsCircuitValue256(val: CircuitValue256): JsCircuitValue256 {
+ return new JsCircuitValue256(val.hi().cell(), val.lo().cell());
+}
+
+function toJsCircuitBn254G1Affine(point: CircuitBn254G1Affine): JsCircuitBn254G1Affine {
+ return new JsCircuitBn254G1Affine(toJsCircuitValue256(point.x), toJsCircuitValue256(point.y));
+}
+
+function toJsCircuitBn254Fq2(point: CircuitBn254Fq2): JsCircuitBn254Fq2 {
+ return new JsCircuitBn254Fq2(toJsCircuitValue256(point.c0), toJsCircuitValue256(point.c1));
+}
+
+function toJsCircuitBn254G2Affine(point: CircuitBn254G2Affine): JsCircuitBn254G2Affine {
+ const x = toJsCircuitBn254Fq2(point.x);
+ const y = toJsCircuitBn254Fq2(point.y);
+ return new JsCircuitBn254G2Affine(x,y);
+}
+
+function toJsCircuitSecp256k1Affine(point: CircuitSecp256k1Affine): JsCircuitSecp256k1Affine{
+ return new JsCircuitSecp256k1Affine(toJsCircuitValue256(point.x), toJsCircuitValue256(point.y));
+}
diff --git a/halo2-lib-js/src/halo2lib/index.ts b/halo2-lib-js/src/halo2lib/index.ts
index 57e72e3..92f0304 100644
--- a/halo2-lib-js/src/halo2lib/index.ts
+++ b/halo2-lib-js/src/halo2lib/index.ts
@@ -1,3 +1,4 @@
-export * from './CircuitValue';
-export * from './CircuitValue256';
-export * from './functions';
+export * from "./CircuitValue";
+export * from "./CircuitValue256";
+export * from "./functions";
+export * from "./ecc";
diff --git a/halo2-lib-js/src/shared/docs/halo2Docs.d.ts b/halo2-lib-js/src/shared/docs/halo2Docs.d.ts
index 2d058e2..83d27b1 100644
--- a/halo2-lib-js/src/shared/docs/halo2Docs.d.ts
+++ b/halo2-lib-js/src/shared/docs/halo2Docs.d.ts
@@ -1,6 +1,7 @@
// Generated by dts-bundle-generator v8.0.1
import { Halo2Wasm } from '@axiom-crypto/halo2-wasm/web';
+import { Bn254FqPoint, Bn254G1AffinePoint, Bn254G2AffinePoint, JsCircuitBn254Fq2, JsCircuitBn254G1Affine, JsCircuitBn254G2Affine, JsCircuitSecp256k1Affine, JsCircuitValue256, Secp256k1AffinePoint } from "@axiom-crypto/halo2-wasm/web";
declare class CircuitValue {
private _value;
@@ -15,6 +16,44 @@ declare class CircuitValue {
address(): string;
}
+declare class CircuitValue256 {
+ private _value;
+ private _circuitValue;
+ private _halo2Lib;
+ constructor(_halo2Lib: Halo2Wasm, { value, hi, lo, }: {
+ value?: bigint | string | number;
+ hi?: CircuitValue;
+ lo?: CircuitValue;
+ });
+ hi(): CircuitValue;
+ lo(): CircuitValue;
+ hex(): string;
+ value(): bigint;
+ toCircuitValue(): CircuitValue;
+}
+
+export interface CircuitBn254Fq2 {
+ c0: CircuitValue256;
+ c1: CircuitValue256;
+}
+
+export interface CircuitBn254G1Affine {
+ x: CircuitValue256;
+ y: CircuitValue256;
+}
+
+export interface CircuitBn254G2Affine {
+ x: CircuitBn254Fq2;
+ y: CircuitBn254Fq2;
+}
+
+export interface CircuitSecp256k1Affine {
+ x: CircuitValue256;
+ y: CircuitValue256;
+}
+
+
+
export type RawCircuitInput = string | number | bigint;
/**
@@ -287,10 +326,93 @@ declare const value: (a: CircuitValue) => any;
*/
declare const log: (...args: any) => void;
declare const console: {
- /**
- * Logs any *non CircuitValue* to the console. Use `log` for logging `CircuitValue`s.
- * @param args The values to log.
- */
- log: (...args: any) => void;
+ /**
+ * Logs any *non CircuitValue* to the console. Use `log` for logging `CircuitValue`s.
+ * @param args The values to log.
+ */
+ log: (...args: any) => void;
}
-declare const ecdsaBenchmark: (sk: bigint, msg_hash: bigint, k: bigint) => CircuitValue;
\ No newline at end of file
+declare const ecdsaBenchmark: (sk: bigint, msg_hash: bigint, k: bigint) => CircuitValue;
+
+//ecc
+
+/**
+ *
+ * @param val The field point to load, in hi-lo form. The hi, lo values must have been constrained to be `uint128`s.
+ * @returns `Bn254FqPoint` whose internals are opaque to the user.
+ */
+declare const loadBn254Fq: (val: CircuitValue256) => Bn254FqPoint;
+
+/**
+*
+* @param val
+* @returns `val` in hi-lo form
+*/
+declare const convertBn254FqToCircuitValue256: (val: Bn254FqPoint) => CircuitValue256;
+
+/**
+ * @param point The affine point to load, with coordinates `CircuitValue256`. The hi, lo values must have been constrained to be `uint128`s.
+ * @returns `Bn254G1AffinePoint`, which has been constrained to lie on the curve. Currently this point is not allowed to be identity (0, 0).
+ */
+declare const loadBn254G1: (point: CircuitBn254G1Affine) => Bn254G1AffinePoint;
+
+/**
+ * Sums the values of the provided G1 affine points
+ *
+ * @param points - The array of `CircuitBn254G1Affine` points. All coordinates are in hi, lo form, and we assume they have been range checked to be `uint128`s.
+ * @returns The sum of all these points as `Bn254G1AffinePoint`.
+ */
+declare const bn254G1Sum: (points: Array) => Bn254G1AffinePoint
+
+/**
+ * Subtracts the 2 points and returns the value. Constrains that the points are not equal and also one is not the negative of the other (this would be a point doubling, which requires a different formula).
+ *
+ * @returns The subtraction of these points.
+ * @param g1Point1 - G1 point, x,y in hi lo format for each coordinate
+ * @param g1Point2 - G1 point, x,y in hi lo format for each coordinate
+ */
+declare const bn254G1SubUnequal: (g1Point1: CircuitBn254G1Affine, g1Point2: CircuitBn254G1Affine) => Bn254G1AffinePoint;
+
+/**
+ * @param point The affine point to load, with coordinates `CircuitBn254Fq2`. The hi, lo values must have been constrained to be `uint128`s.
+ * @returns `Bn254G2AffinePoint`, which has been constrained to lie on the curve. Currently this point is not allowed to be identity (Fq2(0), Fq2(0)).
+ */
+declare const loadBn254G2: (point: CircuitBn254G2Affine) => Bn254G2AffinePoint;
+
+/**
+ * Sums the values of the provided G2 affine points
+ *
+ * @param points - The array of `CircuitBn254G2Affine` points. All coordinates are `CircuitBn254Fq2`, whose coordinates are in hi, lo form, and we assume the hi, lo's have been range checked to be `uint128`s.
+ * @returns The sum of all these points as `Bn254G2AffinePoint`.
+ */
+declare const bn254G2Sum: (points: Array) => Bn254G2AffinePoint;
+
+/**
+ * Verifies that e(lhsG1, lhsG2) = e(rhsG1, rhsG2) by checking e(lhsG1, lhsG2)*e(-rhsG1, rhsG2) === 1
+ * None of the points should be identity.
+ *
+ * @param lhsG1
+ * @param lhsG2
+ * @param rhsG1
+ * @param rhsG2
+ * @returns [CircuitValue] for the result as a boolean (1 if signature verification is successful).
+ */
+declare const bn254PairingCheck: (lhsG1: Bn254G1AffinePoint, lhsG2: Bn254G2AffinePoint, rhsG1: Bn254G1AffinePoint, rhsG2: Bn254G2AffinePoint) => CircuitValue;
+
+
+/**
+ * @param pubkey The public key to load, in the form of an affine elliptic curve point `(x, y)` where `x, y` have type `CircuitValue256`. The hi, lo values of each `CircuitValue256` must have been constrained to be `uint128`s.
+ * @returns `Secp256k1AffinePoint`, the public key as a loaded elliptic curve point. This has been constrained to lie on the curve. The public key is constrained to not be the identity (0, 0).
+ */
+declare const loadSecp256k1Pubkey: (pubkey: CircuitSecp256k1Affine) => Secp256k1AffinePoint;
+
+/**
+ *
+ * Verifies the ECDSA signature `(r, s)` with message hash `msgHash` using the secp256k1 public key `pubkey`. Returns 1 if the signature is valid, 0 otherwise.
+ * @param pubkey
+ * @param r
+ * @param s
+ * @param msgHash
+ * @returns
+ */
+declare const verifySecp256k1ECDSASignature: (pubkey: Secp256k1AffinePoint, r: CircuitValue256, s: CircuitValue256, msgHash: CircuitValue256) => CircuitValue;
\ No newline at end of file
diff --git a/halo2-lib-js/src/shared/docs/halo2Docs.ts b/halo2-lib-js/src/shared/docs/halo2Docs.ts
index bce3e58..0f8035b 100644
--- a/halo2-lib-js/src/shared/docs/halo2Docs.ts
+++ b/halo2-lib-js/src/shared/docs/halo2Docs.ts
@@ -1 +1 @@
-export const halo2Docs = "// Generated by dts-bundle-generator v8.0.1\n\n\ndeclare class CircuitValue {\n\tprivate _value;\n\tprivate _cell;\n\tconstructor(circuit: Halo2Wasm, { value, cell }: {\n\t\tvalue?: bigint | number | string;\n\t\tcell?: number;\n\t});\n\tcell(): number;\n\tvalue(): bigint;\n\tnumber(): number;\n\taddress(): string;\n}\n\ntype RawCircuitInput = string | number | bigint;\n\n/**\n * Creates a circuit variable from a number, bigint, or string.\n *\n * @param a The raw circuit input.\n * @returns The witness cell.\n */\ndeclare const witness: (a: RawCircuitInput) => CircuitValue;\n/**\n * Creates a circuit constant from a number, bigint, or string.\n *\n * @param a The raw circuit input.\n * @returns The constant cell.\n */\ndeclare const constant: (a: RawCircuitInput) => CircuitValue;\n/**\n * Adds two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The sum of the two circuit values.\n */\ndeclare const add: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Subtracts the second circuit value from the first circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The difference between the two circuit values.\n */\ndeclare const sub: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Negates a circuit value.\n *\n * @param a The circuit value to negate.\n * @returns The negation of the circuit value.\n */\ndeclare const neg: (a: CircuitValue) => CircuitValue;\n/**\n * Multiplies two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The product of the two circuit values.\n */\ndeclare const mul: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Multiplies two circuit values and adds a third circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The third circuit value.\n * @returns The result of multiplying the first two circuit values and adding the third circuit value.\n */\ndeclare const mulAdd: (a: CircuitValue, b: CircuitValue, c: CircuitValue) => CircuitValue;\n/**\n * Multiplies a circuit value by the negation of another circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The result of multiplying the first circuit value by the negation of the second circuit value.\n */\ndeclare const mulNot: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Asserts that a circuit value is a bit.\n *\n * @param a The circuit value to assert.\n */\ndeclare const assertBit: (a: CircuitValue) => void;\n/**\n * Asserts that a circuit value is a constant.\n *\n * @param a The circuit value to assert.\n * @param b The raw circuit input.\n */\ndeclare const assertIsConst: (a: CircuitValue, b: RawCircuitInput) => void;\n/**\n * Computes the inner product of two arrays of circuit values.\n *\n * @param a The first array of circuit values.\n * @param b The second array of circuit values.\n * @returns The inner product of the two arrays.\n */\ndeclare const innerProduct: (a: CircuitValue[], b: CircuitValue[]) => CircuitValue;\n/**\n * Computes the sum of an array of circuit values.\n *\n * @param arr The array of circuit values.\n * @returns The sum of the array of circuit values.\n */\ndeclare const sum: (arr: CircuitValue[]) => CircuitValue;\n/**\n * Performs a bitwise AND operation on two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The result of the bitwise AND operation.\n */\ndeclare const and: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Performs a bitwise OR operation on two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The result of the bitwise OR operation.\n */\ndeclare const or: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Performs a bitwise NOT operation on a circuit value.\n *\n * @param a The circuit value.\n * @returns The result of the bitwise NOT operation.\n */\ndeclare const not: (a: CircuitValue) => CircuitValue;\n/**\n * Decrements a circuit value by 1.\n *\n * @param a The circuit value.\n * @returns The decremented circuit value.\n */\ndeclare const dec: (a: CircuitValue) => CircuitValue;\n/**\n * Selects a circuit value based on a condition.\n *\n * @param a The first circuit value.\n * @param b The first circuit value.\n * @param sel The condition boolean circuit value.\n * @returns sel ? a : b\n */\ndeclare const select: (a: CircuitValue, b: CircuitValue, sel: CircuitValue) => CircuitValue;\n/**\n * Performs a bitwise OR-AND operation on three circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The third circuit value.\n * @returns The result of the OR-AND operation.\n */\ndeclare const orAnd: (a: CircuitValue, b: CircuitValue, c: CircuitValue) => CircuitValue;\n/**\n * Converts an array of circuit values to an indicator array.\n *\n * @param bits The array of circuit values.\n * @returns The indicator circuit value.\n */\ndeclare const bitsToIndicator: (bits: CircuitValue[]) => CircuitValue[];\n/**\n * Converts an index circuit value to an indicator circuit value.\n *\n * @param idx The index circuit value.\n * @param len The length of the indicator circuit value.\n * @returns The indicator circuit value.\n */\ndeclare const idxToIndicator: (idx: CircuitValue, len: RawCircuitInput) => CircuitValue[];\n/**\n * Selects circuit values from an array based on an indicator circuit value.\n *\n * @param arr The array of circuit values.\n * @param indicator The indicator circuit value.\n * @returns The selected circuit values.\n */\ndeclare const selectByIndicator: (arr: CircuitValue[], indicator: CircuitValue[]) => CircuitValue;\n/**\n * Selects a circuit value from an array based on an index circuit value.\n *\n * @param arr The array of circuit values.\n * @param idx The index circuit value.\n * @returns The selected circuit value.\n */\ndeclare const selectFromIdx: (arr: CircuitValue[], idx: CircuitValue) => CircuitValue;\n/**\n * Checks if a circuit value is zero.\n *\n * @param a The circuit value to check.\n * @returns The indicator circuit value representing whether the input is zero.\n */\ndeclare const isZero: (a: CircuitValue) => CircuitValue;\n/**\n * Checks if two circuit values are equal.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The indicator circuit value representing whether the two inputs are equal.\n */\ndeclare const isEqual: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Converts a circuit value to an array of bits.\n *\n * @param a The circuit value to convert.\n * @param len The length of the resulting bit array.\n * @returns The array of bits representing the input circuit value.\n */\ndeclare const numToBits: (a: CircuitValue, len: RawCircuitInput) => CircuitValue[];\n/**\n * Asserts that two circuit values are equal.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n */\ndeclare const checkEqual: (a: CircuitValue, b: CircuitValue) => void;\n/**\n * Checks if a circuit value is within a specified range.\n *\n * @param a The circuit value to check.\n * @param b The range of the circuit value.\n */\ndeclare const rangeCheck: (a: CircuitValue, b: RawCircuitInput) => void;\n/**\n * Checks if the first circuit value is less than the second circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The range of the circuit values.\n */\ndeclare const checkLessThan: (a: CircuitValue, b: CircuitValue, c?: string) => void;\n/**\n * Checks if the first circuit value is less than the second circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The range of the circuit values.\n * @returns The indicator circuit value representing whether the first input is less than the second input.\n */\ndeclare const isLessThan: (a: CircuitValue, b: CircuitValue, c?: string) => CircuitValue;\n/**\n * Divides two circuit values and returns the quotient.\n *\n * @param a The dividend circuit value.\n * @param b The divisor circuit value.\n * @returns The quotient.\n *\n*/\ndeclare const div: (a: CircuitValue, b: CircuitValue, c?: string, d?: string) => CircuitValue;\n/**\n * Divides two circuit values and returns the remainder.\n *\n * @param a The dividend circuit value.\n * @param b The divisor circuit value.\n * @returns The remainder.\n *\n*/\ndeclare const mod: (a: CircuitValue, b: CircuitValue, c?: string, d?: string) => CircuitValue;\n/**\n * Raises a circuit value to the power of another circuit value.\n *\n * @param a The base circuit value.\n * @param b The exponent circuit value.\n * @returns The result of the exponentiation.\n */\ndeclare const pow: (a: CircuitValue, b: CircuitValue, c?: string) => CircuitValue;\n/**\n * Computes the Poseidon hash of multiple circuit values.\n *\n * @param args The circuit values to hash.\n * @returns The hash value.\n */\ndeclare const poseidon: (...args: CircuitValue[]) => CircuitValue;\n/**\n * Retrieves the value of a circuit value.\n *\n * @param a The circuit value.\n * @returns The value of the circuit value.\n */\ndeclare const value: (a: CircuitValue) => any;\n/**\n * Logs the provided *circuit* values to the console. Use `console.log` for normal logging.\n *\n * @param args The `CircuitValue`s to log.\n */\ndeclare const log: (...args: any) => void;\ndeclare const console: {\n /**\n * Logs any *non CircuitValue* to the console. Use `log` for logging `CircuitValue`s.\n * @param args The values to log.\n */\n log: (...args: any) => void;\n}\ndeclare const ecdsaBenchmark: (sk: bigint, msg_hash: bigint, k: bigint) => CircuitValue;";
\ No newline at end of file
+export const halo2Docs = "// Generated by dts-bundle-generator v8.0.1\n\n\ndeclare class CircuitValue {\n\tprivate _value;\n\tprivate _cell;\n\tconstructor(circuit: Halo2Wasm, { value, cell }: {\n\t\tvalue?: bigint | number | string;\n\t\tcell?: number;\n\t});\n\tcell(): number;\n\tvalue(): bigint;\n\tnumber(): number;\n\taddress(): string;\n}\n\ndeclare class CircuitValue256 {\n\tprivate _value;\n\tprivate _circuitValue;\n\tprivate _halo2Lib;\n\tconstructor(_halo2Lib: Halo2Wasm, { value, hi, lo, }: {\n\t\tvalue?: bigint | string | number;\n\t\thi?: CircuitValue;\n\t\tlo?: CircuitValue;\n\t});\n\thi(): CircuitValue;\n\tlo(): CircuitValue;\n\thex(): string;\n\tvalue(): bigint;\n\ttoCircuitValue(): CircuitValue;\n}\n\ninterface CircuitBn254Fq2 {\n\tc0: CircuitValue256;\n\tc1: CircuitValue256;\n}\n\ninterface CircuitBn254G1Affine {\n\tx: CircuitValue256;\n\ty: CircuitValue256;\n}\n\ninterface CircuitBn254G2Affine {\n\tx: CircuitBn254Fq2;\n\ty: CircuitBn254Fq2;\n}\n\ninterface CircuitSecp256k1Affine {\n\tx: CircuitValue256;\n\ty: CircuitValue256;\n}\n\n\n\ntype RawCircuitInput = string | number | bigint;\n\n/**\n * Creates a circuit variable from a number, bigint, or string.\n *\n * @param a The raw circuit input.\n * @returns The witness cell.\n */\ndeclare const witness: (a: RawCircuitInput) => CircuitValue;\n/**\n * Creates a circuit constant from a number, bigint, or string.\n *\n * @param a The raw circuit input.\n * @returns The constant cell.\n */\ndeclare const constant: (a: RawCircuitInput) => CircuitValue;\n/**\n * Adds two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The sum of the two circuit values.\n */\ndeclare const add: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Subtracts the second circuit value from the first circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The difference between the two circuit values.\n */\ndeclare const sub: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Negates a circuit value.\n *\n * @param a The circuit value to negate.\n * @returns The negation of the circuit value.\n */\ndeclare const neg: (a: CircuitValue) => CircuitValue;\n/**\n * Multiplies two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The product of the two circuit values.\n */\ndeclare const mul: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Multiplies two circuit values and adds a third circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The third circuit value.\n * @returns The result of multiplying the first two circuit values and adding the third circuit value.\n */\ndeclare const mulAdd: (a: CircuitValue, b: CircuitValue, c: CircuitValue) => CircuitValue;\n/**\n * Multiplies a circuit value by the negation of another circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The result of multiplying the first circuit value by the negation of the second circuit value.\n */\ndeclare const mulNot: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Asserts that a circuit value is a bit.\n *\n * @param a The circuit value to assert.\n */\ndeclare const assertBit: (a: CircuitValue) => void;\n/**\n * Asserts that a circuit value is a constant.\n *\n * @param a The circuit value to assert.\n * @param b The raw circuit input.\n */\ndeclare const assertIsConst: (a: CircuitValue, b: RawCircuitInput) => void;\n/**\n * Computes the inner product of two arrays of circuit values.\n *\n * @param a The first array of circuit values.\n * @param b The second array of circuit values.\n * @returns The inner product of the two arrays.\n */\ndeclare const innerProduct: (a: CircuitValue[], b: CircuitValue[]) => CircuitValue;\n/**\n * Computes the sum of an array of circuit values.\n *\n * @param arr The array of circuit values.\n * @returns The sum of the array of circuit values.\n */\ndeclare const sum: (arr: CircuitValue[]) => CircuitValue;\n/**\n * Performs a bitwise AND operation on two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The result of the bitwise AND operation.\n */\ndeclare const and: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Performs a bitwise OR operation on two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The result of the bitwise OR operation.\n */\ndeclare const or: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Performs a bitwise NOT operation on a circuit value.\n *\n * @param a The circuit value.\n * @returns The result of the bitwise NOT operation.\n */\ndeclare const not: (a: CircuitValue) => CircuitValue;\n/**\n * Decrements a circuit value by 1.\n *\n * @param a The circuit value.\n * @returns The decremented circuit value.\n */\ndeclare const dec: (a: CircuitValue) => CircuitValue;\n/**\n * Selects a circuit value based on a condition.\n *\n * @param a The first circuit value.\n * @param b The first circuit value.\n * @param sel The condition boolean circuit value.\n * @returns sel ? a : b\n */\ndeclare const select: (a: CircuitValue, b: CircuitValue, sel: CircuitValue) => CircuitValue;\n/**\n * Performs a bitwise OR-AND operation on three circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The third circuit value.\n * @returns The result of the OR-AND operation.\n */\ndeclare const orAnd: (a: CircuitValue, b: CircuitValue, c: CircuitValue) => CircuitValue;\n/**\n * Converts an array of circuit values to an indicator array.\n *\n * @param bits The array of circuit values.\n * @returns The indicator circuit value.\n */\ndeclare const bitsToIndicator: (bits: CircuitValue[]) => CircuitValue[];\n/**\n * Converts an index circuit value to an indicator circuit value.\n *\n * @param idx The index circuit value.\n * @param len The length of the indicator circuit value.\n * @returns The indicator circuit value.\n */\ndeclare const idxToIndicator: (idx: CircuitValue, len: RawCircuitInput) => CircuitValue[];\n/**\n * Selects circuit values from an array based on an indicator circuit value.\n *\n * @param arr The array of circuit values.\n * @param indicator The indicator circuit value.\n * @returns The selected circuit values.\n */\ndeclare const selectByIndicator: (arr: CircuitValue[], indicator: CircuitValue[]) => CircuitValue;\n/**\n * Selects a circuit value from an array based on an index circuit value.\n *\n * @param arr The array of circuit values.\n * @param idx The index circuit value.\n * @returns The selected circuit value.\n */\ndeclare const selectFromIdx: (arr: CircuitValue[], idx: CircuitValue) => CircuitValue;\n/**\n * Checks if a circuit value is zero.\n *\n * @param a The circuit value to check.\n * @returns The indicator circuit value representing whether the input is zero.\n */\ndeclare const isZero: (a: CircuitValue) => CircuitValue;\n/**\n * Checks if two circuit values are equal.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The indicator circuit value representing whether the two inputs are equal.\n */\ndeclare const isEqual: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Converts a circuit value to an array of bits.\n *\n * @param a The circuit value to convert.\n * @param len The length of the resulting bit array.\n * @returns The array of bits representing the input circuit value.\n */\ndeclare const numToBits: (a: CircuitValue, len: RawCircuitInput) => CircuitValue[];\n/**\n * Asserts that two circuit values are equal.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n */\ndeclare const checkEqual: (a: CircuitValue, b: CircuitValue) => void;\n/**\n * Checks if a circuit value is within a specified range.\n *\n * @param a The circuit value to check.\n * @param b The range of the circuit value.\n */\ndeclare const rangeCheck: (a: CircuitValue, b: RawCircuitInput) => void;\n/**\n * Checks if the first circuit value is less than the second circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The range of the circuit values.\n */\ndeclare const checkLessThan: (a: CircuitValue, b: CircuitValue, c?: string) => void;\n/**\n * Checks if the first circuit value is less than the second circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The range of the circuit values.\n * @returns The indicator circuit value representing whether the first input is less than the second input.\n */\ndeclare const isLessThan: (a: CircuitValue, b: CircuitValue, c?: string) => CircuitValue;\n/**\n * Divides two circuit values and returns the quotient.\n *\n * @param a The dividend circuit value.\n * @param b The divisor circuit value.\n * @returns The quotient.\n *\n*/\ndeclare const div: (a: CircuitValue, b: CircuitValue, c?: string, d?: string) => CircuitValue;\n/**\n * Divides two circuit values and returns the remainder.\n *\n * @param a The dividend circuit value.\n * @param b The divisor circuit value.\n * @returns The remainder.\n *\n*/\ndeclare const mod: (a: CircuitValue, b: CircuitValue, c?: string, d?: string) => CircuitValue;\n/**\n * Raises a circuit value to the power of another circuit value.\n *\n * @param a The base circuit value.\n * @param b The exponent circuit value.\n * @returns The result of the exponentiation.\n */\ndeclare const pow: (a: CircuitValue, b: CircuitValue, c?: string) => CircuitValue;\n/**\n * Computes the Poseidon hash of multiple circuit values.\n *\n * @param args The circuit values to hash.\n * @returns The hash value.\n */\ndeclare const poseidon: (...args: CircuitValue[]) => CircuitValue;\n/**\n * Retrieves the value of a circuit value.\n *\n * @param a The circuit value.\n * @returns The value of the circuit value.\n */\ndeclare const value: (a: CircuitValue) => any;\n/**\n * Logs the provided *circuit* values to the console. Use `console.log` for normal logging.\n *\n * @param args The `CircuitValue`s to log.\n */\ndeclare const log: (...args: any) => void;\ndeclare const console: {\n\t/**\n\t * Logs any *non CircuitValue* to the console. Use `log` for logging `CircuitValue`s.\n\t * @param args The values to log.\n\t */\n\tlog: (...args: any) => void;\n}\ndeclare const ecdsaBenchmark: (sk: bigint, msg_hash: bigint, k: bigint) => CircuitValue;\n\n//ecc\n\n/**\n * \n * @param val The field point to load, in hi-lo form. The hi, lo values must have been constrained to be `uint128`s.\n * @returns `Bn254FqPoint` whose internals are opaque to the user.\n */\ndeclare const loadBn254Fq: (val: CircuitValue256) => Bn254FqPoint;\n\n/**\n* \n* @param val \n* @returns `val` in hi-lo form\n*/\ndeclare const convertBn254FqToCircuitValue256: (val: Bn254FqPoint) => CircuitValue256;\n\n/**\n\t * @param point The affine point to load, with coordinates `CircuitValue256`. The hi, lo values must have been constrained to be `uint128`s.\n\t * @returns `Bn254G1AffinePoint`, which has been constrained to lie on the curve. Currently this point is not allowed to be identity (0, 0).\n\t */\ndeclare const loadBn254G1: (point: CircuitBn254G1Affine) => Bn254G1AffinePoint;\n\n/**\n * Sums the values of the provided G1 affine points\n *\n * @param points - The array of `CircuitBn254G1Affine` points. All coordinates are in hi, lo form, and we assume they have been range checked to be `uint128`s.\n * @returns The sum of all these points as `Bn254G1AffinePoint`.\n */\ndeclare const bn254G1Sum: (points: Array) => Bn254G1AffinePoint\n\n/**\n * Subtracts the 2 points and returns the value. Constrains that the points are not equal and also one is not the negative of the other (this would be a point doubling, which requires a different formula).\n *\n * @returns The subtraction of these points.\n * @param g1Point1 - G1 point, x,y in hi lo format for each coordinate\n * @param g1Point2 - G1 point, x,y in hi lo format for each coordinate\n */\ndeclare const bn254G1SubUnequal: (g1Point1: CircuitBn254G1Affine, g1Point2: CircuitBn254G1Affine) => Bn254G1AffinePoint;\n\n/**\n * @param point The affine point to load, with coordinates `CircuitBn254Fq2`. The hi, lo values must have been constrained to be `uint128`s.\n * @returns `Bn254G2AffinePoint`, which has been constrained to lie on the curve. Currently this point is not allowed to be identity (Fq2(0), Fq2(0)).\n */\ndeclare const loadBn254G2: (point: CircuitBn254G2Affine) => Bn254G2AffinePoint;\n\n/**\n * Sums the values of the provided G2 affine points\n *\n * @param points - The array of `CircuitBn254G2Affine` points. All coordinates are `CircuitBn254Fq2`, whose coordinates are in hi, lo form, and we assume the hi, lo's have been range checked to be `uint128`s.\n * @returns The sum of all these points as `Bn254G2AffinePoint`.\n */\ndeclare const bn254G2Sum: (points: Array) => Bn254G2AffinePoint;\n\n/** \n * Verifies that e(lhsG1, lhsG2) = e(rhsG1, rhsG2) by checking e(lhsG1, lhsG2)*e(-rhsG1, rhsG2) === 1\n * None of the points should be identity.\n * \n * @param lhsG1\n * @param lhsG2\n * @param rhsG1\n * @param rhsG2\n * @returns [CircuitValue] for the result as a boolean (1 if signature verification is successful).\n */\ndeclare const bn254PairingCheck: (lhsG1: Bn254G1AffinePoint, lhsG2: Bn254G2AffinePoint, rhsG1: Bn254G1AffinePoint, rhsG2: Bn254G2AffinePoint) => CircuitValue;\n\n\n/**\n * @param pubkey The public key to load, in the form of an affine elliptic curve point `(x, y)` where `x, y` have type `CircuitValue256`. The hi, lo values of each `CircuitValue256` must have been constrained to be `uint128`s.\n * @returns `Secp256k1AffinePoint`, the public key as a loaded elliptic curve point. This has been constrained to lie on the curve. The public key is constrained to not be the identity (0, 0).\n */\ndeclare const loadSecp256k1Pubkey: (pubkey: CircuitSecp256k1Affine) => Secp256k1AffinePoint;\n\n/**\n * \n * Verifies the ECDSA signature `(r, s)` with message hash `msgHash` using the secp256k1 public key `pubkey`. Returns 1 if the signature is valid, 0 otherwise.\n * @param pubkey \n * @param r \n * @param s \n * @param msgHash \n * @returns \n */\ndeclare const verifySecp256k1ECDSASignature: (pubkey: Secp256k1AffinePoint, r: CircuitValue256, s: CircuitValue256, msgHash: CircuitValue256) => CircuitValue;";
\ No newline at end of file
diff --git a/halo2-repl/app/page.tsx b/halo2-repl/app/page.tsx
index 4e9aa75..d8d5015 100644
--- a/halo2-repl/app/page.tsx
+++ b/halo2-repl/app/page.tsx
@@ -6,7 +6,9 @@ import Editor, { Monaco } from "@monaco-editor/react";
import { type editor } from 'monaco-editor';
import { useSearchParams, useRouter, usePathname } from "next/navigation";
import { Halo2Repl } from "./worker/halo2repl";
-import { DEFAULT_CIRCUIT_CONFIG, makePublicDocs, halo2Docs } from "@axiom-crypto/halo2-lib-js"
+import { halo2Docs } from "@axiom-crypto/halo2-lib-js/shared/docs/halo2Docs";
+import { makePublicDocs } from "@axiom-crypto/halo2-lib-js/shared/docs/makePublicDocs";
+import { DEFAULT_CIRCUIT_CONFIG } from "@axiom-crypto/halo2-lib-js/circuit/types";
import { DEFAULT_CODE, DEFAULT_INPUT } from "@/utils/constants";
import { fetchGist, fetchGithubAccessToken } from "@/utils/github";
import JSZip from "jszip";
diff --git a/halo2-repl/package.json b/halo2-repl/package.json
index 5a57a4d..0546848 100644
--- a/halo2-repl/package.json
+++ b/halo2-repl/package.json
@@ -9,8 +9,8 @@
"lint": "next lint"
},
"dependencies": {
- "@axiom-crypto/halo2-lib-js": "0.2.1",
- "@axiom-crypto/halo2-wasm": "0.2.3",
+ "@axiom-crypto/halo2-lib-js": "0.2.5",
+ "@axiom-crypto/halo2-wasm": "0.2.5",
"@devbookhq/splitter": "^1.4.2",
"@headlessui/react": "^1.7.17",
"@heroicons/react": "^2.0.18",
@@ -41,4 +41,4 @@
"devDependencies": {
"@types/prettier": "1.18.2"
}
-}
\ No newline at end of file
+}
diff --git a/halo2-repl/pnpm-lock.yaml b/halo2-repl/pnpm-lock.yaml
index 6dde05d..3583c64 100644
--- a/halo2-repl/pnpm-lock.yaml
+++ b/halo2-repl/pnpm-lock.yaml
@@ -6,11 +6,11 @@ settings:
dependencies:
'@axiom-crypto/halo2-lib-js':
- specifier: 0.2.1
- version: 0.2.1
+ specifier: 0.2.5
+ version: 0.2.5
'@axiom-crypto/halo2-wasm':
- specifier: 0.2.3
- version: 0.2.3
+ specifier: 0.2.5
+ version: 0.2.5
'@devbookhq/splitter':
specifier: ^1.4.2
version: 1.4.2
@@ -102,6 +102,10 @@ packages:
engines: {node: '>=0.10.0'}
dev: false
+ /@adraffy/ens-normalize@1.10.0:
+ resolution: {integrity: sha512-nA9XHtlAkYfJxY7bce8DcN7eKxWWCWkU+1GR9d+U6MbNpfwQp8TI7vqOsBsMcHoT4mBu2kypKoSKnghEzOOq5Q==}
+ dev: false
+
/@adraffy/ens-normalize@1.9.2:
resolution: {integrity: sha512-0h+FrQDqe2Wn+IIGFkTCd4aAwTJ+7834Ek1COohCyV26AXhwQ7WQaz+4F/nLOeVl/3BtWHOHLPsq46V8YB46Eg==}
dev: false
@@ -123,19 +127,19 @@ packages:
'@jridgewell/trace-mapping': 0.3.19
dev: false
- /@axiom-crypto/halo2-lib-js@0.2.1:
- resolution: {integrity: sha512-wL7KkPS/WW7UYxMJD1EKiYVbuENN1QrxKu6WM93QDtjW4IScFnDVTiDEgvg50q1l3JqBuvj+seGjFpA7K54ssQ==}
+ /@axiom-crypto/halo2-lib-js@0.2.5:
+ resolution: {integrity: sha512-DFeG13wo7j1kTsL4Jonl/HcG0UNK4TX8JwQqnkxAo+/KJLj5uvdoDxpjndV4PcUXd8krX6Lwc0KRRjkcCPN9mQ==}
dependencies:
- '@axiom-crypto/halo2-wasm': 0.2.3
- ethers: 6.7.1
+ '@axiom-crypto/halo2-wasm': 0.2.5
+ ethers: 6.8.0
prettier: 1.18.2
transitivePeerDependencies:
- bufferutil
- utf-8-validate
dev: false
- /@axiom-crypto/halo2-wasm@0.2.3:
- resolution: {integrity: sha512-Yw5Nh825BiSF0tnvC0kZas4sezR8S6Z4ELJQsVKTaGiZin6416URFxBP5bQDj7u517QaFG8RTx50Do6xPIR8eg==}
+ /@axiom-crypto/halo2-wasm@0.2.5:
+ resolution: {integrity: sha512-89Nn9QOhKsVDMjMC35KLqsauVUWQ3K8/62mUjqDurc4hDg2MgAHUEM5DFQK198tJ7zNoEvDvhv+mWzLmDkUvzg==}
dev: false
/@babel/code-frame@7.22.13:
@@ -2787,6 +2791,22 @@ packages:
- utf-8-validate
dev: false
+ /ethers@6.8.0:
+ resolution: {integrity: sha512-zrFbmQRlraM+cU5mE4CZTLBurZTs2gdp2ld0nG/f3ecBK+x6lZ69KSxBqZ4NjclxwfTxl5LeNufcBbMsTdY53Q==}
+ engines: {node: '>=14.0.0'}
+ dependencies:
+ '@adraffy/ens-normalize': 1.10.0
+ '@noble/curves': 1.2.0
+ '@noble/hashes': 1.3.2
+ '@types/node': 18.15.13
+ aes-js: 4.0.0-beta.5
+ tslib: 2.4.0
+ ws: 8.5.0
+ transitivePeerDependencies:
+ - bufferutil
+ - utf-8-validate
+ dev: false
+
/eventemitter3@4.0.7:
resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==}
dev: false
diff --git a/halo2-wasm/Cargo.toml b/halo2-wasm/Cargo.toml
index c3203bd..13dc0cb 100644
--- a/halo2-wasm/Cargo.toml
+++ b/halo2-wasm/Cargo.toml
@@ -1,40 +1,25 @@
[package]
name = "halo2-wasm"
-version = "0.2.3"
+version = "0.2.5"
edition = "2021"
[lib]
crate-type = ["cdylib", "lib"]
[dependencies]
-wasm-bindgen = "0.2.87"
+wasm-bindgen = { version = "0.2.87" }
-halo2-base = { git = "https://github.com/axiom-crypto/halo2-lib.git", package = "halo2-base", branch="develop", features = [
- "halo2-axiom",
-] }
+halo2-base = { git = "https://github.com/axiom-crypto/halo2-lib.git", package = "halo2-base", branch = "develop", features = ["halo2-axiom"] }
-halo2-ecc = { git = "https://github.com/axiom-crypto/halo2-lib.git", package = "halo2-ecc", branch="develop", default-features = false, features = [
- "halo2-axiom",
-]}
+halo2-ecc = { git = "https://github.com/axiom-crypto/halo2-lib.git", package = "halo2-ecc", branch = "develop", default-features = false, features = ["halo2-axiom"] }
-snark-verifier-sdk = { git = "https://github.com/axiom-crypto/snark-verifier.git", branch="develop", default-features = false, features = [
- "loader_halo2",
- "halo2-axiom",
-] }
-snark-verifier = { git = "https://github.com/axiom-crypto/snark-verifier.git", branch="develop", default-features = false, features = [
- "loader_halo2",
- "halo2-axiom",
-] }
+snark-verifier-sdk = { git = "https://github.com/axiom-crypto/snark-verifier.git", branch = "develop", default-features = false, features = ["loader_halo2", "halo2-axiom"] }
+snark-verifier = { git = "https://github.com/axiom-crypto/snark-verifier.git", branch = "develop", default-features = false, features = ["loader_halo2", "halo2-axiom"] }
getrandom = { version = "0.2", features = ["js"] }
rand = "0.8"
itertools = "0.10"
-web-sys = { version = "0.3", features = [
- "Request",
- "Window",
- "Response",
- "console",
-] }
+web-sys = { version = "0.3", features = ["Request", "Window", "Response", "console"] }
console_error_panic_hook = "0.1.7"
js-sys = "0.3"
serde = { version = "1.0", features = ["derive"] }
@@ -42,10 +27,12 @@ serde-wasm-bindgen = "0.4"
serde_bytes = "0.11"
bincode = "1.3"
tsify = "0.4.5"
+num-bigint = "0.4"
+num-traits = "0.2"
[target.'cfg(target_family = "wasm")'.dependencies]
wasm-bindgen-rayon = { version = "1.0" }
[features]
-default=["rayon"]
-rayon=[]
+default = ["rayon"]
+rayon = []
diff --git a/halo2-wasm/js/js/index.ts b/halo2-wasm/js/js/index.ts
index 1b142f6..08b70a4 100644
--- a/halo2-wasm/js/js/index.ts
+++ b/halo2-wasm/js/js/index.ts
@@ -1,8 +1,12 @@
-import { Halo2Wasm, initPanicHook, Halo2LibWasm, CircuitConfig } from "../../pkg/js/halo2_wasm";
+import {
+ Halo2Wasm, initPanicHook, Halo2LibWasm, CircuitConfig,
+ Bn254FqPoint, Bn254G1AffinePoint, Bn254G2AffinePoint, JsCircuitBn254Fq2, JsCircuitBn254G1Affine, JsCircuitBn254G2Affine, JsCircuitSecp256k1Affine, JsCircuitValue256, Secp256k1AffinePoint
+} from "../../pkg/js/halo2_wasm";
import { getKzgParams } from "../kzg";
import { DEFAULT_CIRCUIT_CONFIG } from "../shared";
export { CircuitConfig, DEFAULT_CIRCUIT_CONFIG, Halo2Wasm, Halo2LibWasm, getKzgParams };
+export { Bn254FqPoint, Bn254G1AffinePoint, Bn254G2AffinePoint, JsCircuitBn254Fq2, JsCircuitBn254G1Affine, JsCircuitBn254G2Affine, JsCircuitSecp256k1Affine, JsCircuitValue256, Secp256k1AffinePoint };
export const getHalo2Wasm = () => {
initPanicHook();
@@ -43,7 +47,7 @@ export abstract class CircuitScaffold {
this.halo2wasm.config(config);
}
- async loadParams(){
+ async loadParams() {
const kzgParams = await getKzgParams(this.config.k);
this.halo2wasm.loadParams(kzgParams);
}
diff --git a/halo2-wasm/js/web/index.ts b/halo2-wasm/js/web/index.ts
index c885193..8800fe3 100644
--- a/halo2-wasm/js/web/index.ts
+++ b/halo2-wasm/js/web/index.ts
@@ -1,8 +1,12 @@
-import init, { initThreadPool, initPanicHook, Halo2Wasm, Halo2LibWasm, CircuitConfig } from "../../pkg/web/halo2_wasm";
+import init, {
+ initThreadPool, initPanicHook, Halo2Wasm, Halo2LibWasm, CircuitConfig,
+ Bn254FqPoint, Bn254G1AffinePoint, Bn254G2AffinePoint, JsCircuitBn254Fq2, JsCircuitBn254G1Affine, JsCircuitBn254G2Affine, JsCircuitSecp256k1Affine, JsCircuitValue256, Secp256k1AffinePoint
+} from "../../pkg/web/halo2_wasm";
import { getKzgParams } from "../kzg";
import { DEFAULT_CIRCUIT_CONFIG } from "../shared";
export { CircuitConfig, DEFAULT_CIRCUIT_CONFIG, Halo2Wasm, Halo2LibWasm, getKzgParams };
+export { Bn254FqPoint, Bn254G1AffinePoint, Bn254G2AffinePoint, JsCircuitBn254Fq2, JsCircuitBn254G1Affine, JsCircuitBn254G2Affine, JsCircuitSecp256k1Affine, JsCircuitValue256, Secp256k1AffinePoint };
export const getHalo2Wasm = async (numThreads: number) => {
await init();
@@ -50,7 +54,7 @@ export abstract class CircuitScaffold {
this.halo2wasm.config(config);
}
- async loadParams(){
+ async loadParams() {
const kzgParams = await getKzgParams(this.config.k);
this.halo2wasm.loadParams(kzgParams);
}
diff --git a/halo2-wasm/package.json b/halo2-wasm/package.json
index 505c7d6..faa15c1 100644
--- a/halo2-wasm/package.json
+++ b/halo2-wasm/package.json
@@ -1,7 +1,7 @@
{
"name": "@axiom-crypto/halo2-wasm",
"description": "Halo2 wasm bindings",
- "version": "0.2.3",
+ "version": "0.2.5",
"main": "index.js",
"types": "index.d.ts",
"scripts": {
diff --git a/halo2-wasm/pnpm-lock.yaml b/halo2-wasm/pnpm-lock.yaml
index 06a0649..8901fa4 100644
--- a/halo2-wasm/pnpm-lock.yaml
+++ b/halo2-wasm/pnpm-lock.yaml
@@ -1,4 +1,4 @@
-lockfileVersion: '6.0'
+lockfileVersion: '6.1'
settings:
autoInstallPeers: true
diff --git a/halo2-wasm/scripts/build.sh b/halo2-wasm/scripts/build.sh
index 02120f8..50d0a8e 100755
--- a/halo2-wasm/scripts/build.sh
+++ b/halo2-wasm/scripts/build.sh
@@ -1,7 +1,7 @@
#!/bin/bash
node ./scripts/updateCargoVersion.js
echo "build.sh start"
-rm -r pkg
+rm -rf pkg
mkdir pkg
./scripts/build-js.sh
./scripts/build-web.sh
diff --git a/halo2-wasm/src/halo2lib.rs b/halo2-wasm/src/halo2lib.rs
index 001dc09..a707b04 100644
--- a/halo2-wasm/src/halo2lib.rs
+++ b/halo2-wasm/src/halo2lib.rs
@@ -1,35 +1,33 @@
use std::cell::RefCell;
use std::rc::Rc;
-use halo2_base::gates::circuit::builder::BaseCircuitBuilder;
-use halo2_base::gates::flex_gate::{GateChip, GateInstructions};
-use halo2_base::gates::range::{RangeChip, RangeInstructions};
-use halo2_base::halo2_proofs::halo2curves::bn256::Fr;
-use halo2_base::halo2_proofs::halo2curves::group::ff::PrimeField;
-// use halo2_base::halo2_proofs::halo2curves::secp256k1::{Fp, Fq, Secp256k1Affine};
-use halo2_base::halo2_proofs::{
- arithmetic::CurveAffine,
- halo2curves::secp256k1::{Fp, Fq, Secp256k1Affine},
+use halo2_base::{
+ gates::{
+ circuit::builder::BaseCircuitBuilder,
+ flex_gate::{GateChip, GateInstructions},
+ range::{RangeChip, RangeInstructions},
+ },
+ halo2_proofs::{arithmetic::CurveAffine, halo2curves::ff::PrimeField},
+ poseidon::hasher::{spec::OptimizedPoseidonSpec, PoseidonHasher},
+ utils::{biguint_to_fe, fe_to_biguint, modulus},
+ AssignedValue, Context,
+ QuantumCell::Existing,
};
-use halo2_base::poseidon::hasher::spec::OptimizedPoseidonSpec;
-use halo2_base::poseidon::hasher::PoseidonHasher;
-use halo2_base::utils::{biguint_to_fe, fe_to_biguint, modulus};
-use halo2_base::AssignedValue;
-use halo2_base::QuantumCell::Existing;
-use halo2_ecc::ecc::ecdsa::ecdsa_verify_no_pubkey_check;
-use halo2_ecc::ecc::EccChip;
-use halo2_ecc::fields::FieldChip;
-use halo2_ecc::secp256k1::{FpChip, FqChip};
use itertools::Itertools;
use wasm_bindgen::prelude::*;
use crate::Halo2Wasm;
+pub mod ecc;
+
const T: usize = 3;
const RATE: usize = 2;
const R_F: usize = 8;
const R_P: usize = 57;
const SECURE_MDS: usize = 0;
+type Fr = ecc::Bn254Fr;
+// TODO: use wasm_bindgen to sync with js CircuitValue type
+type JsCircuitValue = usize;
#[wasm_bindgen]
pub struct Halo2LibWasm {
@@ -66,14 +64,15 @@ impl Halo2LibWasm {
self.range = range;
}
- fn get_assigned_value(&mut self, idx: usize) -> AssignedValue {
- self.builder
- .borrow_mut()
- .main(0)
- .get(idx.try_into().unwrap())
+ fn get_assigned_value(&self, idx: usize) -> AssignedValue {
+ self.builder.borrow().core().phase_manager[0]
+ .threads
+ .last()
+ .unwrap()
+ .get(idx as isize)
}
- fn get_assigned_values(&mut self, a: &[u32]) -> Vec> {
+ fn get_assigned_values(&self, a: &[u32]) -> Vec> {
a.iter()
.map(|x| self.get_assigned_value(*x as usize))
.collect()
@@ -277,7 +276,7 @@ impl Halo2LibWasm {
self.builder.borrow_mut().main(0).constrain_equal(&a, &b);
}
- pub fn range_check(&mut self, a: usize, b: &str) {
+ pub fn range_check(&self, a: usize, b: &str) {
let a = self.get_assigned_value(a);
let b: usize = b.parse().unwrap();
self.range
@@ -351,52 +350,6 @@ impl Halo2LibWasm {
self.to_js_assigned_value(out)
}
- pub fn ecdsa_benchmark(&mut self, sk: u64, msg_hash: u64, k: u64) -> usize {
- // let pk = self.get_assigned_values(pk);
- // let r = self.get_assigned_value(r);
- // let s = self.get_assigned_value(s);
- // let msg_hash = self.get_assigned_value(msg_hash);
-
- let sk = ::ScalarExt::from(sk);
- let pubkey = Secp256k1Affine::from(Secp256k1Affine::generator() * sk);
- let msg_hash = ::ScalarExt::from(msg_hash);
-
- let k = ::ScalarExt::from(k);
- let k_inv = k.invert().unwrap();
-
- let r_point = Secp256k1Affine::from(Secp256k1Affine::generator() * k)
- .coordinates()
- .unwrap();
- let x = r_point.x();
- let x_bigint = fe_to_biguint(x);
-
- let r = biguint_to_fe::(&(x_bigint % modulus::()));
- let s = k_inv * (msg_hash + (r * sk));
-
- let fp_chip = FpChip::::new(&self.range, 88, 3);
- let fq_chip = FqChip::::new(&self.range, 88, 3);
-
- let [m, r, s] =
- [msg_hash, r, s].map(|x| fq_chip.load_private(self.builder.borrow_mut().main(0), x));
-
- let ecc_chip = EccChip::>::new(&fp_chip);
- let pk = ecc_chip
- .load_private_unchecked(self.builder.borrow_mut().main(0), (pubkey.x, pubkey.y));
-
- let res = ecdsa_verify_no_pubkey_check::(
- &ecc_chip,
- self.builder.borrow_mut().main(0),
- pk,
- r,
- s,
- m,
- 4,
- 4,
- );
-
- self.to_js_assigned_value(res)
- }
-
pub fn poseidon(&mut self, a: &[u32]) -> usize {
let a = self.get_assigned_values(a);
let spec = OptimizedPoseidonSpec::::new::();
@@ -426,7 +379,7 @@ impl Halo2LibWasm {
public.push(a);
}
- pub fn log(&mut self, circuit: &mut Halo2Wasm, a: usize) {
+ pub fn log(&mut self, circuit: &Halo2Wasm, a: usize) {
let val = self.value(a);
unsafe {
circuit.log(val);
diff --git a/halo2-wasm/src/halo2lib/ecc.rs b/halo2-wasm/src/halo2lib/ecc.rs
new file mode 100644
index 0000000..8f80991
--- /dev/null
+++ b/halo2-wasm/src/halo2lib/ecc.rs
@@ -0,0 +1,510 @@
+use halo2_base::{utils::BigPrimeField, QuantumCell::Constant};
+use halo2_ecc::{
+ bigint::ProperCrtUint,
+ bn254::pairing::PairingChip,
+ ecc::EcPoint,
+ fields::{fp::FpChip, vector::FieldVector},
+};
+pub use halo2_ecc::{
+ bn254::{Fp12Chip as Bn254Fq12Chip, Fp2Chip as Bn254Fq2Chip, FpChip as Bn254FqChip},
+ ecc::{ecdsa::ecdsa_verify_no_pubkey_check, EccChip},
+ fields::FieldChip,
+ secp256k1::{FpChip as Secp256k1FpChip, FqChip as Secp256k1FqChip},
+};
+use num_bigint::BigUint;
+use num_traits::One;
+use serde::{Deserialize, Serialize};
+use wasm_bindgen::prelude::*;
+
+pub use crate::halo2_proofs::halo2curves::{
+ bn256::{
+ Fq as Bn254Fq, Fq12 as Bn254Fq12, Fq2 as Bn254Fq2, Fr as Bn254Fr,
+ G1Affine as Bn254G1Affine, G2Affine as Bn254G2Affine,
+ },
+ secp256k1::{Fp as Secp256k1Fp, Fq as Secp256k1Fq, Secp256k1Affine},
+};
+
+use super::*;
+
+// We do not allow JS access to the internals of field elements and ec points because Rust types do not allow you to construct them from the internal pieces for safety.
+
+type FqPoint = ProperCrtUint;
+/// We use 3 limbs with 88 bits each.
+/// NOT constrained to be less than the prime.
+#[wasm_bindgen]
+#[derive(Clone, Debug)]
+pub struct Bn254FqPoint(ProperCrtUint);
+#[wasm_bindgen]
+impl Bn254FqPoint {
+ fn to_hi_lo(&self, lib_wasm: &Halo2LibWasm) -> [AssignedValue; 2] {
+ convert_3limbs88bits_to_hi_lo(lib_wasm, self.0.limbs())
+ }
+ pub fn to_circuit_value_256(&self, lib_wasm: &Halo2LibWasm) -> JsCircuitValue256 {
+ let [hi, lo] = self.to_hi_lo(lib_wasm);
+ let [hi, lo] = [hi, lo].map(|x| lib_wasm.to_js_assigned_value(x));
+ JsCircuitValue256 { hi, lo }
+ }
+}
+
+type Fq2Point = FieldVector;
+#[wasm_bindgen]
+#[derive(Clone, Debug)]
+pub struct Bn254Fq2Point(Fq2Point);
+#[wasm_bindgen]
+impl Bn254Fq2Point {
+ pub fn c0(&self) -> Bn254FqPoint {
+ Bn254FqPoint(self.0[0].clone())
+ }
+ pub fn c1(&self) -> Bn254FqPoint {
+ Bn254FqPoint(self.0[1].clone())
+ }
+}
+
+#[wasm_bindgen]
+#[derive(Clone, Debug)]
+pub struct Bn254G1AffinePoint(EcPoint);
+
+#[wasm_bindgen]
+impl Bn254G1AffinePoint {
+ pub fn x(&self) -> Bn254FqPoint {
+ Bn254FqPoint(self.0.x().clone())
+ }
+ pub fn y(&self) -> Bn254FqPoint {
+ Bn254FqPoint(self.0.y().clone())
+ }
+}
+
+#[wasm_bindgen]
+#[derive(Clone, Debug)]
+pub struct Bn254G2AffinePoint(EcPoint);
+
+#[wasm_bindgen]
+impl Bn254G2AffinePoint {
+ pub fn x(&self) -> Bn254Fq2Point {
+ Bn254Fq2Point(self.0.x().clone())
+ }
+ pub fn y(&self) -> Bn254Fq2Point {
+ Bn254Fq2Point(self.0.y().clone())
+ }
+}
+
+/// We use 3 limbs with 88 bits each.
+/// NOT constrained to be less than the prime.
+// This is the base = coordinate field
+#[wasm_bindgen]
+#[derive(Clone, Debug)]
+pub struct Secp256k1FpPoint(ProperCrtUint);
+#[wasm_bindgen]
+impl Secp256k1FpPoint {
+ fn to_hi_lo(&self, lib_wasm: &Halo2LibWasm) -> [AssignedValue; 2] {
+ convert_3limbs88bits_to_hi_lo(lib_wasm, self.0.limbs())
+ }
+ pub fn to_circuit_value_256(&self, lib_wasm: &Halo2LibWasm) -> JsCircuitValue256 {
+ let [hi, lo] = self.to_hi_lo(lib_wasm);
+ let [hi, lo] = [hi, lo].map(|x| lib_wasm.to_js_assigned_value(x));
+ JsCircuitValue256 { hi, lo }
+ }
+}
+
+/// We use 3 limbs with 88 bits each.
+/// NOT constrained to be less than the prime.
+// This is the scalar field
+#[wasm_bindgen]
+#[derive(Clone, Debug)]
+pub struct Secp256k1FqPoint(ProperCrtUint);
+#[wasm_bindgen]
+impl Secp256k1FqPoint {
+ fn to_hi_lo(&self, lib_wasm: &Halo2LibWasm) -> [AssignedValue; 2] {
+ convert_3limbs88bits_to_hi_lo(lib_wasm, self.0.limbs())
+ }
+ pub fn to_circuit_value_256(&self, lib_wasm: &Halo2LibWasm) -> JsCircuitValue256 {
+ let [hi, lo] = self.to_hi_lo(lib_wasm);
+ let [hi, lo] = [hi, lo].map(|x| lib_wasm.to_js_assigned_value(x));
+ JsCircuitValue256 { hi, lo }
+ }
+}
+
+type FpPoint = ProperCrtUint;
+#[wasm_bindgen]
+#[derive(Clone, Debug)]
+pub struct Secp256k1AffinePoint(EcPoint);
+
+#[wasm_bindgen]
+impl Secp256k1AffinePoint {
+ pub fn x(&self) -> Secp256k1FpPoint {
+ Secp256k1FpPoint(self.0.x().clone())
+ }
+ pub fn y(&self) -> Secp256k1FpPoint {
+ Secp256k1FpPoint(self.0.y().clone())
+ }
+}
+
+/// When this type is used, it is **ASSUMED** that the corresponding `hi,lo` [AssignedValue]s have been range checked to be 128 bits each.
+#[wasm_bindgen]
+#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
+pub struct JsCircuitValue256 {
+ pub hi: JsCircuitValue,
+ pub lo: JsCircuitValue,
+}
+#[wasm_bindgen]
+impl JsCircuitValue256 {
+ #[wasm_bindgen(constructor)]
+ pub fn new(hi: JsCircuitValue, lo: JsCircuitValue) -> Self {
+ Self { hi, lo }
+ }
+}
+
+// following notation of https://github.com/paulmillr/noble-curves/tree/main
+#[wasm_bindgen]
+#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
+pub struct JsCircuitBn254Fq2 {
+ pub c0: JsCircuitValue256,
+ pub c1: JsCircuitValue256,
+}
+#[wasm_bindgen]
+impl JsCircuitBn254Fq2 {
+ #[wasm_bindgen(constructor)]
+ pub fn new(c0: JsCircuitValue256, c1: JsCircuitValue256) -> Self {
+ Self { c0, c1 }
+ }
+}
+
+#[wasm_bindgen(getter_with_clone)]
+#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
+pub struct JsCircuitBn254G1Affine {
+ pub x: JsCircuitValue256,
+ pub y: JsCircuitValue256,
+}
+#[wasm_bindgen]
+impl JsCircuitBn254G1Affine {
+ #[wasm_bindgen(constructor)]
+ pub fn new(x: JsCircuitValue256, y: JsCircuitValue256) -> Self {
+ Self { x, y }
+ }
+}
+
+#[wasm_bindgen(getter_with_clone)]
+#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
+pub struct JsCircuitBn254G2Affine {
+ pub x: JsCircuitBn254Fq2,
+ pub y: JsCircuitBn254Fq2,
+}
+#[wasm_bindgen]
+impl JsCircuitBn254G2Affine {
+ #[wasm_bindgen(constructor)]
+ pub fn new(x: JsCircuitBn254Fq2, y: JsCircuitBn254Fq2) -> Self {
+ Self { x, y }
+ }
+}
+
+#[wasm_bindgen(getter_with_clone)]
+#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
+pub struct JsCircuitSecp256k1Affine {
+ pub x: JsCircuitValue256,
+ pub y: JsCircuitValue256,
+}
+#[wasm_bindgen]
+impl JsCircuitSecp256k1Affine {
+ #[wasm_bindgen(constructor)]
+ pub fn new(x: JsCircuitValue256, y: JsCircuitValue256) -> Self {
+ Self { x, y }
+ }
+}
+
+#[wasm_bindgen]
+impl Halo2LibWasm {
+ // TODO: this should not be recreated, but currently blocked by self-referential structs
+ fn bn254_fq_chip(&self) -> Bn254FqChip {
+ let limb_bits = 88;
+ let num_limbs = 3;
+ Bn254FqChip::::new(&self.range, limb_bits, num_limbs)
+ }
+ fn secp256k1_fp_chip(&self) -> Secp256k1FpChip {
+ let limb_bits = 88;
+ let num_limbs = 3;
+ Secp256k1FpChip::::new(&self.range, limb_bits, num_limbs)
+ }
+ fn secp256k1_fq_chip(&self) -> Secp256k1FqChip {
+ let limb_bits = 88;
+ let num_limbs = 3;
+ Secp256k1FqChip::::new(&self.range, limb_bits, num_limbs)
+ }
+
+ /// Takes in CircuitValue256 in hi-lo form and loads internal CircuitBn254Fq type (we use 3 limbs of 88 bits).
+ /// This function does not range check `hi,lo` to be `uint128` in case it's already done elsewhere.
+ pub fn load_bn254_fq(&self, val: JsCircuitValue256) -> Bn254FqPoint {
+ let fq_chip = self.bn254_fq_chip();
+ Bn254FqPoint(self.load_generic_fp_impl::(&fq_chip, val))
+ }
+ /// Doesn't range check limbs of g1_point.
+ /// Does not allow you to load identity point.
+ pub fn load_bn254_g1(&self, point: JsCircuitBn254G1Affine) -> Bn254G1AffinePoint {
+ let fq_chip = self.bn254_fq_chip();
+ let g1_chip = EccChip::new(&fq_chip);
+ self.load_bn254_g1_impl(&g1_chip, point)
+ }
+ /// `g1_points` should be array of `CircuitBn254G1Affine` in hi-lo form.
+ /// This function does not range check `hi,lo` to be `uint128` in case it's already done elsewhere.
+ /// Prevents any g1_points from being identity.
+ pub fn bn254_g1_sum(&self, g1_points: js_sys::Array) -> Bn254G1AffinePoint {
+ let fq_chip = self.bn254_fq_chip();
+ let g1_chip = EccChip::new(&fq_chip);
+ let g1_points: Vec = g1_points
+ .iter()
+ .map(|x| serde_wasm_bindgen::from_value(x).unwrap())
+ .collect();
+ let mut builder = self.builder.borrow_mut();
+ let ctx = builder.main(0);
+ let g1_points: Vec<_> = g1_points
+ .into_iter()
+ .map(|point| self.load_bn254_g1_impl(&g1_chip, point).0)
+ .collect();
+ let sum = g1_chip.sum::(ctx, g1_points);
+ Bn254G1AffinePoint(sum)
+ }
+
+ /// `g1_point_1` and `g1_point_2` are `CircuitBn254G1Affine` points in hi-lo form.
+ /// This function does not range check `hi,lo` to be `uint128` in case it's already done elsewhere
+ /// and also it constraints that g1_point_1.x != g1_point_2.x
+ /// Prevents any g1_points from being identity.
+ pub fn bn254_g1_sub_unequal(
+ &self,
+ g1_point_1: JsCircuitBn254G1Affine,
+ g1_point_2: JsCircuitBn254G1Affine,
+ ) -> Bn254G1AffinePoint {
+ let fq_chip = self.bn254_fq_chip();
+ let g1_chip = EccChip::new(&fq_chip);
+ let mut builder = self.builder.borrow_mut();
+ let ctx = builder.main(0);
+ let g1_point_1_loaded: EcPoint =
+ self.load_bn254_g1_impl(&g1_chip, g1_point_1).0;
+ let g1_point_2_loaded: EcPoint =
+ self.load_bn254_g1_impl(&g1_chip, g1_point_2).0;
+ let diff = g1_chip.sub_unequal(ctx, g1_point_1_loaded, g1_point_2_loaded, true);
+ Bn254G1AffinePoint(diff)
+ }
+
+ /// Doesn't range check limbs of g2_point.
+ /// Does not allow you to load identity point.
+ pub fn load_bn254_g2(&self, point: JsCircuitBn254G2Affine) -> Bn254G2AffinePoint {
+ let fq_chip = self.bn254_fq_chip();
+ let fq2_chip = Bn254Fq2Chip::new(&fq_chip);
+ let g2_chip = EccChip::new(&fq2_chip);
+ self.load_bn254_g2_impl(&g2_chip, point)
+ }
+ /// `g2_points` should be array of `CircuitBn254G2Affine` in hi-lo form.
+ /// This function does not range check `hi,lo` to be `uint128` in case it's already done elsewhere.
+ /// Prevents any g2_points from being identity.
+ pub fn bn254_g2_sum(&self, g2_points: js_sys::Array) -> Bn254G2AffinePoint {
+ let fq_chip = self.bn254_fq_chip();
+ let fq2_chip = Bn254Fq2Chip::new(&fq_chip);
+ let g2_chip = EccChip::new(&fq2_chip);
+ let g2_points: Vec = g2_points
+ .iter()
+ .map(|x| serde_wasm_bindgen::from_value(x).unwrap())
+ .collect();
+ let mut builder = self.builder.borrow_mut();
+ let ctx = builder.main(0);
+ let g2_points: Vec<_> = g2_points
+ .into_iter()
+ .map(|point| self.load_bn254_g2_impl(&g2_chip, point).0)
+ .collect();
+ let sum = g2_chip.sum::(ctx, g2_points);
+ Bn254G2AffinePoint(sum)
+ }
+ /// Verifies that e(lhs_g1, lhs_g2) = e(rhs_g1, rhs_g2) by checking e(lhs_g1, lhs_g2)*e(-rhs_g1, rhs_g2) === 1
+ /// Returns [CircuitValue] for the result as a boolean (1 if signature verification is successful).
+ /// None of the points should be identity.
+ pub fn bn254_pairing_check(
+ &self,
+ lhs_g1: Bn254G1AffinePoint,
+ lhs_g2: Bn254G2AffinePoint,
+ rhs_g1: Bn254G1AffinePoint,
+ rhs_g2: Bn254G2AffinePoint,
+ ) -> JsCircuitValue {
+ let fq_chip = self.bn254_fq_chip();
+ let g1_chip = EccChip::new(&fq_chip);
+ let mut builder = self.builder.borrow_mut();
+ let ctx = builder.main(0);
+ let neg_rhs_g1 = g1_chip.negate(ctx, rhs_g1.0);
+ let pairing_chip = PairingChip::new(&fq_chip);
+
+ let multi_paired = pairing_chip
+ .multi_miller_loop(ctx, vec![(&lhs_g1.0, &lhs_g2.0), (&neg_rhs_g1, &rhs_g2.0)]);
+ let fq12_chip = Bn254Fq12Chip::new(&fq_chip);
+ let result = fq12_chip.final_exp(ctx, multi_paired);
+ let fq12_one = fq12_chip.load_constant(ctx, Bn254Fq12::one());
+ let verification_result = fq12_chip.is_equal(ctx, result, fq12_one);
+ self.to_js_assigned_value(verification_result)
+ }
+
+ /// Doesn't range check limbs of point.
+ /// Pubkey is a point on
+ pub fn load_secp256k1_pubkey(&self, point: JsCircuitSecp256k1Affine) -> Secp256k1AffinePoint {
+ let fp_chip = self.secp256k1_fp_chip();
+ let mut builder = self.builder.borrow_mut();
+ let ctx = builder.main(0);
+ let [x, y] =
+ [point.x, point.y].map(|c| self.load_generic_fp_impl::(&fp_chip, c));
+ let pt = EcPoint::new(x, y);
+ let chip = EccChip::new(&fp_chip);
+ // this prevents pubkey from being identity point:
+ chip.assert_is_on_curve::(ctx, &pt);
+ Secp256k1AffinePoint(pt)
+ }
+
+ /// Assumes all `JsCircuitValue256` limbs have been range checked to be `u128`.
+ pub fn verify_secp256k1_ecdsa_signature(
+ &self,
+ pubkey: Secp256k1AffinePoint,
+ r: JsCircuitValue256,
+ s: JsCircuitValue256,
+ msg_hash: JsCircuitValue256,
+ ) -> JsCircuitValue {
+ let fq_chip = self.secp256k1_fq_chip();
+ let fp_chip = self.secp256k1_fp_chip();
+ let [r, s, msg_hash] = [r, s, msg_hash].map(|x| self.load_generic_fp_impl(&fq_chip, x));
+ let ecc_chip = EccChip::new(&fp_chip);
+ let mut builder = self.builder.borrow_mut();
+ let ctx = builder.main(0);
+ let verification_result =
+ ecdsa_verify_no_pubkey_check::(
+ &ecc_chip, ctx, pubkey.0, r, s, msg_hash, 4, 4,
+ );
+ self.to_js_assigned_value(verification_result)
+ }
+
+ pub fn ecdsa_benchmark(&mut self, sk: u64, msg_hash: u64, k: u64) -> usize {
+ // let pk = self.get_assigned_values(pk);
+ // let r = self.get_assigned_value(r);
+ // let s = self.get_assigned_value(s);
+ // let msg_hash = self.get_assigned_value(msg_hash);
+
+ let sk = ::ScalarExt::from(sk);
+ let pubkey = Secp256k1Affine::from(Secp256k1Affine::generator() * sk);
+ let msg_hash = ::ScalarExt::from(msg_hash);
+
+ let k = ::ScalarExt::from(k);
+ let k_inv = k.invert().unwrap();
+
+ let r_point = Secp256k1Affine::from(Secp256k1Affine::generator() * k)
+ .coordinates()
+ .unwrap();
+ let x = r_point.x();
+ let x_bigint = fe_to_biguint(x);
+
+ let r = biguint_to_fe::(&(x_bigint % modulus::()));
+ let s = k_inv * (msg_hash + (r * sk));
+
+ let fp_chip = self.secp256k1_fp_chip();
+ let fq_chip = self.secp256k1_fq_chip();
+
+ let mut builder = self.builder.borrow_mut();
+ let ctx = builder.main(0);
+ let [m, r, s] = [msg_hash, r, s].map(|x| fq_chip.load_private(ctx, x));
+
+ let ecc_chip = EccChip::new(&fp_chip);
+ let pk = ecc_chip.load_private_unchecked(ctx, (pubkey.x, pubkey.y));
+
+ let res = ecdsa_verify_no_pubkey_check::(
+ &ecc_chip, ctx, pk, r, s, m, 4, 4,
+ );
+
+ self.to_js_assigned_value(res)
+ }
+
+ // private implementations to save recreating chips each time:
+
+ // Doesn't range check hi,lo
+ fn load_generic_fp_impl(
+ &self,
+ fp_chip: &FpChip,
+ val: JsCircuitValue256,
+ ) -> ProperCrtUint {
+ // easiest to just construct the raw bigint, load it as witness, and then constrain against provided circuit value
+ let [hi, lo] = [val.hi, val.lo].map(|x| self.get_assigned_value(x));
+ let [hi_val, lo_val] = [hi, lo].map(|x| fe_to_biguint(x.value()));
+ let fp = (hi_val << 128) + lo_val;
+ assert!(fp < modulus::());
+ let fp = biguint_to_fe::(&fp);
+ let mut builder = self.builder.borrow_mut();
+ let ctx = builder.main(0);
+ let fp = fp_chip.load_private(ctx, fp);
+ // constrain fq actually equals hi << 128 + lo
+ constrain_limbs_equality(ctx, &self.range, [hi, lo], fp.limbs(), fp_chip.limb_bits());
+ fp
+ }
+ /// Doesn't range check limbs of g1_point
+ fn load_bn254_g1_impl(
+ &self,
+ g1_chip: &EccChip>,
+ point: JsCircuitBn254G1Affine,
+ ) -> Bn254G1AffinePoint {
+ let mut builder = self.builder.borrow_mut();
+ let ctx = builder.main(0);
+ let [x, y] = [point.x, point.y]
+ .map(|c| self.load_generic_fp_impl::(g1_chip.field_chip(), c));
+ let pt = EcPoint::new(x, y);
+ g1_chip.assert_is_on_curve::(ctx, &pt);
+ Bn254G1AffinePoint(pt)
+ }
+ /// Doesn't range check limbs of g2_point
+ fn load_bn254_g2_impl(
+ &self,
+ g2_chip: &EccChip>,
+ point: JsCircuitBn254G2Affine,
+ ) -> Bn254G2AffinePoint {
+ let fq_chip = g2_chip.field_chip().fp_chip();
+ let mut builder = self.builder.borrow_mut();
+ let ctx = builder.main(0);
+ let [x, y] = [point.x, point.y].map(|c| {
+ let c0 = self.load_generic_fp_impl::(fq_chip, c.c0);
+ let c1 = self.load_generic_fp_impl::(fq_chip, c.c1);
+ FieldVector(vec![c0, c1])
+ });
+ let pt = EcPoint::new(x, y);
+ g2_chip.assert_is_on_curve::(ctx, &pt);
+ Bn254G2AffinePoint(pt)
+ }
+}
+
+// hardcoding for 3 limbs
+fn constrain_limbs_equality(
+ ctx: &mut Context,
+ range: &RangeChip,
+ [hi, lo]: [AssignedValue; 2],
+ limbs: &[AssignedValue],
+ limb_bits: usize,
+) {
+ assert!(limb_bits <= 128);
+ assert!(limb_bits > 64);
+ // limb_bits, 128 - limb_bits
+ let (limb0, tmp0) = range.div_mod(ctx, lo, BigUint::one() << limb_bits, 128);
+ // limb_bits - (128 - limb_bits) = 2 * limb_bits - 128 > 0
+ let rem_bits = limb_bits - (128 - limb_bits);
+ let (limb2, tmp1) = range.div_mod(ctx, hi, BigUint::one() << rem_bits, 128);
+ let multiplier = biguint_to_fe(&(BigUint::one() << (128 - limb_bits)));
+ let limb1 = range.gate.mul_add(ctx, tmp1, Constant(multiplier), tmp0);
+ for (l0, l1) in limbs.iter().zip_eq([limb0, limb1, limb2]) {
+ ctx.constrain_equal(l0, &l1);
+ }
+}
+
+fn convert_3limbs88bits_to_hi_lo(
+ lib_wasm: &Halo2LibWasm,
+ limbs: &[AssignedValue],
+) -> [AssignedValue; 2] {
+ assert_eq!(limbs.len(), 3);
+ let lo_bits = 128 - 88;
+ let hi_bits = 88 - lo_bits;
+ let mut builder = lib_wasm.builder.borrow_mut();
+ let range = &lib_wasm.range;
+ let gate = &range.gate;
+ let ctx = builder.main(0);
+ let (limb1_lo, limb1_hi) = range.div_mod(ctx, limbs[1], BigUint::one() << lo_bits, 88);
+ let multiplier = biguint_to_fe(&(BigUint::one() << 88));
+ let lo = gate.mul_add(ctx, limb1_lo, Constant(multiplier), limbs[0]);
+ let multiplier = biguint_to_fe(&(BigUint::one() << hi_bits));
+ let hi = gate.mul_add(ctx, limbs[2], Constant(multiplier), limb1_hi);
+ [hi, lo]
+}
diff --git a/halo2-wasm/src/lib.rs b/halo2-wasm/src/lib.rs
index 6eadd2c..5f4b4d2 100644
--- a/halo2-wasm/src/lib.rs
+++ b/halo2-wasm/src/lib.rs
@@ -1,36 +1,47 @@
#![feature(trait_alias)]
-use halo2_base::gates::circuit::builder::BaseCircuitBuilder;
-use halo2_base::gates::circuit::BaseCircuitParams;
-use halo2_base::halo2_proofs::poly::commitment::{Params, ParamsProver};
-use halo2_base::halo2_proofs::{
+
+use std::cell::RefCell;
+use std::io::BufReader;
+use std::rc::Rc;
+
+use halo2_base::{
+ gates::circuit::{builder::BaseCircuitBuilder, BaseCircuitParams},
+ AssignedValue,
+};
+pub use halo2_ecc;
+use halo2_proofs::{
dev::MockProver,
halo2curves::bn256::{Bn256, Fr, G1Affine},
plonk::*,
- poly::kzg::commitment::{KZGCommitmentScheme, ParamsKZG},
- poly::kzg::multiopen::VerifierSHPLONK,
- poly::kzg::strategy::SingleStrategy,
+ poly::{
+ commitment::{Params, ParamsProver},
+ kzg::{
+ commitment::{KZGCommitmentScheme, ParamsKZG},
+ multiopen::VerifierSHPLONK,
+ strategy::SingleStrategy,
+ },
+ },
};
-use halo2_base::AssignedValue;
-use itertools::concat;
-use itertools::Itertools;
+use itertools::{concat, Itertools};
use serde::{Deserialize, Serialize};
use snark_verifier::system::halo2::transcript_initial_state;
-use snark_verifier_sdk::halo2::gen_snark_shplonk;
-use snark_verifier_sdk::halo2::PoseidonTranscript;
-use snark_verifier_sdk::halo2::POSEIDON_SPEC;
-use snark_verifier_sdk::NativeLoader;
-use std::cell::RefCell;
-use std::io::BufReader;
-use std::rc::Rc;
+use snark_verifier_sdk::{
+ halo2::{gen_snark_shplonk, PoseidonTranscript, POSEIDON_SPEC},
+ NativeLoader,
+};
use tsify::Tsify;
use wasm_bindgen::prelude::*;
-mod vkey;
-use vkey::{write_partial_vkey, PartialVerifyingKey};
+
+pub use halo2_base;
+pub use halo2_base::halo2_proofs;
#[cfg(all(target_family = "wasm", feature = "rayon"))]
pub use wasm_bindgen_rayon::init_thread_pool;
pub mod halo2lib;
+mod vkey;
+
+use vkey::{write_partial_vkey, PartialVerifyingKey};
#[wasm_bindgen]
extern "C" {
@@ -80,10 +91,8 @@ pub struct Halo2Wasm {
vk: Option>,
}
-#[wasm_bindgen]
-impl Halo2Wasm {
- #[wasm_bindgen(constructor)]
- pub fn new() -> Self {
+impl Default for Halo2Wasm {
+ fn default() -> Self {
let circuit = BaseCircuitBuilder::new(false);
Halo2Wasm {
circuit: Rc::new(RefCell::new(circuit)),
@@ -94,6 +103,14 @@ impl Halo2Wasm {
vk: None,
}
}
+}
+
+#[wasm_bindgen]
+impl Halo2Wasm {
+ #[wasm_bindgen(constructor)]
+ pub fn new() -> Self {
+ Self::default()
+ }
pub fn clear(&mut self) {
let circuit_params = self.circuit_params.clone().unwrap();
@@ -150,7 +167,12 @@ impl Halo2Wasm {
pub fn set_instances(&mut self, instances: &[u32], col: usize) {
let instances: Vec> = instances
.iter()
- .map(|x| self.circuit.borrow_mut().main(0).get((*x).try_into().unwrap()))
+ .map(|x| {
+ self.circuit
+ .borrow_mut()
+ .main(0)
+ .get((*x).try_into().unwrap())
+ })
.collect();
let public = self.public.get_mut(col).unwrap();
public.clear();
@@ -317,6 +339,7 @@ impl Halo2Wasm {
snark.proof
}
+ /// For console logging only.
pub unsafe fn log(&self, a: String) {
console_log!("{}", a);
}
From 114e8723da75cb1b0d14cc291f079ca0375e29cd Mon Sep 17 00:00:00 2001
From: Jonathan Wang <31040440+jonathanpwang@users.noreply.github.com>
Date: Tue, 31 Oct 2023 09:54:57 -0700
Subject: [PATCH 4/8] [chore] add docs for `newCircuitValue256` (#35)
---
halo2-lib-js/package.json | 2 +-
halo2-lib-js/src/shared/docs/halo2Docs.d.ts | 268 ++++++++++++++------
2 files changed, 187 insertions(+), 83 deletions(-)
diff --git a/halo2-lib-js/package.json b/halo2-lib-js/package.json
index 21e784a..6ce5fb0 100644
--- a/halo2-lib-js/package.json
+++ b/halo2-lib-js/package.json
@@ -1,6 +1,6 @@
{
"name": "@axiom-crypto/halo2-lib-js",
- "version": "0.2.5",
+ "version": "0.2.6",
"description": "Halo2 Javascript library",
"main": "index.js",
"scripts": {
diff --git a/halo2-lib-js/src/shared/docs/halo2Docs.d.ts b/halo2-lib-js/src/shared/docs/halo2Docs.d.ts
index 83d27b1..f7fd553 100644
--- a/halo2-lib-js/src/shared/docs/halo2Docs.d.ts
+++ b/halo2-lib-js/src/shared/docs/halo2Docs.d.ts
@@ -1,59 +1,80 @@
// Generated by dts-bundle-generator v8.0.1
-import { Halo2Wasm } from '@axiom-crypto/halo2-wasm/web';
-import { Bn254FqPoint, Bn254G1AffinePoint, Bn254G2AffinePoint, JsCircuitBn254Fq2, JsCircuitBn254G1Affine, JsCircuitBn254G2Affine, JsCircuitSecp256k1Affine, JsCircuitValue256, Secp256k1AffinePoint } from "@axiom-crypto/halo2-wasm/web";
+import { Halo2Wasm } from "@axiom-crypto/halo2-wasm/web";
+import {
+ Bn254FqPoint,
+ Bn254G1AffinePoint,
+ Bn254G2AffinePoint,
+ JsCircuitBn254Fq2,
+ JsCircuitBn254G1Affine,
+ JsCircuitBn254G2Affine,
+ JsCircuitSecp256k1Affine,
+ JsCircuitValue256,
+ Secp256k1AffinePoint,
+} from "@axiom-crypto/halo2-wasm/web";
declare class CircuitValue {
- private _value;
- private _cell;
- constructor(circuit: Halo2Wasm, { value, cell }: {
- value?: bigint | number | string;
- cell?: number;
- });
- cell(): number;
- value(): bigint;
- number(): number;
- address(): string;
+ private _value;
+ private _cell;
+ constructor(
+ circuit: Halo2Wasm,
+ {
+ value,
+ cell,
+ }: {
+ value?: bigint | number | string;
+ cell?: number;
+ }
+ );
+ cell(): number;
+ value(): bigint;
+ number(): number;
+ address(): string;
}
declare class CircuitValue256 {
- private _value;
- private _circuitValue;
- private _halo2Lib;
- constructor(_halo2Lib: Halo2Wasm, { value, hi, lo, }: {
- value?: bigint | string | number;
- hi?: CircuitValue;
- lo?: CircuitValue;
- });
- hi(): CircuitValue;
- lo(): CircuitValue;
- hex(): string;
- value(): bigint;
- toCircuitValue(): CircuitValue;
+ private _value;
+ private _circuitValue;
+ private _halo2Lib;
+ constructor(
+ _halo2Lib: Halo2Wasm,
+ {
+ value,
+ hi,
+ lo,
+ }: {
+ value?: bigint | string | number;
+ hi?: CircuitValue;
+ lo?: CircuitValue;
+ }
+ );
+ hi(): CircuitValue;
+ lo(): CircuitValue;
+ hex(): string;
+ value(): bigint;
+ toCircuitValue(): CircuitValue;
}
export interface CircuitBn254Fq2 {
- c0: CircuitValue256;
- c1: CircuitValue256;
+ c0: CircuitValue256;
+ c1: CircuitValue256;
}
export interface CircuitBn254G1Affine {
- x: CircuitValue256;
- y: CircuitValue256;
+ x: CircuitValue256;
+ y: CircuitValue256;
}
export interface CircuitBn254G2Affine {
- x: CircuitBn254Fq2;
- y: CircuitBn254Fq2;
+ x: CircuitBn254Fq2;
+ y: CircuitBn254Fq2;
}
export interface CircuitSecp256k1Affine {
- x: CircuitValue256;
- y: CircuitValue256;
+ x: CircuitValue256;
+ y: CircuitValue256;
}
-
-
export type RawCircuitInput = string | number | bigint;
/**
@@ -109,7 +130,11 @@ declare const mul: (a: CircuitValue, b: CircuitValue) => CircuitValue;
* @param c The third circuit value.
* @returns The result of multiplying the first two circuit values and adding the third circuit value.
*/
-declare const mulAdd: (a: CircuitValue, b: CircuitValue, c: CircuitValue) => CircuitValue;
+declare const mulAdd: (
+ a: CircuitValue,
+ b: CircuitValue,
+ c: CircuitValue
+) => CircuitValue;
/**
* Multiplies a circuit value by the negation of another circuit value.
*
@@ -138,7 +163,10 @@ declare const assertIsConst: (a: CircuitValue, b: RawCircuitInput) => void;
* @param b The second array of circuit values.
* @returns The inner product of the two arrays.
*/
-declare const innerProduct: (a: CircuitValue[], b: CircuitValue[]) => CircuitValue;
+declare const innerProduct: (
+ a: CircuitValue[],
+ b: CircuitValue[]
+) => CircuitValue;
/**
* Computes the sum of an array of circuit values.
*
@@ -184,7 +212,11 @@ declare const dec: (a: CircuitValue) => CircuitValue;
* @param sel The condition boolean circuit value.
* @returns sel ? a : b
*/
-declare const select: (a: CircuitValue, b: CircuitValue, sel: CircuitValue) => CircuitValue;
+declare const select: (
+ a: CircuitValue,
+ b: CircuitValue,
+ sel: CircuitValue
+) => CircuitValue;
/**
* Performs a bitwise OR-AND operation on three circuit values.
*
@@ -193,7 +225,11 @@ declare const select: (a: CircuitValue, b: CircuitValue, sel: CircuitValue) => C
* @param c The third circuit value.
* @returns The result of the OR-AND operation.
*/
-declare const orAnd: (a: CircuitValue, b: CircuitValue, c: CircuitValue) => CircuitValue;
+declare const orAnd: (
+ a: CircuitValue,
+ b: CircuitValue,
+ c: CircuitValue
+) => CircuitValue;
/**
* Converts an array of circuit values to an indicator array.
*
@@ -208,7 +244,10 @@ declare const bitsToIndicator: (bits: CircuitValue[]) => CircuitValue[];
* @param len The length of the indicator circuit value.
* @returns The indicator circuit value.
*/
-declare const idxToIndicator: (idx: CircuitValue, len: RawCircuitInput) => CircuitValue[];
+declare const idxToIndicator: (
+ idx: CircuitValue,
+ len: RawCircuitInput
+) => CircuitValue[];
/**
* Selects circuit values from an array based on an indicator circuit value.
*
@@ -216,7 +255,10 @@ declare const idxToIndicator: (idx: CircuitValue, len: RawCircuitInput) => Circu
* @param indicator The indicator circuit value.
* @returns The selected circuit values.
*/
-declare const selectByIndicator: (arr: CircuitValue[], indicator: CircuitValue[]) => CircuitValue;
+declare const selectByIndicator: (
+ arr: CircuitValue[],
+ indicator: CircuitValue[]
+) => CircuitValue;
/**
* Selects a circuit value from an array based on an index circuit value.
*
@@ -224,7 +266,10 @@ declare const selectByIndicator: (arr: CircuitValue[], indicator: CircuitValue[]
* @param idx The index circuit value.
* @returns The selected circuit value.
*/
-declare const selectFromIdx: (arr: CircuitValue[], idx: CircuitValue) => CircuitValue;
+declare const selectFromIdx: (
+ arr: CircuitValue[],
+ idx: CircuitValue
+) => CircuitValue;
/**
* Checks if a circuit value is zero.
*
@@ -247,7 +292,10 @@ declare const isEqual: (a: CircuitValue, b: CircuitValue) => CircuitValue;
* @param len The length of the resulting bit array.
* @returns The array of bits representing the input circuit value.
*/
-declare const numToBits: (a: CircuitValue, len: RawCircuitInput) => CircuitValue[];
+declare const numToBits: (
+ a: CircuitValue,
+ len: RawCircuitInput
+) => CircuitValue[];
/**
* Asserts that two circuit values are equal.
*
@@ -269,7 +317,11 @@ declare const rangeCheck: (a: CircuitValue, b: RawCircuitInput) => void;
* @param b The second circuit value.
* @param c The range of the circuit values.
*/
-declare const checkLessThan: (a: CircuitValue, b: CircuitValue, c?: string) => void;
+declare const checkLessThan: (
+ a: CircuitValue,
+ b: CircuitValue,
+ c?: string
+) => void;
/**
* Checks if the first circuit value is less than the second circuit value.
*
@@ -278,7 +330,11 @@ declare const checkLessThan: (a: CircuitValue, b: CircuitValue, c?: string) => v
* @param c The range of the circuit values.
* @returns The indicator circuit value representing whether the first input is less than the second input.
*/
-declare const isLessThan: (a: CircuitValue, b: CircuitValue, c?: string) => CircuitValue;
+declare const isLessThan: (
+ a: CircuitValue,
+ b: CircuitValue,
+ c?: string
+) => CircuitValue;
/**
* Divides two circuit values and returns the quotient.
*
@@ -286,8 +342,13 @@ declare const isLessThan: (a: CircuitValue, b: CircuitValue, c?: string) => Circ
* @param b The divisor circuit value.
* @returns The quotient.
*
-*/
-declare const div: (a: CircuitValue, b: CircuitValue, c?: string, d?: string) => CircuitValue;
+ */
+declare const div: (
+ a: CircuitValue,
+ b: CircuitValue,
+ c?: string,
+ d?: string
+) => CircuitValue;
/**
* Divides two circuit values and returns the remainder.
*
@@ -295,8 +356,13 @@ declare const div: (a: CircuitValue, b: CircuitValue, c?: string, d?: string) =>
* @param b The divisor circuit value.
* @returns The remainder.
*
-*/
-declare const mod: (a: CircuitValue, b: CircuitValue, c?: string, d?: string) => CircuitValue;
+ */
+declare const mod: (
+ a: CircuitValue,
+ b: CircuitValue,
+ c?: string,
+ d?: string
+) => CircuitValue;
/**
* Raises a circuit value to the power of another circuit value.
*
@@ -304,7 +370,11 @@ declare const mod: (a: CircuitValue, b: CircuitValue, c?: string, d?: string) =>
* @param b The exponent circuit value.
* @returns The result of the exponentiation.
*/
-declare const pow: (a: CircuitValue, b: CircuitValue, c?: string) => CircuitValue;
+declare const pow: (
+ a: CircuitValue,
+ b: CircuitValue,
+ c?: string
+) => CircuitValue;
/**
* Computes the Poseidon hash of multiple circuit values.
*
@@ -326,34 +396,50 @@ declare const value: (a: CircuitValue) => any;
*/
declare const log: (...args: any) => void;
declare const console: {
- /**
- * Logs any *non CircuitValue* to the console. Use `log` for logging `CircuitValue`s.
- * @param args The values to log.
- */
- log: (...args: any) => void;
-}
-declare const ecdsaBenchmark: (sk: bigint, msg_hash: bigint, k: bigint) => CircuitValue;
+ /**
+ * Logs any *non CircuitValue* to the console. Use `log` for logging `CircuitValue`s.
+ * @param args The values to log.
+ */
+ log: (...args: any) => void;
+};
+declare const ecdsaBenchmark: (
+ sk: bigint,
+ msg_hash: bigint,
+ k: bigint
+) => CircuitValue;
+/**
+ * Creates new `CircuitValue256` and range checks `hi, lo` to be `uint128`s.
+ * @param hi
+ * @param lo
+ * @returns
+ */
+declare const newCircuitValue256: (
+ hi: CircuitValue,
+ lo: CircuitValue
+) => CircuitValue256;
//ecc
/**
- *
+ *
* @param val The field point to load, in hi-lo form. The hi, lo values must have been constrained to be `uint128`s.
* @returns `Bn254FqPoint` whose internals are opaque to the user.
*/
declare const loadBn254Fq: (val: CircuitValue256) => Bn254FqPoint;
/**
-*
-* @param val
-* @returns `val` in hi-lo form
-*/
-declare const convertBn254FqToCircuitValue256: (val: Bn254FqPoint) => CircuitValue256;
+ *
+ * @param val
+ * @returns `val` in hi-lo form
+ */
+declare const convertBn254FqToCircuitValue256: (
+ val: Bn254FqPoint
+) => CircuitValue256;
/**
- * @param point The affine point to load, with coordinates `CircuitValue256`. The hi, lo values must have been constrained to be `uint128`s.
- * @returns `Bn254G1AffinePoint`, which has been constrained to lie on the curve. Currently this point is not allowed to be identity (0, 0).
- */
+ * @param point The affine point to load, with coordinates `CircuitValue256`. The hi, lo values must have been constrained to be `uint128`s.
+ * @returns `Bn254G1AffinePoint`, which has been constrained to lie on the curve. Currently this point is not allowed to be identity (0, 0).
+ */
declare const loadBn254G1: (point: CircuitBn254G1Affine) => Bn254G1AffinePoint;
/**
@@ -362,7 +448,9 @@ declare const loadBn254G1: (point: CircuitBn254G1Affine) => Bn254G1AffinePoint;
* @param points - The array of `CircuitBn254G1Affine` points. All coordinates are in hi, lo form, and we assume they have been range checked to be `uint128`s.
* @returns The sum of all these points as `Bn254G1AffinePoint`.
*/
-declare const bn254G1Sum: (points: Array) => Bn254G1AffinePoint
+declare const bn254G1Sum: (
+ points: Array
+) => Bn254G1AffinePoint;
/**
* Subtracts the 2 points and returns the value. Constrains that the points are not equal and also one is not the negative of the other (this would be a point doubling, which requires a different formula).
@@ -371,7 +459,10 @@ declare const bn254G1Sum: (points: Array) => Bn254G1Affine
* @param g1Point1 - G1 point, x,y in hi lo format for each coordinate
* @param g1Point2 - G1 point, x,y in hi lo format for each coordinate
*/
-declare const bn254G1SubUnequal: (g1Point1: CircuitBn254G1Affine, g1Point2: CircuitBn254G1Affine) => Bn254G1AffinePoint;
+declare const bn254G1SubUnequal: (
+ g1Point1: CircuitBn254G1Affine,
+ g1Point2: CircuitBn254G1Affine
+) => Bn254G1AffinePoint;
/**
* @param point The affine point to load, with coordinates `CircuitBn254Fq2`. The hi, lo values must have been constrained to be `uint128`s.
@@ -385,34 +476,47 @@ declare const loadBn254G2: (point: CircuitBn254G2Affine) => Bn254G2AffinePoint;
* @param points - The array of `CircuitBn254G2Affine` points. All coordinates are `CircuitBn254Fq2`, whose coordinates are in hi, lo form, and we assume the hi, lo's have been range checked to be `uint128`s.
* @returns The sum of all these points as `Bn254G2AffinePoint`.
*/
-declare const bn254G2Sum: (points: Array) => Bn254G2AffinePoint;
+declare const bn254G2Sum: (
+ points: Array
+) => Bn254G2AffinePoint;
-/**
+/**
* Verifies that e(lhsG1, lhsG2) = e(rhsG1, rhsG2) by checking e(lhsG1, lhsG2)*e(-rhsG1, rhsG2) === 1
* None of the points should be identity.
- *
+ *
* @param lhsG1
* @param lhsG2
* @param rhsG1
* @param rhsG2
* @returns [CircuitValue] for the result as a boolean (1 if signature verification is successful).
*/
-declare const bn254PairingCheck: (lhsG1: Bn254G1AffinePoint, lhsG2: Bn254G2AffinePoint, rhsG1: Bn254G1AffinePoint, rhsG2: Bn254G2AffinePoint) => CircuitValue;
-
+declare const bn254PairingCheck: (
+ lhsG1: Bn254G1AffinePoint,
+ lhsG2: Bn254G2AffinePoint,
+ rhsG1: Bn254G1AffinePoint,
+ rhsG2: Bn254G2AffinePoint
+) => CircuitValue;
/**
* @param pubkey The public key to load, in the form of an affine elliptic curve point `(x, y)` where `x, y` have type `CircuitValue256`. The hi, lo values of each `CircuitValue256` must have been constrained to be `uint128`s.
* @returns `Secp256k1AffinePoint`, the public key as a loaded elliptic curve point. This has been constrained to lie on the curve. The public key is constrained to not be the identity (0, 0).
*/
-declare const loadSecp256k1Pubkey: (pubkey: CircuitSecp256k1Affine) => Secp256k1AffinePoint;
+declare const loadSecp256k1Pubkey: (
+ pubkey: CircuitSecp256k1Affine
+) => Secp256k1AffinePoint;
/**
- *
+ *
* Verifies the ECDSA signature `(r, s)` with message hash `msgHash` using the secp256k1 public key `pubkey`. Returns 1 if the signature is valid, 0 otherwise.
- * @param pubkey
- * @param r
- * @param s
- * @param msgHash
- * @returns
- */
-declare const verifySecp256k1ECDSASignature: (pubkey: Secp256k1AffinePoint, r: CircuitValue256, s: CircuitValue256, msgHash: CircuitValue256) => CircuitValue;
\ No newline at end of file
+ * @param pubkey
+ * @param r
+ * @param s
+ * @param msgHash
+ * @returns
+ */
+declare const verifySecp256k1ECDSASignature: (
+ pubkey: Secp256k1AffinePoint,
+ r: CircuitValue256,
+ s: CircuitValue256,
+ msgHash: CircuitValue256
+) => CircuitValue;
From 2056cb6987f7490393d3f29af1211771e368d769 Mon Sep 17 00:00:00 2001
From: Jonathan Wang <31040440+jonathanpwang@users.noreply.github.com>
Date: Tue, 31 Oct 2023 21:30:09 -0700
Subject: [PATCH 5/8] [fix] halo2-wasm ecc issues (#36)
Co-authored-by: Roshan <19766713+rpalakkal@users.noreply.github.com>
---
halo2-lib-js/.gitignore | 2 +-
halo2-lib-js/package.json | 7 +-
halo2-lib-js/pnpm-lock.yaml | 8 +-
halo2-lib-js/scripts/convertDTs.js | 2 +-
halo2-lib-js/src/circuit/run.ts | 2 +
halo2-lib-js/src/halo2lib/functions.ts | 56 +++---
halo2-lib-js/src/shared/docs/halo2Docs.d.ts | 199 +++++++-------------
halo2-lib-js/src/shared/docs/halo2Docs.ts | 2 +-
halo2-repl/package.json | 10 +-
halo2-repl/pnpm-lock.yaml | 18 +-
halo2-wasm/Cargo.toml | 2 +-
halo2-wasm/package.json | 2 +-
halo2-wasm/src/halo2lib/ecc.rs | 68 +++++--
13 files changed, 174 insertions(+), 204 deletions(-)
diff --git a/halo2-lib-js/.gitignore b/halo2-lib-js/.gitignore
index 8f1f2a8..adb2fec 100644
--- a/halo2-lib-js/.gitignore
+++ b/halo2-lib-js/.gitignore
@@ -41,4 +41,4 @@ public/kzg_bn256_19.bin
public/kzg_bn256_20.bin
my.d.ts
-src/shared/halo2lib.d.ts
\ No newline at end of file
+src/shared/docs/build.d.ts
\ No newline at end of file
diff --git a/halo2-lib-js/package.json b/halo2-lib-js/package.json
index 6ce5fb0..d97f341 100644
--- a/halo2-lib-js/package.json
+++ b/halo2-lib-js/package.json
@@ -1,10 +1,11 @@
{
"name": "@axiom-crypto/halo2-lib-js",
- "version": "0.2.6",
+ "version": "0.2.9",
"description": "Halo2 Javascript library",
"main": "index.js",
"scripts": {
- "build": "rm -rf ./dist && node ./scripts/convertDTs.js && tsc && node ./scripts/postTsc.js"
+ "build": "rm -rf ./dist && pnpm build:docs && tsc && node ./scripts/postTsc.js",
+ "build:docs": "./node_modules/.bin/dts-bundle-generator src/shared/docs/halo2Docs.d.ts -o src/shared/docs/build.d.ts --external-inlines=@axiom-crypto/halo2-wasm && node ./scripts/convertDTs.js"
},
"keywords": [
"axiom",
@@ -29,7 +30,7 @@
"typescript": "^5.2.2"
},
"dependencies": {
- "@axiom-crypto/halo2-wasm": "0.2.5",
+ "@axiom-crypto/halo2-wasm": "0.2.7",
"ethers": "^6.8.0",
"prettier": "1.18.2"
},
diff --git a/halo2-lib-js/pnpm-lock.yaml b/halo2-lib-js/pnpm-lock.yaml
index ee7e940..f68320f 100644
--- a/halo2-lib-js/pnpm-lock.yaml
+++ b/halo2-lib-js/pnpm-lock.yaml
@@ -6,8 +6,8 @@ settings:
dependencies:
'@axiom-crypto/halo2-wasm':
- specifier: 0.2.5
- version: 0.2.5
+ specifier: 0.2.7
+ version: 0.2.7
ethers:
specifier: ^6.8.0
version: 6.8.0
@@ -58,8 +58,8 @@ packages:
'@jridgewell/trace-mapping': 0.3.20
dev: true
- /@axiom-crypto/halo2-wasm@0.2.5:
- resolution: {integrity: sha512-89Nn9QOhKsVDMjMC35KLqsauVUWQ3K8/62mUjqDurc4hDg2MgAHUEM5DFQK198tJ7zNoEvDvhv+mWzLmDkUvzg==}
+ /@axiom-crypto/halo2-wasm@0.2.7:
+ resolution: {integrity: sha512-pmgFCkCJUlFgh5NCLR59WpWIiBegNxBRAAlA2UxPMga1Pba02ynZgf6SW0tbQaezMiWUdTA9SfpeosovcNI6Yg==}
dev: false
/@babel/code-frame@7.22.13:
diff --git a/halo2-lib-js/scripts/convertDTs.js b/halo2-lib-js/scripts/convertDTs.js
index d8bf37e..b21853c 100644
--- a/halo2-lib-js/scripts/convertDTs.js
+++ b/halo2-lib-js/scripts/convertDTs.js
@@ -1,6 +1,6 @@
const fs = require('fs');
-const halo2libString = fs.readFileSync('src/shared/docs/halo2Docs.d.ts', 'utf8');
+const halo2libString = fs.readFileSync('src/shared/docs/build.d.ts', 'utf8');
const filteredHalo2libString = halo2libString
.split('\n')
.filter(line => !line.trim().startsWith('import'))
diff --git a/halo2-lib-js/src/circuit/run.ts b/halo2-lib-js/src/circuit/run.ts
index 7503ea9..357d986 100644
--- a/halo2-lib-js/src/circuit/run.ts
+++ b/halo2-lib-js/src/circuit/run.ts
@@ -42,6 +42,7 @@ export function Halo2CircuitRunner(circuit: Halo2Wasm, halo2LibWasm: Halo2LibWas
const parsedInputs = parseInputs(inputs);
const fn = eval(`let {${halo2LibFns.join(", ")}} = halo2Lib; (async function({${functionInputs}}) { ${code} })`);
await fn(parsedInputs);
+ circuit.assignInstances();
autoConfigCircuit(circuit, config);
clear();
@@ -62,6 +63,7 @@ export function Halo2CircuitRunner(circuit: Halo2Wasm, halo2LibWasm: Halo2LibWas
let stringifiedInputs = JSON.stringify(inputs);
let parsedInputs = parseInputs(stringifiedInputs);
await f(halo2Lib, parsedInputs);
+ circuit.assignInstances();
}
return Object.freeze({
diff --git a/halo2-lib-js/src/halo2lib/functions.ts b/halo2-lib-js/src/halo2lib/functions.ts
index 75e08aa..7ff100b 100644
--- a/halo2-lib-js/src/halo2lib/functions.ts
+++ b/halo2-lib-js/src/halo2lib/functions.ts
@@ -409,7 +409,7 @@ export class Halo2Lib {
* @returns `Bn254FqPoint` whose internals are opaque to the user.
*/
loadBn254Fq = (val: CircuitValue256): Bn254FqPoint =>{
- return this._halo2lib.load_bn254_fq(toJsCircuitValue256(val));
+ return this._halo2lib.load_bn254_fq(this._toJsCircuitValue256(val));
}
/**
@@ -427,7 +427,7 @@ export class Halo2Lib {
* @returns `Bn254G1AffinePoint`, which has been constrained to lie on the curve. Currently this point is not allowed to be identity (0, 0).
*/
loadBn254G1 = (point: CircuitBn254G1Affine): Bn254G1AffinePoint => {
- return this._halo2lib.load_bn254_g1(toJsCircuitBn254G1Affine(point));
+ return this._halo2lib.load_bn254_g1(this._toJsCircuitBn254G1Affine(point));
}
/**
@@ -437,7 +437,10 @@ export class Halo2Lib {
* @returns The sum of all these points as `Bn254G1AffinePoint`.
*/
bn254G1Sum = (points: Array): Bn254G1AffinePoint => {
- const _points = points.map(toJsCircuitBn254G1Affine);
+ const _points = [];
+ for(let i = 0; i < points.length; i++) {
+ _points.push(this._toJsCircuitBn254G1Affine(points[i]));
+ }
return this._halo2lib.bn254_g1_sum(_points);
};
@@ -450,7 +453,7 @@ export class Halo2Lib {
*/
bn254G1SubUnequal = (g1Point1: CircuitBn254G1Affine, g1Point2: CircuitBn254G1Affine): Bn254G1AffinePoint => {
- return this._halo2lib.bn254_g1_sub_unequal(toJsCircuitBn254G1Affine(g1Point1), toJsCircuitBn254G1Affine(g1Point2));
+ return this._halo2lib.bn254_g1_sub_unequal(this._toJsCircuitBn254G1Affine(g1Point1), this._toJsCircuitBn254G1Affine(g1Point2));
};
/**
@@ -458,7 +461,7 @@ export class Halo2Lib {
* @returns `Bn254G2AffinePoint`, which has been constrained to lie on the curve. Currently this point is not allowed to be identity (Fq2(0), Fq2(0)).
*/
loadBn254G2 = (point: CircuitBn254G2Affine): Bn254G2AffinePoint => {
- return this._halo2lib.load_bn254_g2(toJsCircuitBn254G2Affine(point));
+ return this._halo2lib.load_bn254_g2(this._toJsCircuitBn254G2Affine(point));
}
/**
@@ -468,7 +471,10 @@ export class Halo2Lib {
* @returns The sum of all these points as `Bn254G2AffinePoint`.
*/
bn254G2Sum = (points: Array): Bn254G2AffinePoint => {
- const _points = points.map(toJsCircuitBn254G2Affine);
+ const _points = [];
+ for(let i = 0; i < points.length; i++) {
+ _points.push(this._toJsCircuitBn254G2Affine(points[i]));
+ }
return this._halo2lib.bn254_g2_sum(_points);
}
@@ -491,7 +497,7 @@ export class Halo2Lib {
* @returns `Secp256k1AffinePoint`, the public key as a loaded elliptic curve point. This has been constrained to lie on the curve. The public key is constrained to not be the identity (0, 0).
*/
loadSecp256k1Pubkey = (pubkey: CircuitSecp256k1Affine): Secp256k1AffinePoint => {
- return this._halo2lib.load_secp256k1_pubkey(toJsCircuitSecp256k1Affine(pubkey));
+ return this._halo2lib.load_secp256k1_pubkey(this._toJsCircuitSecp256k1Affine(pubkey));
}
/**
@@ -504,28 +510,26 @@ export class Halo2Lib {
* @returns
*/
verifySecp256k1ECDSASignature = (pubkey: Secp256k1AffinePoint, r: CircuitValue256, s: CircuitValue256, msgHash: CircuitValue256): CircuitValue => {
- return this.Cell(this._halo2lib.verify_secp256k1_ecdsa_signature(pubkey, toJsCircuitValue256(r), toJsCircuitValue256(s), toJsCircuitValue256(msgHash)));
+ return this.Cell(this._halo2lib.verify_secp256k1_ecdsa_signature(pubkey, this._toJsCircuitValue256(r), this._toJsCircuitValue256(s), this._toJsCircuitValue256(msgHash)));
}
-}
-function toJsCircuitValue256(val: CircuitValue256): JsCircuitValue256 {
- return new JsCircuitValue256(val.hi().cell(), val.lo().cell());
-}
+ private _toJsCircuitValue256(val: CircuitValue256) {
+ return this._halo2lib.to_js_circuit_value_256(val.hi().cell(), val.lo().cell());
+ }
-function toJsCircuitBn254G1Affine(point: CircuitBn254G1Affine): JsCircuitBn254G1Affine {
- return new JsCircuitBn254G1Affine(toJsCircuitValue256(point.x), toJsCircuitValue256(point.y));
-}
+ private _toJsCircuitBn254G1Affine(point: CircuitBn254G1Affine) {
+ return this._halo2lib.to_js_circuit_bn254_g1_affine(this._toJsCircuitValue256(point.x), this._toJsCircuitValue256(point.y));
+ }
-function toJsCircuitBn254Fq2(point: CircuitBn254Fq2): JsCircuitBn254Fq2 {
- return new JsCircuitBn254Fq2(toJsCircuitValue256(point.c0), toJsCircuitValue256(point.c1));
-}
+ private _toJsCircuitBn254Fq2(point: CircuitBn254Fq2) {
+ return this._halo2lib.to_js_circuit_bn254_fq2(this._toJsCircuitValue256(point.c0), this._toJsCircuitValue256(point.c1));
+ }
-function toJsCircuitBn254G2Affine(point: CircuitBn254G2Affine): JsCircuitBn254G2Affine {
- const x = toJsCircuitBn254Fq2(point.x);
- const y = toJsCircuitBn254Fq2(point.y);
- return new JsCircuitBn254G2Affine(x,y);
-}
+ private _toJsCircuitBn254G2Affine(point: CircuitBn254G2Affine) {
+ return this._halo2lib.to_js_circuit_bn254_g2_affine(this._toJsCircuitBn254Fq2(point.x), this._toJsCircuitBn254Fq2(point.y));
+ }
-function toJsCircuitSecp256k1Affine(point: CircuitSecp256k1Affine): JsCircuitSecp256k1Affine{
- return new JsCircuitSecp256k1Affine(toJsCircuitValue256(point.x), toJsCircuitValue256(point.y));
-}
+ private _toJsCircuitSecp256k1Affine(point: CircuitSecp256k1Affine) {
+ return this._halo2lib.to_js_circuit_secp256k1_affine(this._toJsCircuitValue256(point.x), this._toJsCircuitValue256(point.y));
+ }
+}
\ No newline at end of file
diff --git a/halo2-lib-js/src/shared/docs/halo2Docs.d.ts b/halo2-lib-js/src/shared/docs/halo2Docs.d.ts
index f7fd553..c84b808 100644
--- a/halo2-lib-js/src/shared/docs/halo2Docs.d.ts
+++ b/halo2-lib-js/src/shared/docs/halo2Docs.d.ts
@@ -1,79 +1,14 @@
// Generated by dts-bundle-generator v8.0.1
-import { Halo2Wasm } from "@axiom-crypto/halo2-wasm/web";
import {
- Bn254FqPoint,
- Bn254G1AffinePoint,
- Bn254G2AffinePoint,
- JsCircuitBn254Fq2,
- JsCircuitBn254G1Affine,
- JsCircuitBn254G2Affine,
- JsCircuitSecp256k1Affine,
- JsCircuitValue256,
- Secp256k1AffinePoint,
+ Bn254FqPoint,
+ Bn254G1AffinePoint,
+ Bn254G2AffinePoint,
+ Secp256k1AffinePoint,
} from "@axiom-crypto/halo2-wasm/web";
-
-declare class CircuitValue {
- private _value;
- private _cell;
- constructor(
- circuit: Halo2Wasm,
- {
- value,
- cell,
- }: {
- value?: bigint | number | string;
- cell?: number;
- }
- );
- cell(): number;
- value(): bigint;
- number(): number;
- address(): string;
-}
-
-declare class CircuitValue256 {
- private _value;
- private _circuitValue;
- private _halo2Lib;
- constructor(
- _halo2Lib: Halo2Wasm,
- {
- value,
- hi,
- lo,
- }: {
- value?: bigint | string | number;
- hi?: CircuitValue;
- lo?: CircuitValue;
- }
- );
- hi(): CircuitValue;
- lo(): CircuitValue;
- hex(): string;
- value(): bigint;
- toCircuitValue(): CircuitValue;
-}
-
-export interface CircuitBn254Fq2 {
- c0: CircuitValue256;
- c1: CircuitValue256;
-}
-
-export interface CircuitBn254G1Affine {
- x: CircuitValue256;
- y: CircuitValue256;
-}
-
-export interface CircuitBn254G2Affine {
- x: CircuitBn254Fq2;
- y: CircuitBn254Fq2;
-}
-
-export interface CircuitSecp256k1Affine {
- x: CircuitValue256;
- y: CircuitValue256;
-}
+import { CircuitValue } from "../../halo2lib/CircuitValue";
+import { CircuitValue256 } from "../../halo2lib/CircuitValue256";
+import { CircuitBn254Fq2, CircuitBn254G1Affine, CircuitBn254G2Affine, CircuitSecp256k1Affine } from "../../halo2lib/ecc";
export type RawCircuitInput = string | number | bigint;
@@ -131,9 +66,9 @@ declare const mul: (a: CircuitValue, b: CircuitValue) => CircuitValue;
* @returns The result of multiplying the first two circuit values and adding the third circuit value.
*/
declare const mulAdd: (
- a: CircuitValue,
- b: CircuitValue,
- c: CircuitValue
+ a: CircuitValue,
+ b: CircuitValue,
+ c: CircuitValue
) => CircuitValue;
/**
* Multiplies a circuit value by the negation of another circuit value.
@@ -164,8 +99,8 @@ declare const assertIsConst: (a: CircuitValue, b: RawCircuitInput) => void;
* @returns The inner product of the two arrays.
*/
declare const innerProduct: (
- a: CircuitValue[],
- b: CircuitValue[]
+ a: CircuitValue[],
+ b: CircuitValue[]
) => CircuitValue;
/**
* Computes the sum of an array of circuit values.
@@ -213,9 +148,9 @@ declare const dec: (a: CircuitValue) => CircuitValue;
* @returns sel ? a : b
*/
declare const select: (
- a: CircuitValue,
- b: CircuitValue,
- sel: CircuitValue
+ a: CircuitValue,
+ b: CircuitValue,
+ sel: CircuitValue
) => CircuitValue;
/**
* Performs a bitwise OR-AND operation on three circuit values.
@@ -226,9 +161,9 @@ declare const select: (
* @returns The result of the OR-AND operation.
*/
declare const orAnd: (
- a: CircuitValue,
- b: CircuitValue,
- c: CircuitValue
+ a: CircuitValue,
+ b: CircuitValue,
+ c: CircuitValue
) => CircuitValue;
/**
* Converts an array of circuit values to an indicator array.
@@ -245,8 +180,8 @@ declare const bitsToIndicator: (bits: CircuitValue[]) => CircuitValue[];
* @returns The indicator circuit value.
*/
declare const idxToIndicator: (
- idx: CircuitValue,
- len: RawCircuitInput
+ idx: CircuitValue,
+ len: RawCircuitInput
) => CircuitValue[];
/**
* Selects circuit values from an array based on an indicator circuit value.
@@ -256,8 +191,8 @@ declare const idxToIndicator: (
* @returns The selected circuit values.
*/
declare const selectByIndicator: (
- arr: CircuitValue[],
- indicator: CircuitValue[]
+ arr: CircuitValue[],
+ indicator: CircuitValue[]
) => CircuitValue;
/**
* Selects a circuit value from an array based on an index circuit value.
@@ -267,8 +202,8 @@ declare const selectByIndicator: (
* @returns The selected circuit value.
*/
declare const selectFromIdx: (
- arr: CircuitValue[],
- idx: CircuitValue
+ arr: CircuitValue[],
+ idx: CircuitValue
) => CircuitValue;
/**
* Checks if a circuit value is zero.
@@ -293,8 +228,8 @@ declare const isEqual: (a: CircuitValue, b: CircuitValue) => CircuitValue;
* @returns The array of bits representing the input circuit value.
*/
declare const numToBits: (
- a: CircuitValue,
- len: RawCircuitInput
+ a: CircuitValue,
+ len: RawCircuitInput
) => CircuitValue[];
/**
* Asserts that two circuit values are equal.
@@ -318,9 +253,9 @@ declare const rangeCheck: (a: CircuitValue, b: RawCircuitInput) => void;
* @param c The range of the circuit values.
*/
declare const checkLessThan: (
- a: CircuitValue,
- b: CircuitValue,
- c?: string
+ a: CircuitValue,
+ b: CircuitValue,
+ c?: string
) => void;
/**
* Checks if the first circuit value is less than the second circuit value.
@@ -331,9 +266,9 @@ declare const checkLessThan: (
* @returns The indicator circuit value representing whether the first input is less than the second input.
*/
declare const isLessThan: (
- a: CircuitValue,
- b: CircuitValue,
- c?: string
+ a: CircuitValue,
+ b: CircuitValue,
+ c?: string
) => CircuitValue;
/**
* Divides two circuit values and returns the quotient.
@@ -344,10 +279,10 @@ declare const isLessThan: (
*
*/
declare const div: (
- a: CircuitValue,
- b: CircuitValue,
- c?: string,
- d?: string
+ a: CircuitValue,
+ b: CircuitValue,
+ c?: string,
+ d?: string
) => CircuitValue;
/**
* Divides two circuit values and returns the remainder.
@@ -358,10 +293,10 @@ declare const div: (
*
*/
declare const mod: (
- a: CircuitValue,
- b: CircuitValue,
- c?: string,
- d?: string
+ a: CircuitValue,
+ b: CircuitValue,
+ c?: string,
+ d?: string
) => CircuitValue;
/**
* Raises a circuit value to the power of another circuit value.
@@ -371,9 +306,9 @@ declare const mod: (
* @returns The result of the exponentiation.
*/
declare const pow: (
- a: CircuitValue,
- b: CircuitValue,
- c?: string
+ a: CircuitValue,
+ b: CircuitValue,
+ c?: string
) => CircuitValue;
/**
* Computes the Poseidon hash of multiple circuit values.
@@ -396,16 +331,16 @@ declare const value: (a: CircuitValue) => any;
*/
declare const log: (...args: any) => void;
declare const console: {
- /**
- * Logs any *non CircuitValue* to the console. Use `log` for logging `CircuitValue`s.
- * @param args The values to log.
- */
- log: (...args: any) => void;
+ /**
+ * Logs any *non CircuitValue* to the console. Use `log` for logging `CircuitValue`s.
+ * @param args The values to log.
+ */
+ log: (...args: any) => void;
};
declare const ecdsaBenchmark: (
- sk: bigint,
- msg_hash: bigint,
- k: bigint
+ sk: bigint,
+ msg_hash: bigint,
+ k: bigint
) => CircuitValue;
/**
@@ -415,8 +350,8 @@ declare const ecdsaBenchmark: (
* @returns
*/
declare const newCircuitValue256: (
- hi: CircuitValue,
- lo: CircuitValue
+ hi: CircuitValue,
+ lo: CircuitValue
) => CircuitValue256;
//ecc
@@ -433,7 +368,7 @@ declare const loadBn254Fq: (val: CircuitValue256) => Bn254FqPoint;
* @returns `val` in hi-lo form
*/
declare const convertBn254FqToCircuitValue256: (
- val: Bn254FqPoint
+ val: Bn254FqPoint
) => CircuitValue256;
/**
@@ -449,7 +384,7 @@ declare const loadBn254G1: (point: CircuitBn254G1Affine) => Bn254G1AffinePoint;
* @returns The sum of all these points as `Bn254G1AffinePoint`.
*/
declare const bn254G1Sum: (
- points: Array
+ points: Array
) => Bn254G1AffinePoint;
/**
@@ -460,8 +395,8 @@ declare const bn254G1Sum: (
* @param g1Point2 - G1 point, x,y in hi lo format for each coordinate
*/
declare const bn254G1SubUnequal: (
- g1Point1: CircuitBn254G1Affine,
- g1Point2: CircuitBn254G1Affine
+ g1Point1: CircuitBn254G1Affine,
+ g1Point2: CircuitBn254G1Affine
) => Bn254G1AffinePoint;
/**
@@ -477,7 +412,7 @@ declare const loadBn254G2: (point: CircuitBn254G2Affine) => Bn254G2AffinePoint;
* @returns The sum of all these points as `Bn254G2AffinePoint`.
*/
declare const bn254G2Sum: (
- points: Array
+ points: Array
) => Bn254G2AffinePoint;
/**
@@ -491,10 +426,10 @@ declare const bn254G2Sum: (
* @returns [CircuitValue] for the result as a boolean (1 if signature verification is successful).
*/
declare const bn254PairingCheck: (
- lhsG1: Bn254G1AffinePoint,
- lhsG2: Bn254G2AffinePoint,
- rhsG1: Bn254G1AffinePoint,
- rhsG2: Bn254G2AffinePoint
+ lhsG1: Bn254G1AffinePoint,
+ lhsG2: Bn254G2AffinePoint,
+ rhsG1: Bn254G1AffinePoint,
+ rhsG2: Bn254G2AffinePoint
) => CircuitValue;
/**
@@ -502,7 +437,7 @@ declare const bn254PairingCheck: (
* @returns `Secp256k1AffinePoint`, the public key as a loaded elliptic curve point. This has been constrained to lie on the curve. The public key is constrained to not be the identity (0, 0).
*/
declare const loadSecp256k1Pubkey: (
- pubkey: CircuitSecp256k1Affine
+ pubkey: CircuitSecp256k1Affine
) => Secp256k1AffinePoint;
/**
@@ -515,8 +450,8 @@ declare const loadSecp256k1Pubkey: (
* @returns
*/
declare const verifySecp256k1ECDSASignature: (
- pubkey: Secp256k1AffinePoint,
- r: CircuitValue256,
- s: CircuitValue256,
- msgHash: CircuitValue256
+ pubkey: Secp256k1AffinePoint,
+ r: CircuitValue256,
+ s: CircuitValue256,
+ msgHash: CircuitValue256
) => CircuitValue;
diff --git a/halo2-lib-js/src/shared/docs/halo2Docs.ts b/halo2-lib-js/src/shared/docs/halo2Docs.ts
index 0f8035b..f655d3a 100644
--- a/halo2-lib-js/src/shared/docs/halo2Docs.ts
+++ b/halo2-lib-js/src/shared/docs/halo2Docs.ts
@@ -1 +1 @@
-export const halo2Docs = "// Generated by dts-bundle-generator v8.0.1\n\n\ndeclare class CircuitValue {\n\tprivate _value;\n\tprivate _cell;\n\tconstructor(circuit: Halo2Wasm, { value, cell }: {\n\t\tvalue?: bigint | number | string;\n\t\tcell?: number;\n\t});\n\tcell(): number;\n\tvalue(): bigint;\n\tnumber(): number;\n\taddress(): string;\n}\n\ndeclare class CircuitValue256 {\n\tprivate _value;\n\tprivate _circuitValue;\n\tprivate _halo2Lib;\n\tconstructor(_halo2Lib: Halo2Wasm, { value, hi, lo, }: {\n\t\tvalue?: bigint | string | number;\n\t\thi?: CircuitValue;\n\t\tlo?: CircuitValue;\n\t});\n\thi(): CircuitValue;\n\tlo(): CircuitValue;\n\thex(): string;\n\tvalue(): bigint;\n\ttoCircuitValue(): CircuitValue;\n}\n\ninterface CircuitBn254Fq2 {\n\tc0: CircuitValue256;\n\tc1: CircuitValue256;\n}\n\ninterface CircuitBn254G1Affine {\n\tx: CircuitValue256;\n\ty: CircuitValue256;\n}\n\ninterface CircuitBn254G2Affine {\n\tx: CircuitBn254Fq2;\n\ty: CircuitBn254Fq2;\n}\n\ninterface CircuitSecp256k1Affine {\n\tx: CircuitValue256;\n\ty: CircuitValue256;\n}\n\n\n\ntype RawCircuitInput = string | number | bigint;\n\n/**\n * Creates a circuit variable from a number, bigint, or string.\n *\n * @param a The raw circuit input.\n * @returns The witness cell.\n */\ndeclare const witness: (a: RawCircuitInput) => CircuitValue;\n/**\n * Creates a circuit constant from a number, bigint, or string.\n *\n * @param a The raw circuit input.\n * @returns The constant cell.\n */\ndeclare const constant: (a: RawCircuitInput) => CircuitValue;\n/**\n * Adds two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The sum of the two circuit values.\n */\ndeclare const add: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Subtracts the second circuit value from the first circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The difference between the two circuit values.\n */\ndeclare const sub: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Negates a circuit value.\n *\n * @param a The circuit value to negate.\n * @returns The negation of the circuit value.\n */\ndeclare const neg: (a: CircuitValue) => CircuitValue;\n/**\n * Multiplies two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The product of the two circuit values.\n */\ndeclare const mul: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Multiplies two circuit values and adds a third circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The third circuit value.\n * @returns The result of multiplying the first two circuit values and adding the third circuit value.\n */\ndeclare const mulAdd: (a: CircuitValue, b: CircuitValue, c: CircuitValue) => CircuitValue;\n/**\n * Multiplies a circuit value by the negation of another circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The result of multiplying the first circuit value by the negation of the second circuit value.\n */\ndeclare const mulNot: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Asserts that a circuit value is a bit.\n *\n * @param a The circuit value to assert.\n */\ndeclare const assertBit: (a: CircuitValue) => void;\n/**\n * Asserts that a circuit value is a constant.\n *\n * @param a The circuit value to assert.\n * @param b The raw circuit input.\n */\ndeclare const assertIsConst: (a: CircuitValue, b: RawCircuitInput) => void;\n/**\n * Computes the inner product of two arrays of circuit values.\n *\n * @param a The first array of circuit values.\n * @param b The second array of circuit values.\n * @returns The inner product of the two arrays.\n */\ndeclare const innerProduct: (a: CircuitValue[], b: CircuitValue[]) => CircuitValue;\n/**\n * Computes the sum of an array of circuit values.\n *\n * @param arr The array of circuit values.\n * @returns The sum of the array of circuit values.\n */\ndeclare const sum: (arr: CircuitValue[]) => CircuitValue;\n/**\n * Performs a bitwise AND operation on two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The result of the bitwise AND operation.\n */\ndeclare const and: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Performs a bitwise OR operation on two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The result of the bitwise OR operation.\n */\ndeclare const or: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Performs a bitwise NOT operation on a circuit value.\n *\n * @param a The circuit value.\n * @returns The result of the bitwise NOT operation.\n */\ndeclare const not: (a: CircuitValue) => CircuitValue;\n/**\n * Decrements a circuit value by 1.\n *\n * @param a The circuit value.\n * @returns The decremented circuit value.\n */\ndeclare const dec: (a: CircuitValue) => CircuitValue;\n/**\n * Selects a circuit value based on a condition.\n *\n * @param a The first circuit value.\n * @param b The first circuit value.\n * @param sel The condition boolean circuit value.\n * @returns sel ? a : b\n */\ndeclare const select: (a: CircuitValue, b: CircuitValue, sel: CircuitValue) => CircuitValue;\n/**\n * Performs a bitwise OR-AND operation on three circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The third circuit value.\n * @returns The result of the OR-AND operation.\n */\ndeclare const orAnd: (a: CircuitValue, b: CircuitValue, c: CircuitValue) => CircuitValue;\n/**\n * Converts an array of circuit values to an indicator array.\n *\n * @param bits The array of circuit values.\n * @returns The indicator circuit value.\n */\ndeclare const bitsToIndicator: (bits: CircuitValue[]) => CircuitValue[];\n/**\n * Converts an index circuit value to an indicator circuit value.\n *\n * @param idx The index circuit value.\n * @param len The length of the indicator circuit value.\n * @returns The indicator circuit value.\n */\ndeclare const idxToIndicator: (idx: CircuitValue, len: RawCircuitInput) => CircuitValue[];\n/**\n * Selects circuit values from an array based on an indicator circuit value.\n *\n * @param arr The array of circuit values.\n * @param indicator The indicator circuit value.\n * @returns The selected circuit values.\n */\ndeclare const selectByIndicator: (arr: CircuitValue[], indicator: CircuitValue[]) => CircuitValue;\n/**\n * Selects a circuit value from an array based on an index circuit value.\n *\n * @param arr The array of circuit values.\n * @param idx The index circuit value.\n * @returns The selected circuit value.\n */\ndeclare const selectFromIdx: (arr: CircuitValue[], idx: CircuitValue) => CircuitValue;\n/**\n * Checks if a circuit value is zero.\n *\n * @param a The circuit value to check.\n * @returns The indicator circuit value representing whether the input is zero.\n */\ndeclare const isZero: (a: CircuitValue) => CircuitValue;\n/**\n * Checks if two circuit values are equal.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The indicator circuit value representing whether the two inputs are equal.\n */\ndeclare const isEqual: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Converts a circuit value to an array of bits.\n *\n * @param a The circuit value to convert.\n * @param len The length of the resulting bit array.\n * @returns The array of bits representing the input circuit value.\n */\ndeclare const numToBits: (a: CircuitValue, len: RawCircuitInput) => CircuitValue[];\n/**\n * Asserts that two circuit values are equal.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n */\ndeclare const checkEqual: (a: CircuitValue, b: CircuitValue) => void;\n/**\n * Checks if a circuit value is within a specified range.\n *\n * @param a The circuit value to check.\n * @param b The range of the circuit value.\n */\ndeclare const rangeCheck: (a: CircuitValue, b: RawCircuitInput) => void;\n/**\n * Checks if the first circuit value is less than the second circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The range of the circuit values.\n */\ndeclare const checkLessThan: (a: CircuitValue, b: CircuitValue, c?: string) => void;\n/**\n * Checks if the first circuit value is less than the second circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The range of the circuit values.\n * @returns The indicator circuit value representing whether the first input is less than the second input.\n */\ndeclare const isLessThan: (a: CircuitValue, b: CircuitValue, c?: string) => CircuitValue;\n/**\n * Divides two circuit values and returns the quotient.\n *\n * @param a The dividend circuit value.\n * @param b The divisor circuit value.\n * @returns The quotient.\n *\n*/\ndeclare const div: (a: CircuitValue, b: CircuitValue, c?: string, d?: string) => CircuitValue;\n/**\n * Divides two circuit values and returns the remainder.\n *\n * @param a The dividend circuit value.\n * @param b The divisor circuit value.\n * @returns The remainder.\n *\n*/\ndeclare const mod: (a: CircuitValue, b: CircuitValue, c?: string, d?: string) => CircuitValue;\n/**\n * Raises a circuit value to the power of another circuit value.\n *\n * @param a The base circuit value.\n * @param b The exponent circuit value.\n * @returns The result of the exponentiation.\n */\ndeclare const pow: (a: CircuitValue, b: CircuitValue, c?: string) => CircuitValue;\n/**\n * Computes the Poseidon hash of multiple circuit values.\n *\n * @param args The circuit values to hash.\n * @returns The hash value.\n */\ndeclare const poseidon: (...args: CircuitValue[]) => CircuitValue;\n/**\n * Retrieves the value of a circuit value.\n *\n * @param a The circuit value.\n * @returns The value of the circuit value.\n */\ndeclare const value: (a: CircuitValue) => any;\n/**\n * Logs the provided *circuit* values to the console. Use `console.log` for normal logging.\n *\n * @param args The `CircuitValue`s to log.\n */\ndeclare const log: (...args: any) => void;\ndeclare const console: {\n\t/**\n\t * Logs any *non CircuitValue* to the console. Use `log` for logging `CircuitValue`s.\n\t * @param args The values to log.\n\t */\n\tlog: (...args: any) => void;\n}\ndeclare const ecdsaBenchmark: (sk: bigint, msg_hash: bigint, k: bigint) => CircuitValue;\n\n//ecc\n\n/**\n * \n * @param val The field point to load, in hi-lo form. The hi, lo values must have been constrained to be `uint128`s.\n * @returns `Bn254FqPoint` whose internals are opaque to the user.\n */\ndeclare const loadBn254Fq: (val: CircuitValue256) => Bn254FqPoint;\n\n/**\n* \n* @param val \n* @returns `val` in hi-lo form\n*/\ndeclare const convertBn254FqToCircuitValue256: (val: Bn254FqPoint) => CircuitValue256;\n\n/**\n\t * @param point The affine point to load, with coordinates `CircuitValue256`. The hi, lo values must have been constrained to be `uint128`s.\n\t * @returns `Bn254G1AffinePoint`, which has been constrained to lie on the curve. Currently this point is not allowed to be identity (0, 0).\n\t */\ndeclare const loadBn254G1: (point: CircuitBn254G1Affine) => Bn254G1AffinePoint;\n\n/**\n * Sums the values of the provided G1 affine points\n *\n * @param points - The array of `CircuitBn254G1Affine` points. All coordinates are in hi, lo form, and we assume they have been range checked to be `uint128`s.\n * @returns The sum of all these points as `Bn254G1AffinePoint`.\n */\ndeclare const bn254G1Sum: (points: Array) => Bn254G1AffinePoint\n\n/**\n * Subtracts the 2 points and returns the value. Constrains that the points are not equal and also one is not the negative of the other (this would be a point doubling, which requires a different formula).\n *\n * @returns The subtraction of these points.\n * @param g1Point1 - G1 point, x,y in hi lo format for each coordinate\n * @param g1Point2 - G1 point, x,y in hi lo format for each coordinate\n */\ndeclare const bn254G1SubUnequal: (g1Point1: CircuitBn254G1Affine, g1Point2: CircuitBn254G1Affine) => Bn254G1AffinePoint;\n\n/**\n * @param point The affine point to load, with coordinates `CircuitBn254Fq2`. The hi, lo values must have been constrained to be `uint128`s.\n * @returns `Bn254G2AffinePoint`, which has been constrained to lie on the curve. Currently this point is not allowed to be identity (Fq2(0), Fq2(0)).\n */\ndeclare const loadBn254G2: (point: CircuitBn254G2Affine) => Bn254G2AffinePoint;\n\n/**\n * Sums the values of the provided G2 affine points\n *\n * @param points - The array of `CircuitBn254G2Affine` points. All coordinates are `CircuitBn254Fq2`, whose coordinates are in hi, lo form, and we assume the hi, lo's have been range checked to be `uint128`s.\n * @returns The sum of all these points as `Bn254G2AffinePoint`.\n */\ndeclare const bn254G2Sum: (points: Array) => Bn254G2AffinePoint;\n\n/** \n * Verifies that e(lhsG1, lhsG2) = e(rhsG1, rhsG2) by checking e(lhsG1, lhsG2)*e(-rhsG1, rhsG2) === 1\n * None of the points should be identity.\n * \n * @param lhsG1\n * @param lhsG2\n * @param rhsG1\n * @param rhsG2\n * @returns [CircuitValue] for the result as a boolean (1 if signature verification is successful).\n */\ndeclare const bn254PairingCheck: (lhsG1: Bn254G1AffinePoint, lhsG2: Bn254G2AffinePoint, rhsG1: Bn254G1AffinePoint, rhsG2: Bn254G2AffinePoint) => CircuitValue;\n\n\n/**\n * @param pubkey The public key to load, in the form of an affine elliptic curve point `(x, y)` where `x, y` have type `CircuitValue256`. The hi, lo values of each `CircuitValue256` must have been constrained to be `uint128`s.\n * @returns `Secp256k1AffinePoint`, the public key as a loaded elliptic curve point. This has been constrained to lie on the curve. The public key is constrained to not be the identity (0, 0).\n */\ndeclare const loadSecp256k1Pubkey: (pubkey: CircuitSecp256k1Affine) => Secp256k1AffinePoint;\n\n/**\n * \n * Verifies the ECDSA signature `(r, s)` with message hash `msgHash` using the secp256k1 public key `pubkey`. Returns 1 if the signature is valid, 0 otherwise.\n * @param pubkey \n * @param r \n * @param s \n * @param msgHash \n * @returns \n */\ndeclare const verifySecp256k1ECDSASignature: (pubkey: Secp256k1AffinePoint, r: CircuitValue256, s: CircuitValue256, msgHash: CircuitValue256) => CircuitValue;";
\ No newline at end of file
+export const halo2Docs = "// Generated by dts-bundle-generator v8.1.2\n\ninterface CircuitStats {\n\tadvice: number;\n\tlookup: number;\n\tfixed: number;\n\tinstance: number;\n\tk: number;\n}\ninterface CircuitConfig {\n\tk: number;\n\tnumAdvice: number;\n\tnumLookupAdvice: number;\n\tnumInstance: number;\n\tnumLookupBits: number;\n\tnumVirtualInstance: number;\n}\ndeclare class Bn254Fq2Point {\n\tfree(): void;\n\t/**\n\t* @returns {Bn254FqPoint}\n\t*/\n\tc0(): Bn254FqPoint;\n\t/**\n\t* @returns {Bn254FqPoint}\n\t*/\n\tc1(): Bn254FqPoint;\n}\ndeclare class Bn254FqPoint {\n\tfree(): void;\n\t/**\n\t* @param {Halo2LibWasm} lib_wasm\n\t* @returns {JsCircuitValue256}\n\t*/\n\tto_circuit_value_256(lib_wasm: Halo2LibWasm): JsCircuitValue256;\n}\ndeclare class Bn254G1AffinePoint {\n\tfree(): void;\n\t/**\n\t* @returns {Bn254FqPoint}\n\t*/\n\tx(): Bn254FqPoint;\n\t/**\n\t* @returns {Bn254FqPoint}\n\t*/\n\ty(): Bn254FqPoint;\n}\ndeclare class Bn254G2AffinePoint {\n\tfree(): void;\n\t/**\n\t* @returns {Bn254Fq2Point}\n\t*/\n\tx(): Bn254Fq2Point;\n\t/**\n\t* @returns {Bn254Fq2Point}\n\t*/\n\ty(): Bn254Fq2Point;\n}\ndeclare class Halo2LibWasm {\n\tfree(): void;\n\t/**\n\t* Takes in CircuitValue256 in hi-lo form and loads internal CircuitBn254Fq type (we use 3 limbs of 88 bits).\n\t* This function does not range check `hi,lo` to be `uint128` in case it's already done elsewhere.\n\t* @param {JsCircuitValue256} val\n\t* @returns {Bn254FqPoint}\n\t*/\n\tload_bn254_fq(val: JsCircuitValue256): Bn254FqPoint;\n\t/**\n\t* Doesn't range check limbs of g1_point.\n\t* Does not allow you to load identity point.\n\t* @param {JsCircuitBn254G1Affine} point\n\t* @returns {Bn254G1AffinePoint}\n\t*/\n\tload_bn254_g1(point: JsCircuitBn254G1Affine): Bn254G1AffinePoint;\n\t/**\n\t* `g1_points` should be array of `CircuitBn254G1Affine` in hi-lo form.\n\t* This function does not range check `hi,lo` to be `uint128` in case it's already done elsewhere.\n\t* Prevents any g1_points from being identity.\n\t* @param {Array} g1_points\n\t* @returns {Bn254G1AffinePoint}\n\t*/\n\tbn254_g1_sum(g1_points: Array): Bn254G1AffinePoint;\n\t/**\n\t* `g1_point_1` and `g1_point_2` are `CircuitBn254G1Affine` points in hi-lo form.\n\t* This function does not range check `hi,lo` to be `uint128` in case it's already done elsewhere\n\t* and also it constraints that g1_point_1.x != g1_point_2.x\n\t* Prevents any g1_points from being identity.\n\t* @param {JsCircuitBn254G1Affine} g1_point_1\n\t* @param {JsCircuitBn254G1Affine} g1_point_2\n\t* @returns {Bn254G1AffinePoint}\n\t*/\n\tbn254_g1_sub_unequal(g1_point_1: JsCircuitBn254G1Affine, g1_point_2: JsCircuitBn254G1Affine): Bn254G1AffinePoint;\n\t/**\n\t* Doesn't range check limbs of g2_point.\n\t* Does not allow you to load identity point.\n\t* @param {JsCircuitBn254G2Affine} point\n\t* @returns {Bn254G2AffinePoint}\n\t*/\n\tload_bn254_g2(point: JsCircuitBn254G2Affine): Bn254G2AffinePoint;\n\t/**\n\t* `g2_points` should be array of `CircuitBn254G2Affine` in hi-lo form.\n\t* This function does not range check `hi,lo` to be `uint128` in case it's already done elsewhere.\n\t* Prevents any g2_points from being identity.\n\t* @param {Array} g2_points\n\t* @returns {Bn254G2AffinePoint}\n\t*/\n\tbn254_g2_sum(g2_points: Array): Bn254G2AffinePoint;\n\t/**\n\t* Verifies that e(lhs_g1, lhs_g2) = e(rhs_g1, rhs_g2) by checking e(lhs_g1, lhs_g2)*e(-rhs_g1, rhs_g2) === 1\n\t* Returns [CircuitValue] for the result as a boolean (1 if signature verification is successful).\n\t* None of the points should be identity.\n\t* @param {Bn254G1AffinePoint} lhs_g1\n\t* @param {Bn254G2AffinePoint} lhs_g2\n\t* @param {Bn254G1AffinePoint} rhs_g1\n\t* @param {Bn254G2AffinePoint} rhs_g2\n\t* @returns {number}\n\t*/\n\tbn254_pairing_check(lhs_g1: Bn254G1AffinePoint, lhs_g2: Bn254G2AffinePoint, rhs_g1: Bn254G1AffinePoint, rhs_g2: Bn254G2AffinePoint): number;\n\t/**\n\t* Doesn't range check limbs of point.\n\t* Pubkey is a point on\n\t* @param {JsCircuitSecp256k1Affine} point\n\t* @returns {Secp256k1AffinePoint}\n\t*/\n\tload_secp256k1_pubkey(point: JsCircuitSecp256k1Affine): Secp256k1AffinePoint;\n\t/**\n\t* Assumes all `JsCircuitValue256` limbs have been range checked to be `u128`.\n\t* @param {Secp256k1AffinePoint} pubkey\n\t* @param {JsCircuitValue256} r\n\t* @param {JsCircuitValue256} s\n\t* @param {JsCircuitValue256} msg_hash\n\t* @returns {number}\n\t*/\n\tverify_secp256k1_ecdsa_signature(pubkey: Secp256k1AffinePoint, r: JsCircuitValue256, s: JsCircuitValue256, msg_hash: JsCircuitValue256): number;\n\t/**\n\t* @param {bigint} sk\n\t* @param {bigint} msg_hash\n\t* @param {bigint} k\n\t* @returns {number}\n\t*/\n\tecdsa_benchmark(sk: bigint, msg_hash: bigint, k: bigint): number;\n\t/**\n\t* @param {number} hi\n\t* @param {number} lo\n\t* @returns {JsCircuitValue256}\n\t*/\n\tto_js_circuit_value_256(hi: number, lo: number): JsCircuitValue256;\n\t/**\n\t* @param {JsCircuitValue256} x\n\t* @param {JsCircuitValue256} y\n\t* @returns {JsCircuitBn254G1Affine}\n\t*/\n\tto_js_circuit_bn254_g1_affine(x: JsCircuitValue256, y: JsCircuitValue256): JsCircuitBn254G1Affine;\n\t/**\n\t* @param {JsCircuitValue256} c0\n\t* @param {JsCircuitValue256} c1\n\t* @returns {JsCircuitBn254Fq2}\n\t*/\n\tto_js_circuit_bn254_fq2(c0: JsCircuitValue256, c1: JsCircuitValue256): JsCircuitBn254Fq2;\n\t/**\n\t* @param {JsCircuitBn254Fq2} x\n\t* @param {JsCircuitBn254Fq2} y\n\t* @returns {JsCircuitBn254G2Affine}\n\t*/\n\tto_js_circuit_bn254_g2_affine(x: JsCircuitBn254Fq2, y: JsCircuitBn254Fq2): JsCircuitBn254G2Affine;\n\t/**\n\t* @param {JsCircuitValue256} x\n\t* @param {JsCircuitValue256} y\n\t* @returns {JsCircuitSecp256k1Affine}\n\t*/\n\tto_js_circuit_secp256k1_affine(x: JsCircuitValue256, y: JsCircuitValue256): JsCircuitSecp256k1Affine;\n\t/**\n\t* @param {Halo2Wasm} circuit\n\t*/\n\tconstructor(circuit: Halo2Wasm);\n\t/**\n\t*/\n\tconfig(): void;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t* @returns {number}\n\t*/\n\tadd(a: number, b: number): number;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t* @returns {number}\n\t*/\n\tsub(a: number, b: number): number;\n\t/**\n\t* @param {number} a\n\t* @returns {number}\n\t*/\n\tneg(a: number): number;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t* @returns {number}\n\t*/\n\tmul(a: number, b: number): number;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t* @param {number} c\n\t* @returns {number}\n\t*/\n\tmul_add(a: number, b: number, c: number): number;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t* @returns {number}\n\t*/\n\tmul_not(a: number, b: number): number;\n\t/**\n\t* @param {number} a\n\t*/\n\tassert_bit(a: number): void;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t* @returns {number}\n\t*/\n\tdiv_unsafe(a: number, b: number): number;\n\t/**\n\t* @param {number} a\n\t* @param {string} b\n\t*/\n\tassert_is_const(a: number, b: string): void;\n\t/**\n\t* @param {Uint32Array} a\n\t* @param {Uint32Array} b\n\t* @returns {number}\n\t*/\n\tinner_product(a: Uint32Array, b: Uint32Array): number;\n\t/**\n\t* @param {Uint32Array} a\n\t* @returns {number}\n\t*/\n\tsum(a: Uint32Array): number;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t* @returns {number}\n\t*/\n\tand(a: number, b: number): number;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t* @returns {number}\n\t*/\n\tor(a: number, b: number): number;\n\t/**\n\t* @param {number} a\n\t* @returns {number}\n\t*/\n\tnot(a: number): number;\n\t/**\n\t* @param {number} a\n\t* @returns {number}\n\t*/\n\tdec(a: number): number;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t* @param {number} sel\n\t* @returns {number}\n\t*/\n\tselect(a: number, b: number, sel: number): number;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t* @param {number} c\n\t* @returns {number}\n\t*/\n\tor_and(a: number, b: number, c: number): number;\n\t/**\n\t* @param {Uint32Array} a\n\t* @returns {Uint32Array}\n\t*/\n\tbits_to_indicator(a: Uint32Array): Uint32Array;\n\t/**\n\t* @param {number} a\n\t* @param {string} b\n\t* @returns {Uint32Array}\n\t*/\n\tidx_to_indicator(a: number, b: string): Uint32Array;\n\t/**\n\t* @param {Uint32Array} a\n\t* @param {Uint32Array} indicator\n\t* @returns {number}\n\t*/\n\tselect_by_indicator(a: Uint32Array, indicator: Uint32Array): number;\n\t/**\n\t* @param {Uint32Array} a\n\t* @param {number} idx\n\t* @returns {number}\n\t*/\n\tselect_from_idx(a: Uint32Array, idx: number): number;\n\t/**\n\t* @param {number} a\n\t* @returns {number}\n\t*/\n\tis_zero(a: number): number;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t* @returns {number}\n\t*/\n\tis_equal(a: number, b: number): number;\n\t/**\n\t* @param {number} a\n\t* @param {string} num_bits\n\t* @returns {Uint32Array}\n\t*/\n\tnum_to_bits(a: number, num_bits: string): Uint32Array;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t*/\n\tconstrain_equal(a: number, b: number): void;\n\t/**\n\t* @param {number} a\n\t* @param {string} b\n\t*/\n\trange_check(a: number, b: string): void;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t* @param {string} size\n\t*/\n\tcheck_less_than(a: number, b: number, size: string): void;\n\t/**\n\t* @param {number} a\n\t* @param {string} b\n\t*/\n\tcheck_less_than_safe(a: number, b: string): void;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t* @param {string} size\n\t* @returns {number}\n\t*/\n\tis_less_than(a: number, b: number, size: string): number;\n\t/**\n\t* @param {number} a\n\t* @param {string} b\n\t* @returns {number}\n\t*/\n\tis_less_than_safe(a: number, b: string): number;\n\t/**\n\t* @param {number} a\n\t* @param {string} b\n\t* @param {string} size\n\t* @returns {Uint32Array}\n\t*/\n\tdiv_mod(a: number, b: string, size: string): Uint32Array;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t* @param {string} a_size\n\t* @param {string} b_size\n\t* @returns {Uint32Array}\n\t*/\n\tdiv_mod_var(a: number, b: number, a_size: string, b_size: string): Uint32Array;\n\t/**\n\t* @param {number} a\n\t* @param {number} b\n\t* @param {string} max_bits\n\t* @returns {number}\n\t*/\n\tpow_var(a: number, b: number, max_bits: string): number;\n\t/**\n\t* @param {Uint32Array} a\n\t* @returns {number}\n\t*/\n\tposeidon(a: Uint32Array): number;\n\t/**\n\t* @param {string} val\n\t* @returns {number}\n\t*/\n\twitness(val: string): number;\n\t/**\n\t* @param {string} val\n\t* @returns {number}\n\t*/\n\tconstant(val: string): number;\n\t/**\n\t* @param {Halo2Wasm} circuit\n\t* @param {number} a\n\t* @param {number} col\n\t*/\n\tmake_public(circuit: Halo2Wasm, a: number, col: number): void;\n\t/**\n\t* @param {Halo2Wasm} circuit\n\t* @param {number} a\n\t*/\n\tlog(circuit: Halo2Wasm, a: number): void;\n\t/**\n\t* @param {number} a\n\t* @returns {string}\n\t*/\n\tvalue(a: number): string;\n\t/**\n\t* @returns {number}\n\t*/\n\tlookup_bits(): number;\n}\ndeclare class Halo2Wasm {\n\tfree(): void;\n\t/**\n\t*/\n\tconstructor();\n\t/**\n\t*/\n\tclear(): void;\n\t/**\n\t*/\n\tclearInstances(): void;\n\t/**\n\t* @param {Uint8Array} proof\n\t*/\n\tverify(proof: Uint8Array): void;\n\t/**\n\t* @param {number} col\n\t* @returns {Uint32Array}\n\t*/\n\tgetInstances(col: number): Uint32Array;\n\t/**\n\t* @param {Uint32Array} instances\n\t* @param {number} col\n\t*/\n\tsetInstances(instances: Uint32Array, col: number): void;\n\t/**\n\t* @param {number} col\n\t* @returns {any}\n\t*/\n\tgetInstanceValues(col: number): any;\n\t/**\n\t* @param {CircuitConfig} config\n\t*/\n\tconfig(config: CircuitConfig): void;\n\t/**\n\t* @returns {CircuitStats}\n\t*/\n\tgetCircuitStats(): CircuitStats;\n\t/**\n\t* @returns {Uint8Array}\n\t*/\n\tgetVk(): Uint8Array;\n\t/**\n\t* @returns {Uint8Array}\n\t*/\n\tgetPartialVk(): Uint8Array;\n\t/**\n\t* @returns {Uint8Array}\n\t*/\n\tgetPk(): Uint8Array;\n\t/**\n\t*/\n\tassignInstances(): void;\n\t/**\n\t*/\n\tmock(): void;\n\t/**\n\t* @param {Uint8Array} params\n\t*/\n\tloadParams(params: Uint8Array): void;\n\t/**\n\t* @param {Uint8Array} vk\n\t*/\n\tloadVk(vk: Uint8Array): void;\n\t/**\n\t* @param {Uint8Array} pk\n\t*/\n\tloadPk(pk: Uint8Array): void;\n\t/**\n\t*/\n\tgenVk(): void;\n\t/**\n\t*/\n\tgenPk(): void;\n\t/**\n\t* @returns {Uint8Array}\n\t*/\n\tprove(): Uint8Array;\n\t/**\n\t* For console logging only.\n\t* @param {string} a\n\t*/\n\tlog(a: string): void;\n}\ndeclare class JsCircuitBn254Fq2 {\n\tfree(): void;\n\t/**\n\t* @param {JsCircuitValue256} c0\n\t* @param {JsCircuitValue256} c1\n\t*/\n\tconstructor(c0: JsCircuitValue256, c1: JsCircuitValue256);\n\t/**\n\t*/\n\tc0: JsCircuitValue256;\n\t/**\n\t*/\n\tc1: JsCircuitValue256;\n}\ndeclare class JsCircuitBn254G1Affine {\n\tfree(): void;\n\t/**\n\t* @param {JsCircuitValue256} x\n\t* @param {JsCircuitValue256} y\n\t*/\n\tconstructor(x: JsCircuitValue256, y: JsCircuitValue256);\n\t/**\n\t*/\n\tx: JsCircuitValue256;\n\t/**\n\t*/\n\ty: JsCircuitValue256;\n}\ndeclare class JsCircuitBn254G2Affine {\n\tfree(): void;\n\t/**\n\t* @param {JsCircuitBn254Fq2} x\n\t* @param {JsCircuitBn254Fq2} y\n\t*/\n\tconstructor(x: JsCircuitBn254Fq2, y: JsCircuitBn254Fq2);\n\t/**\n\t*/\n\tx: JsCircuitBn254Fq2;\n\t/**\n\t*/\n\ty: JsCircuitBn254Fq2;\n}\ndeclare class JsCircuitSecp256k1Affine {\n\tfree(): void;\n\t/**\n\t* @param {JsCircuitValue256} x\n\t* @param {JsCircuitValue256} y\n\t*/\n\tconstructor(x: JsCircuitValue256, y: JsCircuitValue256);\n\t/**\n\t*/\n\tx: JsCircuitValue256;\n\t/**\n\t*/\n\ty: JsCircuitValue256;\n}\ndeclare class JsCircuitValue256 {\n\tfree(): void;\n\t/**\n\t* @param {number} hi\n\t* @param {number} lo\n\t*/\n\tconstructor(hi: number, lo: number);\n\t/**\n\t*/\n\thi: number;\n\t/**\n\t*/\n\tlo: number;\n}\ndeclare class Secp256k1AffinePoint {\n\tfree(): void;\n\t/**\n\t* @returns {Secp256k1FpPoint}\n\t*/\n\tx(): Secp256k1FpPoint;\n\t/**\n\t* @returns {Secp256k1FpPoint}\n\t*/\n\ty(): Secp256k1FpPoint;\n}\ndeclare class Secp256k1FpPoint {\n\tfree(): void;\n\t/**\n\t* @param {Halo2LibWasm} lib_wasm\n\t* @returns {JsCircuitValue256}\n\t*/\n\tto_circuit_value_256(lib_wasm: Halo2LibWasm): JsCircuitValue256;\n}\ndeclare class CircuitValue256 {\n\tprivate _value;\n\tprivate _circuitValue;\n\tprivate _halo2Lib;\n\tconstructor(_halo2Lib: Halo2LibWasm, { value, hi, lo, }: {\n\t\tvalue?: bigint | string | number;\n\t\thi?: CircuitValue;\n\t\tlo?: CircuitValue;\n\t});\n\thi(): CircuitValue;\n\tlo(): CircuitValue;\n\thex(): string;\n\tvalue(): bigint;\n\ttoCircuitValue(): CircuitValue;\n}\ndeclare class CircuitValue {\n\tprivate _value;\n\tprivate _cell;\n\tprivate _circuit;\n\tconstructor(circuit: Halo2LibWasm, { value, cell }: {\n\t\tvalue?: bigint | number | string;\n\t\tcell?: number;\n\t});\n\tcell(): number;\n\tvalue(): bigint;\n\tnumber(): number;\n\taddress(): string;\n\ttoCircuitValue256(): CircuitValue256;\n}\ninterface CircuitBn254Fq2 {\n\tc0: CircuitValue256;\n\tc1: CircuitValue256;\n}\ninterface CircuitBn254G1Affine {\n\tx: CircuitValue256;\n\ty: CircuitValue256;\n}\ninterface CircuitBn254G2Affine {\n\tx: CircuitBn254Fq2;\n\ty: CircuitBn254Fq2;\n}\ninterface CircuitSecp256k1Affine {\n\tx: CircuitValue256;\n\ty: CircuitValue256;\n}\ntype RawCircuitInput = string | number | bigint;\n/**\n * Creates a circuit variable from a number, bigint, or string.\n *\n * @param a The raw circuit input.\n * @returns The witness cell.\n */\ndeclare const witness: (a: RawCircuitInput) => CircuitValue;\n/**\n * Creates a circuit constant from a number, bigint, or string.\n *\n * @param a The raw circuit input.\n * @returns The constant cell.\n */\ndeclare const constant: (a: RawCircuitInput) => CircuitValue;\n/**\n * Adds two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The sum of the two circuit values.\n */\ndeclare const add: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Subtracts the second circuit value from the first circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The difference between the two circuit values.\n */\ndeclare const sub: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Negates a circuit value.\n *\n * @param a The circuit value to negate.\n * @returns The negation of the circuit value.\n */\ndeclare const neg: (a: CircuitValue) => CircuitValue;\n/**\n * Multiplies two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The product of the two circuit values.\n */\ndeclare const mul: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Multiplies two circuit values and adds a third circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The third circuit value.\n * @returns The result of multiplying the first two circuit values and adding the third circuit value.\n */\ndeclare const mulAdd: (a: CircuitValue, b: CircuitValue, c: CircuitValue) => CircuitValue;\n/**\n * Multiplies a circuit value by the negation of another circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The result of multiplying the first circuit value by the negation of the second circuit value.\n */\ndeclare const mulNot: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Asserts that a circuit value is a bit.\n *\n * @param a The circuit value to assert.\n */\ndeclare const assertBit: (a: CircuitValue) => void;\n/**\n * Asserts that a circuit value is a constant.\n *\n * @param a The circuit value to assert.\n * @param b The raw circuit input.\n */\ndeclare const assertIsConst: (a: CircuitValue, b: RawCircuitInput) => void;\n/**\n * Computes the inner product of two arrays of circuit values.\n *\n * @param a The first array of circuit values.\n * @param b The second array of circuit values.\n * @returns The inner product of the two arrays.\n */\ndeclare const innerProduct: (a: CircuitValue[], b: CircuitValue[]) => CircuitValue;\n/**\n * Computes the sum of an array of circuit values.\n *\n * @param arr The array of circuit values.\n * @returns The sum of the array of circuit values.\n */\ndeclare const sum: (arr: CircuitValue[]) => CircuitValue;\n/**\n * Performs a bitwise AND operation on two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The result of the bitwise AND operation.\n */\ndeclare const and: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Performs a bitwise OR operation on two circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The result of the bitwise OR operation.\n */\ndeclare const or: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Performs a bitwise NOT operation on a circuit value.\n *\n * @param a The circuit value.\n * @returns The result of the bitwise NOT operation.\n */\ndeclare const not: (a: CircuitValue) => CircuitValue;\n/**\n * Decrements a circuit value by 1.\n *\n * @param a The circuit value.\n * @returns The decremented circuit value.\n */\ndeclare const dec: (a: CircuitValue) => CircuitValue;\n/**\n * Selects a circuit value based on a condition.\n *\n * @param a The first circuit value.\n * @param b The first circuit value.\n * @param sel The condition boolean circuit value.\n * @returns sel ? a : b\n */\ndeclare const select: (a: CircuitValue, b: CircuitValue, sel: CircuitValue) => CircuitValue;\n/**\n * Performs a bitwise OR-AND operation on three circuit values.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The third circuit value.\n * @returns The result of the OR-AND operation.\n */\ndeclare const orAnd: (a: CircuitValue, b: CircuitValue, c: CircuitValue) => CircuitValue;\n/**\n * Converts an array of circuit values to an indicator array.\n *\n * @param bits The array of circuit values.\n * @returns The indicator circuit value.\n */\ndeclare const bitsToIndicator: (bits: CircuitValue[]) => CircuitValue[];\n/**\n * Converts an index circuit value to an indicator circuit value.\n *\n * @param idx The index circuit value.\n * @param len The length of the indicator circuit value.\n * @returns The indicator circuit value.\n */\ndeclare const idxToIndicator: (idx: CircuitValue, len: RawCircuitInput) => CircuitValue[];\n/**\n * Selects circuit values from an array based on an indicator circuit value.\n *\n * @param arr The array of circuit values.\n * @param indicator The indicator circuit value.\n * @returns The selected circuit values.\n */\ndeclare const selectByIndicator: (arr: CircuitValue[], indicator: CircuitValue[]) => CircuitValue;\n/**\n * Selects a circuit value from an array based on an index circuit value.\n *\n * @param arr The array of circuit values.\n * @param idx The index circuit value.\n * @returns The selected circuit value.\n */\ndeclare const selectFromIdx: (arr: CircuitValue[], idx: CircuitValue) => CircuitValue;\n/**\n * Checks if a circuit value is zero.\n *\n * @param a The circuit value to check.\n * @returns The indicator circuit value representing whether the input is zero.\n */\ndeclare const isZero: (a: CircuitValue) => CircuitValue;\n/**\n * Checks if two circuit values are equal.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @returns The indicator circuit value representing whether the two inputs are equal.\n */\ndeclare const isEqual: (a: CircuitValue, b: CircuitValue) => CircuitValue;\n/**\n * Converts a circuit value to an array of bits.\n *\n * @param a The circuit value to convert.\n * @param len The length of the resulting bit array.\n * @returns The array of bits representing the input circuit value.\n */\ndeclare const numToBits: (a: CircuitValue, len: RawCircuitInput) => CircuitValue[];\n/**\n * Asserts that two circuit values are equal.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n */\ndeclare const checkEqual: (a: CircuitValue, b: CircuitValue) => void;\n/**\n * Checks if a circuit value is within a specified range.\n *\n * @param a The circuit value to check.\n * @param b The range of the circuit value.\n */\ndeclare const rangeCheck: (a: CircuitValue, b: RawCircuitInput) => void;\n/**\n * Checks if the first circuit value is less than the second circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The range of the circuit values.\n */\ndeclare const checkLessThan: (a: CircuitValue, b: CircuitValue, c?: string) => void;\n/**\n * Checks if the first circuit value is less than the second circuit value.\n *\n * @param a The first circuit value.\n * @param b The second circuit value.\n * @param c The range of the circuit values.\n * @returns The indicator circuit value representing whether the first input is less than the second input.\n */\ndeclare const isLessThan: (a: CircuitValue, b: CircuitValue, c?: string) => CircuitValue;\n/**\n * Divides two circuit values and returns the quotient.\n *\n * @param a The dividend circuit value.\n * @param b The divisor circuit value.\n * @returns The quotient.\n *\n */\ndeclare const div: (a: CircuitValue, b: CircuitValue, c?: string, d?: string) => CircuitValue;\n/**\n * Divides two circuit values and returns the remainder.\n *\n * @param a The dividend circuit value.\n * @param b The divisor circuit value.\n * @returns The remainder.\n *\n */\ndeclare const mod: (a: CircuitValue, b: CircuitValue, c?: string, d?: string) => CircuitValue;\n/**\n * Raises a circuit value to the power of another circuit value.\n *\n * @param a The base circuit value.\n * @param b The exponent circuit value.\n * @returns The result of the exponentiation.\n */\ndeclare const pow: (a: CircuitValue, b: CircuitValue, c?: string) => CircuitValue;\n/**\n * Computes the Poseidon hash of multiple circuit values.\n *\n * @param args The circuit values to hash.\n * @returns The hash value.\n */\ndeclare const poseidon: (...args: CircuitValue[]) => CircuitValue;\n/**\n * Retrieves the value of a circuit value.\n *\n * @param a The circuit value.\n * @returns The value of the circuit value.\n */\ndeclare const value: (a: CircuitValue) => any;\n/**\n * Logs the provided *circuit* values to the console. Use `console.log` for normal logging.\n *\n * @param args The `CircuitValue`s to log.\n */\ndeclare const log: (...args: any) => void;\ndeclare const console: {\n\t/**\n\t * Logs any *non CircuitValue* to the console. Use `log` for logging `CircuitValue`s.\n\t * @param args The values to log.\n\t */\n\tlog: (...args: any) => void;\n};\ndeclare const ecdsaBenchmark: (sk: bigint, msg_hash: bigint, k: bigint) => CircuitValue;\n/**\n * Creates new `CircuitValue256` and range checks `hi, lo` to be `uint128`s.\n * @param hi\n * @param lo\n * @returns\n */\ndeclare const newCircuitValue256: (hi: CircuitValue, lo: CircuitValue) => CircuitValue256;\n//ecc\n/**\n *\n * @param val The field point to load, in hi-lo form. The hi, lo values must have been constrained to be `uint128`s.\n * @returns `Bn254FqPoint` whose internals are opaque to the user.\n */\ndeclare const loadBn254Fq: (val: CircuitValue256) => Bn254FqPoint;\n/**\n *\n * @param val\n * @returns `val` in hi-lo form\n */\ndeclare const convertBn254FqToCircuitValue256: (val: Bn254FqPoint) => CircuitValue256;\n/**\n * @param point The affine point to load, with coordinates `CircuitValue256`. The hi, lo values must have been constrained to be `uint128`s.\n * @returns `Bn254G1AffinePoint`, which has been constrained to lie on the curve. Currently this point is not allowed to be identity (0, 0).\n */\ndeclare const loadBn254G1: (point: CircuitBn254G1Affine) => Bn254G1AffinePoint;\n/**\n * Sums the values of the provided G1 affine points\n *\n * @param points - The array of `CircuitBn254G1Affine` points. All coordinates are in hi, lo form, and we assume they have been range checked to be `uint128`s.\n * @returns The sum of all these points as `Bn254G1AffinePoint`.\n */\ndeclare const bn254G1Sum: (points: Array) => Bn254G1AffinePoint;\n/**\n * Subtracts the 2 points and returns the value. Constrains that the points are not equal and also one is not the negative of the other (this would be a point doubling, which requires a different formula).\n *\n * @returns The subtraction of these points.\n * @param g1Point1 - G1 point, x,y in hi lo format for each coordinate\n * @param g1Point2 - G1 point, x,y in hi lo format for each coordinate\n */\ndeclare const bn254G1SubUnequal: (g1Point1: CircuitBn254G1Affine, g1Point2: CircuitBn254G1Affine) => Bn254G1AffinePoint;\n/**\n * @param point The affine point to load, with coordinates `CircuitBn254Fq2`. The hi, lo values must have been constrained to be `uint128`s.\n * @returns `Bn254G2AffinePoint`, which has been constrained to lie on the curve. Currently this point is not allowed to be identity (Fq2(0), Fq2(0)).\n */\ndeclare const loadBn254G2: (point: CircuitBn254G2Affine) => Bn254G2AffinePoint;\n/**\n * Sums the values of the provided G2 affine points\n *\n * @param points - The array of `CircuitBn254G2Affine` points. All coordinates are `CircuitBn254Fq2`, whose coordinates are in hi, lo form, and we assume the hi, lo's have been range checked to be `uint128`s.\n * @returns The sum of all these points as `Bn254G2AffinePoint`.\n */\ndeclare const bn254G2Sum: (points: Array) => Bn254G2AffinePoint;\n/**\n * Verifies that e(lhsG1, lhsG2) = e(rhsG1, rhsG2) by checking e(lhsG1, lhsG2)*e(-rhsG1, rhsG2) === 1\n * None of the points should be identity.\n *\n * @param lhsG1\n * @param lhsG2\n * @param rhsG1\n * @param rhsG2\n * @returns [CircuitValue] for the result as a boolean (1 if signature verification is successful).\n */\ndeclare const bn254PairingCheck: (lhsG1: Bn254G1AffinePoint, lhsG2: Bn254G2AffinePoint, rhsG1: Bn254G1AffinePoint, rhsG2: Bn254G2AffinePoint) => CircuitValue;\n/**\n * @param pubkey The public key to load, in the form of an affine elliptic curve point `(x, y)` where `x, y` have type `CircuitValue256`. The hi, lo values of each `CircuitValue256` must have been constrained to be `uint128`s.\n * @returns `Secp256k1AffinePoint`, the public key as a loaded elliptic curve point. This has been constrained to lie on the curve. The public key is constrained to not be the identity (0, 0).\n */\ndeclare const loadSecp256k1Pubkey: (pubkey: CircuitSecp256k1Affine) => Secp256k1AffinePoint;\n/**\n *\n * Verifies the ECDSA signature `(r, s)` with message hash `msgHash` using the secp256k1 public key `pubkey`. Returns 1 if the signature is valid, 0 otherwise.\n * @param pubkey\n * @param r\n * @param s\n * @param msgHash\n * @returns\n */\ndeclare const verifySecp256k1ECDSASignature: (pubkey: Secp256k1AffinePoint, r: CircuitValue256, s: CircuitValue256, msgHash: CircuitValue256) => CircuitValue;\n\n{};\n";
\ No newline at end of file
diff --git a/halo2-repl/package.json b/halo2-repl/package.json
index 0546848..9ea471a 100644
--- a/halo2-repl/package.json
+++ b/halo2-repl/package.json
@@ -1,6 +1,6 @@
{
- "name": "axiom-repl-client",
- "version": "0.1.0",
+ "name": "@axiom-crypto/halo2-repl",
+ "version": "0.1.1",
"private": true,
"scripts": {
"dev": "next dev",
@@ -9,8 +9,8 @@
"lint": "next lint"
},
"dependencies": {
- "@axiom-crypto/halo2-lib-js": "0.2.5",
- "@axiom-crypto/halo2-wasm": "0.2.5",
+ "@axiom-crypto/halo2-lib-js": "0.2.9",
+ "@axiom-crypto/halo2-wasm": "0.2.7",
"@devbookhq/splitter": "^1.4.2",
"@headlessui/react": "^1.7.17",
"@heroicons/react": "^2.0.18",
@@ -41,4 +41,4 @@
"devDependencies": {
"@types/prettier": "1.18.2"
}
-}
+}
\ No newline at end of file
diff --git a/halo2-repl/pnpm-lock.yaml b/halo2-repl/pnpm-lock.yaml
index 3583c64..9d7c581 100644
--- a/halo2-repl/pnpm-lock.yaml
+++ b/halo2-repl/pnpm-lock.yaml
@@ -6,11 +6,11 @@ settings:
dependencies:
'@axiom-crypto/halo2-lib-js':
- specifier: 0.2.5
- version: 0.2.5
+ specifier: 0.2.9
+ version: 0.2.9
'@axiom-crypto/halo2-wasm':
- specifier: 0.2.5
- version: 0.2.5
+ specifier: 0.2.7
+ version: 0.2.7
'@devbookhq/splitter':
specifier: ^1.4.2
version: 1.4.2
@@ -127,10 +127,10 @@ packages:
'@jridgewell/trace-mapping': 0.3.19
dev: false
- /@axiom-crypto/halo2-lib-js@0.2.5:
- resolution: {integrity: sha512-DFeG13wo7j1kTsL4Jonl/HcG0UNK4TX8JwQqnkxAo+/KJLj5uvdoDxpjndV4PcUXd8krX6Lwc0KRRjkcCPN9mQ==}
+ /@axiom-crypto/halo2-lib-js@0.2.9:
+ resolution: {integrity: sha512-U6XCsV6qROevV8c4CXSOj7uhPYZG7ugU0NlxvrHJvEOGc0GrNm4INVxByb8Eipq2X32jeP8wO3MMS6GlZUwkwQ==}
dependencies:
- '@axiom-crypto/halo2-wasm': 0.2.5
+ '@axiom-crypto/halo2-wasm': 0.2.7
ethers: 6.8.0
prettier: 1.18.2
transitivePeerDependencies:
@@ -138,8 +138,8 @@ packages:
- utf-8-validate
dev: false
- /@axiom-crypto/halo2-wasm@0.2.5:
- resolution: {integrity: sha512-89Nn9QOhKsVDMjMC35KLqsauVUWQ3K8/62mUjqDurc4hDg2MgAHUEM5DFQK198tJ7zNoEvDvhv+mWzLmDkUvzg==}
+ /@axiom-crypto/halo2-wasm@0.2.7:
+ resolution: {integrity: sha512-pmgFCkCJUlFgh5NCLR59WpWIiBegNxBRAAlA2UxPMga1Pba02ynZgf6SW0tbQaezMiWUdTA9SfpeosovcNI6Yg==}
dev: false
/@babel/code-frame@7.22.13:
diff --git a/halo2-wasm/Cargo.toml b/halo2-wasm/Cargo.toml
index 13dc0cb..6a82e9f 100644
--- a/halo2-wasm/Cargo.toml
+++ b/halo2-wasm/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "halo2-wasm"
-version = "0.2.5"
+version = "0.2.7"
edition = "2021"
[lib]
diff --git a/halo2-wasm/package.json b/halo2-wasm/package.json
index faa15c1..643732e 100644
--- a/halo2-wasm/package.json
+++ b/halo2-wasm/package.json
@@ -1,7 +1,7 @@
{
"name": "@axiom-crypto/halo2-wasm",
"description": "Halo2 wasm bindings",
- "version": "0.2.5",
+ "version": "0.2.7",
"main": "index.js",
"types": "index.d.ts",
"scripts": {
diff --git a/halo2-wasm/src/halo2lib/ecc.rs b/halo2-wasm/src/halo2lib/ecc.rs
index 8f80991..1350c92 100644
--- a/halo2-wasm/src/halo2lib/ecc.rs
+++ b/halo2-wasm/src/halo2lib/ecc.rs
@@ -253,13 +253,11 @@ impl Halo2LibWasm {
.iter()
.map(|x| serde_wasm_bindgen::from_value(x).unwrap())
.collect();
- let mut builder = self.builder.borrow_mut();
- let ctx = builder.main(0);
let g1_points: Vec<_> = g1_points
.into_iter()
.map(|point| self.load_bn254_g1_impl(&g1_chip, point).0)
.collect();
- let sum = g1_chip.sum::(ctx, g1_points);
+ let sum = g1_chip.sum::(self.builder.borrow_mut().main(0), g1_points);
Bn254G1AffinePoint(sum)
}
@@ -274,13 +272,16 @@ impl Halo2LibWasm {
) -> Bn254G1AffinePoint {
let fq_chip = self.bn254_fq_chip();
let g1_chip = EccChip::new(&fq_chip);
- let mut builder = self.builder.borrow_mut();
- let ctx = builder.main(0);
let g1_point_1_loaded: EcPoint =
self.load_bn254_g1_impl(&g1_chip, g1_point_1).0;
let g1_point_2_loaded: EcPoint =
self.load_bn254_g1_impl(&g1_chip, g1_point_2).0;
- let diff = g1_chip.sub_unequal(ctx, g1_point_1_loaded, g1_point_2_loaded, true);
+ let diff = g1_chip.sub_unequal(
+ self.builder.borrow_mut().main(0),
+ g1_point_1_loaded,
+ g1_point_2_loaded,
+ true,
+ );
Bn254G1AffinePoint(diff)
}
@@ -303,13 +304,11 @@ impl Halo2LibWasm {
.iter()
.map(|x| serde_wasm_bindgen::from_value(x).unwrap())
.collect();
- let mut builder = self.builder.borrow_mut();
- let ctx = builder.main(0);
let g2_points: Vec<_> = g2_points
.into_iter()
.map(|point| self.load_bn254_g2_impl(&g2_chip, point).0)
.collect();
- let sum = g2_chip.sum::(ctx, g2_points);
+ let sum = g2_chip.sum::(self.builder.borrow_mut().main(0), g2_points);
Bn254G2AffinePoint(sum)
}
/// Verifies that e(lhs_g1, lhs_g2) = e(rhs_g1, rhs_g2) by checking e(lhs_g1, lhs_g2)*e(-rhs_g1, rhs_g2) === 1
@@ -342,14 +341,12 @@ impl Halo2LibWasm {
/// Pubkey is a point on
pub fn load_secp256k1_pubkey(&self, point: JsCircuitSecp256k1Affine) -> Secp256k1AffinePoint {
let fp_chip = self.secp256k1_fp_chip();
- let mut builder = self.builder.borrow_mut();
- let ctx = builder.main(0);
let [x, y] =
[point.x, point.y].map(|c| self.load_generic_fp_impl::(&fp_chip, c));
let pt = EcPoint::new(x, y);
let chip = EccChip::new(&fp_chip);
// this prevents pubkey from being identity point:
- chip.assert_is_on_curve::(ctx, &pt);
+ chip.assert_is_on_curve::(self.builder.borrow_mut().main(0), &pt);
Secp256k1AffinePoint(pt)
}
@@ -413,6 +410,41 @@ impl Halo2LibWasm {
self.to_js_assigned_value(res)
}
+ pub fn to_js_circuit_value_256(&self, hi: usize, lo: usize) -> JsCircuitValue256 {
+ JsCircuitValue256 {
+ hi,
+ lo
+ }
+ }
+
+ pub fn to_js_circuit_bn254_g1_affine(&self, x: JsCircuitValue256, y: JsCircuitValue256) -> JsCircuitBn254G1Affine {
+ JsCircuitBn254G1Affine {
+ x,
+ y
+ }
+ }
+
+ pub fn to_js_circuit_bn254_fq2(&self, c0: JsCircuitValue256, c1: JsCircuitValue256) -> JsCircuitBn254Fq2 {
+ JsCircuitBn254Fq2 {
+ c0,
+ c1
+ }
+ }
+
+ pub fn to_js_circuit_bn254_g2_affine(&self, x: JsCircuitBn254Fq2, y: JsCircuitBn254Fq2) -> JsCircuitBn254G2Affine {
+ JsCircuitBn254G2Affine {
+ x,
+ y
+ }
+ }
+
+ pub fn to_js_circuit_secp256k1_affine(&self, x: JsCircuitValue256, y: JsCircuitValue256) -> JsCircuitSecp256k1Affine {
+ JsCircuitSecp256k1Affine {
+ x,
+ y
+ }
+ }
+
// private implementations to save recreating chips each time:
// Doesn't range check hi,lo
@@ -440,12 +472,10 @@ impl Halo2LibWasm {
g1_chip: &EccChip>,
point: JsCircuitBn254G1Affine,
) -> Bn254G1AffinePoint {
- let mut builder = self.builder.borrow_mut();
- let ctx = builder.main(0);
let [x, y] = [point.x, point.y]
.map(|c| self.load_generic_fp_impl::(g1_chip.field_chip(), c));
let pt = EcPoint::new(x, y);
- g1_chip.assert_is_on_curve::(ctx, &pt);
+ g1_chip.assert_is_on_curve::(self.builder.borrow_mut().main(0), &pt);
Bn254G1AffinePoint(pt)
}
/// Doesn't range check limbs of g2_point
@@ -455,15 +485,13 @@ impl Halo2LibWasm {
point: JsCircuitBn254G2Affine,
) -> Bn254G2AffinePoint {
let fq_chip = g2_chip.field_chip().fp_chip();
- let mut builder = self.builder.borrow_mut();
- let ctx = builder.main(0);
let [x, y] = [point.x, point.y].map(|c| {
let c0 = self.load_generic_fp_impl::(fq_chip, c.c0);
let c1 = self.load_generic_fp_impl::(fq_chip, c.c1);
FieldVector(vec![c0, c1])
});
let pt = EcPoint::new(x, y);
- g2_chip.assert_is_on_curve::(ctx, &pt);
+ g2_chip.assert_is_on_curve::(self.builder.borrow_mut().main(0), &pt);
Bn254G2AffinePoint(pt)
}
}
@@ -479,7 +507,7 @@ fn constrain_limbs_equality(
assert!(limb_bits <= 128);
assert!(limb_bits > 64);
// limb_bits, 128 - limb_bits
- let (limb0, tmp0) = range.div_mod(ctx, lo, BigUint::one() << limb_bits, 128);
+ let (tmp0, limb0) = range.div_mod(ctx, lo, BigUint::one() << limb_bits, 128);
// limb_bits - (128 - limb_bits) = 2 * limb_bits - 128 > 0
let rem_bits = limb_bits - (128 - limb_bits);
let (limb2, tmp1) = range.div_mod(ctx, hi, BigUint::one() << rem_bits, 128);
@@ -501,7 +529,7 @@ fn convert_3limbs88bits_to_hi_lo(
let range = &lib_wasm.range;
let gate = &range.gate;
let ctx = builder.main(0);
- let (limb1_lo, limb1_hi) = range.div_mod(ctx, limbs[1], BigUint::one() << lo_bits, 88);
+ let (limb1_hi, limb1_lo) = range.div_mod(ctx, limbs[1], BigUint::one() << lo_bits, 88);
let multiplier = biguint_to_fe(&(BigUint::one() << 88));
let lo = gate.mul_add(ctx, limb1_lo, Constant(multiplier), limbs[0]);
let multiplier = biguint_to_fe(&(BigUint::one() << hi_bits));
From fbaa488e5a9c02938bbb2a8cbe0549777c468787 Mon Sep 17 00:00:00 2001
From: Roshan <19766713+rpalakkal@users.noreply.github.com>
Date: Fri, 3 Nov 2023 20:54:04 -0400
Subject: [PATCH 6/8] feat: hi lo conversion (#33)
---
halo2-wasm/Cargo.toml | 1 +
halo2-wasm/src/halo2lib.rs | 70 ++++++++++++++++++++++++++++++++++++--
2 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/halo2-wasm/Cargo.toml b/halo2-wasm/Cargo.toml
index 6a82e9f..783767c 100644
--- a/halo2-wasm/Cargo.toml
+++ b/halo2-wasm/Cargo.toml
@@ -29,6 +29,7 @@ bincode = "1.3"
tsify = "0.4.5"
num-bigint = "0.4"
num-traits = "0.2"
+num-integer = "0.1.45"
[target.'cfg(target_family = "wasm")'.dependencies]
wasm-bindgen-rayon = { version = "1.0" }
diff --git a/halo2-wasm/src/halo2lib.rs b/halo2-wasm/src/halo2lib.rs
index a707b04..39366e0 100644
--- a/halo2-wasm/src/halo2lib.rs
+++ b/halo2-wasm/src/halo2lib.rs
@@ -1,4 +1,4 @@
-use std::cell::RefCell;
+use std::{cell::RefCell, str::FromStr};
use std::rc::Rc;
use halo2_base::{
@@ -11,9 +11,12 @@ use halo2_base::{
poseidon::hasher::{spec::OptimizedPoseidonSpec, PoseidonHasher},
utils::{biguint_to_fe, fe_to_biguint, modulus},
AssignedValue, Context,
- QuantumCell::Existing,
+ QuantumCell::{Constant, Existing},
};
use itertools::Itertools;
+use num_bigint::BigUint;
+use num_integer::Integer;
+use num_traits::One;
use wasm_bindgen::prelude::*;
use crate::Halo2Wasm;
@@ -319,7 +322,7 @@ impl Halo2LibWasm {
pub fn div_mod(&mut self, a: usize, b: &str, size: &str) -> Vec {
let a = self.get_assigned_value(a);
- let b: usize = b.parse().unwrap();
+ let b = BigUint::from_str(b).unwrap();
let size: usize = size.parse().unwrap();
let out = self
.range
@@ -328,6 +331,67 @@ impl Halo2LibWasm {
self.to_js_assigned_values(out)
}
+ pub fn to_hi_lo(&mut self, a: usize) -> Vec {
+ let a = self.get_assigned_value(a);
+ let a_val = a.value();
+ let a_bytes = a_val.to_bytes();
+
+ let mut a_lo_bytes = [0u8; 32];
+ let mut a_hi_bytes = [0u8; 32];
+ a_lo_bytes[..16].copy_from_slice(&a_bytes[..16]);
+ a_hi_bytes[..16].copy_from_slice(&a_bytes[16..]);
+ let a_lo = Fr::from_bytes(&a_lo_bytes).unwrap();
+ let a_hi = Fr::from_bytes(&a_hi_bytes).unwrap();
+
+ let a_lo = self.builder.borrow_mut().main(0).load_witness(a_lo);
+ let a_hi = self.builder.borrow_mut().main(0).load_witness(a_hi);
+
+ let (a_hi_max, a_lo_max) = modulus::().div_mod_floor(&(BigUint::one() << 128));
+
+ //check a_hi < r // 2**128
+ let check_1 = self.range.is_big_less_than_safe(
+ self.builder.borrow_mut().main(0),
+ a_hi,
+ a_hi_max.clone(),
+ );
+
+ //check (a_hi == r // 2 ** 128 AND a_lo < r % 2**128)
+ let a_hi_max_fe = biguint_to_fe::(&a_hi_max);
+ let a_lo_max_fe = biguint_to_fe::(&a_lo_max);
+ let check_2_hi = self.gate.is_equal(
+ self.builder.borrow_mut().main(0),
+ a_hi,
+ Constant(a_hi_max_fe),
+ );
+ self.range.range_check(self.builder.borrow_mut().main(0), a_lo, 128);
+ let check_2_lo =
+ self.range
+ .is_less_than(self.builder.borrow_mut().main(0), a_lo, Constant(a_lo_max_fe), 128);
+ let check_2 = self
+ .gate
+ .and(self.builder.borrow_mut().main(0), check_2_hi, check_2_lo);
+
+ //constrain (check_1 || check_2) == 1
+ let check = self
+ .gate
+ .add(self.builder.borrow_mut().main(0), check_1, check_2);
+ self.gate.assert_is_const(self.builder.borrow_mut().main(0), &check, &Fr::one());
+
+ let a_reconstructed = self.gate.mul_add(
+ self.builder.borrow_mut().main(0),
+ a_hi,
+ Constant(self.gate.pow_of_two()[128]),
+ a_lo,
+ );
+ self.builder
+ .borrow_mut()
+ .main(0)
+ .constrain_equal(&a, &a_reconstructed);
+
+ let out = vec![a_hi, a_lo];
+ self.to_js_assigned_values(out)
+ }
+
pub fn div_mod_var(&mut self, a: usize, b: usize, a_size: &str, b_size: &str) -> Vec {
let a = self.get_assigned_value(a);
let b = self.get_assigned_value(b);
From b7914db663e76ae3ab26a25decfd589fc84016b0 Mon Sep 17 00:00:00 2001
From: Roshan <19766713+rpalakkal@users.noreply.github.com>
Date: Wed, 8 Nov 2023 11:34:07 -0500
Subject: [PATCH 7/8] feat: add function to convert from hi-lo to single
AssignedValue (#39)
---
halo2-wasm/Cargo.toml | 2 +-
halo2-wasm/package.json | 2 +-
halo2-wasm/src/halo2lib.rs | 91 ++++++++++++++++++++++++++------------
3 files changed, 64 insertions(+), 31 deletions(-)
diff --git a/halo2-wasm/Cargo.toml b/halo2-wasm/Cargo.toml
index 783767c..0dd0fb7 100644
--- a/halo2-wasm/Cargo.toml
+++ b/halo2-wasm/Cargo.toml
@@ -1,6 +1,6 @@
[package]
name = "halo2-wasm"
-version = "0.2.7"
+version = "0.2.8"
edition = "2021"
[lib]
diff --git a/halo2-wasm/package.json b/halo2-wasm/package.json
index 643732e..02df4cf 100644
--- a/halo2-wasm/package.json
+++ b/halo2-wasm/package.json
@@ -1,7 +1,7 @@
{
"name": "@axiom-crypto/halo2-wasm",
"description": "Halo2 wasm bindings",
- "version": "0.2.7",
+ "version": "0.2.8",
"main": "index.js",
"types": "index.d.ts",
"scripts": {
diff --git a/halo2-wasm/src/halo2lib.rs b/halo2-wasm/src/halo2lib.rs
index 39366e0..67d6882 100644
--- a/halo2-wasm/src/halo2lib.rs
+++ b/halo2-wasm/src/halo2lib.rs
@@ -1,5 +1,5 @@
-use std::{cell::RefCell, str::FromStr};
use std::rc::Rc;
+use std::{cell::RefCell, str::FromStr};
use halo2_base::{
gates::{
@@ -331,6 +331,11 @@ impl Halo2LibWasm {
self.to_js_assigned_values(out)
}
+ /// Returns a 256-bit hi-lo pair from a single CircuitValue
+ ///
+ /// See `check_hi_lo` for what is constrained.
+ ///
+ /// * `a`: the CircuitValue to split into hi-lo
pub fn to_hi_lo(&mut self, a: usize) -> Vec {
let a = self.get_assigned_value(a);
let a_val = a.value();
@@ -346,27 +351,60 @@ impl Halo2LibWasm {
let a_lo = self.builder.borrow_mut().main(0).load_witness(a_lo);
let a_hi = self.builder.borrow_mut().main(0).load_witness(a_hi);
- let (a_hi_max, a_lo_max) = modulus::().div_mod_floor(&(BigUint::one() << 128));
+ let a_reconstructed = self.check_hi_lo(a_hi, a_lo);
- //check a_hi < r // 2**128
- let check_1 = self.range.is_big_less_than_safe(
- self.builder.borrow_mut().main(0),
- a_hi,
- a_hi_max.clone(),
- );
+ self.builder
+ .borrow_mut()
+ .main(0)
+ .constrain_equal(&a, &a_reconstructed);
- //check (a_hi == r // 2 ** 128 AND a_lo < r % 2**128)
- let a_hi_max_fe = biguint_to_fe::(&a_hi_max);
- let a_lo_max_fe = biguint_to_fe::(&a_lo_max);
- let check_2_hi = self.gate.is_equal(
+ let out = vec![a_hi, a_lo];
+ self.to_js_assigned_values(out)
+ }
+
+ /// Returns a single CircuitValue from a hi-lo pair
+ ///
+ /// NOTE: this can fail if the hi-lo pair is greater than the Fr modulus.
+ /// See `check_hi_lo` for what is constrained.
+ ///
+ /// * `hi`: the high 128 bits of the CircuitValue
+ /// * `lo`: the low 128 bits of the CircuitValue
+ pub fn from_hi_lo(&mut self, hi: usize, lo: usize) -> usize {
+ let hi = self.get_assigned_value(hi);
+ let lo = self.get_assigned_value(lo);
+
+ let out = self.check_hi_lo(hi, lo);
+
+ self.to_js_assigned_value(out)
+ }
+
+ /// Constrains and returns a single CircuitValue from a hi-lo pair
+ ///
+ /// Constrains (hi < r // 2^128) OR (hi == r // 2^128 AND lo < r % 2^128)
+ /// * `hi`: the high 128 bits of the CircuitValue
+ /// * `lo`: the low 128 bits of the CircuitValue
+ fn check_hi_lo(&mut self, hi: AssignedValue, lo: AssignedValue) -> AssignedValue {
+ let (hi_max, lo_max) = modulus::().div_mod_floor(&(BigUint::one() << 128));
+
+ //check hi < r // 2**128
+ let check_1 =
+ self.range
+ .is_big_less_than_safe(self.builder.borrow_mut().main(0), hi, hi_max.clone());
+
+ //check (hi == r // 2 ** 128 AND lo < r % 2**128)
+ let hi_max_fe = biguint_to_fe::(&hi_max);
+ let lo_max_fe = biguint_to_fe::(&lo_max);
+ let check_2_hi =
+ self.gate
+ .is_equal(self.builder.borrow_mut().main(0), hi, Constant(hi_max_fe));
+ self.range
+ .range_check(self.builder.borrow_mut().main(0), lo, 128);
+ let check_2_lo = self.range.is_less_than(
self.builder.borrow_mut().main(0),
- a_hi,
- Constant(a_hi_max_fe),
+ lo,
+ Constant(lo_max_fe),
+ 128,
);
- self.range.range_check(self.builder.borrow_mut().main(0), a_lo, 128);
- let check_2_lo =
- self.range
- .is_less_than(self.builder.borrow_mut().main(0), a_lo, Constant(a_lo_max_fe), 128);
let check_2 = self
.gate
.and(self.builder.borrow_mut().main(0), check_2_hi, check_2_lo);
@@ -375,21 +413,16 @@ impl Halo2LibWasm {
let check = self
.gate
.add(self.builder.borrow_mut().main(0), check_1, check_2);
- self.gate.assert_is_const(self.builder.borrow_mut().main(0), &check, &Fr::one());
+ self.gate
+ .assert_is_const(self.builder.borrow_mut().main(0), &check, &Fr::one());
- let a_reconstructed = self.gate.mul_add(
+ let combined = self.gate.mul_add(
self.builder.borrow_mut().main(0),
- a_hi,
+ hi,
Constant(self.gate.pow_of_two()[128]),
- a_lo,
+ lo,
);
- self.builder
- .borrow_mut()
- .main(0)
- .constrain_equal(&a, &a_reconstructed);
-
- let out = vec![a_hi, a_lo];
- self.to_js_assigned_values(out)
+ combined
}
pub fn div_mod_var(&mut self, a: usize, b: usize, a_size: &str, b_size: &str) -> Vec {
From 5f67a3b214c2d10f59aeb904e56c5d1cd997aaa7 Mon Sep 17 00:00:00 2001
From: Roshan <19766713+rpalakkal@users.noreply.github.com>
Date: Wed, 8 Nov 2023 15:04:28 -0500
Subject: [PATCH 8/8] feat: add unit tests for halo2-wasm (#40)
---
.github/workflows/halo2-wasm-tests.yml | 23 ++
.gitignore | 3 +-
Cargo.toml | 31 ++-
halo2-wasm/.cargo/config.toml | 2 +-
halo2-wasm/.gitignore | 1 +
halo2-wasm/Cargo.toml | 1 +
halo2-wasm/params/kzg_bn254_10.srs | Bin 0 -> 131332 bytes
halo2-wasm/readme.md | 2 +-
halo2-wasm/src/halo2lib.rs | 10 +-
halo2-wasm/src/lib.rs | 3 +
halo2-wasm/src/tests/gate.rs | 334 +++++++++++++++++++++++++
halo2-wasm/src/tests/mod.rs | 3 +
halo2-wasm/src/tests/range.rs | 128 ++++++++++
halo2-wasm/src/tests/utils.rs | 146 +++++++++++
14 files changed, 678 insertions(+), 9 deletions(-)
create mode 100644 .github/workflows/halo2-wasm-tests.yml
create mode 100644 halo2-wasm/params/kzg_bn254_10.srs
create mode 100644 halo2-wasm/src/tests/gate.rs
create mode 100644 halo2-wasm/src/tests/mod.rs
create mode 100644 halo2-wasm/src/tests/range.rs
create mode 100644 halo2-wasm/src/tests/utils.rs
diff --git a/.github/workflows/halo2-wasm-tests.yml b/.github/workflows/halo2-wasm-tests.yml
new file mode 100644
index 0000000..cdb200d
--- /dev/null
+++ b/.github/workflows/halo2-wasm-tests.yml
@@ -0,0 +1,23 @@
+name: halo2-wasm Tests
+
+on:
+ push:
+ paths:
+ - "halo2-wasm/**"
+
+defaults:
+ run:
+ working-directory: halo2-wasm
+
+jobs:
+ halo2-wasm-tests:
+ runs-on: ubuntu-latest-64core-256ram
+ steps:
+ - uses: actions/checkout@v3
+ - name: Build
+ run: |
+ rustup toolchain install nightly-2023-08-12-x86_64-unknown-linux-gnu
+ rustup component add rust-src --toolchain nightly-2023-08-12-x86_64-unknown-linux-gnu
+ cargo build --target=x86_64-unknown-linux-gnu --verbose
+ - name: Test
+ run: cargo test --target=x86_64-unknown-linux-gnu
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index f2f9e58..9377bc1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
target
-Cargo.lock
\ No newline at end of file
+Cargo.lock
+.DS_Store
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index c5ee73b..7c1b8a9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,3 +1,32 @@
[workspace]
members = ["halo2-wasm"]
-resolver = "2"
\ No newline at end of file
+resolver = "2"
+
+[profile.dev]
+opt-level = 3
+debug = 2 # change to 0 or 2 for more or less debug info
+overflow-checks = true
+incremental = true
+
+# Local "release" mode, more optimized than dev but faster to compile than release
+[profile.local]
+inherits = "dev"
+opt-level = 3
+# Set this to 1 or 2 to get more useful backtraces
+debug = 1
+debug-assertions = false
+panic = 'unwind'
+# better recompile times
+incremental = true
+lto = "thin"
+codegen-units = 16
+
+[profile.release]
+opt-level = 3
+debug = false
+debug-assertions = false
+lto = "fat"
+# `codegen-units = 1` can lead to WORSE performance - always bench to find best profile for your machine!
+# codegen-units = 1
+panic = "unwind"
+incremental = false
\ No newline at end of file
diff --git a/halo2-wasm/.cargo/config.toml b/halo2-wasm/.cargo/config.toml
index d8c03ec..43d6b86 100644
--- a/halo2-wasm/.cargo/config.toml
+++ b/halo2-wasm/.cargo/config.toml
@@ -5,4 +5,4 @@ rustflags = ["-C", "target-feature=+atomics,+bulk-memory,+mutable-globals", "-C"
build-std = ["panic_abort", "std"]
[build]
-target = "wasm32-unknown-unknown"
+target = "aarch64-apple-darwin"
diff --git a/halo2-wasm/.gitignore b/halo2-wasm/.gitignore
index 8035057..3d9967a 100644
--- a/halo2-wasm/.gitignore
+++ b/halo2-wasm/.gitignore
@@ -6,3 +6,4 @@ pkg
dist
.vscode
node_modules
+*.bin
diff --git a/halo2-wasm/Cargo.toml b/halo2-wasm/Cargo.toml
index 0dd0fb7..7d2f31b 100644
--- a/halo2-wasm/Cargo.toml
+++ b/halo2-wasm/Cargo.toml
@@ -30,6 +30,7 @@ tsify = "0.4.5"
num-bigint = "0.4"
num-traits = "0.2"
num-integer = "0.1.45"
+paste = "1.0.14"
[target.'cfg(target_family = "wasm")'.dependencies]
wasm-bindgen-rayon = { version = "1.0" }
diff --git a/halo2-wasm/params/kzg_bn254_10.srs b/halo2-wasm/params/kzg_bn254_10.srs
new file mode 100644
index 0000000000000000000000000000000000000000..6c640d76d5e2bb994101fc80068ee5d8b7e7a136
GIT binary patch
literal 131332
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
%kwL
z^TW{sn9Um0)R?2-(bZO05m-uQ-Uj3!SxQD?7VuJxq?Bu;%9|1M3c3z5ej4k+Zm7##
z;(c{5iB9iUhKg)Xn7*3dmn{y*&E>+az`NvfFSYyZzKj0Mg?R+%-{t&T3uiR$e!~dZ
zVbn3F1Vgw*)G^%?VxsGfhVC(2%V#
za*+|Ne!e)Ky84tHt!o3*@*uSuGK1G%mN>2OT^7z#E>SGhmfv2D#~ILU5SRvVJ-8KHOO)4-5ePCSA`I;WO&Dc9szCLGbu0#pn+wH6dHoPDc-q%D5C}S}cb<20L|6mDI=a4zv
zJggmPX9O%)Xyg0%Rvmr?EtN2L0Dz5uCr@{a*J&9LmLDk=a&XJ=7d2f?NeSMPr%nbL
z?v3^$K!W#CX~Q8i1!n;IhkR4f`7>jp@9o^kGqAZ}B&JyV(|Wev{SiT_{r(Dl$Qac(
zX2vq{c3Js(f!nXgGoD!P$WF-?!!Z$XV`3g;e3PrG`6?#1un~Yu#z<>@X_jA<#jcS2
z(Fbxn$TxMM5d@CfyyS!IoMb@bB*}l~m<63{f0R
zR0dRzA0CWXY6L3Ow{G!_Cbg`5A=L>;49`qw%Z
zP&2~~?W7L(g~|(C4^t)WX3ISqjh|D9=$hL_j4kPHR^j*vD&zSbM)jc`rrQssMlSkS
zshO{!0A6>zrDCe)2h9?AcpxU_Bsl=}@zDfHtCyG6%c+wwwvGl+L5)QhRbKht_#|RD
zc0GlqIq)rj+nQ*mSrm?wXE=f`oJnl3HZQi;83H9Us^@7J(mxx&YOK2|r)!_{OqlP1
zk^a%0!tO+H_?d}}wJT1G{+|%2<+ePw1{ppVA5<%7n~pF&CZrp9o}IGj9)Dlz9NY`I
z1XQpCHN}gPALdArNSup6LC-!Mi^CzY<6ij<6!irUN(Ot#$Z3D*h;%+haKg5ZD~b^}
z0*P?S?;M>RmahcgH8FV+0o_h)c(4$`iF>>mC7qiu$Z@yV9fj)22do;}!-3iYR>R)K
zYDOS<-MKFlbIt(spH+ktorTm5w|XX<^se3`2)c0CLNoPH=PJT3TuKb6x5gK%w3Vz%
z+H@$xuzVAX$$NDU(O4Z;_c^6xH29w}VPIxaLdRBQ&-oOgV9??;Z{#CdI6lhXP12H$
z`wef!H83EVy~vYZ+3_4Y_S7l?BA(}&@j`JH(_K%HNu=NOyqGih62_JBk!vFg-rVd3
zZ8v0imr3Ig4$#3JCn|qDkA{XRmXiak-hAd8fCBc<90E<
zf#=LsT&@(m;d+tk7=M_o|6T+*j+D^?OPxTAFP&87H(-xcfHW>TTjZ2C!Ofd$&R*sP
z2xSe$^N+29I|(4(J+*YMgvJ~*Q2f>~MyBm08Ds{4RwN-6^4y`%AHR1SuXf
zR$Je}L~wO|tK}U@K^fPPjfMEzEu4+$TB<(Le}!nm7fH7D!4fpEsShW?i2v8i7dpcS
zCX76rJ~eJVWCINtpvA`r<_NAZ1OW~!K|sX|2h7xisEj^?!)aBN(eZ+w9V%A7XZ|s2
zp@=32k~OcRIzV2z*Hd~JmzF(%${DKmAo=4*z$JKqSRF0W#P@uSP=T2KM_q_8j}UmK
zL>KTush{q6%X8rUqlhoP^l5xI_0MN;2-m$t{aIfxyXZ^jpw{g1N#F-gXeuxG(qZ=;
z5fLSbsl}mR-4jcs`)=s;4fTFOs!D7*E}aBlZK##eD@_dE=l3o#?YhjwPce>Ry%
zmfDcmBQj>HIMxk7*EBk!JG20#-nr;bndeI~cq{W^h&4(7$VA`1<9+gYt
zYg3_n|4R4MsE0Z&eP>)FQVQ=KhNcwaqd_QBT0`LRsdbg5awQL4T6t(j!LE+97Z%;l
zV9FoOcshw&;S>w9Hizp}rL6o@9Ngud&_a=5anRv|12ijpSSYPRC9QFBCA1jkFx*)B
zNv}knuG!A|=yn0-veYVDSv__~H`tWeZlu;8tm&6KeD#o-;i0aZVmYOHrdt98DlbpC
z0xqKDM7r;qOAZSZ$#2(1#JnN3jnFspb+0bI5J#w?Q{mlh<>@X4k0_0YZ+V;zB3aaS
z)u1WU*B=ZfUNh&3fcg~d3|TrY{q8<<(GVBU4(Wsk#9!{Q3BMeaF_X3rfN{+8OS0s1
zr*Q~UQR!Pv9k$B}MX}ejK$|NHOKpMIhQlFA`?jka=~?Qn;4|Z(hdA!pO^XAs1l$a_
zN={(y`+BqB41k)^O;d~JQhZP0-cw=5g6K}jW2P6~xI8qG8pjc04kv9Ls|PY`-2QL(
z8WT6}X@kEPU)>@T3moKAwD>00C23%-qnXQP4|P9D8Xy!@o6n7x8|4owY(@%Hf4?8t
z5G5)YxKcvKJ*NK)^KPzNGA<@!K2aU4q(26P*@3{`uBrCbitXk`021%ltRVwqXT_0hoPM>O+C~MSKLQiP1%BS=6v!ky9%|
zdO!823yu#lApK=2<4y1`saG220Im={PPFb)XAWG}OlAG_1;l8VTW~!YrQ$=0q{j_B
z$fc(Hddg8|aYyNXNaP8#!$}VO8IBcHR<+rcGyo6R4S0gpB3VHE^}Vfa|MET{U?7sR
zi9PYfYTV{2Eu|HfnncIXy)iUzI34p_Zn2wHm^fGAeMWf68$N>|UOFI!@hN%pH#iBT
zbYzMbW_A*5DO?hPuSPK>K{Oo;rwJlbR*1?dGT2b+3NL@+vDOiQ?}0}_^oJEDy|P@2
zvJwE@GXPF-0n!gmn(?iVYw7J^ZNLhYNWa7r1AIf!YI_)Qj+hN6;^6zv-NXgOIOxB5
zdFDLw>mQAVTg%TL??48^+4`vvlnucw4Tip6+avU;HM)ExX6%p@yO+FjWM%}{`GYON
zTKo1F?|24Q|B|x)yWMAkBenc3H9GU+K*koe8eKo-Ea%A&jKIuOm6<8ntWqP=@a@9KKA6((Y_uc>v;GA*C1uCE!Ch8
zQ?u2R*%1II_}Kh5!E3mON1G51Sgz6LN>1RU)lk$b-dZb5TYsidWxCJaC@NUjoevj|
zb6DpsN?Iled7Pf$yiCOy>((}&frKX#9E!X?#|jGgzZ9vt8C(Egq?-f(FVRq)>yMs%
zA775?w2Wj=S1=7+j}=dM=1+mcwi5OzhH!%@ta%Q!ry^XmnOhb!Ng4=e?g#6$YOaC2T1mexAvYJScq45GkdRIEPsr&};gFDf$H?WtoXPe~Kjw=^oz8xS)K
zd2a0uI}9#7SREWW|0pN)>Tvj>?V)x@ZkjK
zZoI9wH;Cl1w}G&{EL}1V6o?5D;_wg{5Hc3pX2R$deyH)XR&w`1Q6AA?iM@p)L!=;!
z9`?B1dP2aJ-`u!$8bXwqLZDzElK1#`kRgClf8Zq-N_*jvE0V9<#2qOmhu1&X0t)2;
z1VKs(=fJy*sGb1)!eSNIMH2GZhB-mBEs+9O#m@F0nOV^G;5=`mtfAu|KB|7`4mGCnf^P)c0(^+lqdKyj9*v-4XWZ
zcmLCEHY14x+D(ZYcNh#Ag%sct-KfgP3E6fh5O|yJ*dviqPxnrMD_D+%VwWDiNd6H@
zA+CJ#T3Di_hF5U`=XLCnlwi>S^j+LrOWXmWOfUC|HslV2P
z6EZec&~gmFPnF>#On{BCa>egmv)(%T*Xvb4?v3g$YNk9`#1}3{17M%ix;TO&3CXoX
zyp%w#cDFw-D(zq6xD>OI-`*!CnEjq5i`K$AVS_%E6raDh#}$Gzi^Brxzpg5F#-Jg3
zmoZ8H+&Ebd%>Sq$zy4QUd6&84CFZnQrFslbRKFNFmA9k}{y$o2A-qcZCgXM-1u!H~
zrgUPDg*r_UM6xQXBHYzoBOhrM6njhdW?_zCs(ROF!W^U3F#a2utF8kv&r`!+!T&|5
zc4I>4hauy}L1H*Xcd6M6tKNM@R5J~P#v~L|To#~VtuZc}|HX!|*Jn}+7!9bllg^^b
zNtg+`PwTTy#?%|brv&`)n}7qzIlG)6X4+^$T3l+)N$L?9W`JHJLf!a7+#TT?$nn_c
z;+a_V7l2+IU5F>z;u#CZ2LiY8G$8pvEY-cij8jMTVyL!8oej2^vquX*Z3+-BwW4av
ztQJ{B73u7g_eu^Y2C=COo%_h`ey64s
zHd{&bOpp(26gV6>mcx(}8&xt?(NGhbSxk=*xkYRHPj&>JC_e~5-_a|@^d-q+wCXe_
zGSkL(eZ9bWJZra*ek~0^y4V>Cm|sP5m9yVcS{xfY1K-Grn&!^={@70Eu0M6dZK4h$
z(V_&0b@nWvLxK44;IY-O=f_0Dy=ZZVCkQv>In5MlGw*y{Cmc%zisQCWYZJfIa6#um
zZ{KH_Dp$GC3W5XwT$ESD;{_R-Y-|#)kh*aX`o|mj{R%&%>UWgcfJthG}yYv)kyjd|^3Gvr0!Ym)?q%
z>+CJ&@^|hIwp%_EjyDga*4LK-C{sEa-$@&jQqrfbpvWE3!3A4+Ak-jtz6iZ@>n$rR
z-s#Nbu8F{yXErw&9{?brF43d03;pG`z^~ml_OeJXQmzvLLK5F
zK(}3~ZA3oxQatAV%HA`0iiGnd6qe1N9<&+i(HmgHX6FCmOnOe!0EeiCCrEXspM@t>
zE*Prp*Hn9}&kzm*%Ky}lP3UDC+i3+Rf(2xZ(EYz;L+g^hA+dt13soNofRYSp?rq1|VvGQK
zcczcvt&;@V?Hne%pc)^8f}qDLN*T&&8a0QeVwWXNg>{Z4$B33ZG(G!t0
zszi;GOR3*mnz9YlWn0x+u_{UQV$@|3zXby+g^bz4tT^!T2Q2E2u5|)_CvPIwNosas
z8WAS*Brvf@<5Td6EGP7O#=-ENOuiDvE-+<3JFn843BFcj4$oM;26cY{GLPNG&QA_(kX0Jv<-U%nM*99ngpQViz+dk135?A~
z4jKd@9Rvie@jD8iK$qH`mq2h@g~<4Ifh=b7;KJu!_Pmt!*k}^u=TAX=DSv+tby?CP
zuK~mh11M}ib%o4+=!uf_L8A;Qvf!3wt#Dk$MeMmcswWEZsPdGczg^&{>V0~s{0|eVgqM?1XhLwj
zO1b1|LI;FQwW=w4=}`#qd+{F>i*&|+p1Y9N&Ya_&XuIX9az)ZL-#r#2J4)1^{L`+?
zWBKy6iuQXFq5mh240R1d>3ci&tVkxu@Mm
z5KjvR6QK*$Gr<)L=Ef3zC0#rr=UF2M&|iIF>JN5i1@V(ps&P7`*D}vF{05$FY3C@*Wjc`T$9KwLMoW31o*js6s{z
zV>C_iCqf~69R?c8`oFOcqNN*~t~YM`>b8A`t=5v}HGQdUp6L(s`KJ65W#9sCyLVB?
z!&gixs2^G*IyK|fq406g^LGMk(3=H%;sc1EE4tT^5U-K_3%@1xU4iRAGUS&!Y6OaP$kEJ3^Abn;<;&Cf_ryGGfc}mQmkzKo
z&QFMw|b%1uz
zgYSM6zg8ivGVdqF1i9&KoI#qarR-q{b81BZ0XSDLSn-=n)ho3QDk%bezG~#|tWsA2
z;&$Z6gkt(N`|9|{I0d#Q0TMn`>vIizzxZd5k*)H@ZThWa+*p2Y$bd!e-_Ma#8?lQZHm=l3sp&7x`fY6zDSP
zMDT=NGmWeC?UeQl|x2n8lxf%WfDv_8w$7dFlw0_^lcQtmEJk
zQ{@Is5<>xaJN|!R<3!T`g0DjwHZOT(3Q<)|Hex03DVMx|M+ho$ux_nWQ!nYJ5^YQX
z&2%!1$g_@2N~Jn*!-y{jy_^eOUhx9{jS24=xoiCoIF3$;Re3lcUmT{@?t+Zgz`!Pn
z+#O;ann}JD
z@Voi~ys#0L>t~qUiF-vJz4vByVfF@Ne940T?dg&9c8!PODWnil5vp79Eq(~^pwh2T
zoq8%N`}V+X%40b#+$W7i~z4(ZhHE6b4vGg{C4cJbtv|4s>vNv(b)Ii0gL=eMcj
zXbq?ZzHF
z9NEk=YldJMg2@z%i_0Hx#>@ERcw`jORfh?nZiOqvks(3CiK!{)gR+MZ;q3?Dyy}}o
zb^s+Tu5)j-$x@aYnFYE%Thn97!n6x#gXmX_8`uK&%H9b{2irNwzmBb_LSj8VGk@cRz
zF8I&Tzuz}K^&@rkCF6*0%l4JsD#P(5WY!i|?^c3Fl9WZ0nbl)RQUSGam)ZH=JVfJe
zIg;d-i+>E%Rin3;p(>tsPRWhw*@Ojv+Z?V!TPAEVwFzCgm7f#hj-_}U%SI3-1R-24
zgbnJ@degevhSajG(mh6Ti^c@6G3odz8~`KDigREdt61HLV}J+#M=A9r{2QRHY(h
zZoOZG+Jh5WEuk#`fc*K!g9f2$vWqVi`o{V)a%d?82Ti^Oec*Ngr6Ci@S{^GxvHXeV
z$wL2arWP0l&21u`Q6O*_%Zt}wh=fZGRURqzI5XK>YW>ote*umL@thr^$eA~!C~*a*
zbXfTu4wpJRIT21a??bg)J+$Dg5xgtpBkGR-#DsgGUy5K^_Cd--?!X#7Z4vX9MwrG_
z9ApR{kddX@2HG6T8<{cYeAP_RLxgXHRj=5?Q`g|P*Fzg;SD$hSq8%88PNfeHKEs)H
z^oEAZB+}md*2^Zm-j&5n^cmf7l;dD*&WTdA5T_Vp6_5@f`#R^-a2ZgU&LbhI0K08IyAYs+t}!qNR=v)u)}0WvT9^tZE{G!
zrB?>Q{oKVnHjMP{Dl*@7WV#`cdxdw=5-cI|b$YQR2byuNzTsDkY~Z&=mKl6&-MKC!
z(*+|427qJFQrxX-Qk9Oo_4TfpURAS}@0O(+-d+s}5I1{$alD{($8GQ&gmIRC<+7R5UKON
z#_bKTrSL$_(+ai-oM-@1hP@Rjr>%7_s?L23)~WezPUJ3p@hpWk+sfs4VSyJ%z`PpQ
z4^%*mi%2O}_EF{s@?Ioc>pk^W4dM{F&T@&+=h#qVJpdy>+`ocMvYV~y#?}({A3Wb3
zA%i%vQftdHJ1>w2bvJroQ-DHzJ$avKh=yj{-|uWFrun93QN90}PA*R_Z+tJO&F|Ii*iqS53&Y=pu)JEAy&Iv{Dh*4i0O8w}I3zs*j9%>#<7d
zQgyN!m8TBQmTPpyC&mCyv&6vr4A?&}$+@pkpHQg-#b8O6eE+N+@`zZ-GdX_WU_JKF
zkE@vqjw|OS>yP(A0dH@ALZh4_M1LjuI9W=^uOpj(=E-LZYN8?^83hiQd~&uOu3A(I
z+*ijua`Bbr=XW3oV4;SXLFS=?NeA7<{5g6GK>~o$xH8af-p<^hZ-v+t4+HpU(2`(f%XtLGk};0%tV_0!SO
zVtGyPPAwf^>uYWBnJ!5YZ+;OS)J1drsij8KXVBd=S+!w!VFI|$Vp)!=^6J2&`GGtU
z<+Zf-tS_kA-JrT-;aK||4x*6D(lzK?k!7EUzGg6DELsk=npPU`O5AH+cG;E5+NX&5~)S&
z+pITqHj&nUtccP45KZQ8{I^rE7g1!WtjaW;Wx3^g-xe&eY?Wa
z^e(K(ct;VYcrvkQ_D*jCooOik8N>3KRb|-XMg2biUF067i4UmIBM)yLGKGdB!ocN7
z&hQJf&dFW5J2R%f>Fv)R_ct3h=7yZ!<^lT)y{Ncu=o_jisTPBv8@w(l!XwubK{797
z<>T*&Tus0y#A3B@;+RGc5&!(ZP!-p_r=&PS|I`5~{*>X)SSPk2UW*r(a1hxUytri<
zh~f8hxorw{H6yzgHS0eU1|xmUecJ3~%wCxgLUm<-8k9J_)d
zjS&vj+>Qm9%!$2vLWH2py;RklYXbRIl#WO3k6l_NKXuXP)-dYrHG^)u?r@3%-FFTg($5OSI2B1r%=Pa`TGs%)3f0wUotf}A+
zxJVkavDP;{C4xFK+->X^N9}4E;&jK?7|{i3cKd@&uuR?wlT2mD?inShn%fy^nE?AA
zSqU9|NkxvRZxA^`0hw_1vf^mPDpTrUj-ivJ2-x-&0bm@b3XSl9V0-+kbJoxa!*4=7
zYCxZXt1nncZ{gW2Tz-fab$4J?-v7>j+t)?DE10AQmDRnTZeUt=d
zMp~mouiI%iG)c^5St^nBXtE9~w8H8U&y!zsGG}%+5^UY3%)Z)CpEFZ0tGV`w4n(bj
z)}*y8A<07b1LR!ia@T4kG0l(9#Eo~8YAskd{}ftFL=VRpG}F1oR;|oHsiJc29Qly1
zYG$dA6ta;@!}@M
zFtW4+m4)IfANpx&%Ck`PvPepvj0nd@)>CpUC;yOY@?Wx@pdES87iP{SJL`dqE)df8
zQ(AY<6~KW2J>z{09sk6_+&^@S2E5tRma@fb$bxDaS_=^(Na`RHNvlUFm~`kzNJUPl
zh*><_qnytzLhvL+ggJZ18+znUegxuVGn7xJf8vPLXLp0EP@`5ziuR4z;k_OHokId
z99XU^Y6P9E_pzfxZk%`w0#D8}nQu{MBVZXt+w870&B8J+R^f76{qtPuI4r@W!Hspu
z?)wA5aQ@n;>}{DQbj!LDUfZ{y(T+`0lo9~@-j$D8p;d%
zbV13MeG>j9qh#`SR(jj;5J-5lwXPG^2n`$>fY+!7Wuh}yZdVExP3uZ#(o_(b?4~LM
z6j&k+8&dumVDi=T@CX(iG7}j9oS%o?UxxBq-|d8|>Ox`J#gKs;*&;z7HnESDj1uSt
z$oht$5Tp@TybGf&ztW*xhLIK<-_g_cadQM6-hr$tGF&y8*C*pM{SgeAMB8PyVUs-E
z3Z4jRBB^%;LFU3I*dT+9CP+H|jlwC?+Ak>9S21Rh|9Sl@hhw%Q23bWU%+i2Lm(S18
z`L_G@AxEbfdPY(s+%eT*_&p3XjfbijH+l8LvZwxzTVFNN50x53BZwRK(0~fEz`ojJ
ztp(T`Dal1UV?s=oyCb|ArT3Qn?M8{gytC-4mr2CEH!g=I^I_Ak5=Y#zR9pFdncsWn
zsUbZ&p^pqWc?w5BF@X{WE-~lz=>)=eh9-$c<_r2}48y063gBY$kwDKtAGAven!k^_
zv$PX|LAF{x@AeAd%7L7bv05c?F=#J-A6k7S90}sc~Iz5H%0x4{nV4at-k;_uLTL
z1h-jn1mE)+vqYp(&|#jQ@XWtkO(^eA>VX^sqOuL;D3z75@YlQ;DoB-vm_fP%
z6rI5jDpSF{dg;zyML!pkEtHqUAq1uHL-
z3~yu9!a_qrN^Ay&ehZ`bLCm;R&SpOJ!upjJD3ij8XaLP$Uyoo+(HX9KQF*xE)CK{N
ziAOtq&%rs=Je2y`*l>8&a_qLS&osp`551=}!Rw
zb#v-nh((Fe0vt^rD^R{_45ZeAfbO>t@5+;JX38^-
z=`bs!|8?bHjGLkWCJX(6lUwSymKdTES>v{fk5x2G7rJ~|-m;!)7p>nu$|{VsAmvF-
zvR9-K+{q%l_724Awjlk8EWC!^*NFc#F5^q7U5?wPEbb2}*g6QBYOR~sVlrxO4E1;W
z7kLlU*hq|{>R^qR8MR#?CkDpd1u?|^mCR(HYHCp?7gjl0I>t1pD@z21I@P-;_-|_z
z2{%n0hMq>bJ^=)^4o7~?7?
zo!1$+1RQ}qjes|?PP5Zag`mY4MMF$1I{R?_3(oHZ;ksP
z0-Q75Rn&woZ2xyYO3fghArEK9LEhRcRz#GMtM%2sqqY0-jL;~A1%4GqR-^bD=nC+@
zpGheMqG4f&2{l)a$h66>emg+dvR%6z%>AW`Xf@5v1%BfwbDO8k$>#T|b@dvezggTo
zrKlNVRB(8zXt|0VM1Qv5>oq
zreJj--=k+*bV!H!wf)G_nn{;
zvi{uO_1nxUk`2dBU#M#VcbF<&ec}nStwol8IhBc%^VIb_w69_-drLQ#>4yFuwJ4E;
zD)PWqI_?Culy0Ko58AeG`ys3t34K$)hA32T&4Lw>EzNByB4>qxY+_=PWe<_Oslprx|YVBft3RY%QVRz4(k(oR6)5y
z6l9m!$qy5W2OGUJmgF|)CGR3{fqU{NCxc(NY^a~W77q1gNO(0VYWqp#dDe9r`QJ%a4tUrG(
z)0Q_UH3>SyW!3bBhBwE3Gb8HF1d?-sP@@+q+K)E_Rfr=0U1y=IPg*&wBNI~CwS?v<
zmx0qn-ln_^n$AZd<4d`m$
zRFnay;Iq%AAq>y4HIh_c{LSKJ6J^=
zxHesuhiA!d?PZD87Yj>FV~LA&*KzZHxVMwhNF8~G(z#Llto6q(}~nxD)m$Xft7
zqB1)-2H-nEjB(s3wHz{O*XC(|QG#D*`c4DBFVKP{?s!BGU&QdSffh&x4LV?MNfAsr
ziaqJ|iOtzRy6ti+?6k|D)Ak%lgZm8xM}U*LV#w%`!0kBFwHY1H8Pwp0`hXH7bG=Xh
zw(Te_wd{JJxrh^$wxJfzez5r)!eeM6E`;8E(fBQo)bj-+{yKeqlCXSv>Pwp&O!DED
zGA+5@l_hbA^)ySanX|kTwDTz>g=M+N1w*omsRs4cq-Gde)puXI`9p5~7620xn3JOq
z6<818nrF_dLeg~F@3she3_I6*bfV;b9OtOe+E;SrE
zPz@J$LEwHHqVR9)tPB#SHk=ia73RiTfd351V7aR84RH31m8$jyt@v$TCpdjcp$9POYD*6Xo(Nv!5J4q^v2{T$uYMGVl(mcowev4mJ~jf0s9
z@ck2SH}&p;97u$3E#}*V*|oyEGEPTAFBLwv+XuHVIPEyz40v^F1u2qbuh9au
zM3&~F9Zh&)>=<${-pA<<&tLGWldQZ(dUeGLa1KjB@uY&7b4QR>u+4iLBCmLkE2}tO
zpTmd*-U(~xwq$dziYV23ucOJpLk`0rz_mA7!0d{(hVtJE7?2v++$CFr?YLLbOOlo$
zbe6gTGJ)Cr-Qmr&w~HW%$8fa@fz4PPK~yKmw-(yUgm@VvZm_DYeR4q}B(2k3Nn@!4
zZsGYvkEx?k$FPJPqv3W4s~!&D22jrFzPO2-k3HBiT`sarj}_JYp&k{aJFUJVQs&$P9o`JKEz?|0$F%$4RjUBi*EJ?RIEKFSs4v;^OfX;7dfC