Compare commits

..

66 Commits

Author SHA1 Message Date
Ethan
afff3a637d switch from oauth2: prefix or x-access-token 2025-05-28 16:15:55 -05:00
Ethan
538d7e52ad update fine grained access token name space. 2025-05-28 09:01:52 -05:00
Ethan
4e857c2d63 h2 repo ezkl-verifier 2025-05-27 09:06:15 -05:00
dante
87e5079fe7 Merge branch 'main' into vka-hashing 2025-05-26 10:57:30 -04:00
Ethan
6d8e2bd2f2 *test encode_evm_calldata function. 2025-05-20 17:28:14 -05:00
dante
9f1e4773ab Update wasm.rs 2025-05-19 09:51:12 -04:00
dante
d32d7d0225 Update rust.yml 2025-05-18 20:40:02 -04:00
dante
d67a5e82d5 Update rust.yml 2025-05-18 13:27:47 -04:00
dante
ff8ec62916 fix 2025-05-18 13:17:35 -04:00
dante
96b46d8628 refactor: poseidon bindings 2025-05-18 12:44:53 -04:00
Ethan
1028b9d3cc *rmv hard coded contracts in eth.rs 2025-05-15 19:38:47 -05:00
Ethan
c367500b38 move encode_calldata from h2-sol-ver to main repo. 2025-05-15 16:08:54 -05:00
dante
00fcddbed3 Update mod.rs 2025-05-10 09:54:47 +01:00
dante
e1d09985da fix: unused 2025-05-10 09:30:37 +01:00
dante
5309366438 refactor: rm unstable buf_read_has_data_left 2025-05-10 09:29:43 +01:00
dante
ed67713de9 fix: move logging related deps 2025-05-08 12:09:06 +01:00
dante
ce7235b0db chore: feature gate logging 2025-05-08 11:46:08 +01:00
Ethan
716916f58d *remove atttest data contract from contracts directory 2025-05-06 17:02:04 -05:00
Ethan
5c9f518039 *rmv da tests 2025-05-01 09:03:32 -05:00
Ethan
343ceb9030 rmv foundry solidity tests 2025-04-30 15:43:18 -05:00
Ethan
14c99223e7 rmv awaits for gen witness and calibrate for py bindings. 2025-04-30 11:21:00 -05:00
Ethan
f683ee2239 *patch minor issues in python and wasm bindings
*rmv post build bundle modifications to wasm nodejs target
2025-04-29 19:11:28 -05:00
Ethan
479773b16e Merge branch 'local-evm-verify-wasm' into vka-hashing 2025-04-29 18:35:49 -05:00
dante
0562911b73 Update python.rs 2025-04-29 17:55:32 -04:00
dante
6e36b5bb4c fix: compiles 2025-04-29 16:04:46 -04:00
dante
00ab001fc7 fix: actually universal bindings 2025-04-29 14:28:16 -04:00
dante
037d954d2a refactor: ios -> universal binding 2025-04-29 13:59:33 -04:00
dante
4e4fd7dba0 Merge branch 'vka-hashing' of https://github.com/zkonduit/ezkl into vka-hashing 2025-04-29 12:39:32 -04:00
dante
17d2f5db36 fix: ios 2025-04-29 12:33:47 -04:00
dante
94ad885cda refactor: DataSource enum -> struct (#979) 2025-04-29 12:22:34 -04:00
dante
0ef1f35e59 fix: uniffi bindings 2025-04-29 12:12:56 -04:00
dante
808ab7d0de chore: feature-gate eth (#978) 2025-04-29 12:02:23 -04:00
dante
68b2c96b97 Merge branch 'vka-hashing' of https://github.com/zkonduit/ezkl into vka-hashing 2025-04-29 11:31:20 -04:00
dante
9a0ab22fdb fix matches 2025-04-29 11:31:13 -04:00
dante
f2b1de3740 Merge branch 'main' into vka-hashing 2025-04-29 11:26:04 -04:00
Ethan
dcb888ff1e fix wasm package graph data import error 2025-04-28 16:29:09 -05:00
Ethan
26f465e70c bring back zizmor analysis 2025-04-28 08:21:26 -05:00
Ethan
8eef53213d rmv data attestation 2025-04-27 19:36:54 -05:00
Ethan
a1345966d7 configure Git credentials more persistently 2025-04-27 18:09:37 -05:00
Ethan
640061c850 set git config after action checkouts 2025-04-27 17:48:30 -05:00
Ethan
da7db7d88d use git config local instead of global 2025-04-27 17:20:24 -05:00
Ethan
a55f75ff3f rmv debug statement on token 2025-04-24 11:19:19 -05:00
Ethan
bf6f704827 debug token 2025-04-24 10:56:27 -05:00
Ethan
0dbfdf4672 debug token 2025-04-24 10:54:56 -05:00
Ethan
98299356a6 *fix syntax error on yaml 2025-04-24 10:51:24 -05:00
Ethan
04805d2a91 move token env to job level 2025-04-24 10:42:35 -05:00
Ethan
ca18cf29bb set token as global env var 2025-04-24 10:36:37 -05:00
Ethan
78f8e23b55 use verification ezkl token 2025-04-24 10:26:15 -05:00
Ethan
7d40926082 activate git fetch with cli on runner 2025-04-24 09:53:20 -05:00
Ethan
e2c8182871 *update python bindings 2025-04-24 09:43:55 -05:00
Ethan
4f077c9134 *use https for loading h2 sol verifier crate 2025-04-23 21:57:07 -05:00
Ethan
038805ce02 Merge branch 'main' into vka-hashing 2025-04-23 21:32:56 -05:00
Ethan
0fb87c9a20 *update lock 2025-04-23 21:30:43 -05:00
Ethan
77423a6d07 *check that on-chain rescaled instances match what is stored in proof file. 2025-04-23 21:25:35 -05:00
Ethan
8b416c7a00 *comment out swift package test 2025-04-21 04:31:51 -05:00
Ethan
73ec5e549a *temporarily disable zizmor + swift package on ci. 2025-04-21 04:27:36 -05:00
Ethan
28386d8442 vka hashing + rescaling 2025-04-21 04:13:31 -05:00
Ethan
1b12f9256d should fail to verify when evm revert occurs 2025-03-07 14:47:16 -05:00
Ethan
59495f3385 *build wasm package for p-v-evm 2025-03-07 09:50:22 -05:00
Ethan
4a49517ba2 *undo auto formatting of proof.json 2025-03-06 19:08:18 -05:00
Ethan
d36b185037 *update proof 2025-03-06 18:45:51 -05:00
Ethan
a579826c9c js error utf -> hex helper 2025-03-06 17:06:07 -05:00
Ethan
ed6bce0657 more robust utf8_bytes_to_hex_decoded 2025-03-06 16:50:34 -05:00
Ethan
98ee20a38f *bump initial wasm memory allocation
*utf8 => hex encoding
2025-03-06 16:02:28 -05:00
Ethan
77caac3981 *fix compiled model version mismatch
*deprecate in-browser-evm-verifier pkg
2025-03-06 14:52:40 -05:00
Ethan
342cbc4408 *add local evm verify to wasm bundle 2025-03-06 11:53:22 -05:00
32 changed files with 1260 additions and 1143 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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
@@ -48,12 +49,11 @@ jobs:
RUST_BACKTRACE: 1
PCRE2_SYS_STATIC: 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:
@@ -64,6 +64,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
@@ -118,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:
@@ -151,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
@@ -200,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'

View File

@@ -30,10 +30,28 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- 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
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3
@@ -53,11 +71,28 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- 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: Build
@@ -73,9 +108,28 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- 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: Docs
@@ -91,9 +145,28 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
with:
toolchain: nightly-2025-05-01
toolchain: nightly-2025-02-17
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -116,9 +189,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
# - uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -144,17 +217,35 @@ jobs:
ultra-overflow-tests_og-lookup:
permissions:
contents: read
runs-on: [ non-gpu, non-sgx ]
runs-on: non-gpu
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- 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
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -180,22 +271,37 @@ jobs:
ultra-overflow-tests:
permissions:
contents: read
runs-on: [ non-gpu, non-sgx ]
runs-on: non-gpu
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- 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
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
with:
crate: cargo-nextest
@@ -222,16 +328,32 @@ jobs:
runs-on: ubuntu-latest-16-cores
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- 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
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -244,21 +366,35 @@ jobs:
wasm32-tests:
permissions:
contents: read
runs-on: ubuntu-latest-64-cores
runs-on: non-gpu
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
# add `atomics` and `bulk-memory` to RUSTFLAGS to enable wasm-bindgen tests
RUSTFLAGS: "-C target-feature=+atomics,+bulk-memory"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- 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
- uses: jetli/wasm-pack-action@0d096b08b4e5a7de8c28de67e11e945404e9eefa #v0.4.0
@@ -271,22 +407,16 @@ jobs:
- name: Install wasm32-unknown-unknown
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
- name: Create webdriver.json to disable timeouts
run: |
echo '{"args": ["--headless", "--disable-gpu", "--disable-dev-shm-usage", "--no-sandbox"]}' > webdriver.json
run: rustup component add rust-src --toolchain nightly-2025-02-17-x86_64-unknown-linux-gnu
- name: Run wasm verifier tests
run: |
ulimit -n 65536
WASM_BINDGEN_TEST_THREADS=1 \
WASM_BINDGEN_TEST_TIMEOUT=1800 \
CHROMEDRIVER_ARGS="--log-level=INFO" \
wasm-pack test --chrome --headless -- -Z build-std="panic_abort,std" --features web -- --nocapture
# on mac:
# AR=/opt/homebrew/opt/llvm/bin/llvm-ar CC=/opt/homebrew/opt/llvm/bin/clang wasm-pack test --firefox --headless -- -Z build-std="panic_abort,std" --features web
run: wasm-pack test --chrome --headless -- -Z build-std="panic_abort,std" --features web
mock-proving-tests:
permissions:
contents: read
runs-on: [ non-gpu, non-sgx ]
runs-on: non-gpu
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
@@ -294,10 +424,27 @@ jobs:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- uses: actions-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
with:
toolchain: nightly-2025-05-01
toolchain: nightly-2025-02-17
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -356,27 +503,38 @@ jobs:
prove-and-verify-evm-tests:
permissions:
contents: read
runs-on: [ non-gpu, non-sgx ]
# needs: [build, library-tests, docs, python-tests, python-integration-tests]
runs-on: non-gpu
needs: [build, library-tests, docs, python-tests, python-integration-tests]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
RUSTFLAGS: "-C target-feature=+atomics,+bulk-memory"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- 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
- uses: jetli/wasm-pack-action@0d096b08b4e5a7de8c28de67e11e945404e9eefa #v0.4.0
with:
# Pin to version 0.12.1
version: "v0.12.1"
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
with:
crate: cargo-nextest
@@ -394,27 +552,27 @@ jobs:
node-version: "18.12.1"
cache: "pnpm"
- 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 dependencies for js tests and package
run: |
pnpm install --frozen-lockfile
# - name: Install solc
# run: (hash svm 2>/dev/null || cargo install svm-rs) && svm install 0.8.20 && solc --version
- name: Install Anvil
run: cargo install --git https://github.com/foundry-rs/foundry --rev 56b806a3ba7866a3b061093bebd0fa2ace97f1fc --locked anvil --force
run: cargo install --git https://github.com/foundry-rs/foundry --rev 62cdea8ff9e6efef011f77e295823b5f2dbeb3a1 --locked anvil --force
- name: Build wasm package for nodejs target.
run: |
wasm-pack build --target nodejs --out-dir ./tests/wasm/nodejs . -- -Z build-std="panic_abort,std"
- name: KZG prove and verify tests (EVM)
run: cargo nextest run --verbose "tests_evm::kzg_evm_prove_and_verify_::" --test-threads 1
- name: KZG prove and verify tests (EVM + reusable verifier + col-overflow)
run: cargo nextest run --verbose tests_evm::kzg_evm_prove_and_verify_reusable_verifier --features reusable-verifier --test-threads 1
run: cargo nextest run --verbose tests_evm::kzg_evm_prove_and_verify_reusable_verifier --test-threads 1
- name: KZG prove and verify tests (EVM + kzg all)
run: cargo nextest run --verbose tests_evm::kzg_evm_kzg_all_prove_and_verify --test-threads 1
- name: KZG prove and verify tests (EVM + kzg inputs)
run: cargo nextest run --verbose tests_evm::kzg_evm_kzg_input_prove_and_verify --test-threads 1
- name: KZG prove and verify tests (EVM + kzg params)
run: cargo nextest run --verbose tests_evm::kzg_evm_kzg_params_prove_and_verify --test-threads 1
- name: KZG prove and verify tests (EVM)
run: cargo nextest run --verbose tests_evm::kzg_evm_prove_and_verify --test-threads 1
- name: KZG prove and verify tests (EVM + hashed inputs)
run: cargo nextest run --verbose tests_evm::kzg_evm_hashed_input_prove_and_verify --test-threads 1
- name: KZG prove and verify tests (EVM + hashed params)
@@ -431,9 +589,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
# - uses: jetli/wasm-pack-action@0d096b08b4e5a7de8c28de67e11e945404e9eefa #v0.4.0
@@ -441,7 +599,7 @@ jobs:
# # Pin to version 0.12.1
# version: 'v0.12.1'
# - name: Add rust-src
# run: rustup component add rust-src --toolchain nightly-2025-05-01
# run: rustup component add rust-src --toolchain nightly-2025-02-17
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
# with:
# persist-credentials: false
@@ -459,21 +617,36 @@ jobs:
prove-and-verify-tests:
permissions:
contents: read
runs-on: [ non-gpu, non-sgx ]
runs-on: non-gpu
needs: [build, library-tests, docs]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
RUSTFLAGS: "-C target-feature=+atomics,+bulk-memory"
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- 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
- uses: jetli/wasm-pack-action@0d096b08b4e5a7de8c28de67e11e945404e9eefa #v0.4.0
@@ -484,7 +657,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
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
@@ -549,13 +722,13 @@ 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: 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
# - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
# - uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
# with:
@@ -585,16 +758,32 @@ jobs:
needs: [build, library-tests, docs, python-tests, python-integration-tests]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- uses: dtolnay/rust-toolchain@4f94fbe7e03939b0e674bcc9ca609a16088f63ff #nightly branch, TODO: update when required
with:
toolchain: nightly-2025-05-01
toolchain: nightly-2025-02-17
override: true
components: rustfmt, clippy
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -612,9 +801,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
# - uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -631,16 +820,32 @@ jobs:
needs: [build, library-tests, docs, python-tests, python-integration-tests]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- 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
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -657,16 +862,32 @@ jobs:
needs: [build, library-tests, docs, python-tests, python-integration-tests]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- 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
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -676,7 +897,7 @@ jobs:
# - name: Install solc
# run: (hash svm 2>/dev/null || cargo install svm-rs) && svm install 0.8.20 && solc --version
- name: Install Anvil
run: cargo install --git https://github.com/foundry-rs/foundry --rev 56b806a3ba7866a3b061093bebd0fa2ace97f1fc --locked anvil --force
run: cargo install --git https://github.com/foundry-rs/foundry --rev 62cdea8ff9e6efef011f77e295823b5f2dbeb3a1 --locked anvil --force
- name: KZG prove and verify aggr tests
run: cargo nextest run --verbose tests_evm::kzg_evm_aggr_prove_and_verify_::t --test-threads 4 -- --include-ignored
@@ -687,16 +908,32 @@ jobs:
needs: [build, library-tests, docs]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- 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
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -709,23 +946,39 @@ jobs:
python-tests:
permissions:
contents: read
runs-on: [ non-gpu, non-sgx ]
runs-on: non-gpu
needs: [build, library-tests, docs]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
with:
python-version: "3.12"
- 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: Install cmake
@@ -735,32 +988,48 @@ jobs:
- name: Setup Virtual Env and Install python dependencies
run: python -m venv .env --clear; source .env/bin/activate; pip install -r requirements.txt;
- name: Install Anvil
run: cargo install --git https://github.com/foundry-rs/foundry --rev 56b806a3ba7866a3b061093bebd0fa2ace97f1fc --locked anvil --force
run: cargo install --git https://github.com/foundry-rs/foundry --rev 62cdea8ff9e6efef011f77e295823b5f2dbeb3a1 --locked anvil --force
- name: Build python ezkl
run: source .env/bin/activate; unset CONDA_PREFIX; maturin develop --features python-bindings,reusable-verifier --profile=test-runs
run: source .env/bin/activate; unset CONDA_PREFIX; maturin develop --features python-bindings --profile=test-runs
- name: Run pytest
run: source .env/bin/activate; pip install pytest-asyncio; pytest -vv
accuracy-measurement-tests:
permissions:
contents: read
runs-on: [ non-gpu, non-sgx ]
runs-on: non-gpu
needs: [build, library-tests, docs, python-tests, python-integration-tests]
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
with:
python-version: "3.12"
- 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
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -770,7 +1039,7 @@ jobs:
- name: Setup Virtual Env and Install python dependencies
run: python -m venv .env --clear; source .env/bin/activate; pip install -r requirements.txt;
- name: Build python ezkl
run: source .env/bin/activate; unset CONDA_PREFIX; maturin develop --features python-bindings,reusable-verifier --profile=test-runs
run: source .env/bin/activate; unset CONDA_PREFIX; maturin develop --features python-bindings --profile=test-runs
- name: Public inputs
run: source .env/bin/activate; cargo nextest run --verbose tests::accuracy_measurement_public_inputs_
- name: fixed params
@@ -786,19 +1055,35 @@ jobs:
runs-on: large-self-hosted
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
with:
python-version: "3.11"
- 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
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -808,13 +1093,13 @@ jobs:
# - name: Install solc
# run: (hash svm 2>/dev/null || cargo install svm-rs) && svm install 0.8.20 && solc --version
- name: Install Anvil
run: cargo install --git https://github.com/foundry-rs/foundry --rev 56b806a3ba7866a3b061093bebd0fa2ace97f1fc --locked anvil --force
run: cargo install --git https://github.com/foundry-rs/foundry --rev 62cdea8ff9e6efef011f77e295823b5f2dbeb3a1 --locked anvil --force
- name: Install pip
run: python -m ensurepip --upgrade
- name: Setup Virtual Env and Install python dependencies
run: python -m venv .env --clear; source .env/bin/activate; pip install -r requirements.txt; python -m ensurepip --upgrade
- name: Build python ezkl
run: source .env/bin/activate; unset CONDA_PREFIX; maturin develop --features python-bindings,reusable-verifier --profile=test-runs
run: source .env/bin/activate; unset CONDA_PREFIX; maturin develop --features python-bindings --profile=test-runs
- name: Cat and Dog notebook
run: source .env/bin/activate; cargo nextest run py_tests::tests::cat_and_dog_notebook_
- name: All notebooks
@@ -849,16 +1134,32 @@ jobs:
runs-on: macos-latest
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- 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
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
@@ -866,7 +1167,7 @@ jobs:
crate: cargo-nextest
locked: true
- name: Run ios tests
run: CARGO_BUILD_TARGET=aarch64-apple-darwin RUSTUP_TOOLCHAIN=nightly-2025-05-01-aarch64-apple-darwin cargo test --test ios_integration_tests --features ios-bindings-test --no-default-features
run: CARGO_BUILD_TARGET=aarch64-apple-darwin RUSTUP_TOOLCHAIN=nightly-2025-02-17-aarch64-apple-darwin cargo test --test ios_integration_tests --features ios-bindings-test --no-default-features
swift-package-tests:
permissions:
@@ -876,15 +1177,32 @@ jobs:
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
steps:
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
with:
persist-credentials: false
- name: Configure Git credentials
run: |
if [ -z "$EVM_VERIFIER_EZKL_TOKEN" ]; then
echo "❌ EVM_VERIFIER_EZKL_TOKEN is empty check repo/org secrets" >&2
exit 1
fi
# For libgit2 (what Cargo uses internally)
git config --global credential.helper store
echo "https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com" > ~/.git-credentials
chmod 600 ~/.git-credentials
# Also set URL replacement with oauth2 format
git config --global \
url."https://oauth2:${EVM_VERIFIER_EZKL_TOKEN}@github.com/".insteadOf \
"https://github.com/"
env:
EVM_VERIFIER_EZKL_TOKEN: ${{ secrets.EVM_VERIFIER_EZKL_TOKEN }}
- 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: Build EzklCoreBindings

View File

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

2
Cargo.lock generated
View File

@@ -2585,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",

View File

@@ -227,7 +227,6 @@ default = [
"precompute-coset",
"no-banner",
"parallel-poly-read",
"reusable-verifier",
]
onnx = ["dep:tract-onnx"]
python-bindings = ["pyo3", "pyo3-log", "pyo3-async-runtimes", "pyo3-stub-gen"]
@@ -282,7 +281,6 @@ macos-metal = ["halo2_proofs/macos"]
ios-metal = ["halo2_proofs/ios"]
jemalloc = ["dep:jemallocator"]
mimalloc = ["dep:mimalloc"]
reusable-verifier = []
[patch.crates-io]

312
abis/DataAttestation.json Normal file
View 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
View 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
View 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"
}
]

