mirror of
https://github.com/zkonduit/ezkl.git
synced 2026-01-13 08:17:57 -05:00
Compare commits
66 Commits
v22.2.4
...
vka-hashin
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afff3a637d | ||
|
|
538d7e52ad | ||
|
|
4e857c2d63 | ||
|
|
87e5079fe7 | ||
|
|
6d8e2bd2f2 | ||
|
|
9f1e4773ab | ||
|
|
d32d7d0225 | ||
|
|
d67a5e82d5 | ||
|
|
ff8ec62916 | ||
|
|
96b46d8628 | ||
|
|
1028b9d3cc | ||
|
|
c367500b38 | ||
|
|
00fcddbed3 | ||
|
|
e1d09985da | ||
|
|
5309366438 | ||
|
|
ed67713de9 | ||
|
|
ce7235b0db | ||
|
|
716916f58d | ||
|
|
5c9f518039 | ||
|
|
343ceb9030 | ||
|
|
14c99223e7 | ||
|
|
f683ee2239 | ||
|
|
479773b16e | ||
|
|
0562911b73 | ||
|
|
6e36b5bb4c | ||
|
|
00ab001fc7 | ||
|
|
037d954d2a | ||
|
|
4e4fd7dba0 | ||
|
|
17d2f5db36 | ||
|
|
94ad885cda | ||
|
|
0ef1f35e59 | ||
|
|
808ab7d0de | ||
|
|
68b2c96b97 | ||
|
|
9a0ab22fdb | ||
|
|
f2b1de3740 | ||
|
|
dcb888ff1e | ||
|
|
26f465e70c | ||
|
|
8eef53213d | ||
|
|
a1345966d7 | ||
|
|
640061c850 | ||
|
|
da7db7d88d | ||
|
|
a55f75ff3f | ||
|
|
bf6f704827 | ||
|
|
0dbfdf4672 | ||
|
|
98299356a6 | ||
|
|
04805d2a91 | ||
|
|
ca18cf29bb | ||
|
|
78f8e23b55 | ||
|
|
7d40926082 | ||
|
|
e2c8182871 | ||
|
|
4f077c9134 | ||
|
|
038805ce02 | ||
|
|
0fb87c9a20 | ||
|
|
77423a6d07 | ||
|
|
8b416c7a00 | ||
|
|
73ec5e549a | ||
|
|
28386d8442 | ||
|
|
1b12f9256d | ||
|
|
59495f3385 | ||
|
|
4a49517ba2 | ||
|
|
d36b185037 | ||
|
|
a579826c9c | ||
|
|
ed6bce0657 | ||
|
|
98ee20a38f | ||
|
|
77caac3981 | ||
|
|
342cbc4408 |
22
.github/workflows/benchmarks.yml
vendored
22
.github/workflows/benchmarks.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2023-06-27
|
||||
override: true
|
||||
@@ -32,7 +32,7 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2023-06-27
|
||||
override: true
|
||||
@@ -49,7 +49,7 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2023-06-27
|
||||
override: true
|
||||
@@ -66,7 +66,7 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2023-06-27
|
||||
override: true
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2023-06-27
|
||||
override: true
|
||||
@@ -100,7 +100,7 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2023-06-27
|
||||
override: true
|
||||
@@ -117,7 +117,7 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2023-06-27
|
||||
override: true
|
||||
@@ -134,7 +134,7 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2023-06-27
|
||||
override: true
|
||||
@@ -151,7 +151,7 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2023-06-27
|
||||
override: true
|
||||
@@ -168,7 +168,7 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2023-06-27
|
||||
override: true
|
||||
@@ -185,7 +185,7 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2023-06-27
|
||||
override: true
|
||||
|
||||
8
.github/workflows/engine.yml
vendored
8
.github/workflows/engine.yml
vendored
@@ -21,19 +21,17 @@ jobs:
|
||||
name: publish-wasm-bindings
|
||||
env:
|
||||
RELEASE_TAG: ${{ github.ref_name }}
|
||||
RUSTFLAGS: "-C target-feature=+atomics,+bulk-memory"
|
||||
runs-on: ubuntu-latest
|
||||
if: startsWith(github.ref, 'refs/tags/')
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-02-17
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
cache: false
|
||||
- uses: jetli/wasm-pack-action@0d096b08b4e5a7de8c28de67e11e945404e9eefa #v0.4.0
|
||||
with:
|
||||
# Pin to version 0.12.1
|
||||
@@ -42,7 +40,7 @@ jobs:
|
||||
run: rustup target add wasm32-unknown-unknown
|
||||
|
||||
- name: Add rust-src
|
||||
run: rustup component add rust-src --toolchain nightly-2025-05-01-x86_64-unknown-linux-gnu
|
||||
run: rustup component add rust-src --toolchain nightly-2025-02-17-x86_64-unknown-linux-gnu
|
||||
- name: Install binaryen
|
||||
run: |
|
||||
set -e
|
||||
|
||||
4
.github/workflows/large-tests.yml
vendored
4
.github/workflows/large-tests.yml
vendored
@@ -13,9 +13,9 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-02-17
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: nanoGPT Mock
|
||||
|
||||
17
.github/workflows/pypi-gpu.yml
vendored
17
.github/workflows/pypi-gpu.yml
vendored
@@ -27,8 +27,6 @@ jobs:
|
||||
target: [x86_64]
|
||||
env:
|
||||
RELEASE_TAG: ${{ github.ref_name }}
|
||||
RUSTFLAGS: "-C linker=gcc"
|
||||
OPENSSL_NO_VENDOR: 1
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
@@ -38,16 +36,6 @@ jobs:
|
||||
python-version: 3.12
|
||||
architecture: x64
|
||||
|
||||
|
||||
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential g++ gcc cmake libclang-dev llvm-dev libstdc++-12-dev libc6 libc6-dev libssl-dev pkg-config
|
||||
|
||||
- name: Force rebuild icicle dependencies
|
||||
run: cargo clean -p icicle-runtime -p icicle-core -p icicle-hash -p icicle-bn254
|
||||
|
||||
- name: Set pyproject.toml version to match github tag and rename ezkl to ezkl-gpu
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -55,12 +43,11 @@ jobs:
|
||||
sed "s/ezkl/ezkl-gpu/" pyproject.toml.orig > pyproject.toml.tmp
|
||||
sed "s/0\\.0\\.0/${RELEASE_TAG//v}/" pyproject.toml.tmp > pyproject.toml
|
||||
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2023-06-27
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
cache: false
|
||||
|
||||
- name: Set Cargo.toml version to match github tag and rename ezkl to ezkl-gpu
|
||||
shell: bash
|
||||
@@ -83,7 +70,7 @@ jobs:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: auto
|
||||
container: off
|
||||
args: --release --out dist --features python-bindings,gpu-accelerated
|
||||
args: --release --out dist --features python-bindings,icicle
|
||||
|
||||
- name: Install built wheel
|
||||
if: matrix.target == 'x86_64'
|
||||
|
||||
10
.github/workflows/pypi.yml
vendored
10
.github/workflows/pypi.yml
vendored
@@ -48,12 +48,11 @@ jobs:
|
||||
mv Cargo.lock Cargo.lock.orig
|
||||
sed "s/0\\.0\\.0/${RELEASE_TAG//v}/" Cargo.lock.orig >Cargo.lock
|
||||
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-02-17
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
cache: false
|
||||
|
||||
- name: Build wheels
|
||||
if: matrix.target == 'universal2-apple-darwin'
|
||||
@@ -114,12 +113,11 @@ jobs:
|
||||
mv Cargo.lock Cargo.lock.orig
|
||||
sed "s/0\\.0\\.0/${RELEASE_TAG//v}/" Cargo.lock.orig >Cargo.lock
|
||||
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-02-17
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
cache: false
|
||||
|
||||
- name: Build wheels
|
||||
uses: PyO3/maturin-action@5f8a1b3b0aad13193f46c9131f9b9e663def8ce5 #v1.46.0
|
||||
|
||||
33
.github/workflows/release.yml
vendored
33
.github/workflows/release.yml
vendored
@@ -26,6 +26,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
echo "EZKL_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
echo "version is: ${{ env.EZKL_VERSION }}"
|
||||
|
||||
- name: Create Github Release
|
||||
id: create-release
|
||||
@@ -47,32 +48,23 @@ jobs:
|
||||
TARGET_DIR: ./target
|
||||
RUST_BACKTRACE: 1
|
||||
PCRE2_SYS_STATIC: 1
|
||||
RUSTFLAGS: "-C linker=gcc"
|
||||
OPENSSL_NO_VENDOR: 1
|
||||
steps:
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-02-17
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
cache: false
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Install build dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y build-essential g++ gcc cmake libclang-dev llvm-dev libstdc++-12-dev libc6 libc6-dev libssl-dev pkg-config
|
||||
|
||||
- name: Force rebuild icicle dependencies
|
||||
run: cargo clean -p icicle-runtime -p icicle-core -p icicle-hash -p icicle-bn254
|
||||
|
||||
- name: Get release version from tag
|
||||
shell: bash
|
||||
run: |
|
||||
echo "EZKL_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
echo "version is: ${{ env.EZKL_VERSION }}"
|
||||
|
||||
- name: Set Cargo.toml version to match github tag
|
||||
shell: bash
|
||||
@@ -88,7 +80,7 @@ jobs:
|
||||
sudo apt-get update
|
||||
|
||||
- name: Build release binary
|
||||
run: cargo build --release -Z sparse-registry --features gpu-accelerated
|
||||
run: cargo build --release -Z sparse-registry --features icicle
|
||||
|
||||
- name: Build archive
|
||||
shell: bash
|
||||
@@ -127,27 +119,27 @@ jobs:
|
||||
include:
|
||||
- build: windows-msvc
|
||||
os: windows-latest
|
||||
rust: nightly-2025-05-01
|
||||
rust: nightly-2025-02-17
|
||||
target: x86_64-pc-windows-msvc
|
||||
- build: macos
|
||||
os: macos-13
|
||||
rust: nightly-2025-05-01
|
||||
rust: nightly-2025-02-17
|
||||
target: x86_64-apple-darwin
|
||||
- build: macos-aarch64
|
||||
os: macos-13
|
||||
rust: nightly-2025-05-01
|
||||
rust: nightly-2025-02-17
|
||||
target: aarch64-apple-darwin
|
||||
- build: linux-musl
|
||||
os: ubuntu-22.04
|
||||
rust: nightly-2025-05-01
|
||||
rust: nightly-2025-02-17
|
||||
target: x86_64-unknown-linux-musl
|
||||
- build: linux-gnu
|
||||
os: ubuntu-22.04
|
||||
rust: nightly-2025-05-01
|
||||
rust: nightly-2025-02-17
|
||||
target: x86_64-unknown-linux-gnu
|
||||
- build: linux-aarch64
|
||||
os: ubuntu-22.04
|
||||
rust: nightly-2025-05-01
|
||||
rust: nightly-2025-02-17
|
||||
target: aarch64-unknown-linux-gnu
|
||||
|
||||
steps:
|
||||
@@ -160,6 +152,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
echo "EZKL_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
echo "version is: ${{ env.EZKL_VERSION }}"
|
||||
|
||||
- name: Set Cargo.toml version to match github tag
|
||||
shell: bash
|
||||
@@ -209,7 +202,7 @@ jobs:
|
||||
|
||||
- name: Build release binary (asm)
|
||||
if: matrix.build == 'linux-gnu'
|
||||
run: ${{ env.CARGO }} build --release ${{ env.TARGET_FLAGS }} -Z sparse-registry --features mimalloc
|
||||
run: ${{ env.CARGO }} build --release ${{ env.TARGET_FLAGS }} -Z sparse-registry --features asm,mimalloc
|
||||
|
||||
- name: Build release binary (metal)
|
||||
if: matrix.build == 'macos-aarch64'
|
||||
|
||||
845
.github/workflows/rust.yml
vendored
845
.github/workflows/rust.yml
vendored
File diff suppressed because it is too large
Load Diff
4
.github/workflows/static-analysis.yml
vendored
4
.github/workflows/static-analysis.yml
vendored
@@ -15,9 +15,9 @@ jobs:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-02-17
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
|
||||
|
||||
302
Cargo.lock
generated
302
Cargo.lock
generated
@@ -881,6 +881,17 @@ dependencies = [
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi 0.1.19",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aurora-engine-modexp"
|
||||
version = "1.2.0"
|
||||
@@ -959,6 +970,29 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.69.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "271383c67ccabffb7381723dea0672a673f292304fcb45c01cc648c7a8d58088"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools 0.12.1",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"log",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash 1.1.0",
|
||||
"shlex",
|
||||
"syn 2.0.101",
|
||||
"which",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.3"
|
||||
@@ -1177,6 +1211,15 @@ dependencies = [
|
||||
"shlex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
@@ -1227,7 +1270,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
|
||||
dependencies = [
|
||||
"ciborium-io",
|
||||
"half",
|
||||
"half 2.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "2.34.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"textwrap 0.11.0",
|
||||
"unicode-width 0.1.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1258,7 +1323,7 @@ version = "4.5.47"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06f5378ea264ad4f82bbc826628b5aad714a75abf6ece087e923010eb937fb6"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"clap 4.5.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1445,6 +1510,32 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b01d6de93b2b6c65e17c634a26653a29d107b3c98c607c765bf38d041531cd8f"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"cast",
|
||||
"clap 2.34.0",
|
||||
"criterion-plot 0.4.5",
|
||||
"csv",
|
||||
"itertools 0.10.5",
|
||||
"lazy_static",
|
||||
"num-traits",
|
||||
"oorandom",
|
||||
"plotters",
|
||||
"rayon",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde_cbor",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"tinytemplate",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion"
|
||||
version = "0.5.1"
|
||||
@@ -1454,8 +1545,8 @@ dependencies = [
|
||||
"anes",
|
||||
"cast",
|
||||
"ciborium",
|
||||
"clap",
|
||||
"criterion-plot",
|
||||
"clap 4.5.37",
|
||||
"criterion-plot 0.5.0",
|
||||
"is-terminal",
|
||||
"itertools 0.10.5",
|
||||
"num-traits",
|
||||
@@ -1471,6 +1562,16 @@ dependencies = [
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion-plot"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876"
|
||||
dependencies = [
|
||||
"cast",
|
||||
"itertools 0.10.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "criterion-plot"
|
||||
version = "0.5.0"
|
||||
@@ -1543,6 +1644,27 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf"
|
||||
dependencies = [
|
||||
"csv-core",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv-core"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "5.5.3"
|
||||
@@ -1943,12 +2065,12 @@ dependencies = [
|
||||
"bincode",
|
||||
"camino",
|
||||
"chrono",
|
||||
"clap",
|
||||
"clap 4.5.37",
|
||||
"clap_complete",
|
||||
"colored",
|
||||
"colored_json",
|
||||
"console_error_panic_hook",
|
||||
"criterion",
|
||||
"criterion 0.5.1",
|
||||
"ecc",
|
||||
"env_logger 0.10.2",
|
||||
"ethabi",
|
||||
@@ -1960,7 +2082,6 @@ dependencies = [
|
||||
"halo2_solidity_verifier",
|
||||
"halo2curves 0.7.0 (git+https://github.com/privacy-scaling-explorations/halo2curves?rev=b753a832e92d5c86c5c997327a9cf9de86a18851)",
|
||||
"hex",
|
||||
"icicle-runtime",
|
||||
"indicatif",
|
||||
"instant",
|
||||
"itertools 0.10.5",
|
||||
@@ -2207,7 +2328,7 @@ version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8640e34b88f7652208ce9e88b1a37a2ae95227d84abec377ccd3c5cfeb141ed4"
|
||||
dependencies = [
|
||||
"rustix",
|
||||
"rustix 1.0.5",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
@@ -2400,6 +2521,12 @@ dependencies = [
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "1.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403"
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.6.0"
|
||||
@@ -2414,7 +2541,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "halo2_gadgets"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/zkonduit/halo2?branch=ac%2Fconditional-compilation-icicle2#1dd2090741f006fd031a07da7f3c9dfce5e0015e"
|
||||
source = "git+https://github.com/zkonduit/halo2#f441c920be45f8f05d2c06a173d82e8885a5ed4d"
|
||||
dependencies = [
|
||||
"arrayvec 0.7.6",
|
||||
"bitvec",
|
||||
@@ -2431,7 +2558,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "halo2_proofs"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/zkonduit/halo2#1dd2090741f006fd031a07da7f3c9dfce5e0015e?branch=ac%2Fconditional-compilation-icicle2#1dd2090741f006fd031a07da7f3c9dfce5e0015e"
|
||||
source = "git+https://github.com/zkonduit/halo2#f441c920be45f8f05d2c06a173d82e8885a5ed4d"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"blake2b_simd",
|
||||
@@ -2441,7 +2568,7 @@ dependencies = [
|
||||
"halo2curves 0.7.0 (git+https://github.com/privacy-scaling-explorations/halo2curves?rev=b753a832e92d5c86c5c997327a9cf9de86a18851)",
|
||||
"icicle-bn254",
|
||||
"icicle-core",
|
||||
"icicle-runtime",
|
||||
"icicle-cuda-runtime",
|
||||
"instant",
|
||||
"lazy_static",
|
||||
"log",
|
||||
@@ -2449,7 +2576,7 @@ dependencies = [
|
||||
"mopro-msm",
|
||||
"rand_chacha 0.3.1",
|
||||
"rand_core 0.6.4",
|
||||
"rustc-hash",
|
||||
"rustc-hash 2.1.1",
|
||||
"serde",
|
||||
"sha3 0.9.1",
|
||||
"tracing",
|
||||
@@ -2458,7 +2585,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "halo2_solidity_verifier"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/zkonduit/ezkl-verifier?branch=main#a518a917f076adb851a1ae39e09527f8dbde5000"
|
||||
source = "git+https://github.com/zkonduit/ezkl-verifier?branch=main#ff30972bf729d046f0c903ad91703af1a9e33a8f"
|
||||
dependencies = [
|
||||
"askama",
|
||||
"blake2b_simd",
|
||||
@@ -2664,6 +2791,15 @@ version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.9"
|
||||
@@ -2855,45 +2991,33 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "icicle-bn254"
|
||||
version = "3.7.0"
|
||||
source = "git+https://github.com/ingonyama-zk/icicle?branch=emir%2Fgate_eval_2#012e00694f4cf399fe7a42d9cfbfa6cd7a60f876"
|
||||
version = "2.8.0"
|
||||
source = "git+https://github.com/ingonyama-zk/icicle?branch=ezkl-icicle2#5dfe006a0f1bc62ea82ca297709bbf3d22a2ca25"
|
||||
dependencies = [
|
||||
"cmake",
|
||||
"criterion 0.3.6",
|
||||
"icicle-core",
|
||||
"icicle-hash",
|
||||
"icicle-runtime",
|
||||
"icicle-cuda-runtime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icicle-core"
|
||||
version = "3.7.0"
|
||||
source = "git+https://github.com/ingonyama-zk/icicle?branch=emir%2Fgate_eval_2#012e00694f4cf399fe7a42d9cfbfa6cd7a60f876"
|
||||
version = "2.8.0"
|
||||
source = "git+https://github.com/ingonyama-zk/icicle?branch=ezkl-icicle2#5dfe006a0f1bc62ea82ca297709bbf3d22a2ca25"
|
||||
dependencies = [
|
||||
"criterion 0.3.6",
|
||||
"hex",
|
||||
"icicle-runtime",
|
||||
"once_cell",
|
||||
"rand 0.8.5",
|
||||
"icicle-cuda-runtime",
|
||||
"rayon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icicle-hash"
|
||||
version = "3.7.0"
|
||||
source = "git+https://github.com/ingonyama-zk/icicle?branch=emir%2Fgate_eval_2#012e00694f4cf399fe7a42d9cfbfa6cd7a60f876"
|
||||
name = "icicle-cuda-runtime"
|
||||
version = "2.8.0"
|
||||
source = "git+https://github.com/ingonyama-zk/icicle?branch=ezkl-icicle2#5dfe006a0f1bc62ea82ca297709bbf3d22a2ca25"
|
||||
dependencies = [
|
||||
"cmake",
|
||||
"icicle-core",
|
||||
"icicle-runtime",
|
||||
"rand 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icicle-runtime"
|
||||
version = "3.7.0"
|
||||
source = "git+https://github.com/ingonyama-zk/icicle?branch=emir%2Fgate_eval_2#012e00694f4cf399fe7a42d9cfbfa6cd7a60f876"
|
||||
dependencies = [
|
||||
"cmake",
|
||||
"once_cell",
|
||||
"bindgen",
|
||||
"bitflags 1.3.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3346,12 +3470,28 @@ dependencies = [
|
||||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.172"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libm"
|
||||
version = "0.2.13"
|
||||
@@ -3379,6 +3519,12 @@ dependencies = [
|
||||
"redox_syscall",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.9.4"
|
||||
@@ -3817,7 +3963,7 @@ dependencies = [
|
||||
"num-traits",
|
||||
"pyo3",
|
||||
"pyo3-build-config",
|
||||
"rustc-hash",
|
||||
"rustc-hash 2.1.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4248,6 +4394,16 @@ version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "664ec5419c51e34154eec046ebcba56312d5a2fc3b09a06da188e1ad21afadf6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn 2.0.101",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "primal-check"
|
||||
version = "0.3.4"
|
||||
@@ -4500,7 +4656,7 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rustc-hash",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustls",
|
||||
"socket2",
|
||||
"thiserror 2.0.12",
|
||||
@@ -4519,7 +4675,7 @@ dependencies = [
|
||||
"getrandom 0.3.2",
|
||||
"rand 0.9.1",
|
||||
"ring",
|
||||
"rustc-hash",
|
||||
"rustc-hash 2.1.1",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"slab",
|
||||
@@ -5017,6 +5173,12 @@ version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
@@ -5062,6 +5224,19 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys 0.4.15",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "1.0.5"
|
||||
@@ -5071,7 +5246,7 @@ dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"linux-raw-sys 0.9.4",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
@@ -5319,6 +5494,16 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_cbor"
|
||||
version = "0.11.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
|
||||
dependencies = [
|
||||
"half 1.8.3",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
@@ -5765,7 +5950,7 @@ dependencies = [
|
||||
"fastrand",
|
||||
"getrandom 0.3.2",
|
||||
"once_cell",
|
||||
"rustix",
|
||||
"rustix 1.0.5",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
@@ -5811,6 +5996,15 @@ dependencies = [
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
|
||||
dependencies = [
|
||||
"unicode-width 0.1.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.16.2"
|
||||
@@ -6204,7 +6398,7 @@ dependencies = [
|
||||
"downcast-rs",
|
||||
"dyn-clone",
|
||||
"dyn-hash",
|
||||
"half",
|
||||
"half 2.6.0",
|
||||
"itertools 0.12.1",
|
||||
"lazy_static",
|
||||
"maplit",
|
||||
@@ -6239,7 +6433,7 @@ dependencies = [
|
||||
"downcast-rs",
|
||||
"dyn-clone",
|
||||
"dyn-hash",
|
||||
"half",
|
||||
"half 2.6.0",
|
||||
"lazy_static",
|
||||
"liquid",
|
||||
"liquid-core",
|
||||
@@ -6420,7 +6614,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"paste",
|
||||
"serde",
|
||||
"textwrap",
|
||||
"textwrap 0.16.2",
|
||||
"toml 0.5.11",
|
||||
"uniffi_meta",
|
||||
"uniffi_testing",
|
||||
@@ -6512,7 +6706,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cef408229a3a407fafa4c36dc4f6ece78a6fb258ab28d2b64bddd49c8cb680f6"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"textwrap",
|
||||
"textwrap 0.16.2",
|
||||
"uniffi_meta",
|
||||
"uniffi_testing",
|
||||
"weedle2",
|
||||
@@ -6852,6 +7046,18 @@ dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87ba24419a2078cd2b0f2ede2691b6c66d8e47836da3b6db8265ebad47afbfc7"
|
||||
dependencies = [
|
||||
"either",
|
||||
"home",
|
||||
"once_cell",
|
||||
"rustix 0.38.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
@@ -7229,7 +7435,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rustix",
|
||||
"rustix 1.0.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
||||
41
Cargo.toml
41
Cargo.toml
@@ -16,12 +16,12 @@ crate-type = ["cdylib", "rlib", "staticlib"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
halo2_gadgets = { git = "https://github.com/zkonduit/halo2", branch= "ac/conditional-compilation-icicle2" }
|
||||
halo2_gadgets = { git = "https://github.com/zkonduit/halo2" }
|
||||
halo2curves = { git = "https://github.com/privacy-scaling-explorations/halo2curves", rev = "b753a832e92d5c86c5c997327a9cf9de86a18851", features = [
|
||||
"derive_serde",
|
||||
] }
|
||||
halo2_proofs = { git = "https://github.com/zkonduit/halo2", package = "halo2_proofs", branch= "ac/conditional-compilation-icicle2", features = [
|
||||
"circuit-params", "mv-lookup"
|
||||
halo2_proofs = { git = "https://github.com/zkonduit/halo2", package = "halo2_proofs", features = [
|
||||
"circuit-params",
|
||||
] }
|
||||
rand = { version = "0.8", default-features = false }
|
||||
itertools = { version = "0.10.3", default-features = false }
|
||||
@@ -33,10 +33,10 @@ thiserror = { version = "1.0.38", default-features = false }
|
||||
hex = { version = "0.4.3", default-features = false }
|
||||
halo2_wrong_ecc = { git = "https://github.com/zkonduit/halo2wrong", branch = "ac/chunked-mv-lookup", package = "ecc" }
|
||||
snark-verifier = { git = "https://github.com/zkonduit/snark-verifier", branch = "ac/chunked-mv-lookup", features = [
|
||||
"derive_serde", "mv-lookup"
|
||||
"derive_serde",
|
||||
] }
|
||||
halo2_solidity_verifier = { git = "https://github.com/zkonduit/ezkl-verifier", branch = "main", optional = true, features = [
|
||||
"evm", "mv-lookup",
|
||||
"evm",
|
||||
] }
|
||||
maybe-rayon = { version = "0.1.1", default-features = false }
|
||||
bincode = { version = "1.3.3", default-features = false }
|
||||
@@ -103,10 +103,6 @@ uniffi_bindgen = { version = "=0.28.0", optional = true }
|
||||
camino = { version = "^1.1", optional = true }
|
||||
uuid = { version = "1.10.0", features = ["v4"], optional = true }
|
||||
|
||||
# GPU / device related things (optional - only enabled with gpu-accelerated feature)
|
||||
icicle-runtime = { git = "https://github.com/ingonyama-zk/icicle", branch="emir/gate_eval_2", package="icicle-runtime", optional = true }
|
||||
|
||||
|
||||
[target.'cfg(not(all(target_arch = "wasm32", target_os = "unknown")))'.dependencies]
|
||||
colored = { version = "2.0.0", default-features = false, optional = true }
|
||||
env_logger = { version = "0.10.0", default-features = false, optional = true }
|
||||
@@ -226,13 +222,11 @@ required-features = ["python-bindings"]
|
||||
[features]
|
||||
web = ["wasm-bindgen-rayon"]
|
||||
default = [
|
||||
"eth",
|
||||
"dep:halo2_solidity_verifier",
|
||||
"eth-mv-lookup",
|
||||
"ezkl",
|
||||
"precompute-coset",
|
||||
"no-banner",
|
||||
"parallel-poly-read",
|
||||
"reusable-verifier",
|
||||
]
|
||||
onnx = ["dep:tract-onnx"]
|
||||
python-bindings = ["pyo3", "pyo3-log", "pyo3-async-runtimes", "pyo3-stub-gen"]
|
||||
@@ -241,7 +235,7 @@ universal-bindings = [
|
||||
"mv-lookup",
|
||||
"precompute-coset",
|
||||
"parallel-poly-read",
|
||||
"dep:halo2_solidity_verifier"
|
||||
"solidity-verifier-mv-lookup",
|
||||
]
|
||||
logging = ["dep:colored", "dep:env_logger", "dep:chrono"]
|
||||
ios-bindings = ["universal-bindings"]
|
||||
@@ -267,6 +261,10 @@ ezkl = [
|
||||
"logging",
|
||||
]
|
||||
eth = ["dep:alloy", "dep:foundry-compilers", "dep:ethabi"]
|
||||
solidity-verifier = ["dep:halo2_solidity_verifier"]
|
||||
solidity-verifier-mv-lookup = ["halo2_solidity_verifier/mv-lookup"]
|
||||
eth-mv-lookup = ["solidity-verifier-mv-lookup", "mv-lookup", "eth"]
|
||||
eth-original-lookup = ["eth", "solidity-verifier"]
|
||||
parallel-poly-read = [
|
||||
"halo2_proofs/circuit-params",
|
||||
"halo2_proofs/parallel-poly-read",
|
||||
@@ -275,7 +273,7 @@ mv-lookup = ["halo2_proofs/mv-lookup", "snark-verifier/mv-lookup"]
|
||||
asm = ["halo2curves/asm", "halo2_proofs/asm"]
|
||||
precompute-coset = ["halo2_proofs/precompute-coset"]
|
||||
det-prove = []
|
||||
gpu-accelerated = ["halo2_proofs/gpu-accelerated", "dep:icicle-runtime"]
|
||||
icicle = ["halo2_proofs/icicle_gpu"]
|
||||
empty-cmd = []
|
||||
no-banner = []
|
||||
no-update = []
|
||||
@@ -283,24 +281,11 @@ macos-metal = ["halo2_proofs/macos"]
|
||||
ios-metal = ["halo2_proofs/ios"]
|
||||
jemalloc = ["dep:jemallocator"]
|
||||
mimalloc = ["dep:mimalloc"]
|
||||
reusable-verifier = []
|
||||
|
||||
|
||||
[patch.'https://github.com/zkonduit/halo2']
|
||||
halo2_proofs = { git = "https://github.com/zkonduit/halo2#1dd2090741f006fd031a07da7f3c9dfce5e0015e", package = "halo2_proofs", branch= "ac/conditional-compilation-icicle2", features = [
|
||||
"circuit-params", "mv-lookup"
|
||||
] }
|
||||
|
||||
[patch.'https://github.com/zkonduit/halo2#f441c920be45f8f05d2c06a173d82e8885a5ed4d']
|
||||
halo2_proofs = { git = "https://github.com/zkonduit/halo2#1dd2090741f006fd031a07da7f3c9dfce5e0015e", package = "halo2_proofs", branch= "ac/conditional-compilation-icicle2", features = [
|
||||
"circuit-params", "mv-lookup"
|
||||
] }
|
||||
|
||||
|
||||
[patch.crates-io]
|
||||
uniffi_testing = { git = "https://github.com/ElusAegis/uniffi-rs", branch = "feat/testing-feature-build-fix" }
|
||||
|
||||
|
||||
[profile.release]
|
||||
# debug = true
|
||||
rustflags = ["-C", "relocation-model=pic"]
|
||||
@@ -315,5 +300,3 @@ opt-level = 3
|
||||
|
||||
[package.metadata.wasm-pack.profile.release]
|
||||
wasm-opt = ["-O4", "--flexible-inline-max-function-size", "4294967295"]
|
||||
|
||||
|
||||
|
||||
312
abis/DataAttestation.json
Normal file
312
abis/DataAttestation.json
Normal file
@@ -0,0 +1,312 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_contractAddresses",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "_callData",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "_decimals",
|
||||
"type": "uint256[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "_bits",
|
||||
"type": "uint256[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "_instanceOffset",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "HALF_ORDER",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ORDER",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "instances",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"name": "attestData",
|
||||
"outputs": [],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "callData",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "contractAddress",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "encoded",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "getInstancesCalldata",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "instances",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "encoded",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "getInstancesMemory",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "instances",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "index",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getScalars",
|
||||
"outputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "decimals",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "bits",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"internalType": "struct DataAttestation.Scalars",
|
||||
"name": "",
|
||||
"type": "tuple"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "instanceOffset",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "x",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "y",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "denominator",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "mulDiv",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "result",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "int256",
|
||||
"name": "x",
|
||||
"type": "int256"
|
||||
},
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "decimals",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "bits",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"internalType": "struct DataAttestation.Scalars",
|
||||
"name": "_scalars",
|
||||
"type": "tuple"
|
||||
}
|
||||
],
|
||||
"name": "quantizeData",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "int256",
|
||||
"name": "quantized_data",
|
||||
"type": "int256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "staticCall",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "int256",
|
||||
"name": "x",
|
||||
"type": "int256"
|
||||
}
|
||||
],
|
||||
"name": "toFieldElement",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "field_element",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "verifier",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "encoded",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "verifyWithDataAttestation",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
98
abis/QuantizeData.json
Normal file
98
abis/QuantizeData.json
Normal file
@@ -0,0 +1,98 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "int256[]",
|
||||
"name": "quantized_data",
|
||||
"type": "int256[]"
|
||||
}
|
||||
],
|
||||
"name": "check_is_valid_field_element",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "output",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes[]",
|
||||
"name": "data",
|
||||
"type": "bytes[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "decimals",
|
||||
"type": "uint256[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "scales",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"name": "quantize_data_multi",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "int256[]",
|
||||
"name": "quantized_data",
|
||||
"type": "int256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "decimals",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "scales",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"name": "quantize_data_single",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "int256[]",
|
||||
"name": "quantized_data",
|
||||
"type": "int256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "int64[]",
|
||||
"name": "quantized_data",
|
||||
"type": "int64[]"
|
||||
}
|
||||
],
|
||||
"name": "to_field_element",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "output",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
32
abis/TestReads.json
Normal file
32
abis/TestReads.json
Normal file
@@ -0,0 +1,32 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "int256[]",
|
||||
"name": "_numbers",
|
||||
"type": "int256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "arr",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "int256",
|
||||
"name": "",
|
||||
"type": "int256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
@@ -9,6 +9,6 @@ pytest==8.1.1
|
||||
tomli==2.0.1
|
||||
typing-extensions==4.10.0
|
||||
zipp==3.18.1
|
||||
onnx==1.17.0
|
||||
onnx==1.15.0
|
||||
onnxruntime==1.17.1
|
||||
numpy==1.26.4
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2025-05-01"
|
||||
channel = "nightly-2025-02-17"
|
||||
components = ["rustfmt", "clippy"]
|
||||
|
||||
229
setup-gpu.sh
229
setup-gpu.sh
@@ -1,229 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Default installation directory
|
||||
DEFAULT_INSTALL_DIR="/opt/icicle/lib/backend/halo2"
|
||||
|
||||
# Halo2 repository details
|
||||
HALO2_REPO="https://github.com/zkonduit/halo2"
|
||||
HALO2_BRANCH="ac/conditional-compilation-icicle2"
|
||||
|
||||
# Parse command line arguments
|
||||
AUTO_YES=false
|
||||
for arg in "$@"; do
|
||||
case $arg in
|
||||
-y|--yes)
|
||||
AUTO_YES=true
|
||||
shift
|
||||
;;
|
||||
-h|--help)
|
||||
echo "Usage: $0 [OPTIONS]"
|
||||
echo "Options:"
|
||||
echo " -y, --yes Automatically answer 'yes' to all prompts"
|
||||
echo " -h, --help Show this help message"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $arg"
|
||||
echo "Use -h or --help for usage information"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo -e "${GREEN}EZKL GPU Setup Script${NC}"
|
||||
echo -e "${GREEN}=====================${NC}"
|
||||
echo ""
|
||||
|
||||
# Parse commit hash from Cargo.lock
|
||||
echo "Parsing halo2 commit hash from Cargo.lock..."
|
||||
if [ ! -f "Cargo.lock" ]; then
|
||||
echo -e "${RED}Error: Cargo.lock not found. Please run this script from the project root.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
HALO2_COMMIT=$(grep "github\.com/zkonduit/halo2?" Cargo.lock | grep -v "halo2wrong" | head -1 | grep -o "#[a-f0-9]\{40\}" | cut -c2-)
|
||||
|
||||
if [ -z "$HALO2_COMMIT" ]; then
|
||||
echo -e "${RED}Error: Could not parse halo2 commit hash from Cargo.lock${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Found halo2 commit: $HALO2_COMMIT${NC}"
|
||||
echo ""
|
||||
echo "This script will:"
|
||||
echo "1. Sparse checkout the halo2 repository at commit $HALO2_COMMIT"
|
||||
echo "2. Extract only the icicle/backend/cuda/ directory"
|
||||
echo "3. Set the ICICLE_BACKEND_INSTALL_DIR environment variable"
|
||||
echo ""
|
||||
|
||||
# Check if user wants to override the default directory
|
||||
if [ "$AUTO_YES" = true ]; then
|
||||
INSTALL_DIR="$DEFAULT_INSTALL_DIR"
|
||||
echo -e "${GREEN}Using default installation directory: ${INSTALL_DIR}${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}Default installation directory: ${DEFAULT_INSTALL_DIR}${NC}"
|
||||
read -p "Do you want to use a different directory? [y/N]: " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
read -p "Enter the installation directory: " INSTALL_DIR
|
||||
INSTALL_DIR="${INSTALL_DIR/#\~/$HOME}" # Expand ~ to $HOME
|
||||
else
|
||||
INSTALL_DIR="$DEFAULT_INSTALL_DIR"
|
||||
fi
|
||||
|
||||
# Confirm the installation directory
|
||||
echo ""
|
||||
echo -e "${YELLOW}Installation directory: ${INSTALL_DIR}${NC}"
|
||||
read -p "Continue with this directory? [y/N]: " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo -e "${RED}Setup cancelled by user.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Check if ICICLE_BACKEND_INSTALL_DIR is already set
|
||||
if [ ! -z "$ICICLE_BACKEND_INSTALL_DIR" ] && [ "$AUTO_YES" = false ]; then
|
||||
echo ""
|
||||
echo -e "${YELLOW}Warning: ICICLE_BACKEND_INSTALL_DIR is already set to: $ICICLE_BACKEND_INSTALL_DIR${NC}"
|
||||
read -p "Do you want to override it? [y/N]: " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo -e "${RED}Setup cancelled by user.${NC}"
|
||||
exit 1
|
||||
fi
|
||||
elif [ ! -z "$ICICLE_BACKEND_INSTALL_DIR" ] && [ "$AUTO_YES" = true ]; then
|
||||
echo -e "${GREEN}Overriding existing ICICLE_BACKEND_INSTALL_DIR (was: $ICICLE_BACKEND_INSTALL_DIR)${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}Starting GPU setup...${NC}"
|
||||
|
||||
# Create installation directory
|
||||
echo "Creating installation directory..."
|
||||
mkdir -p "$INSTALL_DIR"
|
||||
|
||||
# Create temporary directory for sparse checkout
|
||||
TEMP_DIR=$(mktemp -d)
|
||||
echo "Using temporary directory: $TEMP_DIR"
|
||||
|
||||
# Clone with sparse checkout
|
||||
echo "Cloning halo2 repository with sparse checkout..."
|
||||
cd "$TEMP_DIR"
|
||||
git clone --filter=blob:none --sparse "$HALO2_REPO" halo2
|
||||
cd halo2
|
||||
|
||||
# Checkout the specific branch and commit
|
||||
echo "Checking out branch $HALO2_BRANCH at commit $HALO2_COMMIT..."
|
||||
git checkout "$HALO2_BRANCH"
|
||||
git checkout "$HALO2_COMMIT"
|
||||
|
||||
# Configure sparse checkout
|
||||
echo "Configuring sparse checkout for icicle/backend/cuda/..."
|
||||
git sparse-checkout init --cone
|
||||
git sparse-checkout set icicle/backend/cuda/
|
||||
|
||||
# Copy the icicle directory to the installation location
|
||||
if [ -d "icicle/backend/cuda" ]; then
|
||||
echo "Copying icicle/backend/cuda/ to $INSTALL_DIR..."
|
||||
cp -r icicle/backend/cuda/* "$INSTALL_DIR/"
|
||||
echo -e "${GREEN}Files copied successfully!${NC}"
|
||||
else
|
||||
echo -e "${RED}Error: icicle/backend/cuda directory not found in the repository${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clean up temporary directory
|
||||
echo "Cleaning up temporary files..."
|
||||
rm -rf "$TEMP_DIR"
|
||||
|
||||
# Ask user about setting environment variable permanently
|
||||
SETUP_PERMANENT_ENV=false
|
||||
if [ "$AUTO_YES" = true ]; then
|
||||
SETUP_PERMANENT_ENV=true
|
||||
echo ""
|
||||
echo -e "${GREEN}Setting ICICLE_BACKEND_INSTALL_DIR environment variable permanently...${NC}"
|
||||
else
|
||||
echo ""
|
||||
echo -e "${YELLOW}Do you want to set ICICLE_BACKEND_INSTALL_DIR environment variable permanently?${NC}"
|
||||
echo "This will add 'export ICICLE_BACKEND_INSTALL_DIR=\"$INSTALL_DIR\"' to your shell configuration file."
|
||||
read -p "Set environment variable permanently? [y/N]: " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
SETUP_PERMANENT_ENV=true
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$SETUP_PERMANENT_ENV" = true ]; then
|
||||
echo "Setting ICICLE_BACKEND_INSTALL_DIR environment variable..."
|
||||
|
||||
# Detect shell and set environment variable accordingly
|
||||
if [ -n "$ZSH_VERSION" ]; then
|
||||
SHELL_RC="$HOME/.zshrc"
|
||||
elif [ -n "$BASH_VERSION" ]; then
|
||||
SHELL_RC="$HOME/.bashrc"
|
||||
else
|
||||
# Try to detect based on $SHELL
|
||||
case "$SHELL" in
|
||||
*/zsh)
|
||||
SHELL_RC="$HOME/.zshrc"
|
||||
;;
|
||||
*/bash)
|
||||
SHELL_RC="$HOME/.bashrc"
|
||||
;;
|
||||
*)
|
||||
SHELL_RC="$HOME/.profile"
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Add environment variable to shell configuration
|
||||
ENV_EXPORT="export ICICLE_BACKEND_INSTALL_DIR=\"$INSTALL_DIR\""
|
||||
|
||||
# Check if the variable is already set in the file
|
||||
if [ -f "$SHELL_RC" ] && grep -q "ICICLE_BACKEND_INSTALL_DIR" "$SHELL_RC"; then
|
||||
# Replace existing line
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# macOS
|
||||
sed -i '' "s|export ICICLE_BACKEND_INSTALL_DIR=.*|$ENV_EXPORT|" "$SHELL_RC"
|
||||
else
|
||||
# Linux
|
||||
sed -i "s|export ICICLE_BACKEND_INSTALL_DIR=.*|$ENV_EXPORT|" "$SHELL_RC"
|
||||
fi
|
||||
echo "Updated existing ICICLE_BACKEND_INSTALL_DIR in $SHELL_RC"
|
||||
else
|
||||
# Add new line
|
||||
echo "$ENV_EXPORT" >> "$SHELL_RC"
|
||||
echo "Added ICICLE_BACKEND_INSTALL_DIR to $SHELL_RC"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Environment variable set permanently.${NC}"
|
||||
else
|
||||
echo "Skipping permanent environment variable setup."
|
||||
fi
|
||||
|
||||
# Export for current session regardless
|
||||
export ICICLE_BACKEND_INSTALL_DIR="$INSTALL_DIR"
|
||||
echo "Environment variable set for current session."
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}GPU setup completed successfully!${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Important:${NC}"
|
||||
echo "1. The ICICLE_BACKEND_INSTALL_DIR environment variable has been set to: $INSTALL_DIR"
|
||||
if [ "$SETUP_PERMANENT_ENV" = true ]; then
|
||||
echo "2. Please restart your terminal or run: source $SHELL_RC"
|
||||
else
|
||||
echo "2. To use GPU features, set: export ICICLE_BACKEND_INSTALL_DIR=\"$INSTALL_DIR\""
|
||||
fi
|
||||
echo "3. You can now build with GPU support using: cargo build --features gpu-accelerated"
|
||||
echo ""
|
||||
echo -e "${GREEN}Setup complete!${NC}"
|
||||
@@ -15,6 +15,9 @@ use log::{error, info};
|
||||
#[cfg(not(any(target_arch = "wasm32", feature = "no-banner")))]
|
||||
use rand::prelude::SliceRandom;
|
||||
#[cfg(all(feature = "ezkl", not(target_arch = "wasm32")))]
|
||||
#[cfg(feature = "icicle")]
|
||||
use std::env;
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
#[cfg(all(feature = "ezkl", not(target_arch = "wasm32")))]
|
||||
pub async fn main() {
|
||||
@@ -28,7 +31,12 @@ pub async fn main() {
|
||||
init_logger();
|
||||
#[cfg(not(any(target_arch = "wasm32", feature = "no-banner")))]
|
||||
banner();
|
||||
|
||||
#[cfg(feature = "icicle")]
|
||||
if env::var("ENABLE_ICICLE_GPU").is_ok() {
|
||||
info!("Running with ICICLE GPU");
|
||||
} else {
|
||||
info!("Running with CPU");
|
||||
}
|
||||
debug!(
|
||||
"command: \n {}",
|
||||
&command.as_json().to_colored_json_auto().unwrap()
|
||||
|
||||
@@ -93,6 +93,17 @@ impl From<PyG1> for G1 {
|
||||
}
|
||||
}
|
||||
|
||||
impl pyo3::ToPyObject for PyG1 {
|
||||
fn to_object(&self, py: pyo3::Python) -> pyo3::PyObject {
|
||||
let g1_dict = pyo3::types::PyDict::new(py);
|
||||
|
||||
g1_dict.set_item("x", self.x.to_object(py)).unwrap();
|
||||
g1_dict.set_item("y", self.y.to_object(py)).unwrap();
|
||||
g1_dict.set_item("z", self.z.to_object(py)).unwrap();
|
||||
g1_dict.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// pyclass containing the struct used for G1
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -124,6 +135,16 @@ impl From<PyG1Affine> for G1Affine {
|
||||
}
|
||||
}
|
||||
|
||||
impl pyo3::ToPyObject for PyG1Affine {
|
||||
fn to_object(&self, py: pyo3::Python) -> pyo3::PyObject {
|
||||
let g1_dict = pyo3::types::PyDict::new(py);
|
||||
|
||||
g1_dict.set_item("x", self.x.to_object(py)).unwrap();
|
||||
g1_dict.set_item("y", self.y.to_object(py)).unwrap();
|
||||
g1_dict.into()
|
||||
}
|
||||
}
|
||||
|
||||
/// Python class containing the struct used for run_args
|
||||
///
|
||||
/// Returns
|
||||
@@ -140,9 +161,6 @@ struct PyRunArgs {
|
||||
#[pyo3(get, set)]
|
||||
/// int: The denominator in the fixed point representation used when quantizing parameters
|
||||
pub param_scale: crate::Scale,
|
||||
/// int: The scale to rebase to (optional). If None, we rebase to the max of input_scale and param_scale
|
||||
/// This is an advanced parameter that should be used with caution
|
||||
pub rebase_scale: Option<crate::Scale>,
|
||||
#[pyo3(get, set)]
|
||||
/// int: If the scale is ever > scale_rebase_multiplier * input_scale then the scale is rebased to input_scale (this a more advanced parameter, use with caution)
|
||||
pub scale_rebase_multiplier: u32,
|
||||
@@ -209,7 +227,6 @@ impl From<PyRunArgs> for RunArgs {
|
||||
bounded_log_lookup: py_run_args.bounded_log_lookup,
|
||||
input_scale: py_run_args.input_scale,
|
||||
param_scale: py_run_args.param_scale,
|
||||
rebase_scale: py_run_args.rebase_scale,
|
||||
num_inner_cols: py_run_args.num_inner_cols,
|
||||
scale_rebase_multiplier: py_run_args.scale_rebase_multiplier,
|
||||
lookup_range: py_run_args.lookup_range,
|
||||
@@ -236,7 +253,6 @@ impl Into<PyRunArgs> for RunArgs {
|
||||
bounded_log_lookup: self.bounded_log_lookup,
|
||||
input_scale: self.input_scale,
|
||||
param_scale: self.param_scale,
|
||||
rebase_scale: self.rebase_scale,
|
||||
num_inner_cols: self.num_inner_cols,
|
||||
scale_rebase_multiplier: self.scale_rebase_multiplier,
|
||||
lookup_range: self.lookup_range,
|
||||
@@ -678,7 +694,7 @@ fn ipa_commit(
|
||||
.map_err(|_| PyIOError::new_err("Failed to load circuit settings"))?;
|
||||
|
||||
let srs_path =
|
||||
crate::execute::get_srs_path(settings.run_args.logrows, srs_path, Commitments::IPA);
|
||||
crate::execute::get_srs_path(settings.run_args.logrows, srs_path, Commitments::KZG);
|
||||
|
||||
let srs = load_srs_prover::<IPACommitmentScheme<G1Affine>>(srs_path)
|
||||
.map_err(|_| PyIOError::new_err("Failed to load srs"))?;
|
||||
@@ -868,7 +884,7 @@ fn gen_srs(srs_path: PathBuf, logrows: usize) -> PyResult<()> {
|
||||
))]
|
||||
#[gen_stub_pyfunction]
|
||||
fn get_srs(
|
||||
py: Python<'_>,
|
||||
py: Python,
|
||||
settings_path: Option<PathBuf>,
|
||||
logrows: Option<u32>,
|
||||
srs_path: Option<PathBuf>,
|
||||
@@ -1085,7 +1101,7 @@ fn gen_witness(
|
||||
let err_str = format!("Failed to generate witness: {}", e);
|
||||
PyRuntimeError::new_err(err_str)
|
||||
})?;
|
||||
Python::with_gil(|py| Ok(output.into_pyobject(py).unwrap().into()))
|
||||
Python::with_gil(|py| Ok(output.to_object(py)))
|
||||
}
|
||||
|
||||
/// Mocks the prover
|
||||
@@ -1267,7 +1283,7 @@ fn prove(
|
||||
PyRuntimeError::new_err(err_str)
|
||||
})?;
|
||||
|
||||
Python::with_gil(|py| Ok(snark.into_pyobject(py).unwrap().into()))
|
||||
Python::with_gil(|py| Ok(snark.to_object(py)))
|
||||
}
|
||||
|
||||
/// Verifies a given proof
|
||||
@@ -1633,7 +1649,7 @@ fn encode_evm_calldata<'a>(
|
||||
))]
|
||||
#[gen_stub_pyfunction]
|
||||
fn create_evm_verifier(
|
||||
py: Python<'_>,
|
||||
py: Python,
|
||||
vk_path: PathBuf,
|
||||
settings_path: PathBuf,
|
||||
sol_code_path: PathBuf,
|
||||
@@ -1660,7 +1676,6 @@ fn create_evm_verifier(
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "reusable-verifier")]
|
||||
/// Creates an Evm VK artifact. This command generated a VK with circuit specific meta data encoding in memory for use by the reusable H2 verifier.
|
||||
/// This is useful for deploying verifier that were otherwise too big to fit on chain and required aggregation.
|
||||
///
|
||||
@@ -1694,7 +1709,7 @@ fn create_evm_verifier(
|
||||
))]
|
||||
#[gen_stub_pyfunction]
|
||||
fn create_evm_vka(
|
||||
py: Python<'_>,
|
||||
py: Python,
|
||||
vk_path: PathBuf,
|
||||
settings_path: PathBuf,
|
||||
vka_path: PathBuf,
|
||||
@@ -1724,7 +1739,7 @@ fn create_evm_vka(
|
||||
))]
|
||||
#[gen_stub_pyfunction]
|
||||
fn deploy_evm(
|
||||
py: Python<'_>,
|
||||
py: Python,
|
||||
addr_path: PathBuf,
|
||||
rpc_url: String,
|
||||
sol_code_path: PathBuf,
|
||||
@@ -1751,7 +1766,6 @@ fn deploy_evm(
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "reusable-verifier")]
|
||||
/// Registers a VKA on the EZKL reusable verifier contract
|
||||
///
|
||||
/// Arguments
|
||||
@@ -1908,7 +1922,7 @@ fn verify_evm<'a>(
|
||||
))]
|
||||
#[gen_stub_pyfunction]
|
||||
fn create_evm_verifier_aggr(
|
||||
py: Python<'_>,
|
||||
py: Python,
|
||||
aggregation_settings: Vec<PathBuf>,
|
||||
vk_path: PathBuf,
|
||||
sol_code_path: PathBuf,
|
||||
@@ -1979,13 +1993,11 @@ fn ezkl(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
||||
m.add_function(wrap_pyfunction!(compile_circuit, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(verify_aggr, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(create_evm_verifier, m)?)?;
|
||||
#[cfg(feature = "reusable-verifier")]
|
||||
m.add_function(wrap_pyfunction!(create_evm_vka, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(deploy_evm, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(verify_evm, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(create_evm_verifier_aggr, m)?)?;
|
||||
m.add_function(wrap_pyfunction!(encode_evm_calldata, m)?)?;
|
||||
#[cfg(feature = "reusable-verifier")]
|
||||
m.add_function(wrap_pyfunction!(register_vka, m)?)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -7,7 +7,11 @@ use halo2_proofs::{
|
||||
};
|
||||
use log::debug;
|
||||
#[cfg(feature = "python-bindings")]
|
||||
use pyo3::{conversion::FromPyObject, exceptions::PyValueError, prelude::*, IntoPyObject};
|
||||
use pyo3::{
|
||||
conversion::{FromPyObject, IntoPy},
|
||||
exceptions::PyValueError,
|
||||
prelude::*,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
#[cfg(all(feature = "ezkl", not(target_arch = "wasm32")))]
|
||||
use tosubcommand::ToFlags;
|
||||
@@ -82,17 +86,12 @@ impl CheckMode {
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
/// Converts CheckMode into a PyObject (Required for CheckMode to be compatible with Python)
|
||||
impl<'py> IntoPyObject<'py> for CheckMode {
|
||||
type Target = pyo3::PyAny;
|
||||
type Output = pyo3::Bound<'py, Self::Target>;
|
||||
type Error = pyo3::PyErr;
|
||||
|
||||
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
|
||||
let result = match self {
|
||||
CheckMode::SAFE => "safe",
|
||||
CheckMode::UNSAFE => "unsafe",
|
||||
};
|
||||
Ok(result.into_pyobject(py)?.into_any())
|
||||
impl IntoPy<PyObject> for CheckMode {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
match self {
|
||||
CheckMode::SAFE => "safe".to_object(py),
|
||||
CheckMode::UNSAFE => "unsafe".to_object(py),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4626,7 +4626,7 @@ pub(crate) fn rescale<F: PrimeField + TensorType + PartialOrd + std::hash::Hash>
|
||||
let mut rescaled_inputs = vec![];
|
||||
for (i, ri) in values.iter().enumerate() {
|
||||
if scales[i].1 == 1 {
|
||||
rescaled_inputs.push((*ri).clone());
|
||||
rescaled_inputs.push(ri.clone().clone());
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -5709,13 +5709,13 @@ pub fn ln<F: PrimeField + TensorType + PartialOrd + std::hash::Hash>(
|
||||
let abs_distance_to_prior_pow2 = l1_distance(config, region, &[&input, &prior_pow2])?;
|
||||
|
||||
// because we round up this can be equal
|
||||
let is_closest_to_0: ValTensor<F> = less_equal(
|
||||
let is_closest_to_0: ValTensor<F> = less(
|
||||
config,
|
||||
region,
|
||||
&[&abs_distance_to_claimed, &abs_distance_to_next_pow2],
|
||||
)?;
|
||||
|
||||
let is_closest_to_1 = less_equal(
|
||||
let is_closest_to_1 = less(
|
||||
config,
|
||||
region,
|
||||
&[&abs_distance_to_claimed, &abs_distance_to_prior_pow2],
|
||||
|
||||
@@ -364,15 +364,7 @@ impl<
|
||||
};
|
||||
Ok(Some(if self.decomp {
|
||||
log::debug!("constraining constant to be decomp");
|
||||
super::layouts::decompose(
|
||||
config,
|
||||
region,
|
||||
&[&value],
|
||||
®ion.base(),
|
||||
®ion.legs(),
|
||||
false,
|
||||
)?
|
||||
.1
|
||||
super::layouts::decompose(config, region, &[&value], ®ion.base(), ®ion.legs(), false)?.1
|
||||
} else {
|
||||
log::debug!("constraining constant to be identity");
|
||||
super::layouts::identity(config, region, &[&value])?
|
||||
|
||||
@@ -93,17 +93,12 @@ pub const DEFAULT_VKA_DIGEST: &str = "vka.digest";
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
/// Converts TranscriptType into a PyObject (Required for TranscriptType to be compatible with Python)
|
||||
impl<'py> IntoPyObject<'py> for TranscriptType {
|
||||
type Target = pyo3::PyAny;
|
||||
type Output = pyo3::Bound<'py, Self::Target>;
|
||||
type Error = pyo3::PyErr;
|
||||
|
||||
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
|
||||
let result = match self {
|
||||
TranscriptType::Poseidon => "poseidon",
|
||||
TranscriptType::EVM => "evm",
|
||||
};
|
||||
Ok(result.into_pyobject(py)?.into_any())
|
||||
impl IntoPy<PyObject> for TranscriptType {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
match self {
|
||||
TranscriptType::Poseidon => "poseidon".to_object(py),
|
||||
TranscriptType::EVM => "evm".to_object(py),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "python-bindings")]
|
||||
@@ -262,20 +257,17 @@ impl From<&str> for H160Flag {
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
/// Converts CalibrationTarget into a PyObject (Required for CalibrationTarget to be compatible with Python)
|
||||
impl<'py> IntoPyObject<'py> for CalibrationTarget {
|
||||
type Target = pyo3::PyAny;
|
||||
type Output = pyo3::Bound<'py, Self::Target>;
|
||||
type Error = pyo3::PyErr;
|
||||
|
||||
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
|
||||
let result = match self {
|
||||
CalibrationTarget::Resources { col_overflow: true } => "resources/col-overflow",
|
||||
impl IntoPy<PyObject> for CalibrationTarget {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
match self {
|
||||
CalibrationTarget::Resources { col_overflow: true } => {
|
||||
"resources/col-overflow".to_object(py)
|
||||
}
|
||||
CalibrationTarget::Resources {
|
||||
col_overflow: false,
|
||||
} => "resources",
|
||||
CalibrationTarget::Accuracy => "accuracy",
|
||||
};
|
||||
Ok(result.into_pyobject(py)?.into_any())
|
||||
} => "resources".to_object(py),
|
||||
CalibrationTarget::Accuracy => "accuracy".to_object(py),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -297,17 +289,12 @@ impl<'source> FromPyObject<'source> for CalibrationTarget {
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
/// Converts ContractType into a PyObject (Required for ContractType to be compatible with Python)
|
||||
impl<'py> IntoPyObject<'py> for ContractType {
|
||||
type Target = pyo3::PyAny;
|
||||
type Output = pyo3::Bound<'py, Self::Target>;
|
||||
type Error = pyo3::PyErr;
|
||||
|
||||
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
|
||||
let result = match self {
|
||||
ContractType::Verifier { reusable: true } => "verifier/reusable",
|
||||
ContractType::Verifier { reusable: false } => "verifier",
|
||||
};
|
||||
Ok(result.into_pyobject(py)?.into_any())
|
||||
impl IntoPy<PyObject> for ContractType {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
match self {
|
||||
ContractType::Verifier { reusable: true } => "verifier/reusable".to_object(py),
|
||||
ContractType::Verifier { reusable: false } => "verifier".to_object(py),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -726,7 +713,7 @@ pub enum Commands {
|
||||
#[arg(long, default_value = DEFAULT_CALLDATA, value_hint = clap::ValueHint::FilePath)]
|
||||
calldata_path: Option<PathBuf>,
|
||||
/// The path to the serialized VKA file
|
||||
#[cfg_attr(all(feature = "reusable-verifier", not(target_arch = "wasm32")), arg(long, value_hint = clap::ValueHint::Other))]
|
||||
#[arg(long, value_hint = clap::ValueHint::Other)]
|
||||
vka_path: Option<PathBuf>,
|
||||
},
|
||||
/// Creates an Evm verifier for a single proof
|
||||
@@ -748,17 +735,13 @@ pub enum Commands {
|
||||
/// The path to output the Solidity verifier ABI
|
||||
#[arg(long, default_value = DEFAULT_VERIFIER_ABI, value_hint = clap::ValueHint::FilePath)]
|
||||
abi_path: Option<PathBuf>,
|
||||
/// Whether to render the verifier as reusable or not. If true, you will need to deploy a VK artifact, passing it as part of the calldata to the verifier.
|
||||
#[cfg_attr(all(feature = "reusable-verifier", not(target_arch = "wasm32")), arg(short = 'R', long, default_value = DEFAULT_RENDER_REUSABLE, action = clap::ArgAction::SetTrue))]
|
||||
/// Whether the to render the verifier as reusable or not. If true, you will need to deploy a VK artifact, passing it as part of the calldata to the verifier.
|
||||
#[arg(long, default_value = DEFAULT_RENDER_REUSABLE, action = clap::ArgAction::SetTrue)]
|
||||
reusable: Option<bool>,
|
||||
},
|
||||
/// Creates an evm verifier artifact to be used by the reusable verifier
|
||||
#[command(name = "create-evm-vka")]
|
||||
#[cfg(all(
|
||||
feature = "eth",
|
||||
feature = "reusable-verifier",
|
||||
not(target_arch = "wasm32")
|
||||
))]
|
||||
#[cfg(all(feature = "eth", not(target_arch = "wasm32")))]
|
||||
CreateEvmVka {
|
||||
/// The path to SRS, if None will use ~/.ezkl/srs/kzg{logrows}.srs
|
||||
#[arg(long, value_hint = clap::ValueHint::FilePath)]
|
||||
@@ -800,8 +783,8 @@ pub enum Commands {
|
||||
// logrows used for aggregation circuit
|
||||
#[arg(long, default_value = DEFAULT_AGGREGATED_LOGROWS, value_hint = clap::ValueHint::Other)]
|
||||
logrows: Option<u32>,
|
||||
/// Whether to render the verifier as reusable or not. If true, you will need to deploy a VK artifact, passing it as part of the calldata to the verifier.
|
||||
#[cfg_attr(all(feature = "reusable-verifier", not(target_arch = "wasm32")), arg(short = 'R', long, action = clap::ArgAction::SetTrue))]
|
||||
/// Whether the to render the verifier as reusable or not. If true, you will need to deploy a VK artifact, passing it as part of the calldata to the verifier.
|
||||
#[arg(long, default_value = DEFAULT_RENDER_REUSABLE, action = clap::ArgAction::SetTrue)]
|
||||
reusable: Option<bool>,
|
||||
},
|
||||
/// Verifies a proof, returning accept or reject
|
||||
@@ -862,7 +845,6 @@ pub enum Commands {
|
||||
#[arg(short = 'P', long, value_hint = clap::ValueHint::Other)]
|
||||
private_key: Option<String>,
|
||||
/// Contract type to be deployed
|
||||
#[cfg(all(feature = "reusable-verifier", not(target_arch = "wasm32")))]
|
||||
#[arg(long = "contract-type", short = 'C', default_value = DEFAULT_CONTRACT_DEPLOYMENT_TYPE, value_hint = clap::ValueHint::Other)]
|
||||
contract: ContractType,
|
||||
},
|
||||
@@ -880,7 +862,7 @@ pub enum Commands {
|
||||
#[arg(short = 'U', long, value_hint = clap::ValueHint::Url)]
|
||||
rpc_url: String,
|
||||
/// The path to the serialized vka file
|
||||
#[cfg_attr(all(feature = "reusable-verifier", not(target_arch = "wasm32")), arg(long, value_hint = clap::ValueHint::FilePath))]
|
||||
#[arg(long, value_hint = clap::ValueHint::FilePath)]
|
||||
vka_path: Option<PathBuf>,
|
||||
/// The path to the serialized encoded calldata file generated via the encode_calldata command
|
||||
#[arg(long, value_hint = clap::ValueHint::FilePath)]
|
||||
@@ -888,7 +870,7 @@ pub enum Commands {
|
||||
},
|
||||
/// Registers a VKA, returning the its digest used to identify it on-chain.
|
||||
#[command(name = "register-vka")]
|
||||
#[cfg(feature = "reusable-verifier")]
|
||||
#[cfg(all(feature = "eth", not(target_arch = "wasm32")))]
|
||||
RegisterVka {
|
||||
/// RPC URL for an Ethereum node, if None will use Anvil but WON'T persist state
|
||||
#[arg(short = 'U', long, value_hint = clap::ValueHint::Url)]
|
||||
|
||||
92
src/eth.rs
92
src/eth.rs
@@ -3,7 +3,7 @@ use crate::pfsys::{encode_calldata, Snark};
|
||||
use alloy::contract::CallBuilder;
|
||||
use alloy::core::primitives::Address as H160;
|
||||
use alloy::core::primitives::Bytes;
|
||||
use alloy::core::primitives::I256;
|
||||
use alloy::core::primitives::U256;
|
||||
use alloy::dyn_abi::abi::TokenSeq;
|
||||
// use alloy::providers::Middleware;
|
||||
use alloy::json_abi::JsonAbi;
|
||||
@@ -279,7 +279,7 @@ pub async fn verify_proof_via_solidity(
|
||||
// From result[96..], iterate through 32 byte chunks converting them to U256
|
||||
let rescaled_instances = result.to_vec()[96..]
|
||||
.chunks_exact(32)
|
||||
.map(|chunk| I256::try_from_be_slice(chunk).unwrap().to_string())
|
||||
.map(|chunk| U256::from_be_slice(chunk).to_string())
|
||||
.collect::<Vec<_>>();
|
||||
if let Some(pretty) = &proof.pretty_public_inputs {
|
||||
// 1️⃣ collect reference decimals --------------------------------------
|
||||
@@ -433,95 +433,43 @@ pub async fn get_contract_artifacts(
|
||||
///
|
||||
/// `"1541748046875000000"` → `"1.541748046875000000"`
|
||||
/// `"273690402507781982"` → `"0.273690402507781982"`
|
||||
/// `"-892333984375000000"` → `"-0.892333984375000000"`
|
||||
fn to_decimal_18(s: &str) -> String {
|
||||
let is_negative = s.starts_with('-');
|
||||
let s = if is_negative { &s[1..] } else { s };
|
||||
let s = s.trim_start_matches('0');
|
||||
|
||||
if s.is_empty() {
|
||||
return "0".into();
|
||||
}
|
||||
|
||||
if s.len() <= 18 {
|
||||
// pad on the left so we always have exactly 18 fraction digits
|
||||
let result = format!("0.{:0>18}", s);
|
||||
return if is_negative {
|
||||
format!("-{}", result)
|
||||
} else {
|
||||
result
|
||||
};
|
||||
return format!("0.{:0>18}", s);
|
||||
}
|
||||
|
||||
let split = s.len() - 18;
|
||||
let result = format!("{}.{}", &s[..split], &s[split..]);
|
||||
if is_negative {
|
||||
format!("-{}", result)
|
||||
} else {
|
||||
result
|
||||
}
|
||||
format!("{}.{}", &s[..split], &s[split..]) // ← correct slice here
|
||||
}
|
||||
/// "Banker's‐round" comparison: compare the **decimal** produced
|
||||
|
||||
/// “Banker’s‐round” comparison: compare the **decimal** produced
|
||||
/// by `instance` to the reference string `expected`.
|
||||
///
|
||||
/// * Only the first 18 digits of the expected fraction part are compared.
|
||||
/// * All digits present in the truncated `expected` (integer part **and** first 18 fraction digits)
|
||||
/// * All digits present in `expected` (integer part **and** fraction)
|
||||
/// must match exactly.
|
||||
/// * Excess digits in `instance` are ignored **unless** the very first
|
||||
/// excess digit ≥ 5; in that case we round the last compared digit
|
||||
/// excess digit ≥ 5; in that case we round the last compared digit
|
||||
/// and check again.
|
||||
fn scaled_matches(instance: &str, expected: &str) -> bool {
|
||||
let inst_dec = to_decimal_18(instance);
|
||||
let (inst_int, inst_frac) = inst_dec.split_once('.').unwrap_or((&inst_dec, ""));
|
||||
let (exp_int, exp_frac) = expected.split_once('.').unwrap_or((expected, ""));
|
||||
|
||||
// Normalize both integer parts to handle "-" vs "-0"
|
||||
let normalized_inst_int = if inst_int == "-" { "-0" } else { inst_int };
|
||||
let normalized_exp_int = if exp_int == "-" { "-0" } else { exp_int };
|
||||
|
||||
// integer part must be identical
|
||||
if normalized_inst_int != normalized_exp_int {
|
||||
if inst_int != exp_int {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If expected has more than 18 decimal places, round it to 18 places
|
||||
let exp_frac_truncated = if exp_frac.len() > 18 {
|
||||
let truncated = &exp_frac[..18];
|
||||
let next_digit = exp_frac.chars().nth(18).unwrap_or('0');
|
||||
|
||||
if next_digit >= '6' {
|
||||
// Need to round up the 18th digit
|
||||
let mut rounded = truncated.chars().collect::<Vec<_>>();
|
||||
let mut carry = true;
|
||||
for d in rounded.iter_mut().rev() {
|
||||
if !carry {
|
||||
break;
|
||||
}
|
||||
let v = d.to_digit(10).unwrap() + 1;
|
||||
*d = char::from_digit(v % 10, 10).unwrap();
|
||||
carry = v == 10;
|
||||
}
|
||||
if carry {
|
||||
// All 18 digits were 9s - this would carry to integer part
|
||||
// For now, return the original truncated (this edge case may need special handling)
|
||||
truncated.to_string()
|
||||
} else {
|
||||
rounded.into_iter().collect::<String>()
|
||||
}
|
||||
} else {
|
||||
truncated.to_string()
|
||||
}
|
||||
} else {
|
||||
exp_frac.to_string()
|
||||
};
|
||||
let exp_frac_truncated = exp_frac_truncated.as_str();
|
||||
|
||||
// fraction‑part comparison with optional rounding
|
||||
let cmp_len = exp_frac_truncated.len();
|
||||
let cmp_len = exp_frac.len();
|
||||
let inst_cmp = &inst_frac[..cmp_len.min(inst_frac.len())];
|
||||
let trailing = inst_frac.chars().nth(cmp_len).unwrap_or('0');
|
||||
|
||||
if inst_cmp == exp_frac_truncated {
|
||||
if inst_cmp == exp_frac {
|
||||
true // exact match
|
||||
} else if trailing >= '5' {
|
||||
// need to round
|
||||
@@ -538,20 +486,12 @@ fn scaled_matches(instance: &str, expected: &str) -> bool {
|
||||
}
|
||||
if carry {
|
||||
// 0.999… → 1.000…
|
||||
// Handle negative numbers in the carry case
|
||||
let is_negative = normalized_inst_int.starts_with('-');
|
||||
let abs_int = normalized_inst_int.trim_start_matches('-');
|
||||
let incremented =
|
||||
(num::BigUint::parse_bytes(abs_int.as_bytes(), 10).unwrap() + 1u32).to_string();
|
||||
let expected_after_carry = if is_negative {
|
||||
format!("-{}", incremented)
|
||||
} else {
|
||||
incremented
|
||||
};
|
||||
return normalized_exp_int == expected_after_carry
|
||||
&& exp_frac_truncated.chars().all(|c| c == '0');
|
||||
return exp_int
|
||||
== &(num::BigUint::parse_bytes(exp_int.as_bytes(), 10).unwrap() + 1u32)
|
||||
.to_string()
|
||||
&& exp_frac.chars().all(|c| c == '0');
|
||||
}
|
||||
rounded.into_iter().collect::<String>() == exp_frac_truncated
|
||||
rounded.into_iter().collect::<String>() == exp_frac
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ use crate::circuit::region::RegionSettings;
|
||||
use crate::circuit::CheckMode;
|
||||
use crate::commands::CalibrationTarget;
|
||||
#[cfg(all(feature = "eth", not(target_arch = "wasm32")))]
|
||||
use crate::eth::deploy_contract_via_solidity;
|
||||
#[cfg(all(feature = "reusable-verifier", not(target_arch = "wasm32")))]
|
||||
use crate::eth::register_vka_via_rv;
|
||||
use crate::eth::{deploy_contract_via_solidity, register_vka_via_rv};
|
||||
#[allow(unused_imports)]
|
||||
#[cfg(all(feature = "eth", not(target_arch = "wasm32")))]
|
||||
use crate::eth::{get_contract_artifacts, verify_proof_via_solidity};
|
||||
@@ -26,8 +24,6 @@ use colored::Colorize;
|
||||
#[cfg(unix)]
|
||||
use gag::Gag;
|
||||
use halo2_proofs::dev::VerifyFailure;
|
||||
#[cfg(feature = "gpu-accelerated")]
|
||||
use halo2_proofs::icicle::try_load_and_set_backend_device;
|
||||
use halo2_proofs::plonk::{self, Circuit};
|
||||
use halo2_proofs::poly::commitment::{CommitmentScheme, Params};
|
||||
use halo2_proofs::poly::commitment::{ParamsProver, Verifier};
|
||||
@@ -48,8 +44,6 @@ use halo2_solidity_verifier;
|
||||
use halo2curves::bn256::{Bn256, Fr, G1Affine};
|
||||
use halo2curves::ff::{FromUniformBytes, WithSmallOrderMulGroup};
|
||||
use halo2curves::serde::SerdeObject;
|
||||
#[cfg(feature = "gpu-accelerated")]
|
||||
use icicle_runtime::{stream::IcicleStream, warmup};
|
||||
use indicatif::{ProgressBar, ProgressStyle};
|
||||
use instant::Instant;
|
||||
use itertools::Itertools;
|
||||
@@ -91,22 +85,6 @@ lazy_static! {
|
||||
|
||||
}
|
||||
|
||||
/// Set the device used for computation.
|
||||
#[cfg(feature = "gpu-accelerated")]
|
||||
pub fn set_device() {
|
||||
if std::env::var("ICICLE_BACKEND_INSTALL_DIR").is_ok() {
|
||||
info!("Running with ICICLE GPU");
|
||||
try_load_and_set_backend_device("CUDA");
|
||||
match warmup(&IcicleStream::default()) {
|
||||
Ok(_) => info!("GPU warmed :)"),
|
||||
Err(e) => log::error!("GPU warmup failed: {:?}", e),
|
||||
}
|
||||
} else {
|
||||
info!("Running with CPU: 'ICICLE_BACKEND_INSTALL_DIR' not set");
|
||||
try_load_and_set_backend_device("CPU");
|
||||
}
|
||||
}
|
||||
|
||||
/// A wrapper for execution errors
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ExecutionError {
|
||||
@@ -128,8 +106,6 @@ lazy_static::lazy_static! {
|
||||
|
||||
/// Run an ezkl command with given args
|
||||
pub async fn run(command: Commands) -> Result<String, EZKLError> {
|
||||
#[cfg(feature = "gpu-accelerated")]
|
||||
set_device();
|
||||
// set working dir
|
||||
std::env::set_current_dir(WORKING_DIR.as_path())?;
|
||||
|
||||
@@ -244,11 +220,7 @@ pub async fn run(command: Commands) -> Result<String, EZKLError> {
|
||||
vka_path,
|
||||
)
|
||||
.map(|e| serde_json::to_string(&e).unwrap()),
|
||||
#[cfg(all(
|
||||
feature = "eth",
|
||||
feature = "reusable-verifier",
|
||||
not(target_arch = "wasm32")
|
||||
))]
|
||||
#[cfg(all(feature = "eth", not(target_arch = "wasm32")))]
|
||||
Commands::CreateEvmVka {
|
||||
vk_path,
|
||||
srs_path,
|
||||
@@ -426,7 +398,6 @@ pub async fn run(command: Commands) -> Result<String, EZKLError> {
|
||||
addr_path,
|
||||
optimizer_runs,
|
||||
private_key,
|
||||
#[cfg(all(feature = "reusable-verifier", not(target_arch = "wasm32")))]
|
||||
contract,
|
||||
} => {
|
||||
deploy_evm(
|
||||
@@ -435,10 +406,7 @@ pub async fn run(command: Commands) -> Result<String, EZKLError> {
|
||||
addr_path.unwrap_or(DEFAULT_CONTRACT_ADDRESS.into()),
|
||||
optimizer_runs,
|
||||
private_key,
|
||||
#[cfg(all(feature = "reusable-verifier", not(target_arch = "wasm32")))]
|
||||
contract,
|
||||
#[cfg(not(all(feature = "reusable-verifier", not(target_arch = "wasm32"))))]
|
||||
ContractType::default(),
|
||||
)
|
||||
.await
|
||||
}
|
||||
@@ -459,7 +427,7 @@ pub async fn run(command: Commands) -> Result<String, EZKLError> {
|
||||
)
|
||||
.await
|
||||
}
|
||||
#[cfg(feature = "reusable-verifier")]
|
||||
#[cfg(all(feature = "eth", not(target_arch = "wasm32")))]
|
||||
Commands::RegisterVka {
|
||||
addr_verifier,
|
||||
vka_path,
|
||||
@@ -1143,7 +1111,6 @@ pub(crate) fn calibrate(
|
||||
|
||||
let mut num_failed = 0;
|
||||
let mut num_passed = 0;
|
||||
let mut failure_reasons = vec![];
|
||||
|
||||
for ((input_scale, param_scale), scale_rebase_multiplier) in range_grid {
|
||||
pb.set_message(format!(
|
||||
@@ -1176,13 +1143,6 @@ pub(crate) fn calibrate(
|
||||
Ok(c) => c,
|
||||
Err(e) => {
|
||||
error!("circuit creation from run args failed: {:?}", e);
|
||||
failure_reasons.push(format!(
|
||||
"i-scale: {}, p-scale: {}, rebase-(x): {}, reason: {}",
|
||||
input_scale.to_string().blue(),
|
||||
param_scale.to_string().blue(),
|
||||
scale_rebase_multiplier.to_string().yellow(),
|
||||
e
|
||||
));
|
||||
pb.inc(1);
|
||||
num_failed += 1;
|
||||
continue;
|
||||
@@ -1227,13 +1187,6 @@ pub(crate) fn calibrate(
|
||||
error!("forward pass failed: {:?}", e);
|
||||
pb.inc(1);
|
||||
num_failed += 1;
|
||||
failure_reasons.push(format!(
|
||||
"i-scale: {}, p-scale: {}, rebase-(x): {}, reason: {}",
|
||||
input_scale.to_string().blue(),
|
||||
param_scale.to_string().blue(),
|
||||
scale_rebase_multiplier.to_string().yellow(),
|
||||
e
|
||||
));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -1288,8 +1241,7 @@ pub(crate) fn calibrate(
|
||||
num_rows: new_settings.num_rows,
|
||||
total_assignments: new_settings.total_assignments,
|
||||
total_const_size: new_settings.total_const_size,
|
||||
dynamic_lookup_params: new_settings.dynamic_lookup_params,
|
||||
shuffle_params: new_settings.shuffle_params,
|
||||
total_dynamic_col_size: new_settings.total_dynamic_col_size,
|
||||
..settings.clone()
|
||||
};
|
||||
|
||||
@@ -1300,14 +1252,7 @@ pub(crate) fn calibrate(
|
||||
found_settings.as_json()?.to_colored_json_auto()?
|
||||
);
|
||||
num_passed += 1;
|
||||
} else if let Err(res) = res {
|
||||
failure_reasons.push(format!(
|
||||
"i-scale: {}, p-scale: {}, rebase-(x): {}, reason: {}",
|
||||
input_scale.to_string().blue(),
|
||||
param_scale.to_string().blue(),
|
||||
scale_rebase_multiplier.to_string().yellow(),
|
||||
res.to_string().red()
|
||||
));
|
||||
} else {
|
||||
num_failed += 1;
|
||||
}
|
||||
|
||||
@@ -1317,13 +1262,6 @@ pub(crate) fn calibrate(
|
||||
pb.finish_with_message("Calibration Done.");
|
||||
|
||||
if found_params.is_empty() {
|
||||
if !failure_reasons.is_empty() {
|
||||
error!("Calibration failed for the following reasons:");
|
||||
for reason in failure_reasons {
|
||||
error!("{}", reason);
|
||||
}
|
||||
}
|
||||
|
||||
return Err("calibration failed, could not find any suitable parameters given the calibration dataset".into());
|
||||
}
|
||||
|
||||
@@ -1522,7 +1460,7 @@ pub(crate) async fn create_evm_verifier(
|
||||
Ok(String::new())
|
||||
}
|
||||
|
||||
#[cfg(feature = "reusable-verifier")]
|
||||
#[cfg(all(feature = "eth", not(target_arch = "wasm32")))]
|
||||
pub(crate) async fn create_evm_vka(
|
||||
vk_path: PathBuf,
|
||||
srs_path: Option<PathBuf>,
|
||||
@@ -1530,7 +1468,6 @@ pub(crate) async fn create_evm_vka(
|
||||
vka_path: PathBuf,
|
||||
decimals: usize,
|
||||
) -> Result<String, EZKLError> {
|
||||
log::warn!("Reusable verifier support is experimental and may change in the future. Use at your own risk.");
|
||||
let settings = GraphSettings::load(&settings_path)?;
|
||||
let commitment: Commitments = settings.run_args.commitment.into();
|
||||
let params = load_params_verifier::<KZGCommitmentScheme<Bn256>>(
|
||||
@@ -1613,7 +1550,7 @@ pub(crate) async fn deploy_evm(
|
||||
Ok(String::new())
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "reusable-verifier", not(target_arch = "wasm32")))]
|
||||
#[cfg(all(feature = "eth", not(target_arch = "wasm32")))]
|
||||
pub(crate) async fn register_vka(
|
||||
rpc_url: String,
|
||||
rv_addr: H160Flag,
|
||||
@@ -1621,7 +1558,6 @@ pub(crate) async fn register_vka(
|
||||
vka_digest_path: PathBuf,
|
||||
private_key: Option<String>,
|
||||
) -> Result<String, EZKLError> {
|
||||
log::warn!("Reusable verifier support is experimental and may change in the future. Use at your own risk.");
|
||||
// Load the vka, which is bincode serialized, from the vka_path
|
||||
let bytes = std::fs::read(vka_path)?;
|
||||
let vka_buf: Vec<[u8; 32]> = bincode::deserialize(&bytes)
|
||||
|
||||
@@ -7,7 +7,9 @@ use halo2curves::bn256::Fr as Fp;
|
||||
#[cfg(feature = "python-bindings")]
|
||||
use pyo3::prelude::*;
|
||||
#[cfg(feature = "python-bindings")]
|
||||
use pyo3::IntoPyObject;
|
||||
use pyo3::types::PyDict;
|
||||
#[cfg(feature = "python-bindings")]
|
||||
use pyo3::ToPyObject;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use std::io::BufReader;
|
||||
use std::io::BufWriter;
|
||||
@@ -19,6 +21,10 @@ use tract_onnx::tract_core::{
|
||||
value::TValue,
|
||||
};
|
||||
|
||||
type Decimals = u8;
|
||||
type Call = String;
|
||||
type RPCUrl = String;
|
||||
|
||||
/// Represents different types of values that can be stored in a file source
|
||||
/// Used for handling various input types in zero-knowledge proofs
|
||||
#[derive(Clone, Debug, PartialOrd, PartialEq)]
|
||||
@@ -31,22 +37,6 @@ pub enum FileSourceInner {
|
||||
Field(Fp),
|
||||
}
|
||||
|
||||
impl From<Fp> for FileSourceInner {
|
||||
fn from(value: Fp) -> Self {
|
||||
FileSourceInner::Field(value)
|
||||
}
|
||||
}
|
||||
impl From<bool> for FileSourceInner {
|
||||
fn from(value: bool) -> Self {
|
||||
FileSourceInner::Bool(value)
|
||||
}
|
||||
}
|
||||
impl From<f64> for FileSourceInner {
|
||||
fn from(value: f64) -> Self {
|
||||
FileSourceInner::Float(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl FileSourceInner {
|
||||
/// Returns true if the value is a floating point number
|
||||
pub fn is_float(&self) -> bool {
|
||||
@@ -169,11 +159,115 @@ impl<'de> Deserialize<'de> for FileSourceInner {
|
||||
|
||||
/// A collection of input values from a file source
|
||||
/// Organized as a vector of vectors where each inner vector represents a row/entry
|
||||
pub type DataSource = Vec<Vec<FileSourceInner>>;
|
||||
pub type FileSource = Vec<Vec<FileSourceInner>>;
|
||||
|
||||
/// Represents which parts of the model (input/output) are attested to on-chain
|
||||
pub type InputOutput = (bool, bool);
|
||||
|
||||
/// Configuration for accessing on-chain data sources
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialOrd, PartialEq)]
|
||||
pub struct OnChainSource {
|
||||
/// Call specifications for fetching data
|
||||
pub call: CallToAccount,
|
||||
/// RPC endpoint URL for accessing the chain
|
||||
pub rpc: RPCUrl,
|
||||
}
|
||||
|
||||
impl OnChainSource {
|
||||
/// Creates a new OnChainSource
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `call` - Call specification
|
||||
/// * `rpc` - RPC endpoint URL
|
||||
pub fn new(call: CallToAccount, rpc: RPCUrl) -> Self {
|
||||
OnChainSource { call, rpc }
|
||||
}
|
||||
}
|
||||
|
||||
/// Specification for view-only calls to fetch on-chain data
|
||||
/// Used for data attestation in smart contract verification
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialOrd, PartialEq)]
|
||||
pub struct CallsToAccount {
|
||||
/// Vector of (call data, decimals) pairs
|
||||
/// call_data: ABI-encoded function call
|
||||
/// decimals: Number of decimal places for float conversion
|
||||
pub call_data: Vec<(Call, Decimals)>,
|
||||
/// Contract address to call
|
||||
pub address: String,
|
||||
}
|
||||
|
||||
/// Specification for a single view-only call returning an array
|
||||
#[derive(Clone, Debug, Deserialize, Serialize, Default, PartialOrd, PartialEq)]
|
||||
pub struct CallToAccount {
|
||||
/// ABI-encoded function call data
|
||||
pub call_data: Call,
|
||||
/// Number of decimal places for float conversion
|
||||
pub decimals: Vec<Decimals>,
|
||||
/// Contract address to call
|
||||
pub address: String,
|
||||
}
|
||||
|
||||
/// Represents different sources of input/output data for the EZKL model
|
||||
#[derive(Clone, Debug, Serialize, PartialOrd, PartialEq)]
|
||||
pub struct DataSource(FileSource);
|
||||
|
||||
impl DataSource {
|
||||
/// Gets the underlying file source data
|
||||
pub fn values(&self) -> &FileSource {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for DataSource {
|
||||
fn default() -> Self {
|
||||
DataSource(vec![vec![]])
|
||||
}
|
||||
}
|
||||
|
||||
impl From<FileSource> for DataSource {
|
||||
fn from(data: FileSource) -> Self {
|
||||
DataSource(data)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<Vec<Fp>>> for DataSource {
|
||||
fn from(data: Vec<Vec<Fp>>) -> Self {
|
||||
DataSource(
|
||||
data.iter()
|
||||
.map(|e| e.iter().map(|e| FileSourceInner::Field(*e)).collect())
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Vec<Vec<f64>>> for DataSource {
|
||||
fn from(data: Vec<Vec<f64>>) -> Self {
|
||||
DataSource(
|
||||
data.iter()
|
||||
.map(|e| e.iter().map(|e| FileSourceInner::Float(*e)).collect())
|
||||
.collect(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Note: Always use JSON serialization for untagged enums
|
||||
impl<'de> Deserialize<'de> for DataSource {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let this_json: Box<serde_json::value::RawValue> = Deserialize::deserialize(deserializer)?;
|
||||
|
||||
// Try deserializing as FileSource first
|
||||
let first_try: Result<FileSource, _> = serde_json::from_str(this_json.get());
|
||||
if let Ok(t) = first_try {
|
||||
return Ok(DataSource(t));
|
||||
}
|
||||
|
||||
Err(serde::de::Error::custom("failed to deserialize DataSource"))
|
||||
}
|
||||
}
|
||||
|
||||
/// Container for input and output data for graph computations
|
||||
///
|
||||
/// Important: Always use JSON serialization for GraphData to handle enum variants correctly
|
||||
@@ -203,7 +297,7 @@ impl GraphData {
|
||||
datum_types: &[tract_onnx::prelude::DatumType],
|
||||
) -> Result<TVec<TValue>, GraphError> {
|
||||
let mut inputs = TVec::new();
|
||||
for (i, input) in self.input_data.iter().enumerate() {
|
||||
for (i, input) in self.input_data.values().iter().enumerate() {
|
||||
if !input.is_empty() {
|
||||
let dt = datum_types[i];
|
||||
let input = input.iter().map(|e| e.to_float()).collect::<Vec<f64>>();
|
||||
@@ -244,7 +338,7 @@ impl GraphData {
|
||||
}
|
||||
}
|
||||
Ok(GraphData {
|
||||
input_data,
|
||||
input_data: DataSource(input_data),
|
||||
output_data: None,
|
||||
})
|
||||
}
|
||||
@@ -330,7 +424,12 @@ impl GraphData {
|
||||
) -> Result<Vec<Self>, GraphError> {
|
||||
let mut batched_inputs = vec![];
|
||||
|
||||
let iterable = self.input_data.clone();
|
||||
let iterable = match self {
|
||||
GraphData {
|
||||
input_data: DataSource(data),
|
||||
output_data: _,
|
||||
} => data.clone(),
|
||||
};
|
||||
|
||||
// Process each input tensor according to its shape
|
||||
for (i, shape) in input_shapes.iter().enumerate() {
|
||||
@@ -375,12 +474,12 @@ impl GraphData {
|
||||
for input in batched_inputs.iter() {
|
||||
batch.push(input[i].clone());
|
||||
}
|
||||
input_batches.push(batch);
|
||||
input_batches.push(DataSource(batch));
|
||||
}
|
||||
|
||||
// Ensure at least one batch exists
|
||||
if input_batches.is_empty() {
|
||||
input_batches.push(vec![vec![]]);
|
||||
input_batches.push(DataSource(vec![vec![]]));
|
||||
}
|
||||
|
||||
// Create GraphData instance for each batch
|
||||
@@ -399,14 +498,28 @@ impl GraphData {
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_data_source_serialization_round_trip() {
|
||||
// Test backwards compatibility with old format
|
||||
let source = DataSource::from(vec![vec![0.053_262_424, 0.074_970_566, 0.052_355_476]]);
|
||||
let serialized = serde_json::to_string(&source).unwrap();
|
||||
const JSON: &str = r#"[[0.053262424,0.074970566,0.052355476]]"#;
|
||||
assert_eq!(serialized, JSON);
|
||||
|
||||
let expect = serde_json::from_str::<DataSource>(JSON)
|
||||
.map_err(|e| e.to_string())
|
||||
.unwrap();
|
||||
assert_eq!(expect, source);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_graph_input_serialization_round_trip() {
|
||||
// Test serialization/deserialization of graph input
|
||||
let file = GraphData::new(vec![vec![
|
||||
0.05326242372393608.into(),
|
||||
0.07497056573629379.into(),
|
||||
0.05235547572374344.into(),
|
||||
]]);
|
||||
let file = GraphData::new(DataSource::from(vec![vec![
|
||||
0.05326242372393608,
|
||||
0.07497056573629379,
|
||||
0.05235547572374344,
|
||||
]]));
|
||||
|
||||
let serialized = serde_json::to_string(&file).unwrap();
|
||||
const JSON: &str = r#"{"input_data":[[0.05326242372393608,0.07497056573629379,0.05235547572374344]],"output_data":null}"#;
|
||||
@@ -427,23 +540,34 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
impl ToPyObject for CallToAccount {
|
||||
fn to_object(&self, py: Python) -> PyObject {
|
||||
let dict = PyDict::new(py);
|
||||
dict.set_item("account", &self.address).unwrap();
|
||||
dict.set_item("call_data", &self.call_data).unwrap();
|
||||
dict.set_item("decimals", &self.decimals).unwrap();
|
||||
dict.to_object(py)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
impl ToPyObject for DataSource {
|
||||
fn to_object(&self, py: Python) -> PyObject {
|
||||
self.0.to_object(py)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
use crate::pfsys::field_to_string;
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
impl<'py> IntoPyObject<'py> for FileSourceInner {
|
||||
type Target = pyo3::PyAny;
|
||||
type Output = pyo3::Bound<'py, Self::Target>;
|
||||
type Error = pyo3::PyErr;
|
||||
|
||||
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
|
||||
impl ToPyObject for FileSourceInner {
|
||||
fn to_object(&self, py: Python) -> PyObject {
|
||||
match self {
|
||||
FileSourceInner::Field(data) => {
|
||||
let s = field_to_string(&data);
|
||||
Ok(pyo3::types::PyString::new(py, &s).into_any())
|
||||
}
|
||||
FileSourceInner::Bool(data) => Ok(pyo3::types::PyBool::new(py, data).as_any().clone()),
|
||||
FileSourceInner::Float(data) => Ok(pyo3::types::PyFloat::new(py, data).into_any()),
|
||||
FileSourceInner::Field(data) => field_to_string(data).to_object(py),
|
||||
FileSourceInner::Bool(data) => data.to_object(py),
|
||||
FileSourceInner::Float(data) => data.to_object(py),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
702
src/graph/mod.rs
702
src/graph/mod.rs
@@ -26,11 +26,11 @@ use itertools::Itertools;
|
||||
use tosubcommand::ToFlags;
|
||||
|
||||
#[cfg(any(not(feature = "ezkl"), target_arch = "wasm32"))]
|
||||
use self::input::GraphData;
|
||||
use self::input::{FileSource, GraphData};
|
||||
|
||||
use self::errors::GraphError;
|
||||
#[cfg(all(feature = "ezkl", not(target_arch = "wasm32")))]
|
||||
use self::input::GraphData;
|
||||
use self::input::{FileSource, GraphData};
|
||||
use self::modules::{GraphModules, ModuleConfigs, ModuleForwardResult, ModuleSizes};
|
||||
use crate::circuit::lookup::LookupOp;
|
||||
use crate::circuit::modules::ModulePlanner;
|
||||
@@ -61,7 +61,7 @@ use pyo3::types::PyDict;
|
||||
#[cfg(feature = "python-bindings")]
|
||||
use pyo3::types::PyDictMethods;
|
||||
#[cfg(feature = "python-bindings")]
|
||||
use pyo3::IntoPyObject;
|
||||
use pyo3::ToPyObject;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::ops::Deref;
|
||||
@@ -319,12 +319,8 @@ impl GraphWitness {
|
||||
}
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
impl<'py> IntoPyObject<'py> for GraphWitness {
|
||||
type Target = pyo3::PyAny;
|
||||
type Output = pyo3::Bound<'py, Self::Target>;
|
||||
type Error = pyo3::PyErr;
|
||||
|
||||
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
|
||||
impl ToPyObject for GraphWitness {
|
||||
fn to_object(&self, py: Python) -> PyObject {
|
||||
// Create a Python dictionary
|
||||
let dict = PyDict::new(py);
|
||||
let dict_inputs = PyDict::new(py);
|
||||
@@ -387,7 +383,7 @@ impl<'py> IntoPyObject<'py> for GraphWitness {
|
||||
dict.set_item("processed_outputs", dict_outputs).unwrap();
|
||||
}
|
||||
|
||||
Ok(dict.into_any())
|
||||
dict.to_object(py)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -417,29 +413,8 @@ fn insert_polycommit_pydict(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
|
||||
/// Parameters for dynamic lookups
|
||||
/// serde should flatten this struct
|
||||
pub struct DynamicLookupParams {
|
||||
/// total dynamic column size
|
||||
pub total_dynamic_col_size: usize,
|
||||
/// max dynamic column input length
|
||||
pub max_dynamic_input_len: usize,
|
||||
/// number of dynamic lookups
|
||||
pub num_dynamic_lookups: usize,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
|
||||
/// Parameters for shuffle operations
|
||||
pub struct ShuffleParams {
|
||||
/// number of shuffles
|
||||
pub num_shuffles: usize,
|
||||
/// total shuffle column size
|
||||
pub total_shuffle_col_size: usize,
|
||||
}
|
||||
|
||||
/// model parameters
|
||||
#[derive(Clone, Debug, Default, PartialEq)]
|
||||
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq)]
|
||||
pub struct GraphSettings {
|
||||
/// run args
|
||||
pub run_args: RunArgs,
|
||||
@@ -449,10 +424,16 @@ pub struct GraphSettings {
|
||||
pub total_assignments: usize,
|
||||
/// total const size
|
||||
pub total_const_size: usize,
|
||||
/// dynamic lookup parameters, flattened for backwards compatibility, serialize and deserialize flattened for backwards compatibility
|
||||
pub dynamic_lookup_params: DynamicLookupParams,
|
||||
/// shuffle parameters, flattened for backwards compatibility
|
||||
pub shuffle_params: ShuffleParams,
|
||||
/// total dynamic column size
|
||||
pub total_dynamic_col_size: usize,
|
||||
/// max dynamic column input length
|
||||
pub max_dynamic_input_len: usize,
|
||||
/// number of dynamic lookups
|
||||
pub num_dynamic_lookups: usize,
|
||||
/// number of shuffles
|
||||
pub num_shuffles: usize,
|
||||
/// total shuffle column size
|
||||
pub total_shuffle_col_size: usize,
|
||||
/// the shape of public inputs to the model (in order of appearance)
|
||||
pub model_instance_shapes: Vec<Vec<usize>>,
|
||||
/// model output scales
|
||||
@@ -479,485 +460,6 @@ pub struct GraphSettings {
|
||||
pub output_types: Option<Vec<InputType>>,
|
||||
}
|
||||
|
||||
impl Serialize for GraphSettings {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
if serializer.is_human_readable() {
|
||||
// JSON format - use flattened fields for backwards compatibility
|
||||
use serde::ser::SerializeStruct;
|
||||
let mut state = serializer.serialize_struct("GraphSettings", 21)?;
|
||||
state.serialize_field("run_args", &self.run_args)?;
|
||||
state.serialize_field("num_rows", &self.num_rows)?;
|
||||
state.serialize_field("total_assignments", &self.total_assignments)?;
|
||||
state.serialize_field("total_const_size", &self.total_const_size)?;
|
||||
|
||||
// Flatten DynamicLookupParams fields
|
||||
state.serialize_field(
|
||||
"total_dynamic_col_size",
|
||||
&self.dynamic_lookup_params.total_dynamic_col_size,
|
||||
)?;
|
||||
state.serialize_field(
|
||||
"max_dynamic_input_len",
|
||||
&self.dynamic_lookup_params.max_dynamic_input_len,
|
||||
)?;
|
||||
state.serialize_field(
|
||||
"num_dynamic_lookups",
|
||||
&self.dynamic_lookup_params.num_dynamic_lookups,
|
||||
)?;
|
||||
|
||||
// Flatten ShuffleParams fields
|
||||
state.serialize_field("num_shuffles", &self.shuffle_params.num_shuffles)?;
|
||||
state.serialize_field(
|
||||
"total_shuffle_col_size",
|
||||
&self.shuffle_params.total_shuffle_col_size,
|
||||
)?;
|
||||
|
||||
state.serialize_field("model_instance_shapes", &self.model_instance_shapes)?;
|
||||
state.serialize_field("model_output_scales", &self.model_output_scales)?;
|
||||
state.serialize_field("model_input_scales", &self.model_input_scales)?;
|
||||
state.serialize_field("module_sizes", &self.module_sizes)?;
|
||||
state.serialize_field("required_lookups", &self.required_lookups)?;
|
||||
state.serialize_field("required_range_checks", &self.required_range_checks)?;
|
||||
state.serialize_field("check_mode", &self.check_mode)?;
|
||||
state.serialize_field("version", &self.version)?;
|
||||
state.serialize_field("num_blinding_factors", &self.num_blinding_factors)?;
|
||||
state.serialize_field("timestamp", &self.timestamp)?;
|
||||
state.serialize_field("input_types", &self.input_types)?;
|
||||
state.serialize_field("output_types", &self.output_types)?;
|
||||
state.end()
|
||||
} else {
|
||||
// Binary format (bincode) - use nested struct format
|
||||
use serde::ser::SerializeTuple;
|
||||
let mut state = serializer.serialize_tuple(18)?;
|
||||
state.serialize_element(&self.run_args)?;
|
||||
state.serialize_element(&self.num_rows)?;
|
||||
state.serialize_element(&self.total_assignments)?;
|
||||
state.serialize_element(&self.total_const_size)?;
|
||||
state.serialize_element(&self.dynamic_lookup_params)?;
|
||||
state.serialize_element(&self.shuffle_params)?;
|
||||
state.serialize_element(&self.model_instance_shapes)?;
|
||||
state.serialize_element(&self.model_output_scales)?;
|
||||
state.serialize_element(&self.model_input_scales)?;
|
||||
state.serialize_element(&self.module_sizes)?;
|
||||
state.serialize_element(&self.required_lookups)?;
|
||||
state.serialize_element(&self.required_range_checks)?;
|
||||
state.serialize_element(&self.check_mode)?;
|
||||
state.serialize_element(&self.version)?;
|
||||
state.serialize_element(&self.num_blinding_factors)?;
|
||||
state.serialize_element(&self.timestamp)?;
|
||||
state.serialize_element(&self.input_types)?;
|
||||
state.serialize_element(&self.output_types)?;
|
||||
state.end()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for GraphSettings {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
use serde::de::{self, MapAccess, Visitor};
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(field_identifier, rename_all = "snake_case")]
|
||||
enum Field {
|
||||
RunArgs,
|
||||
NumRows,
|
||||
TotalAssignments,
|
||||
TotalConstSize,
|
||||
// Flattened DynamicLookupParams fields
|
||||
TotalDynamicColSize,
|
||||
MaxDynamicInputLen,
|
||||
NumDynamicLookups,
|
||||
// Flattened ShuffleParams fields
|
||||
NumShuffles,
|
||||
TotalShuffleColSize,
|
||||
ModelInstanceShapes,
|
||||
ModelOutputScales,
|
||||
ModelInputScales,
|
||||
ModuleSizes,
|
||||
RequiredLookups,
|
||||
RequiredRangeChecks,
|
||||
CheckMode,
|
||||
Version,
|
||||
NumBlindingFactors,
|
||||
Timestamp,
|
||||
InputTypes,
|
||||
OutputTypes,
|
||||
// Legacy nested struct fields for backwards compatibility
|
||||
DynamicLookupParams,
|
||||
ShuffleParams,
|
||||
}
|
||||
|
||||
struct GraphSettingsVisitor;
|
||||
|
||||
impl<'de> Visitor<'de> for GraphSettingsVisitor {
|
||||
type Value = GraphSettings;
|
||||
|
||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
formatter.write_str("struct GraphSettings")
|
||||
}
|
||||
|
||||
fn visit_map<V>(self, mut map: V) -> Result<GraphSettings, V::Error>
|
||||
where
|
||||
V: MapAccess<'de>,
|
||||
{
|
||||
let mut run_args = None;
|
||||
let mut num_rows = None;
|
||||
let mut total_assignments = None;
|
||||
let mut total_const_size = None;
|
||||
let mut total_dynamic_col_size = None;
|
||||
let mut max_dynamic_input_len = None;
|
||||
let mut num_dynamic_lookups = None;
|
||||
let mut num_shuffles = None;
|
||||
let mut total_shuffle_col_size = None;
|
||||
let mut model_instance_shapes = None;
|
||||
let mut model_output_scales = None;
|
||||
let mut model_input_scales = None;
|
||||
let mut module_sizes = None;
|
||||
let mut required_lookups = None;
|
||||
let mut required_range_checks = None;
|
||||
let mut check_mode = None;
|
||||
let mut version = None;
|
||||
let mut num_blinding_factors = None;
|
||||
let mut timestamp = None;
|
||||
let mut input_types = None;
|
||||
let mut output_types = None;
|
||||
|
||||
while let Some(key) = map.next_key()? {
|
||||
match key {
|
||||
Field::RunArgs => {
|
||||
if run_args.is_some() {
|
||||
return Err(de::Error::duplicate_field("run_args"));
|
||||
}
|
||||
run_args = Some(map.next_value()?);
|
||||
}
|
||||
Field::NumRows => {
|
||||
if num_rows.is_some() {
|
||||
return Err(de::Error::duplicate_field("num_rows"));
|
||||
}
|
||||
num_rows = Some(map.next_value()?);
|
||||
}
|
||||
Field::TotalAssignments => {
|
||||
if total_assignments.is_some() {
|
||||
return Err(de::Error::duplicate_field("total_assignments"));
|
||||
}
|
||||
total_assignments = Some(map.next_value()?);
|
||||
}
|
||||
Field::TotalConstSize => {
|
||||
if total_const_size.is_some() {
|
||||
return Err(de::Error::duplicate_field("total_const_size"));
|
||||
}
|
||||
total_const_size = Some(map.next_value()?);
|
||||
}
|
||||
Field::TotalDynamicColSize => {
|
||||
if total_dynamic_col_size.is_some() {
|
||||
return Err(de::Error::duplicate_field("total_dynamic_col_size"));
|
||||
}
|
||||
total_dynamic_col_size = Some(map.next_value()?);
|
||||
}
|
||||
Field::MaxDynamicInputLen => {
|
||||
if max_dynamic_input_len.is_some() {
|
||||
return Err(de::Error::duplicate_field("max_dynamic_input_len"));
|
||||
}
|
||||
max_dynamic_input_len = Some(map.next_value()?);
|
||||
}
|
||||
Field::NumDynamicLookups => {
|
||||
if num_dynamic_lookups.is_some() {
|
||||
return Err(de::Error::duplicate_field("num_dynamic_lookups"));
|
||||
}
|
||||
num_dynamic_lookups = Some(map.next_value()?);
|
||||
}
|
||||
Field::NumShuffles => {
|
||||
if num_shuffles.is_some() {
|
||||
return Err(de::Error::duplicate_field("num_shuffles"));
|
||||
}
|
||||
num_shuffles = Some(map.next_value()?);
|
||||
}
|
||||
Field::TotalShuffleColSize => {
|
||||
if total_shuffle_col_size.is_some() {
|
||||
return Err(de::Error::duplicate_field("total_shuffle_col_size"));
|
||||
}
|
||||
total_shuffle_col_size = Some(map.next_value()?);
|
||||
}
|
||||
Field::ModelInstanceShapes => {
|
||||
if model_instance_shapes.is_some() {
|
||||
return Err(de::Error::duplicate_field("model_instance_shapes"));
|
||||
}
|
||||
model_instance_shapes = Some(map.next_value()?);
|
||||
}
|
||||
Field::ModelOutputScales => {
|
||||
if model_output_scales.is_some() {
|
||||
return Err(de::Error::duplicate_field("model_output_scales"));
|
||||
}
|
||||
model_output_scales = Some(map.next_value()?);
|
||||
}
|
||||
Field::ModelInputScales => {
|
||||
if model_input_scales.is_some() {
|
||||
return Err(de::Error::duplicate_field("model_input_scales"));
|
||||
}
|
||||
model_input_scales = Some(map.next_value()?);
|
||||
}
|
||||
Field::ModuleSizes => {
|
||||
if module_sizes.is_some() {
|
||||
return Err(de::Error::duplicate_field("module_sizes"));
|
||||
}
|
||||
module_sizes = Some(map.next_value()?);
|
||||
}
|
||||
Field::RequiredLookups => {
|
||||
if required_lookups.is_some() {
|
||||
return Err(de::Error::duplicate_field("required_lookups"));
|
||||
}
|
||||
required_lookups = Some(map.next_value()?);
|
||||
}
|
||||
Field::RequiredRangeChecks => {
|
||||
if required_range_checks.is_some() {
|
||||
return Err(de::Error::duplicate_field("required_range_checks"));
|
||||
}
|
||||
required_range_checks = Some(map.next_value()?);
|
||||
}
|
||||
Field::CheckMode => {
|
||||
if check_mode.is_some() {
|
||||
return Err(de::Error::duplicate_field("check_mode"));
|
||||
}
|
||||
check_mode = Some(map.next_value()?);
|
||||
}
|
||||
Field::Version => {
|
||||
if version.is_some() {
|
||||
return Err(de::Error::duplicate_field("version"));
|
||||
}
|
||||
version = Some(map.next_value()?);
|
||||
}
|
||||
Field::NumBlindingFactors => {
|
||||
if num_blinding_factors.is_some() {
|
||||
return Err(de::Error::duplicate_field("num_blinding_factors"));
|
||||
}
|
||||
num_blinding_factors = map.next_value()?;
|
||||
}
|
||||
Field::Timestamp => {
|
||||
if timestamp.is_some() {
|
||||
return Err(de::Error::duplicate_field("timestamp"));
|
||||
}
|
||||
timestamp = Some(map.next_value()?);
|
||||
}
|
||||
Field::InputTypes => {
|
||||
if input_types.is_some() {
|
||||
return Err(de::Error::duplicate_field("input_types"));
|
||||
}
|
||||
input_types = map.next_value()?;
|
||||
}
|
||||
Field::OutputTypes => {
|
||||
if output_types.is_some() {
|
||||
return Err(de::Error::duplicate_field("output_types"));
|
||||
}
|
||||
output_types = map.next_value()?;
|
||||
}
|
||||
// Handle legacy nested struct fields for backwards compatibility
|
||||
Field::DynamicLookupParams => {
|
||||
let legacy_params: DynamicLookupParams = map.next_value()?;
|
||||
if total_dynamic_col_size.is_none() {
|
||||
total_dynamic_col_size = Some(legacy_params.total_dynamic_col_size);
|
||||
}
|
||||
if max_dynamic_input_len.is_none() {
|
||||
max_dynamic_input_len = Some(legacy_params.max_dynamic_input_len);
|
||||
}
|
||||
if num_dynamic_lookups.is_none() {
|
||||
num_dynamic_lookups = Some(legacy_params.num_dynamic_lookups);
|
||||
}
|
||||
}
|
||||
Field::ShuffleParams => {
|
||||
let legacy_params: ShuffleParams = map.next_value()?;
|
||||
if num_shuffles.is_none() {
|
||||
num_shuffles = Some(legacy_params.num_shuffles);
|
||||
}
|
||||
if total_shuffle_col_size.is_none() {
|
||||
total_shuffle_col_size = Some(legacy_params.total_shuffle_col_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let run_args = run_args.ok_or_else(|| de::Error::missing_field("run_args"))?;
|
||||
let num_rows = num_rows.ok_or_else(|| de::Error::missing_field("num_rows"))?;
|
||||
let total_assignments = total_assignments
|
||||
.ok_or_else(|| de::Error::missing_field("total_assignments"))?;
|
||||
let total_const_size =
|
||||
total_const_size.ok_or_else(|| de::Error::missing_field("total_const_size"))?;
|
||||
let model_instance_shapes = model_instance_shapes
|
||||
.ok_or_else(|| de::Error::missing_field("model_instance_shapes"))?;
|
||||
let model_output_scales = model_output_scales
|
||||
.ok_or_else(|| de::Error::missing_field("model_output_scales"))?;
|
||||
let model_input_scales = model_input_scales
|
||||
.ok_or_else(|| de::Error::missing_field("model_input_scales"))?;
|
||||
let module_sizes =
|
||||
module_sizes.ok_or_else(|| de::Error::missing_field("module_sizes"))?;
|
||||
let required_lookups =
|
||||
required_lookups.ok_or_else(|| de::Error::missing_field("required_lookups"))?;
|
||||
let required_range_checks = required_range_checks
|
||||
.ok_or_else(|| de::Error::missing_field("required_range_checks"))?;
|
||||
let check_mode =
|
||||
check_mode.ok_or_else(|| de::Error::missing_field("check_mode"))?;
|
||||
let version = version.ok_or_else(|| de::Error::missing_field("version"))?;
|
||||
|
||||
// Build the nested structs from flattened fields, with defaults if missing
|
||||
let dynamic_lookup_params = DynamicLookupParams {
|
||||
total_dynamic_col_size: total_dynamic_col_size.unwrap_or_default(),
|
||||
max_dynamic_input_len: max_dynamic_input_len.unwrap_or_default(),
|
||||
num_dynamic_lookups: num_dynamic_lookups.unwrap_or_default(),
|
||||
};
|
||||
|
||||
let shuffle_params = ShuffleParams {
|
||||
num_shuffles: num_shuffles.unwrap_or_default(),
|
||||
total_shuffle_col_size: total_shuffle_col_size.unwrap_or_default(),
|
||||
};
|
||||
|
||||
Ok(GraphSettings {
|
||||
run_args,
|
||||
num_rows,
|
||||
total_assignments,
|
||||
total_const_size,
|
||||
dynamic_lookup_params,
|
||||
shuffle_params,
|
||||
model_instance_shapes,
|
||||
model_output_scales,
|
||||
model_input_scales,
|
||||
module_sizes,
|
||||
required_lookups,
|
||||
required_range_checks,
|
||||
check_mode,
|
||||
version,
|
||||
num_blinding_factors,
|
||||
timestamp,
|
||||
input_types,
|
||||
output_types,
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_seq<V>(self, mut seq: V) -> Result<GraphSettings, V::Error>
|
||||
where
|
||||
V: serde::de::SeqAccess<'de>,
|
||||
{
|
||||
use serde::de::Error;
|
||||
|
||||
// For bincode compatibility, deserialize in the same order as tuple serialization
|
||||
let run_args = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(0, &self))?;
|
||||
let num_rows = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(1, &self))?;
|
||||
let total_assignments = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(2, &self))?;
|
||||
let total_const_size = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(3, &self))?;
|
||||
let dynamic_lookup_params = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(4, &self))?;
|
||||
let shuffle_params = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(5, &self))?;
|
||||
let model_instance_shapes = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(6, &self))?;
|
||||
let model_output_scales = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(7, &self))?;
|
||||
let model_input_scales = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(8, &self))?;
|
||||
let module_sizes = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(9, &self))?;
|
||||
let required_lookups = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(10, &self))?;
|
||||
let required_range_checks = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(11, &self))?;
|
||||
let check_mode = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(12, &self))?;
|
||||
let version = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(13, &self))?;
|
||||
let num_blinding_factors = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(14, &self))?;
|
||||
let timestamp = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(15, &self))?;
|
||||
let input_types = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(16, &self))?;
|
||||
let output_types = seq
|
||||
.next_element()?
|
||||
.ok_or_else(|| Error::invalid_length(17, &self))?;
|
||||
|
||||
Ok(GraphSettings {
|
||||
run_args,
|
||||
num_rows,
|
||||
total_assignments,
|
||||
total_const_size,
|
||||
dynamic_lookup_params,
|
||||
shuffle_params,
|
||||
model_instance_shapes,
|
||||
model_output_scales,
|
||||
model_input_scales,
|
||||
module_sizes,
|
||||
required_lookups,
|
||||
required_range_checks,
|
||||
check_mode,
|
||||
version,
|
||||
num_blinding_factors,
|
||||
timestamp,
|
||||
input_types,
|
||||
output_types,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Universal deserializer that works with both JSON (map) and bincode (tuple)
|
||||
if deserializer.is_human_readable() {
|
||||
// JSON format - use struct/map deserialization with flattened fields
|
||||
const FIELDS: &'static [&'static str] = &[
|
||||
"run_args",
|
||||
"num_rows",
|
||||
"total_assignments",
|
||||
"total_const_size",
|
||||
"total_dynamic_col_size",
|
||||
"max_dynamic_input_len",
|
||||
"num_dynamic_lookups",
|
||||
"num_shuffles",
|
||||
"total_shuffle_col_size",
|
||||
"model_instance_shapes",
|
||||
"model_output_scales",
|
||||
"model_input_scales",
|
||||
"module_sizes",
|
||||
"required_lookups",
|
||||
"required_range_checks",
|
||||
"check_mode",
|
||||
"version",
|
||||
"num_blinding_factors",
|
||||
"timestamp",
|
||||
"input_types",
|
||||
"output_types",
|
||||
"dynamic_lookup_params",
|
||||
"shuffle_params",
|
||||
];
|
||||
deserializer.deserialize_struct("GraphSettings", FIELDS, GraphSettingsVisitor)
|
||||
} else {
|
||||
// Binary format (bincode) - use tuple deserialization
|
||||
deserializer.deserialize_tuple(18, GraphSettingsVisitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl GraphSettings {
|
||||
/// Calc the number of rows required for lookup tables
|
||||
pub fn lookup_log_rows(&self) -> u32 {
|
||||
@@ -993,16 +495,15 @@ impl GraphSettings {
|
||||
}
|
||||
|
||||
fn dynamic_lookup_and_shuffle_logrows(&self) -> u32 {
|
||||
(self.dynamic_lookup_params.total_dynamic_col_size as f64
|
||||
+ self.shuffle_params.total_shuffle_col_size as f64)
|
||||
(self.total_dynamic_col_size as f64 + self.total_shuffle_col_size as f64)
|
||||
.log2()
|
||||
.ceil() as u32
|
||||
}
|
||||
|
||||
/// calculate the number of rows required for the dynamic lookup and shuffle
|
||||
pub fn dynamic_lookup_and_shuffle_logrows_with_blinding(&self) -> u32 {
|
||||
(self.dynamic_lookup_params.total_dynamic_col_size as f64
|
||||
+ self.shuffle_params.total_shuffle_col_size as f64
|
||||
(self.total_dynamic_col_size as f64
|
||||
+ self.total_shuffle_col_size as f64
|
||||
+ RESERVED_BLINDING_ROWS as f64)
|
||||
.log2()
|
||||
.ceil() as u32
|
||||
@@ -1010,14 +511,13 @@ impl GraphSettings {
|
||||
|
||||
/// calculate the number of rows required for the dynamic lookup and shuffle
|
||||
pub fn min_dynamic_lookup_and_shuffle_logrows_with_blinding(&self) -> u32 {
|
||||
(self.dynamic_lookup_params.max_dynamic_input_len as f64 + RESERVED_BLINDING_ROWS as f64)
|
||||
(self.max_dynamic_input_len as f64 + RESERVED_BLINDING_ROWS as f64)
|
||||
.log2()
|
||||
.ceil() as u32
|
||||
}
|
||||
|
||||
fn dynamic_lookup_and_shuffle_col_size(&self) -> usize {
|
||||
self.dynamic_lookup_params.total_dynamic_col_size
|
||||
+ self.shuffle_params.total_shuffle_col_size
|
||||
self.total_dynamic_col_size + self.total_shuffle_col_size
|
||||
}
|
||||
|
||||
/// calculate the number of rows required for the module constraints
|
||||
@@ -1153,12 +653,12 @@ impl GraphSettings {
|
||||
|
||||
/// requires dynamic lookup
|
||||
pub fn requires_dynamic_lookup(&self) -> bool {
|
||||
self.dynamic_lookup_params.num_dynamic_lookups > 0
|
||||
self.num_dynamic_lookups > 0
|
||||
}
|
||||
|
||||
/// requires dynamic shuffle
|
||||
pub fn requires_shuffle(&self) -> bool {
|
||||
self.shuffle_params.num_shuffles > 0
|
||||
self.num_shuffles > 0
|
||||
}
|
||||
|
||||
/// any kzg visibility
|
||||
@@ -1456,13 +956,13 @@ impl GraphCircuit {
|
||||
let shapes = self.model().graph.input_shapes()?;
|
||||
let scales = self.model().graph.get_input_scales();
|
||||
let input_types = self.model().graph.get_input_types()?;
|
||||
self.load_file_data(&data.input_data, &shapes, scales, input_types)
|
||||
self.load_file_data(data.input_data.values(), &shapes, scales, input_types)
|
||||
}
|
||||
|
||||
///
|
||||
pub fn load_file_data(
|
||||
&mut self,
|
||||
file_data: &DataSource,
|
||||
file_data: &FileSource,
|
||||
shapes: &Vec<Vec<usize>>,
|
||||
scales: Vec<crate::Scale>,
|
||||
input_types: Vec<InputType>,
|
||||
@@ -2155,153 +1655,3 @@ impl Circuit<Fp> for GraphCircuit {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
/// Tests for the graph module
|
||||
pub mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_graph_settings_serialization_roundtrip() {
|
||||
use crate::{CheckMode, RunArgs};
|
||||
|
||||
// Create a test GraphSettings with nested structs
|
||||
let original = GraphSettings {
|
||||
run_args: RunArgs::default(),
|
||||
num_rows: 1000,
|
||||
total_assignments: 500,
|
||||
total_const_size: 100,
|
||||
dynamic_lookup_params: DynamicLookupParams {
|
||||
total_dynamic_col_size: 42,
|
||||
max_dynamic_input_len: 128,
|
||||
num_dynamic_lookups: 5,
|
||||
},
|
||||
shuffle_params: ShuffleParams {
|
||||
num_shuffles: 3,
|
||||
total_shuffle_col_size: 256,
|
||||
},
|
||||
model_instance_shapes: vec![vec![1, 2, 3]],
|
||||
model_output_scales: vec![],
|
||||
model_input_scales: vec![],
|
||||
module_sizes: ModuleSizes::default(),
|
||||
required_lookups: vec![],
|
||||
required_range_checks: vec![],
|
||||
check_mode: CheckMode::SAFE,
|
||||
version: "1.0.0".to_string(),
|
||||
num_blinding_factors: Some(5),
|
||||
timestamp: Some(123456789),
|
||||
input_types: None,
|
||||
output_types: None,
|
||||
};
|
||||
|
||||
// Test 1: JSON serialization roundtrip with flattened format
|
||||
let json_str = serde_json::to_string_pretty(&original).unwrap();
|
||||
println!("JSON serialized (flattened):\n{}", json_str);
|
||||
|
||||
// Verify the JSON contains flattened fields
|
||||
assert!(json_str.contains("\"total_dynamic_col_size\": 42"));
|
||||
assert!(json_str.contains("\"max_dynamic_input_len\": 128"));
|
||||
assert!(json_str.contains("\"num_dynamic_lookups\": 5"));
|
||||
assert!(json_str.contains("\"num_shuffles\": 3"));
|
||||
assert!(json_str.contains("\"total_shuffle_col_size\": 256"));
|
||||
|
||||
// Verify the JSON does NOT contain nested structs
|
||||
assert!(!json_str.contains("\"dynamic_lookup_params\""));
|
||||
assert!(!json_str.contains("\"shuffle_params\""));
|
||||
|
||||
// Deserialize from JSON
|
||||
let deserialized: GraphSettings = serde_json::from_str(&json_str).unwrap();
|
||||
assert_eq!(original, deserialized);
|
||||
|
||||
// now do JSON bytes
|
||||
let json_bytes = serde_json::to_vec(&original).unwrap();
|
||||
let deserialized_from_bytes: GraphSettings = serde_json::from_slice(&json_bytes).unwrap();
|
||||
assert_eq!(original, deserialized_from_bytes);
|
||||
|
||||
// Test 2: Bincode serialization roundtrip
|
||||
let bincode_data = bincode::serialize(&original).unwrap();
|
||||
let bincode_deserialized: GraphSettings = bincode::deserialize(&bincode_data).unwrap();
|
||||
assert_eq!(original, bincode_deserialized);
|
||||
|
||||
// Test 3: Backwards compatibility - deserialize old nested format
|
||||
let old_format_json = r#"{
|
||||
"run_args": {
|
||||
"tolerance": {
|
||||
"val": 0.0,
|
||||
"scale": 1.0
|
||||
},
|
||||
"input_scale": 0,
|
||||
"param_scale": 0,
|
||||
"scale_rebase_multiplier": 10,
|
||||
"lookup_range": [
|
||||
0,
|
||||
0
|
||||
],
|
||||
"logrows": 6,
|
||||
"num_inner_cols": 2,
|
||||
"variables": [
|
||||
[
|
||||
"batch_size",
|
||||
1
|
||||
]
|
||||
],
|
||||
"input_visibility": "Private",
|
||||
"output_visibility": "Public",
|
||||
"param_visibility": "Private",
|
||||
"rebase_frac_zero_constants": false,
|
||||
"check_mode": "UNSAFE",
|
||||
"commitment": "KZG",
|
||||
"decomp_base": 128,
|
||||
"decomp_legs": 2,
|
||||
"bounded_log_lookup": false,
|
||||
"ignore_range_check_inputs_outputs": false
|
||||
},
|
||||
"num_rows": 236,
|
||||
"total_assignments": 472,
|
||||
"total_const_size": 4,
|
||||
"total_dynamic_col_size": 0,
|
||||
"max_dynamic_input_len": 0,
|
||||
"num_dynamic_lookups": 0,
|
||||
"num_shuffles": 0,
|
||||
"total_shuffle_col_size": 0,
|
||||
"model_instance_shapes": [
|
||||
[
|
||||
1,
|
||||
4
|
||||
]
|
||||
],
|
||||
"model_output_scales": [
|
||||
0
|
||||
],
|
||||
"model_input_scales": [
|
||||
0
|
||||
],
|
||||
"module_sizes": {
|
||||
"polycommit": [],
|
||||
"poseidon": [
|
||||
0,
|
||||
[
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"required_lookups": [],
|
||||
"required_range_checks": [
|
||||
[
|
||||
-1,
|
||||
1
|
||||
],
|
||||
[
|
||||
0,
|
||||
127
|
||||
]
|
||||
],
|
||||
"check_mode": "UNSAFE",
|
||||
"version": "0.0.0",
|
||||
"num_blinding_factors": null,
|
||||
"timestamp": 1741214578354
|
||||
}"#;
|
||||
|
||||
let _backwards_compatible: GraphSettings = serde_json::from_str(old_format_json).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,8 +12,6 @@ use crate::circuit::Input;
|
||||
use crate::circuit::InputType;
|
||||
use crate::circuit::Unknown;
|
||||
use crate::fieldutils::IntegerRep;
|
||||
use crate::graph::DynamicLookupParams;
|
||||
use crate::graph::ShuffleParams;
|
||||
use crate::tensor::ValType;
|
||||
use crate::{
|
||||
circuit::{lookup::LookupOp, BaseConfig as PolyConfig, CheckMode, Op},
|
||||
@@ -102,10 +100,12 @@ pub type NodeGraph = BTreeMap<usize, NodeType>;
|
||||
pub struct DummyPassRes {
|
||||
/// number of rows use
|
||||
pub num_rows: usize,
|
||||
/// dynamic lookup parameters
|
||||
pub dynamic_lookup_params: DynamicLookupParams,
|
||||
/// shuffle parameters
|
||||
pub shuffle_params: ShuffleParams,
|
||||
/// num dynamic lookups
|
||||
pub num_dynamic_lookups: usize,
|
||||
/// max dynamic lookup input len
|
||||
pub max_dynamic_input_len: usize,
|
||||
/// dynamic lookup col size
|
||||
pub dynamic_lookup_col_coord: usize,
|
||||
/// num shuffles
|
||||
pub num_shuffles: usize,
|
||||
/// shuffle
|
||||
@@ -585,13 +585,16 @@ impl Model {
|
||||
num_rows: res.num_rows,
|
||||
total_assignments: res.linear_coord,
|
||||
required_lookups: res.lookup_ops.into_iter().collect(),
|
||||
max_dynamic_input_len: res.max_dynamic_input_len,
|
||||
required_range_checks: res.range_checks.into_iter().collect(),
|
||||
model_output_scales: self.graph.get_output_scales()?,
|
||||
model_input_scales: self.graph.get_input_scales(),
|
||||
input_types: self.get_input_types().ok(),
|
||||
output_types: Some(self.get_output_types()),
|
||||
dynamic_lookup_params: res.dynamic_lookup_params,
|
||||
shuffle_params: res.shuffle_params,
|
||||
num_dynamic_lookups: res.num_dynamic_lookups,
|
||||
total_dynamic_col_size: res.dynamic_lookup_col_coord,
|
||||
num_shuffles: res.num_shuffles,
|
||||
total_shuffle_col_size: res.shuffle_col_coord,
|
||||
total_const_size: res.total_const_size,
|
||||
check_mode,
|
||||
version: env!("CARGO_PKG_VERSION").to_string(),
|
||||
@@ -1520,21 +1523,15 @@ impl Model {
|
||||
let res = DummyPassRes {
|
||||
num_rows: region.row(),
|
||||
linear_coord: region.linear_coord(),
|
||||
dynamic_lookup_params: DynamicLookupParams {
|
||||
total_dynamic_col_size: region.dynamic_lookup_col_coord(),
|
||||
max_dynamic_input_len: region.max_dynamic_input_len(),
|
||||
num_dynamic_lookups: region.dynamic_lookup_index(),
|
||||
},
|
||||
shuffle_params: ShuffleParams {
|
||||
num_shuffles: region.shuffle_index(),
|
||||
total_shuffle_col_size: region.shuffle_col_coord(),
|
||||
},
|
||||
max_dynamic_input_len: region.max_dynamic_input_len(),
|
||||
total_const_size: region.total_constants(),
|
||||
lookup_ops: region.used_lookups(),
|
||||
range_checks: region.used_range_checks(),
|
||||
max_lookup_inputs: region.max_lookup_inputs(),
|
||||
min_lookup_inputs: region.min_lookup_inputs(),
|
||||
max_range_size: region.max_range_size(),
|
||||
num_dynamic_lookups: region.dynamic_lookup_index(),
|
||||
dynamic_lookup_col_coord: region.dynamic_lookup_col_coord(),
|
||||
num_shuffles: region.shuffle_index(),
|
||||
shuffle_col_coord: region.shuffle_col_coord(),
|
||||
outputs,
|
||||
|
||||
@@ -695,8 +695,8 @@ impl Node {
|
||||
opkind = opkind.homogenous_rescale(in_scales.clone())?.into();
|
||||
let mut out_scale = opkind.out_scale(in_scales.clone())?;
|
||||
// rescale the inputs if necessary to get consistent fixed points, we select the largest scale (highest precision)
|
||||
let rebase_scale = scales.get_rebase_scale();
|
||||
opkind = RebaseScale::rebase(opkind, rebase_scale, out_scale, scales.rebase_multiplier);
|
||||
let global_scale = scales.get_max();
|
||||
opkind = RebaseScale::rebase(opkind, global_scale, out_scale, scales.rebase_multiplier);
|
||||
|
||||
out_scale = opkind.out_scale(in_scales)?;
|
||||
|
||||
|
||||
@@ -8,7 +8,9 @@ use halo2curves::ff::PrimeField;
|
||||
use itertools::Itertools;
|
||||
use log::debug;
|
||||
#[cfg(feature = "python-bindings")]
|
||||
use pyo3::{exceptions::PyValueError, FromPyObject, IntoPyObject, PyResult, Python};
|
||||
use pyo3::{
|
||||
exceptions::PyValueError, FromPyObject, IntoPy, PyObject, PyResult, Python, ToPyObject,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
#[cfg(all(feature = "ezkl", not(target_arch = "wasm32")))]
|
||||
use tosubcommand::ToFlags;
|
||||
@@ -105,33 +107,27 @@ impl<'a> From<&'a str> for Visibility {
|
||||
}
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
impl<'py> IntoPyObject<'py> for Visibility {
|
||||
type Target = pyo3::PyAny;
|
||||
type Output = pyo3::Bound<'py, Self::Target>;
|
||||
type Error = pyo3::PyErr;
|
||||
|
||||
impl IntoPy<PyObject> for Visibility {
|
||||
/// Converts Visibility to Python object
|
||||
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
match self {
|
||||
Visibility::Private => Ok("private".into_pyobject(py)?.into_any()),
|
||||
Visibility::Public => Ok("public".into_pyobject(py)?.into_any()),
|
||||
Visibility::Fixed => Ok("fixed".into_pyobject(py)?.into_any()),
|
||||
Visibility::KZGCommit => Ok("polycommit".into_pyobject(py)?.into_any()),
|
||||
Visibility::Private => "private".to_object(py),
|
||||
Visibility::Public => "public".to_object(py),
|
||||
Visibility::Fixed => "fixed".to_object(py),
|
||||
Visibility::KZGCommit => "polycommit".to_object(py),
|
||||
Visibility::Hashed {
|
||||
hash_is_public,
|
||||
outlets,
|
||||
} => {
|
||||
if hash_is_public {
|
||||
Ok("hashed/public".into_pyobject(py)?.into_any())
|
||||
"hashed/public".to_object(py)
|
||||
} else {
|
||||
let outlets = outlets
|
||||
.iter()
|
||||
.map(|o| o.to_string())
|
||||
.collect_vec()
|
||||
.join(",");
|
||||
Ok(format!("hashed/private/{}", outlets)
|
||||
.into_pyobject(py)?
|
||||
.into_any())
|
||||
format!("hashed/private/{}", outlets).to_object(py)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -250,8 +246,6 @@ pub struct VarScales {
|
||||
pub params: crate::Scale,
|
||||
/// Multiplier for scale rebasing
|
||||
pub rebase_multiplier: u32,
|
||||
/// rebase scale factor (optional). if None, we rebase to the max of input_scale and param_scale
|
||||
pub rebase_scale: Option<crate::Scale>,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for VarScales {
|
||||
@@ -271,21 +265,11 @@ impl VarScales {
|
||||
std::cmp::min(self.input, self.params)
|
||||
}
|
||||
|
||||
/// Returns the scale to rebase to, if specified
|
||||
pub fn get_rebase_scale(&self) -> crate::Scale {
|
||||
if let Some(rebase_scale) = self.rebase_scale {
|
||||
rebase_scale
|
||||
} else {
|
||||
self.get_max()
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates VarScales from runtime arguments
|
||||
pub fn from_args(args: &RunArgs) -> Self {
|
||||
Self {
|
||||
input: args.input_scale,
|
||||
params: args.param_scale,
|
||||
rebase_scale: args.rebase_scale,
|
||||
rebase_multiplier: args.scale_rebase_multiplier,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,10 +288,6 @@ pub struct RunArgs {
|
||||
/// Higher values provide more precision but increase circuit complexity
|
||||
#[cfg_attr(all(feature = "ezkl", not(target_arch = "wasm32")), arg(long, default_value = "7", value_hint = clap::ValueHint::Other))]
|
||||
pub param_scale: Scale,
|
||||
/// Scale to rebase to when the input scale exceeds rebase_scale * multiplier. If None we rebase to the max of input_scale and param_scale
|
||||
/// This is an advanced parameter that should be used with caution
|
||||
#[cfg_attr(all(feature = "ezkl", not(target_arch = "wasm32")), arg(long, required = false, value_hint = clap::ValueHint::Other))]
|
||||
pub rebase_scale: Option<Scale>,
|
||||
/// Scale rebase threshold multiplier
|
||||
/// When scale exceeds input_scale * multiplier, it is rebased to input_scale
|
||||
/// Advanced parameter that should be used with caution
|
||||
@@ -382,15 +378,14 @@ impl Default for RunArgs {
|
||||
bounded_log_lookup: false,
|
||||
input_scale: 7,
|
||||
param_scale: 7,
|
||||
rebase_scale: None,
|
||||
scale_rebase_multiplier: 1,
|
||||
lookup_range: (-32768, 32768),
|
||||
logrows: 17,
|
||||
num_inner_cols: 2,
|
||||
variables: vec![("batch_size".to_string(), 1)],
|
||||
input_visibility: Visibility::Public,
|
||||
input_visibility: Visibility::Private,
|
||||
output_visibility: Visibility::Public,
|
||||
param_visibility: Visibility::Fixed,
|
||||
param_visibility: Visibility::Private,
|
||||
rebase_frac_zero_constants: false,
|
||||
check_mode: CheckMode::UNSAFE,
|
||||
commitment: None,
|
||||
|
||||
@@ -187,17 +187,12 @@ impl From<ProofType> for StrategyType {
|
||||
}
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
impl<'py> pyo3::IntoPyObject<'py> for ProofType {
|
||||
type Target = pyo3::PyAny;
|
||||
type Output = pyo3::Bound<'py, Self::Target>;
|
||||
type Error = pyo3::PyErr;
|
||||
|
||||
fn into_pyobject(self, py: pyo3::Python<'py>) -> Result<Self::Output, Self::Error> {
|
||||
let result = match self {
|
||||
ProofType::Single => "Single",
|
||||
ProofType::ForAggr => "ForAggr",
|
||||
};
|
||||
Ok(result.into_pyobject(py)?.into_any())
|
||||
impl ToPyObject for ProofType {
|
||||
fn to_object(&self, py: Python) -> PyObject {
|
||||
match self {
|
||||
ProofType::Single => "Single".to_object(py),
|
||||
ProofType::ForAggr => "ForAggr".to_object(py),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -250,17 +245,12 @@ impl std::fmt::Display for StrategyType {
|
||||
}
|
||||
#[cfg(feature = "python-bindings")]
|
||||
/// Converts StrategyType into a PyObject (Required for StrategyType to be compatible with Python)
|
||||
impl<'py> pyo3::IntoPyObject<'py> for StrategyType {
|
||||
type Target = pyo3::PyAny;
|
||||
type Output = pyo3::Bound<'py, Self::Target>;
|
||||
type Error = pyo3::PyErr;
|
||||
|
||||
fn into_pyobject(self, py: pyo3::Python<'py>) -> Result<Self::Output, Self::Error> {
|
||||
let result = match self {
|
||||
StrategyType::Single => "single",
|
||||
StrategyType::Accum => "accum",
|
||||
};
|
||||
Ok(result.into_pyobject(py)?.into_any())
|
||||
impl pyo3::IntoPy<PyObject> for StrategyType {
|
||||
fn into_py(self, py: Python) -> PyObject {
|
||||
match self {
|
||||
StrategyType::Single => "single".to_object(py),
|
||||
StrategyType::Accum => "accum".to_object(py),
|
||||
}
|
||||
}
|
||||
}
|
||||
#[cfg(feature = "python-bindings")]
|
||||
@@ -314,6 +304,16 @@ impl ToFlags for TranscriptType {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
impl ToPyObject for TranscriptType {
|
||||
fn to_object(&self, py: Python) -> PyObject {
|
||||
match self {
|
||||
TranscriptType::Poseidon => "Poseidon".to_object(py),
|
||||
TranscriptType::EVM => "EVM".to_object(py),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
///
|
||||
pub fn g1affine_to_pydict(g1affine_dict: &pyo3::Bound<'_, PyDict>, g1affine: &G1Affine) {
|
||||
@@ -401,19 +401,14 @@ where
|
||||
}
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
use pyo3::{types::PyDict, IntoPyObject, Python};
|
||||
use pyo3::{types::PyDict, PyObject, Python, ToPyObject};
|
||||
#[cfg(feature = "python-bindings")]
|
||||
impl<'py, F: PrimeField + SerdeObject + Serialize, C: CurveAffine + Serialize> IntoPyObject<'py>
|
||||
for Snark<F, C>
|
||||
impl<F: PrimeField + SerdeObject + Serialize, C: CurveAffine + Serialize> ToPyObject for Snark<F, C>
|
||||
where
|
||||
C::Scalar: Serialize + DeserializeOwned,
|
||||
C::ScalarExt: Serialize + DeserializeOwned,
|
||||
{
|
||||
type Target = pyo3::PyAny;
|
||||
type Output = pyo3::Bound<'py, Self::Target>;
|
||||
type Error = pyo3::PyErr;
|
||||
|
||||
fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
|
||||
fn to_object(&self, py: Python) -> PyObject {
|
||||
let dict = PyDict::new(py);
|
||||
let field_elems: Vec<Vec<String>> = self
|
||||
.instances
|
||||
@@ -423,9 +418,9 @@ where
|
||||
dict.set_item("instances", field_elems).unwrap();
|
||||
let hex_proof = hex::encode(&self.proof);
|
||||
dict.set_item("proof", format!("0x{}", hex_proof)).unwrap();
|
||||
dict.set_item("transcript_type", self.transcript_type.into_pyobject(py)?)
|
||||
dict.set_item("transcript_type", self.transcript_type.to_object(py))
|
||||
.unwrap();
|
||||
Ok(dict.into_any())
|
||||
dict.to_object(py)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -329,7 +329,7 @@ pub fn resize<T: TensorType + Send + Sync>(
|
||||
|
||||
let cartesian_coord: Vec<Vec<usize>> = new_shape
|
||||
.iter()
|
||||
.map(|d| 0..*d)
|
||||
.map(|d| (0..*d))
|
||||
.multi_cartesian_product()
|
||||
.collect();
|
||||
|
||||
@@ -1218,7 +1218,7 @@ pub fn intercalate_values<T: TensorType>(
|
||||
let cartesian_coord = output
|
||||
.dims()
|
||||
.iter()
|
||||
.map(|d| 0..*d)
|
||||
.map(|d| (0..*d))
|
||||
.multi_cartesian_product()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@@ -1263,7 +1263,7 @@ pub fn one_hot(
|
||||
let cartesian_coord = output
|
||||
.dims()
|
||||
.iter()
|
||||
.map(|d| 0..*d)
|
||||
.map(|d| (0..*d))
|
||||
.multi_cartesian_product()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@@ -1341,7 +1341,7 @@ pub fn pad<T: TensorType>(
|
||||
let cartesian_coord = image
|
||||
.dims()
|
||||
.iter()
|
||||
.map(|d| 0..*d)
|
||||
.map(|d| (0..*d))
|
||||
.multi_cartesian_product()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
||||
Binary file not shown.
@@ -3,7 +3,7 @@
|
||||
mod native_tests {
|
||||
|
||||
// use ezkl::circuit::table::RESERVED_BLINDING_ROWS_PAD;
|
||||
use ezkl::graph::input::GraphData;
|
||||
use ezkl::graph::input::{FileSource, GraphData};
|
||||
use ezkl::graph::GraphSettings;
|
||||
use ezkl::pfsys::Snark;
|
||||
use ezkl::Commitments;
|
||||
@@ -163,18 +163,14 @@ mod native_tests {
|
||||
let data = GraphData::from_path(format!("{}/{}/input.json", test_dir, test).into())
|
||||
.expect("failed to load input data");
|
||||
|
||||
let duplicated_input_data = data
|
||||
let duplicated_input_data: FileSource = data
|
||||
.input_data
|
||||
.into_iter()
|
||||
.map(|input| {
|
||||
(0..num_batches)
|
||||
.map(move |_| input.clone())
|
||||
.flatten()
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
.values()
|
||||
.iter()
|
||||
.map(|data| (0..num_batches).flat_map(|_| data.clone()).collect())
|
||||
.collect();
|
||||
|
||||
let duplicated_data = GraphData::new(duplicated_input_data);
|
||||
let duplicated_data = GraphData::new(duplicated_input_data.into());
|
||||
|
||||
let res =
|
||||
duplicated_data.save(format!("{}/{}/input.json", test_dir, output_dir).into());
|
||||
@@ -313,63 +309,63 @@ mod native_tests {
|
||||
"integer_div", // 98
|
||||
];
|
||||
|
||||
const WASM_TESTS: [&str; 44] = [
|
||||
"1l_mlp", // 0
|
||||
"1l_slice", // 1
|
||||
"1l_concat", // 2
|
||||
"1l_flatten", // 3
|
||||
const WASM_TESTS: [&str; 46] = [
|
||||
"1l_mlp",
|
||||
"1l_slice",
|
||||
"1l_concat",
|
||||
"1l_flatten",
|
||||
// "1l_average",
|
||||
"1l_div", // 4
|
||||
"1l_pad", // 5
|
||||
"1l_reshape", // 6
|
||||
"1l_eltwise_div", // 7
|
||||
"1l_sigmoid", // 8
|
||||
"1l_sqrt", // 9
|
||||
"1l_softmax", // 10
|
||||
"1l_div",
|
||||
"1l_pad",
|
||||
"1l_reshape",
|
||||
"1l_eltwise_div",
|
||||
"1l_sigmoid",
|
||||
"1l_sqrt",
|
||||
"1l_softmax",
|
||||
// "1l_instance_norm",
|
||||
"1l_batch_norm", // 11
|
||||
"1l_prelu", // 12
|
||||
"1l_leakyrelu", // 13
|
||||
"1l_gelu_noappx", // 14
|
||||
"1l_batch_norm",
|
||||
"1l_prelu",
|
||||
"1l_leakyrelu",
|
||||
"1l_gelu_noappx",
|
||||
// "1l_gelu_tanh_appx",
|
||||
"1l_relu", // 15
|
||||
"1l_downsample", // 16
|
||||
"1l_tanh", // 17
|
||||
"2l_relu_sigmoid_small", // 18
|
||||
"2l_relu_fc", // 19
|
||||
"2l_relu_small", // 20
|
||||
"2l_relu_sigmoid", // 21
|
||||
"1l_conv", // 22
|
||||
"2l_sigmoid_small", // 23
|
||||
"2l_relu_sigmoid_conv", // 24
|
||||
// "3l_relu_conv_fc",
|
||||
// "4l_relu_conv_fc",
|
||||
"1l_erf", // 25
|
||||
"1l_var", // 26
|
||||
"1l_elu", // 27
|
||||
"min", // 28
|
||||
"max", // 29
|
||||
"1l_max_pool", // 30
|
||||
"1l_conv_transpose", // 31
|
||||
"1l_upsample", // 32
|
||||
"1l_identity", // 33
|
||||
"1l_relu",
|
||||
"1l_downsample",
|
||||
"1l_tanh",
|
||||
"2l_relu_sigmoid_small",
|
||||
"2l_relu_fc",
|
||||
"2l_relu_small",
|
||||
"2l_relu_sigmoid",
|
||||
"1l_conv",
|
||||
"2l_sigmoid_small",
|
||||
"2l_relu_sigmoid_conv",
|
||||
"3l_relu_conv_fc",
|
||||
"4l_relu_conv_fc",
|
||||
"1l_erf",
|
||||
"1l_var",
|
||||
"1l_elu",
|
||||
"min",
|
||||
"max",
|
||||
"1l_max_pool",
|
||||
"1l_conv_transpose",
|
||||
"1l_upsample",
|
||||
"1l_identity",
|
||||
// "idolmodel",
|
||||
"trig", // 34
|
||||
"prelu_gmm", // 35
|
||||
"lstm", // 36
|
||||
"rnn", // 37
|
||||
"quantize_dequantize", // 38
|
||||
"1l_where", // 39
|
||||
"boolean", // 40
|
||||
"boolean_identity", // 41
|
||||
"gradient_boosted_trees", // 42
|
||||
"1l_topk", // 43
|
||||
// "xgboost",
|
||||
// "lightgbm",
|
||||
// "hummingbird_decision_tree",
|
||||
"trig",
|
||||
"prelu_gmm",
|
||||
"lstm",
|
||||
"rnn",
|
||||
"quantize_dequantize",
|
||||
"1l_where",
|
||||
"boolean",
|
||||
"boolean_identity",
|
||||
"gradient_boosted_trees",
|
||||
"1l_topk",
|
||||
// "xgboost",
|
||||
// "lightgbm",
|
||||
// "hummingbird_decision_tree",
|
||||
];
|
||||
|
||||
#[cfg(not(feature = "gpu-accelerated"))]
|
||||
#[cfg(not(feature = "icicle"))]
|
||||
const TESTS_AGGR: [&str; 21] = [
|
||||
"1l_mlp",
|
||||
"1l_flatten",
|
||||
@@ -394,7 +390,7 @@ mod native_tests {
|
||||
"1l_max_pool",
|
||||
];
|
||||
|
||||
#[cfg(feature = "gpu-accelerated")]
|
||||
#[cfg(feature = "icicle")]
|
||||
const TESTS_AGGR: [&str; 3] = ["1l_mlp", "1l_flatten", "1l_average"];
|
||||
|
||||
const TESTS_EVM: [&str; 23] = [
|
||||
@@ -454,12 +450,11 @@ mod native_tests {
|
||||
use crate::native_tests::TESTS_AGGR;
|
||||
use test_case::test_case;
|
||||
use crate::native_tests::aggr_prove_and_verify;
|
||||
#[cfg(not(feature = "gpu-accelerated"))]
|
||||
use crate::native_tests::kzg_aggr_mock_prove_and_verify;
|
||||
use tempdir::TempDir;
|
||||
use ezkl::Commitments;
|
||||
|
||||
#[cfg(not(feature="gpu-accelerated"))]
|
||||
#[cfg(not(feature="icicle"))]
|
||||
seq!(N in 0..=20 {
|
||||
|
||||
#(#[test_case(TESTS_AGGR[N])])*
|
||||
@@ -493,7 +488,7 @@ mod native_tests {
|
||||
|
||||
});
|
||||
|
||||
#[cfg(feature="gpu-accelerated")]
|
||||
#[cfg(feature="icicle")]
|
||||
seq!(N in 0..=2 {
|
||||
#(#[test_case(TESTS_AGGR[N])])*
|
||||
fn kzg_aggr_prove_and_verify_(test: &str) {
|
||||
@@ -521,8 +516,8 @@ mod native_tests {
|
||||
use crate::native_tests::mock;
|
||||
use crate::native_tests::accuracy_measurement;
|
||||
use crate::native_tests::prove_and_verify;
|
||||
// use crate::native_tests::run_js_tests;
|
||||
// use crate::native_tests::render_circuit;
|
||||
use crate::native_tests::run_js_tests;
|
||||
use crate::native_tests::render_circuit;
|
||||
use crate::native_tests::model_serialization_different_binaries;
|
||||
|
||||
use tempdir::TempDir;
|
||||
@@ -552,15 +547,15 @@ mod native_tests {
|
||||
|
||||
seq!(N in 0..=98 {
|
||||
|
||||
// #(#[test_case(TESTS[N])])*
|
||||
// #[ignore]
|
||||
// fn render_circuit_(test: &str) {
|
||||
// crate::native_tests::init_binary();
|
||||
// let test_dir = TempDir::new(test).unwrap();
|
||||
// let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(path, test);
|
||||
// render_circuit(path, test.to_string());
|
||||
// test_dir.close().unwrap();
|
||||
// }
|
||||
#(#[test_case(TESTS[N])])*
|
||||
#[ignore]
|
||||
fn render_circuit_(test: &str) {
|
||||
crate::native_tests::init_binary();
|
||||
let test_dir = TempDir::new(test).unwrap();
|
||||
let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(path, test);
|
||||
render_circuit(path, test.to_string());
|
||||
test_dir.close().unwrap();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -912,7 +907,7 @@ mod native_tests {
|
||||
|
||||
});
|
||||
|
||||
seq!(N in 0..=43 {
|
||||
seq!(N in 0..=45 {
|
||||
|
||||
#(#[test_case(WASM_TESTS[N])])*
|
||||
fn kzg_prove_and_verify_with_overflow_(test: &str) {
|
||||
@@ -922,8 +917,8 @@ mod native_tests {
|
||||
env_logger::init();
|
||||
let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(path, test);
|
||||
prove_and_verify(path, test.to_string(), "safe", "private", "private", "public", 1, None, true, "single", Commitments::KZG, 2);
|
||||
// #[cfg(not(feature = "gpu-accelerated"))]
|
||||
// run_js_tests(path, test.to_string(), "testWasm", false);
|
||||
#[cfg(not(feature = "icicle"))]
|
||||
run_js_tests(path, test.to_string(), "testWasm", false);
|
||||
test_dir.close().unwrap();
|
||||
}
|
||||
|
||||
@@ -935,8 +930,8 @@ mod native_tests {
|
||||
env_logger::init();
|
||||
let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(path, test);
|
||||
prove_and_verify(path, test.to_string(), "safe", "hashed", "private", "public", 1, None, true, "single", Commitments::KZG, 2);
|
||||
// #[cfg(not(feature = "gpu-accelerated"))]
|
||||
// run_js_tests(path, test.to_string(), "testWasm", false);
|
||||
#[cfg(not(feature = "icicle"))]
|
||||
run_js_tests(path, test.to_string(), "testWasm", false);
|
||||
test_dir.close().unwrap();
|
||||
}
|
||||
|
||||
@@ -948,8 +943,8 @@ mod native_tests {
|
||||
env_logger::init();
|
||||
let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(path, test);
|
||||
prove_and_verify(path, test.to_string(), "safe", "private", "fixed", "public", 1, None, true, "single", Commitments::KZG, 2);
|
||||
// #[cfg(not(feature = "gpu-accelerated"))]
|
||||
// run_js_tests(path, test.to_string(), "testWasm", false);
|
||||
#[cfg(not(feature = "icicle"))]
|
||||
run_js_tests(path, test.to_string(), "testWasm", false);
|
||||
test_dir.close().unwrap();
|
||||
}
|
||||
|
||||
@@ -996,7 +991,6 @@ mod native_tests {
|
||||
use crate::native_tests::kzg_evm_aggr_prove_and_verify;
|
||||
use tempdir::TempDir;
|
||||
use crate::native_tests::Hardfork;
|
||||
#[cfg(not(feature = "gpu-accelerated"))]
|
||||
use crate::native_tests::run_js_tests;
|
||||
use ezkl::logger::init_logger;
|
||||
use crate::native_tests::lazy_static;
|
||||
@@ -1023,7 +1017,7 @@ mod native_tests {
|
||||
|
||||
});
|
||||
|
||||
seq!(N in 0..=98 {
|
||||
seq!(N in 0..4 {
|
||||
#(#[test_case(TESTS[N])])*
|
||||
fn kzg_evm_prove_and_verify_reusable_verifier_(test: &str) {
|
||||
crate::native_tests::init_binary();
|
||||
@@ -1033,7 +1027,7 @@ mod native_tests {
|
||||
init_logger();
|
||||
log::error!("Running kzg_evm_prove_and_verify_reusable_verifier_ for test: {}", test);
|
||||
// default vis
|
||||
let reusable_verifier_address: String = kzg_evm_prove_and_verify_reusable_verifier(2, path, test.to_string(), "public", "private", "private", &mut REUSABLE_VERIFIER_ADDR.lock().unwrap(), false);
|
||||
let reusable_verifier_address: String = kzg_evm_prove_and_verify_reusable_verifier(2, path, test.to_string(), "private", "private", "public", &mut REUSABLE_VERIFIER_ADDR.lock().unwrap(), false);
|
||||
// public/public vis
|
||||
let reusable_verifier_address: String = kzg_evm_prove_and_verify_reusable_verifier(2, path, test.to_string(), "public", "private", "public", &mut Some(reusable_verifier_address), false);
|
||||
// hashed input
|
||||
@@ -1055,7 +1049,7 @@ mod native_tests {
|
||||
|
||||
#(#[test_case(TESTS[N])])*
|
||||
fn kzg_evm_prove_and_verify_reusable_verifier_with_overflow_(test: &str) {
|
||||
// verifier too big to fit on chain with overflow calibration target or num instances exceed 0x10000
|
||||
// verifier too big to fit on chain with overflow calibration target
|
||||
if test == "1l_eltwise_div" || test == "lenet_5" || test == "ltsf" || test == "lstm_large" {
|
||||
return;
|
||||
}
|
||||
@@ -1097,7 +1091,7 @@ mod native_tests {
|
||||
let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(path, test);
|
||||
let _anvil_child = crate::native_tests::start_anvil(false, Hardfork::Latest);
|
||||
kzg_evm_prove_and_verify(2, path, test.to_string(), "private", "private", "public");
|
||||
#[cfg(not(feature = "gpu-accelerated"))]
|
||||
#[cfg(not(feature = "icicle"))]
|
||||
run_js_tests(path, test.to_string(), "testBrowserEvmVerify", false);
|
||||
test_dir.close().unwrap();
|
||||
|
||||
@@ -1111,7 +1105,7 @@ mod native_tests {
|
||||
let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(path, test);
|
||||
let mut _anvil_child = crate::native_tests::start_anvil(false, Hardfork::Latest);
|
||||
kzg_evm_prove_and_verify(2, path, test.to_string(), "hashed", "private", "private");
|
||||
#[cfg(not(feature = "gpu-accelerated"))]
|
||||
#[cfg(not(feature = "icicle"))]
|
||||
run_js_tests(path, test.to_string(), "testBrowserEvmVerify", false);
|
||||
test_dir.close().unwrap();
|
||||
}
|
||||
@@ -1128,7 +1122,7 @@ mod native_tests {
|
||||
let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(path, test);
|
||||
let mut _anvil_child = crate::native_tests::start_anvil(false, hardfork);
|
||||
kzg_evm_prove_and_verify(2, path, test.to_string(), "polycommit", "private", "public");
|
||||
#[cfg(not(feature = "gpu-accelerated"))]
|
||||
#[cfg(not(feature = "icicle"))]
|
||||
run_js_tests(path, test.to_string(), "testBrowserEvmVerify", false);
|
||||
test_dir.close().unwrap();
|
||||
}
|
||||
@@ -1141,7 +1135,7 @@ mod native_tests {
|
||||
let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(path, test);
|
||||
let _anvil_child = crate::native_tests::start_anvil(false, Hardfork::Latest);
|
||||
kzg_evm_prove_and_verify(2, path, test.to_string(), "private", "hashed", "public");
|
||||
#[cfg(not(feature = "gpu-accelerated"))]
|
||||
#[cfg(not(feature = "icicle"))]
|
||||
run_js_tests(path, test.to_string(), "testBrowserEvmVerify", false);
|
||||
test_dir.close().unwrap();
|
||||
|
||||
@@ -1154,7 +1148,7 @@ mod native_tests {
|
||||
let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(path, test);
|
||||
let _anvil_child = crate::native_tests::start_anvil(false, Hardfork::Latest);
|
||||
kzg_evm_prove_and_verify(2, path, test.to_string(), "private", "private", "hashed");
|
||||
#[cfg(not(feature = "gpu-accelerated"))]
|
||||
#[cfg(not(feature = "icicle"))]
|
||||
run_js_tests(path, test.to_string(), "testBrowserEvmVerify", false);
|
||||
test_dir.close().unwrap();
|
||||
}
|
||||
@@ -1167,7 +1161,7 @@ mod native_tests {
|
||||
let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(path, test);
|
||||
let _anvil_child = crate::native_tests::start_anvil(false, Hardfork::Latest);
|
||||
kzg_evm_prove_and_verify(2, path, test.to_string(), "private", "polycommit", "public");
|
||||
#[cfg(not(feature = "gpu-accelerated"))]
|
||||
#[cfg(not(feature = "icicle"))]
|
||||
run_js_tests(path, test.to_string(), "testBrowserEvmVerify", false);
|
||||
test_dir.close().unwrap();
|
||||
}
|
||||
@@ -1180,7 +1174,7 @@ mod native_tests {
|
||||
let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(path, test);
|
||||
let _anvil_child = crate::native_tests::start_anvil(false, Hardfork::Latest);
|
||||
kzg_evm_prove_and_verify(2, path, test.to_string(), "private", "private", "polycommit");
|
||||
#[cfg(not(feature = "gpu-accelerated"))]
|
||||
#[cfg(not(feature = "icicle"))]
|
||||
run_js_tests(path, test.to_string(), "testBrowserEvmVerify", false);
|
||||
test_dir.close().unwrap();
|
||||
}
|
||||
@@ -1192,7 +1186,7 @@ mod native_tests {
|
||||
let path = test_dir.path().to_str().unwrap(); crate::native_tests::mv_test_(path, test);
|
||||
let _anvil_child = crate::native_tests::start_anvil(false, Hardfork::Latest);
|
||||
kzg_evm_prove_and_verify(2, path, test.to_string(), "polycommit", "polycommit", "polycommit");
|
||||
#[cfg(not(feature = "gpu-accelerated"))]
|
||||
#[cfg(not(feature = "icicle"))]
|
||||
run_js_tests(path, test.to_string(), "testBrowserEvmVerify", false);
|
||||
test_dir.close().unwrap();
|
||||
}
|
||||
@@ -1559,25 +1553,24 @@ mod native_tests {
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
// // Mock prove (fast, but does not cover some potential issues)
|
||||
// fn render_circuit(test_dir: &str, example_name: String) {
|
||||
// let status = Command::new(format!("{}/{}", *CARGO_TARGET_DIR, TEST_BINARY))
|
||||
// .args([
|
||||
// "render-circuit",
|
||||
// "-M",
|
||||
// format!("{}/{}/network.onnx", test_dir, example_name).as_str(),
|
||||
// "-O",
|
||||
// format!("{}/{}/render.png", test_dir, example_name).as_str(),
|
||||
// "--lookup-range=-32768->32768",
|
||||
// "-K=17",
|
||||
// ])
|
||||
// .status()
|
||||
// .expect("failed to execute process");
|
||||
// assert!(status.success());
|
||||
// }
|
||||
// Mock prove (fast, but does not cover some potential issues)
|
||||
fn render_circuit(test_dir: &str, example_name: String) {
|
||||
let status = Command::new(format!("{}/{}", *CARGO_TARGET_DIR, TEST_BINARY))
|
||||
.args([
|
||||
"render-circuit",
|
||||
"-M",
|
||||
format!("{}/{}/network.onnx", test_dir, example_name).as_str(),
|
||||
"-O",
|
||||
format!("{}/{}/render.png", test_dir, example_name).as_str(),
|
||||
"--lookup-range=-32768->32768",
|
||||
"-K=17",
|
||||
])
|
||||
.status()
|
||||
.expect("failed to execute process");
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
// prove-serialize-verify, the usual full path
|
||||
#[cfg(not(feature = "gpu-accelerated"))]
|
||||
fn kzg_aggr_mock_prove_and_verify(test_dir: &str, example_name: String) {
|
||||
prove_and_verify(
|
||||
test_dir,
|
||||
@@ -2100,7 +2093,7 @@ mod native_tests {
|
||||
rpc_arg.as_str(),
|
||||
addr_path_arg.as_str(),
|
||||
sol_arg.as_str(),
|
||||
"--contract-type=verifier/reusable",
|
||||
"-C=verifier/reusable",
|
||||
];
|
||||
|
||||
let status = Command::new(format!("{}/{}", *CARGO_TARGET_DIR, TEST_BINARY))
|
||||
@@ -2234,7 +2227,6 @@ mod native_tests {
|
||||
}
|
||||
|
||||
// run js browser evm verify tests for a given example
|
||||
#[cfg(not(feature = "gpu-accelerated"))]
|
||||
fn run_js_tests(test_dir: &str, example_name: String, js_test: &str, vk: bool) {
|
||||
let example = format!("--example={}", example_name);
|
||||
let dir = format!("--dir={}", test_dir);
|
||||
@@ -2251,9 +2243,8 @@ mod native_tests {
|
||||
assert!(status.success());
|
||||
}
|
||||
|
||||
#[allow(unused_variables)]
|
||||
fn build_ezkl() {
|
||||
#[cfg(feature = "gpu-accelerated")]
|
||||
#[cfg(feature = "icicle")]
|
||||
let args = [
|
||||
"build",
|
||||
"--profile=test-runs",
|
||||
@@ -2272,16 +2263,17 @@ mod native_tests {
|
||||
"macos-metal",
|
||||
];
|
||||
// not macos-metal and not icicle
|
||||
#[cfg(all(not(feature = "gpu-accelerated"), not(feature = "macos-metal")))]
|
||||
#[cfg(all(not(feature = "icicle"), not(feature = "macos-metal")))]
|
||||
let args = ["build", "--profile=test-runs", "--bin", "ezkl"];
|
||||
#[cfg(feature = "reusable-verifier")]
|
||||
#[cfg(feature = "eth-original-lookup")]
|
||||
let args = [
|
||||
"build",
|
||||
"--profile=test-runs",
|
||||
"--bin",
|
||||
"ezkl",
|
||||
"--no-default-features",
|
||||
"--features",
|
||||
"reusable-verifier",
|
||||
"ezkl,solidity-verifier,eth",
|
||||
];
|
||||
|
||||
let status = Command::new("cargo")
|
||||
|
||||
@@ -352,7 +352,7 @@ def test_prove_and_verify():
|
||||
"for-aggr",
|
||||
srs_path=srs_path,
|
||||
)
|
||||
assert res['transcript_type'] == 'poseidon'
|
||||
assert res['transcript_type'] == 'Poseidon'
|
||||
assert os.path.isfile(proof_path)
|
||||
|
||||
settings_path = os.path.join(folder_path, 'settings.json')
|
||||
@@ -388,7 +388,7 @@ def test_prove_evm():
|
||||
"single",
|
||||
srs_path=srs_path,
|
||||
)
|
||||
assert res['transcript_type'] == 'evm'
|
||||
assert res['transcript_type'] == 'EVM'
|
||||
assert os.path.isfile(proof_path)
|
||||
|
||||
|
||||
|
||||
@@ -42,21 +42,21 @@ mod wasm32 {
|
||||
pub const SRS1: &[u8] = include_bytes!("assets/kzg1.srs");
|
||||
pub const VERIFIER_BYTECODE: &[u8] = include_bytes!("assets/wasm.code");
|
||||
|
||||
// #[wasm_bindgen_test]
|
||||
// async fn can_verify_aggr() {
|
||||
// let value = verifyAggr(
|
||||
// wasm_bindgen::Clamped(PROOF_AGGR.to_vec()),
|
||||
// wasm_bindgen::Clamped(VK_AGGR.to_vec()),
|
||||
// 21,
|
||||
// wasm_bindgen::Clamped(SRS1.to_vec()),
|
||||
// "kzg",
|
||||
// )
|
||||
// .map_err(|_| "failed")
|
||||
// .unwrap();
|
||||
#[wasm_bindgen_test]
|
||||
async fn can_verify_aggr() {
|
||||
let value = verifyAggr(
|
||||
wasm_bindgen::Clamped(PROOF_AGGR.to_vec()),
|
||||
wasm_bindgen::Clamped(VK_AGGR.to_vec()),
|
||||
21,
|
||||
wasm_bindgen::Clamped(SRS1.to_vec()),
|
||||
"kzg",
|
||||
)
|
||||
.map_err(|_| "failed")
|
||||
.unwrap();
|
||||
|
||||
// // should not fail
|
||||
// assert!(value);
|
||||
// }
|
||||
// should not fail
|
||||
assert!(value);
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
async fn verify_encode_verifier_calldata() {
|
||||
|
||||
Reference in New Issue
Block a user