mirror of
https://github.com/zkonduit/ezkl.git
synced 2026-01-14 08:48:01 -05:00
Compare commits
66 Commits
ac/cleanup
...
vka-hashin
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afff3a637d | ||
|
|
538d7e52ad | ||
|
|
4e857c2d63 | ||
|
|
87e5079fe7 | ||
|
|
6d8e2bd2f2 | ||
|
|
9f1e4773ab | ||
|
|
d32d7d0225 | ||
|
|
d67a5e82d5 | ||
|
|
ff8ec62916 | ||
|
|
96b46d8628 | ||
|
|
1028b9d3cc | ||
|
|
c367500b38 | ||
|
|
00fcddbed3 | ||
|
|
e1d09985da | ||
|
|
5309366438 | ||
|
|
ed67713de9 | ||
|
|
ce7235b0db | ||
|
|
716916f58d | ||
|
|
5c9f518039 | ||
|
|
343ceb9030 | ||
|
|
14c99223e7 | ||
|
|
f683ee2239 | ||
|
|
479773b16e | ||
|
|
0562911b73 | ||
|
|
6e36b5bb4c | ||
|
|
00ab001fc7 | ||
|
|
037d954d2a | ||
|
|
4e4fd7dba0 | ||
|
|
17d2f5db36 | ||
|
|
94ad885cda | ||
|
|
0ef1f35e59 | ||
|
|
808ab7d0de | ||
|
|
68b2c96b97 | ||
|
|
9a0ab22fdb | ||
|
|
f2b1de3740 | ||
|
|
dcb888ff1e | ||
|
|
26f465e70c | ||
|
|
8eef53213d | ||
|
|
a1345966d7 | ||
|
|
640061c850 | ||
|
|
da7db7d88d | ||
|
|
a55f75ff3f | ||
|
|
bf6f704827 | ||
|
|
0dbfdf4672 | ||
|
|
98299356a6 | ||
|
|
04805d2a91 | ||
|
|
ca18cf29bb | ||
|
|
78f8e23b55 | ||
|
|
7d40926082 | ||
|
|
e2c8182871 | ||
|
|
4f077c9134 | ||
|
|
038805ce02 | ||
|
|
0fb87c9a20 | ||
|
|
77423a6d07 | ||
|
|
8b416c7a00 | ||
|
|
73ec5e549a | ||
|
|
28386d8442 | ||
|
|
1b12f9256d | ||
|
|
59495f3385 | ||
|
|
4a49517ba2 | ||
|
|
d36b185037 | ||
|
|
a579826c9c | ||
|
|
ed6bce0657 | ||
|
|
98ee20a38f | ||
|
|
77caac3981 | ||
|
|
342cbc4408 |
3
.github/workflows/release.yml
vendored
3
.github/workflows/release.yml
vendored
@@ -26,6 +26,7 @@ jobs:
|
||||
shell: bash
|
||||
run: |
|
||||
echo "EZKL_VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV
|
||||
echo "version is: ${{ env.EZKL_VERSION }}"
|
||||
|
||||
- name: Create Github Release
|
||||
id: create-release
|
||||
@@ -63,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
|
||||
@@ -150,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
|
||||
|
||||
405
.github/workflows/rust.yml
vendored
405
.github/workflows/rust.yml
vendored
@@ -30,6 +30,24 @@ 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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
@@ -53,7 +71,24 @@ 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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
@@ -73,6 +108,25 @@ 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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-02-17
|
||||
@@ -91,6 +145,25 @@ 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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-02-17
|
||||
@@ -151,6 +224,24 @@ 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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
@@ -187,7 +278,24 @@ 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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
@@ -224,7 +332,24 @@ 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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
@@ -241,14 +366,31 @@ 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 }}
|
||||
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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
@@ -266,16 +408,10 @@ jobs:
|
||||
run: rustup target add wasm32-unknown-unknown
|
||||
- name: Add rust-src
|
||||
run: rustup component add rust-src --toolchain nightly-2025-02-17-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
|
||||
- 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:
|
||||
@@ -288,7 +424,24 @@ 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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-02-17
|
||||
@@ -351,14 +504,31 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
runs-on: non-gpu
|
||||
# needs: [build, library-tests, docs, python-tests, python-integration-tests]
|
||||
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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
@@ -393,16 +563,16 @@ jobs:
|
||||
- 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)
|
||||
@@ -455,7 +625,24 @@ 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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
@@ -575,7 +762,24 @@ 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: dtolnay/rust-toolchain@4f94fbe7e03939b0e674bcc9ca609a16088f63ff #nightly branch, TODO: update when required
|
||||
with:
|
||||
@@ -620,7 +824,24 @@ 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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
@@ -645,7 +866,24 @@ 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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
@@ -674,7 +912,24 @@ 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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
@@ -699,7 +954,24 @@ 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/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
|
||||
with:
|
||||
@@ -718,7 +990,7 @@ jobs:
|
||||
- name: Install Anvil
|
||||
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
|
||||
|
||||
@@ -733,7 +1005,24 @@ 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/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
|
||||
with:
|
||||
@@ -750,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
|
||||
@@ -770,7 +1059,24 @@ 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/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
|
||||
with:
|
||||
@@ -793,7 +1099,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; 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
|
||||
@@ -832,7 +1138,24 @@ 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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
@@ -858,6 +1181,24 @@ 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-rs/toolchain@b2417cde72dcf67f306c0ae8e0828a81bf0b189f #v1.0.6
|
||||
with:
|
||||
|
||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -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",
|
||||
|
||||
@@ -281,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
312
abis/DataAttestation.json
Normal file
@@ -0,0 +1,312 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_contractAddresses",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "_callData",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "_decimals",
|
||||
"type": "uint256[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "_bits",
|
||||
"type": "uint256[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "_instanceOffset",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "HALF_ORDER",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ORDER",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "instances",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"name": "attestData",
|
||||
"outputs": [],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "callData",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "contractAddress",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "encoded",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "getInstancesCalldata",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "instances",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "encoded",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "getInstancesMemory",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "instances",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "index",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getScalars",
|
||||
"outputs": [
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "decimals",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "bits",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"internalType": "struct DataAttestation.Scalars",
|
||||
"name": "",
|
||||
"type": "tuple"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "instanceOffset",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "x",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "y",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "denominator",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "mulDiv",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "result",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "int256",
|
||||
"name": "x",
|
||||
"type": "int256"
|
||||
},
|
||||
{
|
||||
"components": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "decimals",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "bits",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"internalType": "struct DataAttestation.Scalars",
|
||||
"name": "_scalars",
|
||||
"type": "tuple"
|
||||
}
|
||||
],
|
||||
"name": "quantizeData",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "int256",
|
||||
"name": "quantized_data",
|
||||
"type": "int256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "staticCall",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "int256",
|
||||
"name": "x",
|
||||
"type": "int256"
|
||||
}
|
||||
],
|
||||
"name": "toFieldElement",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "field_element",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "verifier",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "encoded",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "verifyWithDataAttestation",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
98
abis/QuantizeData.json
Normal file
98
abis/QuantizeData.json
Normal file
@@ -0,0 +1,98 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "int256[]",
|
||||
"name": "quantized_data",
|
||||
"type": "int256[]"
|
||||
}
|
||||
],
|
||||
"name": "check_is_valid_field_element",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "output",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes[]",
|
||||
"name": "data",
|
||||
"type": "bytes[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "decimals",
|
||||
"type": "uint256[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "scales",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"name": "quantize_data_multi",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "int256[]",
|
||||
"name": "quantized_data",
|
||||
"type": "int256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "decimals",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "scales",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"name": "quantize_data_single",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "int256[]",
|
||||
"name": "quantized_data",
|
||||
"type": "int256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "int64[]",
|
||||
"name": "quantized_data",
|
||||
"type": "int64[]"
|
||||
}
|
||||
],
|
||||
"name": "to_field_element",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "output",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "pure",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
32
abis/TestReads.json
Normal file
32
abis/TestReads.json
Normal file
@@ -0,0 +1,32 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "int256[]",
|
||||
"name": "_numbers",
|
||||
"type": "int256[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "arr",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "int256",
|
||||
"name": "",
|
||||
"type": "int256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
@@ -9,6 +9,6 @@ pytest==8.1.1
|
||||
tomli==2.0.1
|
||||
typing-extensions==4.10.0
|
||||
zipp==3.18.1
|
||||
onnx==1.17.0
|
||||
onnx==1.15.0
|
||||
onnxruntime==1.17.1
|
||||
numpy==1.26.4
|
||||
|
||||
@@ -1676,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.
|
||||
///
|
||||
@@ -1767,7 +1766,6 @@ fn deploy_evm(
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(feature = "reusable-verifier")]
|
||||
/// Registers a VKA on the EZKL reusable verifier contract
|
||||
///
|
||||
/// Arguments
|
||||
@@ -1995,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(())
|
||||
}
|
||||
|
||||
@@ -713,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
|
||||
@@ -735,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)]
|
||||
@@ -787,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
|
||||
@@ -849,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,
|
||||
},
|
||||
@@ -867,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)]
|
||||
@@ -875,7 +870,7 @@ pub enum Commands {
|
||||
},
|
||||
/// Registers a VKA, returning the its digest used to identify it on-chain.
|
||||
#[command(name = "register-vka")]
|
||||
#[cfg(feature = "reusable-verifier")]
|
||||
#[cfg(all(feature = "eth", not(target_arch = "wasm32")))]
|
||||
RegisterVka {
|
||||
/// RPC URL for an Ethereum node, if None will use Anvil but WON'T persist state
|
||||
#[arg(short = 'U', long, value_hint = clap::ValueHint::Url)]
|
||||
|
||||
92
src/eth.rs
92
src/eth.rs
@@ -3,7 +3,7 @@ use crate::pfsys::{encode_calldata, Snark};
|
||||
use alloy::contract::CallBuilder;
|
||||
use alloy::core::primitives::Address as H160;
|
||||
use alloy::core::primitives::Bytes;
|
||||
use alloy::core::primitives::I256;
|
||||
use alloy::core::primitives::U256;
|
||||
use alloy::dyn_abi::abi::TokenSeq;
|
||||
// use alloy::providers::Middleware;
|
||||
use alloy::json_abi::JsonAbi;
|
||||
@@ -279,7 +279,7 @@ pub async fn verify_proof_via_solidity(
|
||||
// From result[96..], iterate through 32 byte chunks converting them to U256
|
||||
let rescaled_instances = result.to_vec()[96..]
|
||||
.chunks_exact(32)
|
||||
.map(|chunk| I256::try_from_be_slice(chunk).unwrap().to_string())
|
||||
.map(|chunk| U256::from_be_slice(chunk).to_string())
|
||||
.collect::<Vec<_>>();
|
||||
if let Some(pretty) = &proof.pretty_public_inputs {
|
||||
// 1️⃣ collect reference decimals --------------------------------------
|
||||
@@ -433,95 +433,43 @@ pub async fn get_contract_artifacts(
|
||||
///
|
||||
/// `"1541748046875000000"` → `"1.541748046875000000"`
|
||||
/// `"273690402507781982"` → `"0.273690402507781982"`
|
||||
/// `"-892333984375000000"` → `"-0.892333984375000000"`
|
||||
fn to_decimal_18(s: &str) -> String {
|
||||
let is_negative = s.starts_with('-');
|
||||
let s = if is_negative { &s[1..] } else { s };
|
||||
let s = s.trim_start_matches('0');
|
||||
|
||||
if s.is_empty() {
|
||||
return "0".into();
|
||||
}
|
||||
|
||||
if s.len() <= 18 {
|
||||
// pad on the left so we always have exactly 18 fraction digits
|
||||
let result = format!("0.{:0>18}", s);
|
||||
return if is_negative {
|
||||
format!("-{}", result)
|
||||
} else {
|
||||
result
|
||||
};
|
||||
return format!("0.{:0>18}", s);
|
||||
}
|
||||
|
||||
let split = s.len() - 18;
|
||||
let result = format!("{}.{}", &s[..split], &s[split..]);
|
||||
if is_negative {
|
||||
format!("-{}", result)
|
||||
} else {
|
||||
result
|
||||
}
|
||||
format!("{}.{}", &s[..split], &s[split..]) // ← correct slice here
|
||||
}
|
||||
/// "Banker's‐round" comparison: compare the **decimal** produced
|
||||
|
||||
/// “Banker’s‐round” comparison: compare the **decimal** produced
|
||||
/// by `instance` to the reference string `expected`.
|
||||
///
|
||||
/// * Only the first 18 digits of the expected fraction part are compared.
|
||||
/// * All digits present in the truncated `expected` (integer part **and** first 18 fraction digits)
|
||||
/// * All digits present in `expected` (integer part **and** fraction)
|
||||
/// must match exactly.
|
||||
/// * Excess digits in `instance` are ignored **unless** the very first
|
||||
/// excess digit ≥ 5; in that case we round the last compared digit
|
||||
/// excess digit ≥ 5; in that case we round the last compared digit
|
||||
/// and check again.
|
||||
fn scaled_matches(instance: &str, expected: &str) -> bool {
|
||||
let inst_dec = to_decimal_18(instance);
|
||||
let (inst_int, inst_frac) = inst_dec.split_once('.').unwrap_or((&inst_dec, ""));
|
||||
let (exp_int, exp_frac) = expected.split_once('.').unwrap_or((expected, ""));
|
||||
|
||||
// Normalize both integer parts to handle "-" vs "-0"
|
||||
let normalized_inst_int = if inst_int == "-" { "-0" } else { inst_int };
|
||||
let normalized_exp_int = if exp_int == "-" { "-0" } else { exp_int };
|
||||
|
||||
// integer part must be identical
|
||||
if normalized_inst_int != normalized_exp_int {
|
||||
if inst_int != exp_int {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If expected has more than 18 decimal places, round it to 18 places
|
||||
let exp_frac_truncated = if exp_frac.len() > 18 {
|
||||
let truncated = &exp_frac[..18];
|
||||
let next_digit = exp_frac.chars().nth(18).unwrap_or('0');
|
||||
|
||||
if next_digit >= '6' {
|
||||
// Need to round up the 18th digit
|
||||
let mut rounded = truncated.chars().collect::<Vec<_>>();
|
||||
let mut carry = true;
|
||||
for d in rounded.iter_mut().rev() {
|
||||
if !carry {
|
||||
break;
|
||||
}
|
||||
let v = d.to_digit(10).unwrap() + 1;
|
||||
*d = char::from_digit(v % 10, 10).unwrap();
|
||||
carry = v == 10;
|
||||
}
|
||||
if carry {
|
||||
// All 18 digits were 9s - this would carry to integer part
|
||||
// For now, return the original truncated (this edge case may need special handling)
|
||||
truncated.to_string()
|
||||
} else {
|
||||
rounded.into_iter().collect::<String>()
|
||||
}
|
||||
} else {
|
||||
truncated.to_string()
|
||||
}
|
||||
} else {
|
||||
exp_frac.to_string()
|
||||
};
|
||||
let exp_frac_truncated = exp_frac_truncated.as_str();
|
||||
|
||||
// fraction‑part comparison with optional rounding
|
||||
let cmp_len = exp_frac_truncated.len();
|
||||
let cmp_len = exp_frac.len();
|
||||
let inst_cmp = &inst_frac[..cmp_len.min(inst_frac.len())];
|
||||
let trailing = inst_frac.chars().nth(cmp_len).unwrap_or('0');
|
||||
|
||||
if inst_cmp == exp_frac_truncated {
|
||||
if inst_cmp == exp_frac {
|
||||
true // exact match
|
||||
} else if trailing >= '5' {
|
||||
// need to round
|
||||
@@ -538,20 +486,12 @@ fn scaled_matches(instance: &str, expected: &str) -> bool {
|
||||
}
|
||||
if carry {
|
||||
// 0.999… → 1.000…
|
||||
// Handle negative numbers in the carry case
|
||||
let is_negative = normalized_inst_int.starts_with('-');
|
||||
let abs_int = normalized_inst_int.trim_start_matches('-');
|
||||
let incremented =
|
||||
(num::BigUint::parse_bytes(abs_int.as_bytes(), 10).unwrap() + 1u32).to_string();
|
||||
let expected_after_carry = if is_negative {
|
||||
format!("-{}", incremented)
|
||||
} else {
|
||||
incremented
|
||||
};
|
||||
return normalized_exp_int == expected_after_carry
|
||||
&& exp_frac_truncated.chars().all(|c| c == '0');
|
||||
return exp_int
|
||||
== &(num::BigUint::parse_bytes(exp_int.as_bytes(), 10).unwrap() + 1u32)
|
||||
.to_string()
|
||||
&& exp_frac.chars().all(|c| c == '0');
|
||||
}
|
||||
rounded.into_iter().collect::<String>() == exp_frac_truncated
|
||||
rounded.into_iter().collect::<String>() == exp_frac
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ use crate::circuit::region::RegionSettings;
|
||||
use crate::circuit::CheckMode;
|
||||
use crate::commands::CalibrationTarget;
|
||||
#[cfg(all(feature = "eth", not(target_arch = "wasm32")))]
|
||||
use crate::eth::deploy_contract_via_solidity;
|
||||
#[cfg(all(feature = "reusable-verifier", not(target_arch = "wasm32")))]
|
||||
use crate::eth::register_vka_via_rv;
|
||||
use crate::eth::{deploy_contract_via_solidity, register_vka_via_rv};
|
||||
#[allow(unused_imports)]
|
||||
#[cfg(all(feature = "eth", not(target_arch = "wasm32")))]
|
||||
use crate::eth::{get_contract_artifacts, verify_proof_via_solidity};
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -1277,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;
|
||||
}
|
||||
|
||||
@@ -1294,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());
|
||||
}
|
||||
|
||||
@@ -1499,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>,
|
||||
@@ -1507,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>>(
|
||||
@@ -1590,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,
|
||||
@@ -1598,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)
|
||||
|
||||
@@ -21,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)]
|
||||
@@ -33,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 {
|
||||
@@ -171,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
|
||||
@@ -205,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>>();
|
||||
@@ -246,7 +338,7 @@ impl GraphData {
|
||||
}
|
||||
}
|
||||
Ok(GraphData {
|
||||
input_data,
|
||||
input_data: DataSource(input_data),
|
||||
output_data: None,
|
||||
})
|
||||
}
|
||||
@@ -332,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() {
|
||||
@@ -377,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
|
||||
@@ -401,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}"#;
|
||||
|
||||
@@ -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;
|
||||
@@ -956,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>,
|
||||
|
||||
@@ -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,7 +163,12 @@ 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;
|
||||
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.into());
|
||||
|
||||
@@ -1012,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();
|
||||
@@ -1022,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
|
||||
@@ -1044,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;
|
||||
}
|
||||
@@ -2088,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))
|
||||
@@ -2270,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)
|
||||
|
||||
Reference in New Issue
Block a user