View File

@@ -1,7 +1,7 @@
import ezkl
project = 'ezkl'
release = '22.2.2'
release = '0.0.0'
version = release

View File

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

View File

@@ -1,3 +1,3 @@
[toolchain]
channel = "nightly-2025-05-01"
channel = "nightly-2025-02-17"
components = ["rustfmt", "clippy"]

View File

@@ -93,6 +93,16 @@ 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]
@@ -125,6 +135,15 @@ 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
///
@@ -142,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,
@@ -211,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,
@@ -238,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,
@@ -680,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"))?;
@@ -870,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>,
@@ -1087,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
@@ -1269,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
@@ -1635,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,
@@ -1662,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.
///
@@ -1696,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,
@@ -1726,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,
@@ -1753,7 +1766,6 @@ fn deploy_evm(
})
}
#[cfg(feature = "reusable-verifier")]
/// Registers a VKA on the EZKL reusable verifier contract
///
/// Arguments
@@ -1910,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,
@@ -1981,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(())
}

View File

@@ -8,9 +8,8 @@ use halo2_proofs::{
use log::debug;
#[cfg(feature = "python-bindings")]
use pyo3::{
conversion::FromPyObject,
conversion::{FromPyObject, IntoPy},
exceptions::PyValueError,
IntoPyObject,
prelude::*,
};
use serde::{Deserialize, Serialize};
@@ -87,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),
}
}
}

View File

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

View File

@@ -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,22 +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 {
impl IntoPy<PyObject> for CalibrationTarget {
fn into_py(self, py: Python) -> PyObject {
match self {
CalibrationTarget::Resources { col_overflow: true } => {
"resources/col-overflow"
"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),
}
}
}
@@ -299,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),
}
}
}
@@ -728,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
@@ -750,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)]
@@ -802,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
@@ -864,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,
},
@@ -882,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)]
@@ -890,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)]

View File

@@ -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'sround" comparison: compare the **decimal** produced
/// “Bankersround” 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 digit5; 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();
// fractionpart 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
}

View File

@@ -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};
@@ -222,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,
@@ -404,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(
@@ -413,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
}
@@ -437,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,
@@ -1121,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!(
@@ -1154,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;
@@ -1205,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;
}
}
@@ -1266,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()
};
@@ -1278,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;
}
@@ -1295,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());
}
@@ -1500,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>,
@@ -1508,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>>(
@@ -1591,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,
@@ -1599,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)

View File

@@ -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,29 +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),
}
}
}

View File

@@ -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,434 +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 {
@@ -942,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
@@ -959,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
@@ -1102,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
@@ -1405,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>,
@@ -2104,155 +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();
}
}

View File

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

View File

@@ -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)?;

View File

@@ -9,7 +9,7 @@ use itertools::Itertools;
use log::debug;
#[cfg(feature = "python-bindings")]
use pyo3::{
exceptions::PyValueError, FromPyObject, IntoPyObject, PyResult, Python,
exceptions::PyValueError, FromPyObject, IntoPy, PyObject, PyResult, Python, ToPyObject,
};
use serde::{Deserialize, Serialize};
#[cfg(all(feature = "ezkl", not(target_arch = "wasm32")))]
@@ -107,31 +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,
}
}

View File

@@ -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,7 +378,6 @@ 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,

View File

@@ -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,15 @@ 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")]
///
@@ -402,18 +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)
}
}

View File

@@ -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.

View File

@@ -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,12 +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.input_data.into_iter().map(|input| {
(0..num_batches)
.map(move |_| input.clone()).flatten().collect::<Vec<_>>()
}).collect::<Vec<_>>();
let duplicated_input_data: FileSource = data
.input_data
.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());
@@ -1015,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();
@@ -1025,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
@@ -1047,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;
}
@@ -2091,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))
@@ -2241,7 +2243,6 @@ mod native_tests {
assert!(status.success());
}
#[allow(unused_variables)]
fn build_ezkl() {
#[cfg(feature = "icicle")]
let args = [
@@ -2274,15 +2275,6 @@ mod native_tests {
"--features",
"ezkl,solidity-verifier,eth",
];
#[cfg(feature = "reusable-verifier")]
let args = [
"build",
"--profile=test-runs",
"--bin",
"ezkl",
"--features",
"reusable-verifier",
];
let status = Command::new("cargo")
.args(args)