mirror of
https://github.com/zkonduit/ezkl.git
synced 2026-01-19 19:28:43 -05:00
Compare commits
4 Commits
ac/chebysh
...
release-v2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f494f6758 | ||
|
|
5da444ee72 | ||
|
|
5144991b21 | ||
|
|
64acb1d9d6 |
2
.github/workflows/large-tests.yml
vendored
2
.github/workflows/large-tests.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: nanoGPT Mock
|
||||
|
||||
63
.github/workflows/pypi.yml
vendored
63
.github/workflows/pypi.yml
vendored
@@ -24,12 +24,12 @@ jobs:
|
||||
matrix:
|
||||
target: [x86_64, universal2-apple-darwin]
|
||||
env:
|
||||
RELEASE_TAG: ${{ github.ref_name }}
|
||||
RELEASE_TAG: ${{ github.ref_name }}
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
|
||||
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
|
||||
with:
|
||||
python-version: 3.12
|
||||
architecture: x64
|
||||
@@ -48,22 +48,22 @@ 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-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
cache: false
|
||||
|
||||
- name: Build wheels
|
||||
if: matrix.target == 'universal2-apple-darwin'
|
||||
uses: PyO3/maturin-action@5f8a1b3b0aad13193f46c9131f9b9e663def8ce5 #v1.46.0
|
||||
uses: PyO3/maturin-action@5f8a1b3b0aad13193f46c9131f9b9e663def8ce5 #v1.46.0
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
args: --release --out dist --features python-bindings
|
||||
- name: Build wheels
|
||||
if: matrix.target == 'x86_64'
|
||||
uses: PyO3/maturin-action@5f8a1b3b0aad13193f46c9131f9b9e663def8ce5 #v1.46.0
|
||||
uses: PyO3/maturin-action@5f8a1b3b0aad13193f46c9131f9b9e663def8ce5 #v1.46.0
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
args: --release --out dist --features python-bindings
|
||||
@@ -74,7 +74,7 @@ jobs:
|
||||
python -c "import ezkl"
|
||||
|
||||
- name: Upload wheels
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 #v4.6.0
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 #v4.6.0
|
||||
with:
|
||||
name: dist-macos-${{ matrix.target }}
|
||||
path: dist
|
||||
@@ -88,10 +88,10 @@ jobs:
|
||||
matrix:
|
||||
target: [x64, x86]
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
|
||||
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
|
||||
with:
|
||||
python-version: 3.12
|
||||
architecture: ${{ matrix.target }}
|
||||
@@ -114,15 +114,15 @@ 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-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
cache: false
|
||||
|
||||
- name: Build wheels
|
||||
uses: PyO3/maturin-action@5f8a1b3b0aad13193f46c9131f9b9e663def8ce5 #v1.46.0
|
||||
uses: PyO3/maturin-action@5f8a1b3b0aad13193f46c9131f9b9e663def8ce5 #v1.46.0
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
args: --release --out dist --features python-bindings
|
||||
@@ -132,7 +132,7 @@ jobs:
|
||||
python -c "import ezkl"
|
||||
|
||||
- name: Upload wheels
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 #v4.6.0 #v4.6.0
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 #v4.6.0 #v4.6.0
|
||||
with:
|
||||
name: dist-windows-${{ matrix.target }}
|
||||
path: dist
|
||||
@@ -146,10 +146,10 @@ jobs:
|
||||
matrix:
|
||||
target: [x86_64]
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
|
||||
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
|
||||
with:
|
||||
python-version: 3.12
|
||||
architecture: x64
|
||||
@@ -178,7 +178,7 @@ jobs:
|
||||
sudo apt-get update && sudo apt-get install -y openssl pkg-config libssl-dev
|
||||
|
||||
- name: Build wheels
|
||||
uses: PyO3/maturin-action@5f8a1b3b0aad13193f46c9131f9b9e663def8ce5 #v1.46.0
|
||||
uses: PyO3/maturin-action@5f8a1b3b0aad13193f46c9131f9b9e663def8ce5 #v1.46.0
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: auto
|
||||
@@ -205,7 +205,7 @@ jobs:
|
||||
python -c "import ezkl"
|
||||
|
||||
- name: Upload wheels
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 #v4.6.0
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 #v4.6.0
|
||||
with:
|
||||
name: dist-linux-${{ matrix.target }}
|
||||
path: dist
|
||||
@@ -220,10 +220,10 @@ jobs:
|
||||
target:
|
||||
- x86_64-unknown-linux-musl
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
|
||||
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
|
||||
with:
|
||||
python-version: 3.12
|
||||
architecture: x64
|
||||
@@ -252,7 +252,7 @@ jobs:
|
||||
sudo apt-get update && sudo apt-get install -y pkg-config libssl-dev
|
||||
|
||||
- name: Build wheels
|
||||
uses: PyO3/maturin-action@5f8a1b3b0aad13193f46c9131f9b9e663def8ce5 #v1.46.0
|
||||
uses: PyO3/maturin-action@5f8a1b3b0aad13193f46c9131f9b9e663def8ce5 #v1.46.0
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: musllinux_1_2
|
||||
@@ -273,7 +273,7 @@ jobs:
|
||||
python3 -c "import ezkl"
|
||||
|
||||
- name: Upload wheels
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 #v4.6.0
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 #v4.6.0
|
||||
with:
|
||||
name: dist-musllinux-${{ matrix.target }}
|
||||
path: dist
|
||||
@@ -289,10 +289,10 @@ jobs:
|
||||
- target: aarch64-unknown-linux-musl
|
||||
arch: aarch64
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
|
||||
- uses: actions/setup-python@b64ffcaf5b410884ad320a9cfac8866006a109aa #v4.8.0
|
||||
with:
|
||||
python-version: 3.12
|
||||
|
||||
@@ -315,13 +315,13 @@ jobs:
|
||||
sed "s/0\\.0\\.0/${RELEASE_TAG//v}/" Cargo.lock.orig >Cargo.lock
|
||||
|
||||
- name: Build wheels
|
||||
uses: PyO3/maturin-action@5f8a1b3b0aad13193f46c9131f9b9e663def8ce5 #v1.46.0
|
||||
uses: PyO3/maturin-action@5f8a1b3b0aad13193f46c9131f9b9e663def8ce5 #v1.46.0
|
||||
with:
|
||||
target: ${{ matrix.platform.target }}
|
||||
manylinux: musllinux_1_2
|
||||
args: --release --out dist --features python-bindings
|
||||
|
||||
- uses: uraimo/run-on-arch-action@5397f9e30a9b62422f302092631c99ae1effcd9e #v2.8.1
|
||||
- uses: uraimo/run-on-arch-action@5397f9e30a9b62422f302092631c99ae1effcd9e #v2.8.1
|
||||
name: Install built wheel
|
||||
with:
|
||||
arch: ${{ matrix.platform.arch }}
|
||||
@@ -336,7 +336,7 @@ jobs:
|
||||
python3 -c "import ezkl"
|
||||
|
||||
- name: Upload wheels
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 #v4.6.0
|
||||
uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 #v4.6.0
|
||||
with:
|
||||
name: dist-musllinux-${{ matrix.platform.target }}
|
||||
path: dist
|
||||
@@ -349,7 +349,7 @@ jobs:
|
||||
if: "startsWith(github.ref, 'refs/tags/')"
|
||||
needs: [macos, windows, linux, musllinux, musllinux-cross]
|
||||
steps:
|
||||
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 #v4.1.8
|
||||
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 #v4.1.8
|
||||
with:
|
||||
pattern: dist-*
|
||||
merge-multiple: true
|
||||
@@ -366,11 +366,10 @@ jobs:
|
||||
|
||||
# publishes to PyPI
|
||||
- name: Publish package distributions to PyPI
|
||||
uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc #v1.12.4
|
||||
uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc #v1.12.4
|
||||
with:
|
||||
packages-dir: ./wheels
|
||||
|
||||
|
||||
doc-publish:
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -378,7 +377,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: pypi-publish
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Trigger RTDs build
|
||||
@@ -386,4 +385,4 @@ jobs:
|
||||
with:
|
||||
webhook_url: ${{ secrets.RTDS_WEBHOOK_URL }}
|
||||
webhook_token: ${{ secrets.RTDS_WEBHOOK_TOKEN }}
|
||||
commit_ref: ${{ github.ref_name }}
|
||||
commit_ref: ${{ github.ref_name }}
|
||||
|
||||
36
.github/workflows/release.yml
vendored
36
.github/workflows/release.yml
vendored
@@ -52,7 +52,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
cache: false
|
||||
@@ -98,14 +98,11 @@ jobs:
|
||||
echo "ASSET=build-artifacts/ezkl-linux-gpu.tar.gz" >> $GITHUB_ENV
|
||||
|
||||
- name: Upload release archive
|
||||
uses: actions/upload-release-asset@e8f9f06c4b078e705bd2ea027f0926603fc9b4d5 #v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda #v2.2.1
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.ASSET }}
|
||||
asset_name: ${{ env.ASSET }}
|
||||
asset_content_type: application/octet-stream
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
tag_name: ${{ env.EZKL_VERSION }}
|
||||
files: ${{ env.ASSET }}
|
||||
|
||||
build-release:
|
||||
permissions:
|
||||
@@ -127,27 +124,27 @@ jobs:
|
||||
include:
|
||||
- build: windows-msvc
|
||||
os: windows-latest
|
||||
rust: nightly-2025-05-01
|
||||
rust: nightly-2025-12-01
|
||||
target: x86_64-pc-windows-msvc
|
||||
- build: macos
|
||||
os: macos-13
|
||||
rust: nightly-2025-05-01
|
||||
rust: nightly-2025-12-01
|
||||
target: x86_64-apple-darwin
|
||||
- build: macos-aarch64
|
||||
os: macos-13
|
||||
rust: nightly-2025-05-01
|
||||
rust: nightly-2025-12-01
|
||||
target: aarch64-apple-darwin
|
||||
- build: linux-musl
|
||||
os: ubuntu-22.04
|
||||
rust: nightly-2025-05-01
|
||||
rust: nightly-2025-12-01
|
||||
target: x86_64-unknown-linux-musl
|
||||
- build: linux-gnu
|
||||
os: ubuntu-22.04
|
||||
rust: nightly-2025-05-01
|
||||
rust: nightly-2025-12-01
|
||||
target: x86_64-unknown-linux-gnu
|
||||
- build: linux-aarch64
|
||||
os: ubuntu-22.04
|
||||
rust: nightly-2025-05-01
|
||||
rust: nightly-2025-12-01
|
||||
target: aarch64-unknown-linux-gnu
|
||||
|
||||
steps:
|
||||
@@ -240,11 +237,8 @@ jobs:
|
||||
echo "ASSET=build-artifacts/ezkl-win.zip" >> $GITHUB_ENV
|
||||
|
||||
- name: Upload release archive
|
||||
uses: actions/upload-release-asset@e8f9f06c4b078e705bd2ea027f0926603fc9b4d5 #v1.0.2
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.RELEASE_TOKEN }}
|
||||
uses: softprops/action-gh-release@c95fe1489396fe8a9eb87c0abf8aa5b2ef267fda #v2.2.1
|
||||
with:
|
||||
upload_url: ${{ needs.create-release.outputs.upload_url }}
|
||||
asset_path: ${{ env.ASSET }}
|
||||
asset_name: ${{ env.ASSET }}
|
||||
asset_content_type: application/octet-stream
|
||||
token: ${{ secrets.RELEASE_TOKEN }}
|
||||
tag_name: ${{ env.EZKL_VERSION }}
|
||||
files: ${{ env.ASSET }}
|
||||
|
||||
42
.github/workflows/rust.yml
vendored
42
.github/workflows/rust.yml
vendored
@@ -33,7 +33,7 @@ jobs:
|
||||
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3
|
||||
@@ -58,7 +58,7 @@ jobs:
|
||||
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: install libc6
|
||||
@@ -82,7 +82,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: install libc6
|
||||
@@ -106,7 +106,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: install libc6
|
||||
@@ -140,7 +140,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
|
||||
@@ -185,7 +185,7 @@ jobs:
|
||||
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: install libc6
|
||||
@@ -223,7 +223,7 @@ jobs:
|
||||
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: install libc6
|
||||
@@ -256,7 +256,7 @@ jobs:
|
||||
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
|
||||
@@ -331,7 +331,7 @@ jobs:
|
||||
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
|
||||
@@ -344,11 +344,11 @@ jobs:
|
||||
with:
|
||||
persist-credentials: false
|
||||
- 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-12-01-x86_64-unknown-linux-gnu
|
||||
# - 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 c11315be56183bcbc13235475045670542d542ba --locked anvil --force
|
||||
- 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)
|
||||
@@ -380,11 +380,11 @@ jobs:
|
||||
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
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-12-01-x86_64-unknown-linux-gnu
|
||||
- name: Force rebuild icicle dependencies
|
||||
run: cargo clean -p icicle-runtime -p icicle-core -p icicle-hash -p icicle-bn254
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 #v4.2.2
|
||||
@@ -437,11 +437,11 @@ jobs:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
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-12-01-x86_64-unknown-linux-gnu
|
||||
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
|
||||
with:
|
||||
crate: cargo-nextest
|
||||
@@ -486,7 +486,7 @@ jobs:
|
||||
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: install libc6
|
||||
@@ -520,7 +520,7 @@ jobs:
|
||||
python-version: "3.12"
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- name: Install cmake
|
||||
@@ -530,7 +530,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: 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 c11315be56183bcbc13235475045670542d542ba --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
|
||||
- name: Run pytest
|
||||
@@ -554,7 +554,7 @@ jobs:
|
||||
python-version: "3.12"
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
|
||||
@@ -592,7 +592,7 @@ jobs:
|
||||
python-version: "3.11"
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
- uses: baptiste0928/cargo-install@91c5da15570085bcde6f4d7aed98cb82d6769fd3 #v3.3.0
|
||||
@@ -602,7 +602,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 c11315be56183bcbc13235475045670542d542ba --locked anvil --force
|
||||
- name: Install pip
|
||||
run: python -m ensurepip --upgrade
|
||||
- name: Setup Virtual Env and Install python dependencies
|
||||
|
||||
2
.github/workflows/static-analysis.yml
vendored
2
.github/workflows/static-analysis.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
||||
persist-credentials: false
|
||||
- uses: actions-rust-lang/setup-rust-toolchain@fb51252c7ba57d633bc668f941da052e410add48 #v1.0.6
|
||||
with:
|
||||
toolchain: nightly-2025-05-01
|
||||
toolchain: nightly-2025-12-01
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
|
||||
|
||||
3370
Cargo.lock
generated
3370
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
29
Cargo.toml
29
Cargo.toml
@@ -51,17 +51,16 @@ semver = { version = "1.0.22", optional = true }
|
||||
# evm related deps
|
||||
serde_json = { version = "1.0.97", features = ["float_roundtrip", "raw_value"] }
|
||||
|
||||
alloy = { git = "https://github.com/alloy-rs/alloy", version = "0.1.0", rev = "5fbf57bac99edef9d8475190109a7ea9fb7e5e83", features = [
|
||||
alloy = { version = "1.0", features = [
|
||||
"provider-http",
|
||||
"signers",
|
||||
"contract",
|
||||
"rpc-types-eth",
|
||||
"signer-wallet",
|
||||
"signer-local",
|
||||
"node-bindings",
|
||||
|
||||
], optional = true }
|
||||
|
||||
foundry-compilers = { version = "0.4.1", features = [
|
||||
foundry-compilers = { version = "0.19.1", features = [
|
||||
"svm-solc",
|
||||
], optional = true }
|
||||
ethabi = { version = "18", optional = true }
|
||||
@@ -80,16 +79,16 @@ tokio = { version = "1.35.0", default-features = false, features = [
|
||||
"macros",
|
||||
"rt-multi-thread",
|
||||
], optional = true }
|
||||
pyo3 = { version = "0.24.2", features = [
|
||||
pyo3 = { version = "0.27.2", features = [
|
||||
"extension-module",
|
||||
"abi3-py37",
|
||||
"macros",
|
||||
], default-features = false, optional = true }
|
||||
pyo3-async-runtimes = { git = "https://github.com/PyO3/pyo3-async-runtimes", version = "0.24.0", features = [
|
||||
pyo3-async-runtimes = { git = "https://github.com/PyO3/pyo3-async-runtimes", version = "0.27.0", features = [
|
||||
"attributes",
|
||||
"tokio-runtime",
|
||||
], default-features = false, optional = true }
|
||||
pyo3-log = { version = "0.12.0", default-features = false, optional = true }
|
||||
pyo3-log = { version = "0.13.2", default-features = false, optional = true }
|
||||
tract-onnx = { git = "https://github.com/sonos/tract/", rev = "37132e0397d0a73e5bd3a8615d932dabe44f6736", default-features = false, optional = true }
|
||||
tabled = { version = "0.12.0", optional = true }
|
||||
objc = { version = "0.2.4", optional = true }
|
||||
@@ -186,7 +185,7 @@ harness = false
|
||||
|
||||
|
||||
[[bench]]
|
||||
name = "tanh"
|
||||
name = "sigmoid"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
@@ -194,12 +193,12 @@ name = "relu_lookupless"
|
||||
harness = false
|
||||
|
||||
[[bench]]
|
||||
name = "accum_matmul_tanh"
|
||||
name = "accum_matmul_sigmoid"
|
||||
harness = false
|
||||
|
||||
|
||||
[[bench]]
|
||||
name = "accum_matmul_tanh_overflow"
|
||||
name = "accum_matmul_sigmoid_overflow"
|
||||
harness = false
|
||||
|
||||
[[bin]]
|
||||
@@ -282,11 +281,11 @@ halo2_proofs = { git = "https://github.com/zkonduit/halo2#1dd2090741f006fd031a07
|
||||
[patch.crates-io]
|
||||
uniffi_testing = { git = "https://github.com/ElusAegis/uniffi-rs", branch = "feat/testing-feature-build-fix" }
|
||||
|
||||
# [profile.release]
|
||||
# # debug = true
|
||||
# rustflags = ["-C", "relocation-model=pic"]
|
||||
# lto = "fat"
|
||||
# codegen-units = 1
|
||||
[profile.release]
|
||||
# debug = true
|
||||
rustflags = ["-C", "relocation-model=pic"]
|
||||
lto = "fat"
|
||||
codegen-units = 1
|
||||
# panic = "abort"
|
||||
|
||||
|
||||
|
||||
@@ -155,5 +155,5 @@ Check out `docs/advanced_security` for more advanced information on potential th
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Copyright (c) 2025 Zkonduit Inc.
|
||||
Copyright (c) 2026 Zkonduit Inc.
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ impl Circuit<Fr> for MyCircuit {
|
||||
&a,
|
||||
BITS,
|
||||
k,
|
||||
&LookupOp::Tanh { scale: 1.0.into() },
|
||||
&LookupOp::Sigmoid { scale: 1.0.into() },
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
@@ -95,7 +95,7 @@ impl Circuit<Fr> for MyCircuit {
|
||||
.layout(
|
||||
&mut region,
|
||||
&[&output.unwrap()],
|
||||
Box::new(LookupOp::Tanh { scale: 1.0.into() }),
|
||||
Box::new(LookupOp::Sigmoid { scale: 1.0.into() }),
|
||||
)
|
||||
.unwrap();
|
||||
Ok(())
|
||||
@@ -42,7 +42,7 @@ impl Circuit<Fr> for NLCircuit {
|
||||
.map(|_| VarTensor::new_advice(cs, K, 1, LEN))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let nl = LookupOp::Tanh { scale: 1.0.into() };
|
||||
let nl = LookupOp::Sigmoid { scale: 1.0.into() };
|
||||
|
||||
let mut config = Config::default();
|
||||
|
||||
@@ -68,7 +68,7 @@ impl Circuit<Fr> for NLCircuit {
|
||||
.layout(
|
||||
&mut region,
|
||||
&[&self.input],
|
||||
Box::new(LookupOp::Tanh { scale: 1.0.into() }),
|
||||
Box::new(LookupOp::Sigmoid { scale: 1.0.into() }),
|
||||
)
|
||||
.unwrap();
|
||||
Ok(())
|
||||
@@ -1,7 +1,7 @@
|
||||
import ezkl
|
||||
|
||||
project = 'ezkl'
|
||||
release = '0.0.0'
|
||||
release = '23.0.4'
|
||||
version = release
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
[toolchain]
|
||||
channel = "nightly-2025-05-01"
|
||||
channel = "nightly-2025-12-01"
|
||||
components = ["rustfmt", "clippy"]
|
||||
|
||||
@@ -175,6 +175,9 @@ struct PyRunArgs {
|
||||
/// int: The number of legs used for decomposition
|
||||
#[pyo3(get, set)]
|
||||
pub decomp_legs: usize,
|
||||
/// bool: Should the circuit use unbounded lookups for log
|
||||
#[pyo3(get, set)]
|
||||
pub bounded_log_lookup: bool,
|
||||
/// bool: Should the circuit use range checks for inputs and outputs (set to false if the input is a felt)
|
||||
#[pyo3(get, set)]
|
||||
pub ignore_range_check_inputs_outputs: bool,
|
||||
@@ -199,6 +202,7 @@ impl PyRunArgs {
|
||||
impl From<PyRunArgs> for RunArgs {
|
||||
fn from(py_run_args: PyRunArgs) -> Self {
|
||||
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,
|
||||
@@ -225,6 +229,7 @@ impl Into<PyRunArgs> for RunArgs {
|
||||
fn into(self) -> PyRunArgs {
|
||||
let eps = self.get_epsilon();
|
||||
PyRunArgs {
|
||||
bounded_log_lookup: self.bounded_log_lookup,
|
||||
input_scale: self.input_scale,
|
||||
param_scale: self.param_scale,
|
||||
rebase_scale: self.rebase_scale,
|
||||
@@ -915,18 +920,19 @@ fn calibrate_settings(
|
||||
))]
|
||||
#[gen_stub_pyfunction]
|
||||
fn gen_witness(
|
||||
py: Python<'_>,
|
||||
data: String,
|
||||
model: PathBuf,
|
||||
output: Option<PathBuf>,
|
||||
vk_path: Option<PathBuf>,
|
||||
srs_path: Option<PathBuf>,
|
||||
) -> PyResult<PyObject> {
|
||||
) -> PyResult<Py<PyAny>> {
|
||||
let output =
|
||||
crate::execute::gen_witness(model, data, output, vk_path, srs_path).map_err(|e| {
|
||||
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()))
|
||||
Ok(output.into_pyobject(py).unwrap().unbind())
|
||||
}
|
||||
|
||||
/// Mocks the prover
|
||||
@@ -1048,12 +1054,13 @@ fn setup(
|
||||
))]
|
||||
#[gen_stub_pyfunction]
|
||||
fn prove(
|
||||
py: Python<'_>,
|
||||
witness: PathBuf,
|
||||
model: PathBuf,
|
||||
pk_path: PathBuf,
|
||||
proof_path: Option<PathBuf>,
|
||||
srs_path: Option<PathBuf>,
|
||||
) -> PyResult<PyObject> {
|
||||
) -> PyResult<Py<PyAny>> {
|
||||
let snark = crate::execute::prove(
|
||||
witness,
|
||||
model,
|
||||
@@ -1067,7 +1074,7 @@ fn prove(
|
||||
PyRuntimeError::new_err(err_str)
|
||||
})?;
|
||||
|
||||
Python::with_gil(|py| Ok(snark.into_pyobject(py).unwrap().into()))
|
||||
Ok(snark.into_pyobject(py).unwrap().unbind())
|
||||
}
|
||||
|
||||
/// Verifies a given proof
|
||||
|
||||
@@ -102,9 +102,11 @@ impl<'py> IntoPyObject<'py> for CheckMode {
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
/// Obtains CheckMode from PyObject (Required for CheckMode to be compatible with Python)
|
||||
impl<'source> FromPyObject<'source> for CheckMode {
|
||||
fn extract_bound(ob: &pyo3::Bound<'source, pyo3::PyAny>) -> PyResult<Self> {
|
||||
let trystr = String::extract_bound(ob)?;
|
||||
impl<'py> FromPyObject<'_, 'py> for CheckMode {
|
||||
type Error = pyo3::PyErr;
|
||||
|
||||
fn extract(ob: pyo3::Borrowed<'_, 'py, pyo3::PyAny>) -> Result<Self, Self::Error> {
|
||||
let trystr = String::extract(ob)?;
|
||||
match trystr.to_lowercase().as_str() {
|
||||
"safe" => Ok(CheckMode::SAFE),
|
||||
"unsafe" => Ok(CheckMode::UNSAFE),
|
||||
|
||||
@@ -15,10 +15,7 @@ use serde::{Deserialize, Serialize};
|
||||
pub enum HybridOp {
|
||||
Ln {
|
||||
scale: utils::F32,
|
||||
eps: utils::F32,
|
||||
},
|
||||
Sigmoid {
|
||||
scale: utils::F32,
|
||||
eps: f64,
|
||||
},
|
||||
Rsqrt {
|
||||
input_scale: utils::F32,
|
||||
@@ -142,7 +139,6 @@ impl<F: PrimeField + TensorType + PartialOrd + std::hash::Hash> Op<F> for Hybrid
|
||||
),
|
||||
HybridOp::Sqrt { scale } => format!("SQRT(scale={})", scale),
|
||||
HybridOp::Ln { scale, eps } => format!("LN(scale={}, eps={})", scale, eps),
|
||||
HybridOp::Sigmoid { scale } => format!("SIGMOID(scale={})", scale),
|
||||
HybridOp::RoundHalfToEven { scale, legs } => {
|
||||
format!("ROUND_HALF_TO_EVEN(scale={}, legs={})", scale, legs)
|
||||
}
|
||||
@@ -238,9 +234,6 @@ impl<F: PrimeField + TensorType + PartialOrd + std::hash::Hash> Op<F> for Hybrid
|
||||
HybridOp::Ln { scale, eps } => {
|
||||
layouts::ln(config, region, values[..].try_into()?, *scale, *eps)?
|
||||
}
|
||||
HybridOp::Sigmoid { scale } => {
|
||||
layouts::sigmoid(config, region, values[..].try_into()?, *scale)?
|
||||
}
|
||||
HybridOp::RoundHalfToEven { scale, legs } => {
|
||||
layouts::round_half_to_even(config, region, values[..].try_into()?, *scale, *legs)?
|
||||
}
|
||||
@@ -388,10 +381,7 @@ impl<F: PrimeField + TensorType + PartialOrd + std::hash::Hash> Op<F> for Hybrid
|
||||
HybridOp::Ln {
|
||||
scale: output_scale,
|
||||
eps: _,
|
||||
} => 2 * multiplier_to_scale(output_scale.0 as f64),
|
||||
HybridOp::Sigmoid {
|
||||
scale: output_scale,
|
||||
} => 2 * multiplier_to_scale(output_scale.0 as f64),
|
||||
} => 4 * multiplier_to_scale(output_scale.0 as f64),
|
||||
_ => in_scales[0],
|
||||
};
|
||||
Ok(scale)
|
||||
|
||||
@@ -159,14 +159,14 @@ pub fn diff_less_than<F: PrimeField + TensorType + PartialOrd + std::hash::Hash>
|
||||
values: &[&ValTensor<F>; 2],
|
||||
constant: F,
|
||||
) -> Result<(), CircuitError> {
|
||||
let diff = pairwise(config, region, values, BaseOp::Sub)?;
|
||||
let int_rep_constant = felt_to_integer_rep(constant);
|
||||
range_check(
|
||||
config,
|
||||
region,
|
||||
&[&diff],
|
||||
&(-int_rep_constant, int_rep_constant),
|
||||
)?;
|
||||
let distance = l1_distance(config, region, values)?;
|
||||
|
||||
let constant = create_constant_tensor(constant, 1);
|
||||
let is_less = less(config, region, &[&distance, &constant])?;
|
||||
|
||||
// assert the result is 1
|
||||
let comparison_unit = create_constant_tensor(F::ONE, is_less.len());
|
||||
enforce_equality(config, region, &[&is_less, &comparison_unit])?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -5630,98 +5630,7 @@ pub fn ceil<F: PrimeField + TensorType + PartialOrd + std::hash::Hash>(
|
||||
)
|
||||
}
|
||||
|
||||
fn sixth_order_chebyshev_approximation<
|
||||
F: PrimeField + TensorType + PartialOrd + std::hash::Hash,
|
||||
>(
|
||||
config: &BaseConfig<F>,
|
||||
region: &mut RegionCtx<F>,
|
||||
values: &[&ValTensor<F>; 1],
|
||||
coeffs: &[F],
|
||||
scale: F,
|
||||
) -> Result<ValTensor<F>, CircuitError> {
|
||||
let coeff_tensors: Vec<ValTensor<F>> = coeffs
|
||||
.iter()
|
||||
.map(|c| create_constant_tensor(*c, 1))
|
||||
.collect();
|
||||
|
||||
let x = values[0];
|
||||
|
||||
let x_squared = pairwise(config, region, &[x, x], BaseOp::Mult)?;
|
||||
let x_squared = div(config, region, &[&x_squared], scale)?;
|
||||
let x_cubed = pairwise(config, region, &[&x_squared, x], BaseOp::Mult)?;
|
||||
let x_cubed = div(config, region, &[&x_cubed], scale)?;
|
||||
let x_fourth = pairwise(config, region, &[&x_squared, &x_squared], BaseOp::Mult)?;
|
||||
let x_fourth = div(config, region, &[&x_fourth], scale)?;
|
||||
let x_fifth = pairwise(config, region, &[&x_fourth, x], BaseOp::Mult)?;
|
||||
let x_fifth = div(config, region, &[&x_fifth], scale)?;
|
||||
|
||||
let one = create_constant_tensor(scale, 1);
|
||||
let term1 = pairwise(config, region, &[&coeff_tensors[0], &one], BaseOp::Mult)?;
|
||||
let term2 = pairwise(config, region, &[&coeff_tensors[1], x], BaseOp::Mult)?;
|
||||
let term3 = pairwise(
|
||||
config,
|
||||
region,
|
||||
&[&coeff_tensors[2], &x_squared],
|
||||
BaseOp::Mult,
|
||||
)?;
|
||||
let term4 = pairwise(config, region, &[&coeff_tensors[3], &x_cubed], BaseOp::Mult)?;
|
||||
let term5 = pairwise(
|
||||
config,
|
||||
region,
|
||||
&[&coeff_tensors[4], &x_fourth],
|
||||
BaseOp::Mult,
|
||||
)?;
|
||||
let term6 = pairwise(config, region, &[&coeff_tensors[5], &x_fifth], BaseOp::Mult)?;
|
||||
|
||||
let temp_sum1 = pairwise(config, region, &[&term1, &term2], BaseOp::Add)?;
|
||||
let temp_sum2 = pairwise(config, region, &[&term3, &term4], BaseOp::Add)?;
|
||||
let temp_sum3 = pairwise(config, region, &[&term5, &term6], BaseOp::Add)?;
|
||||
let temp_sum4 = pairwise(config, region, &[&temp_sum2, &temp_sum3], BaseOp::Add)?;
|
||||
let temp_sum5 = pairwise(config, region, &[&temp_sum1, &temp_sum4], BaseOp::Add)?;
|
||||
let claimed_val = temp_sum5;
|
||||
|
||||
Ok(claimed_val)
|
||||
}
|
||||
|
||||
fn fourth_order_chebyshev_approximation_symmetric_func<
|
||||
F: PrimeField + TensorType + PartialOrd + std::hash::Hash,
|
||||
>(
|
||||
config: &BaseConfig<F>,
|
||||
region: &mut RegionCtx<F>,
|
||||
values: &[&ValTensor<F>; 1],
|
||||
coeffs: &[F],
|
||||
scale: F,
|
||||
) -> Result<ValTensor<F>, CircuitError> {
|
||||
let coeff_tensors: Vec<ValTensor<F>> = coeffs
|
||||
.iter()
|
||||
.map(|c| create_constant_tensor(*c, 1))
|
||||
.collect();
|
||||
|
||||
let x = values[0];
|
||||
|
||||
let x_squared = pairwise(config, region, &[x, x], BaseOp::Mult)?;
|
||||
let x_squared = div(config, region, &[&x_squared], scale)?;
|
||||
let x_cubed = pairwise(config, region, &[&x_squared, x], BaseOp::Mult)?;
|
||||
let x_cubed = div(config, region, &[&x_cubed], scale)?;
|
||||
let x_fourth = pairwise(config, region, &[&x_squared, &x_squared], BaseOp::Mult)?;
|
||||
let x_fourth = div(config, region, &[&x_fourth], scale)?;
|
||||
let x_fifth = pairwise(config, region, &[&x_fourth, x], BaseOp::Mult)?;
|
||||
let x_fifth = div(config, region, &[&x_fifth], scale)?;
|
||||
|
||||
let one = create_constant_tensor(scale, 1);
|
||||
|
||||
let term1 = pairwise(config, region, &[&coeff_tensors[0], &one], BaseOp::Mult)?;
|
||||
let term2 = pairwise(config, region, &[&coeff_tensors[1], x], BaseOp::Mult)?;
|
||||
let term4 = pairwise(config, region, &[&coeff_tensors[2], &x_cubed], BaseOp::Mult)?;
|
||||
let term6 = pairwise(config, region, &[&coeff_tensors[3], &x_fifth], BaseOp::Mult)?;
|
||||
let temp_sum1 = pairwise(config, region, &[&term1, &term2], BaseOp::Add)?;
|
||||
let temp_sum2 = pairwise(config, region, &[&term4, &term6], BaseOp::Add)?;
|
||||
let temp_sum3 = pairwise(config, region, &[&temp_sum1, &temp_sum2], BaseOp::Add)?;
|
||||
let claimed_val = temp_sum3;
|
||||
Ok(claimed_val)
|
||||
}
|
||||
|
||||
/// Integer ln approximated using 5 term chebyshev polynomials, optimized over interval [0.1, 5]
|
||||
/// integer ln layout
|
||||
/// # Arguments
|
||||
/// * `config` - BaseConfig
|
||||
/// * `region` - RegionCtx
|
||||
@@ -5747,7 +5656,7 @@ fn fourth_order_chebyshev_approximation_symmetric_func<
|
||||
/// &[1, 1, 2, 2],
|
||||
/// ).unwrap());
|
||||
///
|
||||
/// let result = ln::<Fp>(&dummy_config, &mut dummy_region, &[&x], 2.0.into()).unwrap();
|
||||
/// let result = ln::<Fp>(&dummy_config, &mut dummy_region, &[&x], 2.0.into(), f64::EPSILON).unwrap();
|
||||
/// let expected = Tensor::<IntegerRep>::new(Some(&[4, 0, 4, -8]), &[1, 1, 2, 2]).unwrap();
|
||||
/// assert_eq!(result.int_evals().unwrap(), expected);
|
||||
///
|
||||
@@ -5757,80 +5666,235 @@ pub fn ln<F: PrimeField + TensorType + PartialOrd + std::hash::Hash>(
|
||||
region: &mut RegionCtx<F>,
|
||||
values: &[&ValTensor<F>; 1],
|
||||
scale: utils::F32,
|
||||
eps: utils::F32,
|
||||
eps: f64,
|
||||
) -> Result<ValTensor<F>, CircuitError> {
|
||||
// first generate the claimed val
|
||||
let coeffs = vec![
|
||||
integer_rep_to_felt((-2.619115 * scale.0).round() as IntegerRep), // c0
|
||||
integer_rep_to_felt((5.335041 * scale.0).round() as IntegerRep), // c1
|
||||
integer_rep_to_felt((-3.845028 * scale.0).round() as IntegerRep), // c2
|
||||
integer_rep_to_felt((1.443970 * scale.0).round() as IntegerRep), // c3
|
||||
integer_rep_to_felt((-0.258144 * scale.0).round() as IntegerRep), // c4
|
||||
integer_rep_to_felt((0.017459 * scale.0).round() as IntegerRep), // c5
|
||||
];
|
||||
|
||||
let scale_f = integer_rep_to_felt::<F>(scale.0.round() as IntegerRep);
|
||||
let mut input = values[0].clone();
|
||||
let scale_as_felt = integer_rep_to_felt(scale.0.round() as IntegerRep);
|
||||
|
||||
let res = sixth_order_chebyshev_approximation(config, region, values, &coeffs, scale_f)?;
|
||||
// add eps to avoid log(0)
|
||||
let eps_tensor = create_constant_tensor(
|
||||
integer_rep_to_felt::<F>((eps.0 * scale.0.powi(2)).round() as IntegerRep),
|
||||
res.len(),
|
||||
let triple_scaled_as_felt_tensor =
|
||||
create_constant_tensor(scale_as_felt * scale_as_felt * scale_as_felt, 1);
|
||||
|
||||
// natural ln is log2(x) * ln(2)
|
||||
let ln2 = utils::F32::from(2.0_f32.ln());
|
||||
// now create a constant tensor for ln2 with scale
|
||||
let ln2_tensor: ValTensor<F> = create_constant_tensor(
|
||||
integer_rep_to_felt((ln2.0 * scale.0).round() as IntegerRep),
|
||||
1,
|
||||
);
|
||||
let unit = create_constant_tensor(integer_rep_to_felt(1), 1);
|
||||
let negative_one = create_constant_tensor(integer_rep_to_felt(-1), 1);
|
||||
|
||||
let res = pairwise(config, region, &[&res, &eps_tensor], BaseOp::Add)?;
|
||||
// 2. assign the image
|
||||
if !input.all_prev_assigned() {
|
||||
input = region.assign(&config.custom_gates.inputs[0], &input)?;
|
||||
// don't need to increment because the claimed output is assigned to output and incremented accordingly
|
||||
}
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
let is_assigned = !input.any_unknowns()?;
|
||||
|
||||
/// Sigmoid ln approximated using 5 term chebyshev polynomials, optimized over interval [-6, 6]
|
||||
/// # Arguments
|
||||
/// * `config` - BaseConfig
|
||||
/// * `region` - RegionCtx
|
||||
/// * `values` - &[&ValTensor<F>; 1]
|
||||
/// * `scale` - utils::F32
|
||||
/// # Returns
|
||||
/// * ValTensor<F>
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use ezkl::tensor::Tensor;
|
||||
/// use ezkl::fieldutils::IntegerRep;
|
||||
/// use ezkl::circuit::ops::layouts::sigmoid;
|
||||
/// use ezkl::tensor::val::ValTensor;
|
||||
/// use halo2curves::bn256::Fr as Fp;
|
||||
/// use ezkl::circuit::region::RegionCtx;
|
||||
/// use ezkl::circuit::region::RegionSettings;
|
||||
/// use ezkl::circuit::BaseConfig;
|
||||
/// let dummy_config = BaseConfig::dummy(12, 2);
|
||||
/// let mut dummy_region = RegionCtx::new_dummy(0,2,RegionSettings::all_true(65536, 4));
|
||||
/// let x = ValTensor::from_integer_rep_tensor(Tensor::<IntegerRep>::new(
|
||||
/// Some(&[3, 2, 3, 1]),
|
||||
/// &[1, 1, 2, 2],
|
||||
/// ).unwrap());
|
||||
///
|
||||
/// let result = sigmoid::<Fp>(&dummy_config, &mut dummy_region, &[&x], 2.0.into()).unwrap();
|
||||
/// let expected = Tensor::<IntegerRep>::new(Some(&[4, 0, 4, -8]), &[1, 1, 2, 2]).unwrap();
|
||||
/// assert_eq!(result.int_evals().unwrap(), expected);
|
||||
///
|
||||
/// ```
|
||||
pub fn sigmoid<F: PrimeField + TensorType + PartialOrd + std::hash::Hash>(
|
||||
config: &BaseConfig<F>,
|
||||
region: &mut RegionCtx<F>,
|
||||
values: &[&ValTensor<F>; 1],
|
||||
scale: utils::F32,
|
||||
) -> Result<ValTensor<F>, CircuitError> {
|
||||
// first generate the claimed val
|
||||
let coeffs = vec![
|
||||
integer_rep_to_felt((0.500000 * scale.0.round()) as IntegerRep), // c0
|
||||
integer_rep_to_felt((0.212251 * scale.0.round()) as IntegerRep), // c1
|
||||
integer_rep_to_felt((-0.007144 * scale.0.round()) as IntegerRep), // c3
|
||||
integer_rep_to_felt((0.000100 * scale.0.round()) as IntegerRep), // c5
|
||||
];
|
||||
let mut claimed_output: ValTensor<F> = if is_assigned {
|
||||
let input_evals = input.int_evals()?;
|
||||
// returns an integer with the base 2 logarithm
|
||||
tensor::ops::nonlinearities::ilog2(&input_evals, scale.0 as f64)
|
||||
.par_iter()
|
||||
.map(|x| Value::known(integer_rep_to_felt(*x)))
|
||||
.collect::<Tensor<Value<F>>>()
|
||||
.into()
|
||||
} else {
|
||||
Tensor::new(
|
||||
Some(&vec![Value::<F>::unknown(); input.len()]),
|
||||
&[input.len()],
|
||||
)?
|
||||
.into()
|
||||
};
|
||||
claimed_output.reshape(input.dims())?;
|
||||
let claimed_output = decompose(
|
||||
config,
|
||||
region,
|
||||
&[&claimed_output],
|
||||
®ion.base(),
|
||||
®ion.legs(),
|
||||
true,
|
||||
)?
|
||||
.1;
|
||||
region.increment(claimed_output.len());
|
||||
|
||||
let scale_f = integer_rep_to_felt::<F>(scale.0.round() as IntegerRep);
|
||||
let pow2_of_claimed_output = nonlinearity(
|
||||
config,
|
||||
region,
|
||||
&[&claimed_output],
|
||||
&LookupOp::PowersOfTwo { scale },
|
||||
)?;
|
||||
|
||||
fourth_order_chebyshev_approximation_symmetric_func(config, region, values, &coeffs, scale_f)
|
||||
let num_bits = (std::mem::size_of::<IntegerRep>() * 8) as IntegerRep;
|
||||
|
||||
region.update_max_min_lookup_inputs_force(-num_bits, num_bits)?;
|
||||
|
||||
// now subtract 1 from the claimed output
|
||||
let claimed_output_minus_one =
|
||||
pairwise(config, region, &[&claimed_output, &unit], BaseOp::Sub)?;
|
||||
|
||||
// now add 1 to the claimed output
|
||||
let claimed_output_plus_one = pairwise(config, region, &[&claimed_output, &unit], BaseOp::Add)?;
|
||||
|
||||
// prior power of 2 is less than claimed output
|
||||
let prior_pow2 = nonlinearity(
|
||||
config,
|
||||
region,
|
||||
&[&claimed_output_minus_one],
|
||||
&LookupOp::PowersOfTwo { scale },
|
||||
)?;
|
||||
|
||||
// next power of 2 is greater than claimed output
|
||||
let next_pow2 = nonlinearity(
|
||||
config,
|
||||
region,
|
||||
&[&claimed_output_plus_one],
|
||||
&LookupOp::PowersOfTwo { scale },
|
||||
)?;
|
||||
|
||||
let distance_to_claimed = pairwise(
|
||||
config,
|
||||
region,
|
||||
&[&input, &pow2_of_claimed_output],
|
||||
BaseOp::Sub,
|
||||
)?;
|
||||
|
||||
let abs_distance_to_claimed = abs(config, region, &[&distance_to_claimed])?;
|
||||
|
||||
let abs_distance_to_next_pow2 = l1_distance(config, region, &[&input, &next_pow2])?;
|
||||
|
||||
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(
|
||||
config,
|
||||
region,
|
||||
&[&abs_distance_to_claimed, &abs_distance_to_next_pow2],
|
||||
)?;
|
||||
|
||||
let is_closest_to_1 = less_equal(
|
||||
config,
|
||||
region,
|
||||
&[&abs_distance_to_claimed, &abs_distance_to_prior_pow2],
|
||||
)?;
|
||||
|
||||
let is_closest = and(config, region, &[&is_closest_to_0, &is_closest_to_1])?;
|
||||
|
||||
let mut comparison_unit = create_constant_tensor(integer_rep_to_felt(1), is_closest.len());
|
||||
comparison_unit.reshape(is_closest.dims())?;
|
||||
let assigned_unit = region.assign(&config.custom_gates.inputs[1], &comparison_unit)?;
|
||||
|
||||
enforce_equality(config, region, &[&is_closest, &assigned_unit])?;
|
||||
|
||||
// get a linear interpolation now
|
||||
|
||||
let sign_of_distance_to_claimed = sign(config, region, &[&distance_to_claimed], true)?;
|
||||
let sign_of_distance_to_claimed_is_negative = equals(
|
||||
config,
|
||||
region,
|
||||
&[&sign_of_distance_to_claimed, &negative_one],
|
||||
)?;
|
||||
|
||||
let sign_of_distance_to_claimed_is_positive =
|
||||
not(config, region, &[&sign_of_distance_to_claimed_is_negative])?;
|
||||
|
||||
let pow2_prior_to_claimed_distance = pairwise(
|
||||
config,
|
||||
region,
|
||||
&[&pow2_of_claimed_output, &prior_pow2],
|
||||
BaseOp::Sub,
|
||||
)?;
|
||||
|
||||
let pow2_next_to_claimed_distance = pairwise(
|
||||
config,
|
||||
region,
|
||||
&[&next_pow2, &pow2_of_claimed_output],
|
||||
BaseOp::Sub,
|
||||
)?;
|
||||
|
||||
let recip_pow2_prior_to_claimed_distance = recip(
|
||||
config,
|
||||
region,
|
||||
&[&pow2_prior_to_claimed_distance],
|
||||
scale_as_felt,
|
||||
scale_as_felt * scale_as_felt,
|
||||
eps,
|
||||
)?;
|
||||
|
||||
let interpolated_distance = pairwise(
|
||||
config,
|
||||
region,
|
||||
&[&recip_pow2_prior_to_claimed_distance, &distance_to_claimed],
|
||||
BaseOp::Mult,
|
||||
)?;
|
||||
|
||||
let gated_prior_interpolated_distance = pairwise(
|
||||
config,
|
||||
region,
|
||||
&[
|
||||
&interpolated_distance,
|
||||
&sign_of_distance_to_claimed_is_negative,
|
||||
],
|
||||
BaseOp::Mult,
|
||||
)?;
|
||||
|
||||
let recip_next_to_claimed_distance = recip(
|
||||
config,
|
||||
region,
|
||||
&[&pow2_next_to_claimed_distance],
|
||||
scale_as_felt,
|
||||
scale_as_felt * scale_as_felt,
|
||||
eps,
|
||||
)?;
|
||||
|
||||
let interpolated_distance_next = pairwise(
|
||||
config,
|
||||
region,
|
||||
&[&recip_next_to_claimed_distance, &distance_to_claimed],
|
||||
BaseOp::Mult,
|
||||
)?;
|
||||
|
||||
let gated_next_interpolated_distance = pairwise(
|
||||
config,
|
||||
region,
|
||||
&[
|
||||
&interpolated_distance_next,
|
||||
&sign_of_distance_to_claimed_is_positive,
|
||||
],
|
||||
BaseOp::Mult,
|
||||
)?;
|
||||
|
||||
let scaled_claimed_output = pairwise(
|
||||
config,
|
||||
region,
|
||||
&[&claimed_output, &triple_scaled_as_felt_tensor],
|
||||
BaseOp::Mult,
|
||||
)?;
|
||||
|
||||
let claimed_output = pairwise(
|
||||
config,
|
||||
region,
|
||||
&[&scaled_claimed_output, &gated_prior_interpolated_distance],
|
||||
BaseOp::Add,
|
||||
)?;
|
||||
|
||||
let claimed_output = pairwise(
|
||||
config,
|
||||
region,
|
||||
&[&claimed_output, &gated_next_interpolated_distance],
|
||||
BaseOp::Add,
|
||||
)?;
|
||||
|
||||
// now multiply the claimed output by ln2
|
||||
pairwise(
|
||||
config,
|
||||
region,
|
||||
&[&claimed_output, &ln2_tensor],
|
||||
BaseOp::Mult,
|
||||
)
|
||||
}
|
||||
|
||||
/// round layout
|
||||
|
||||
@@ -17,6 +17,8 @@ pub enum LookupOp {
|
||||
Div { denom: utils::F32 },
|
||||
IsOdd,
|
||||
PowersOfTwo { scale: utils::F32 },
|
||||
Ln { scale: utils::F32 },
|
||||
Sigmoid { scale: utils::F32 },
|
||||
Exp { scale: utils::F32, base: utils::F32 },
|
||||
Cos { scale: utils::F32 },
|
||||
ACos { scale: utils::F32 },
|
||||
@@ -47,9 +49,11 @@ impl LookupOp {
|
||||
pub fn as_path(&self) -> String {
|
||||
match self {
|
||||
LookupOp::Pow { scale, a } => format!("pow_{}_{}", scale, a),
|
||||
LookupOp::Ln { scale } => format!("ln_{}", scale),
|
||||
LookupOp::PowersOfTwo { scale } => format!("pow2_{}", scale),
|
||||
LookupOp::IsOdd => "is_odd".to_string(),
|
||||
LookupOp::Div { denom } => format!("div_{}", denom),
|
||||
LookupOp::Sigmoid { scale } => format!("sigmoid_{}", scale),
|
||||
LookupOp::Erf { scale } => format!("erf_{}", scale),
|
||||
LookupOp::Exp { scale, base } => format!("exp_{}_{}", scale, base),
|
||||
LookupOp::Cos { scale } => format!("cos_{}", scale),
|
||||
@@ -76,6 +80,9 @@ impl LookupOp {
|
||||
let x = x[0].clone().map(|x| felt_to_integer_rep(x));
|
||||
let res =
|
||||
match &self {
|
||||
LookupOp::Ln { scale } => {
|
||||
Ok::<_, TensorError>(tensor::ops::nonlinearities::ln(&x, scale.into()))
|
||||
}
|
||||
LookupOp::PowersOfTwo { scale } => {
|
||||
Ok::<_, TensorError>(tensor::ops::nonlinearities::ipow2(&x, scale.0.into()))
|
||||
}
|
||||
@@ -86,6 +93,9 @@ impl LookupOp {
|
||||
LookupOp::Div { denom } => Ok::<_, TensorError>(
|
||||
tensor::ops::nonlinearities::const_div(&x, f32::from(*denom).into()),
|
||||
),
|
||||
LookupOp::Sigmoid { scale } => {
|
||||
Ok::<_, TensorError>(tensor::ops::nonlinearities::sigmoid(&x, scale.into()))
|
||||
}
|
||||
LookupOp::Erf { scale } => {
|
||||
Ok::<_, TensorError>(tensor::ops::nonlinearities::erffunc(&x, scale.into()))
|
||||
}
|
||||
@@ -148,10 +158,12 @@ impl<F: PrimeField + TensorType + PartialOrd + std::hash::Hash> Op<F> for Lookup
|
||||
/// Returns the name of the operation
|
||||
fn as_string(&self) -> String {
|
||||
match self {
|
||||
LookupOp::Ln { scale } => format!("LN(scale={})", scale),
|
||||
LookupOp::PowersOfTwo { scale } => format!("POWERS_OF_TWO(scale={})", scale),
|
||||
LookupOp::IsOdd => "IS_ODD".to_string(),
|
||||
LookupOp::Pow { a, scale } => format!("POW(scale={}, exponent={})", scale, a),
|
||||
LookupOp::Div { denom, .. } => format!("DIV(denom={})", denom),
|
||||
LookupOp::Sigmoid { scale } => format!("SIGMOID(scale={})", scale),
|
||||
LookupOp::Erf { scale } => format!("ERF(scale={})", scale),
|
||||
LookupOp::Exp { scale, base } => format!("EXP(scale={}, base={})", scale, base),
|
||||
LookupOp::Tan { scale } => format!("TAN(scale={})", scale),
|
||||
|
||||
@@ -2553,7 +2553,7 @@ mod lookup_ultra_overflow {
|
||||
.map(|_| VarTensor::new_advice(cs, 4, 1, 3))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let nl = LookupOp::Tanh { scale: 1.0.into() };
|
||||
let nl = LookupOp::Sigmoid { scale: 1.0.into() };
|
||||
|
||||
let mut config = BaseConfig::default();
|
||||
|
||||
@@ -2586,7 +2586,7 @@ mod lookup_ultra_overflow {
|
||||
.layout(
|
||||
&mut region,
|
||||
&[&self.input],
|
||||
Box::new(LookupOp::Tanh { scale: 1.0.into() }),
|
||||
Box::new(LookupOp::Sigmoid { scale: 1.0.into() }),
|
||||
)
|
||||
.map_err(|_| Error::Synthesis)
|
||||
},
|
||||
|
||||
@@ -238,9 +238,11 @@ impl<'py> IntoPyObject<'py> for CalibrationTarget {
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
/// Obtains CalibrationTarget from PyObject (Required for CalibrationTarget to be compatible with Python)
|
||||
impl<'source> FromPyObject<'source> for CalibrationTarget {
|
||||
fn extract_bound(ob: &pyo3::Bound<'source, pyo3::PyAny>) -> PyResult<Self> {
|
||||
let strval = String::extract_bound(ob)?;
|
||||
impl<'py> FromPyObject<'_, 'py> for CalibrationTarget {
|
||||
type Error = pyo3::PyErr;
|
||||
|
||||
fn extract(ob: pyo3::Borrowed<'_, 'py, pyo3::PyAny>) -> Result<Self, Self::Error> {
|
||||
let strval = String::extract(ob)?;
|
||||
match strval.to_lowercase().as_str() {
|
||||
"resources" => Ok(CalibrationTarget::Resources {
|
||||
col_overflow: false,
|
||||
@@ -270,9 +272,11 @@ impl<'py> IntoPyObject<'py> for ContractType {
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
/// Obtains ContractType from PyObject (Required for ContractType to be compatible with Python)
|
||||
impl<'source> FromPyObject<'source> for ContractType {
|
||||
fn extract_bound(ob: &pyo3::Bound<'source, pyo3::PyAny>) -> PyResult<Self> {
|
||||
let strval = String::extract_bound(ob)?;
|
||||
impl<'py> FromPyObject<'_, 'py> for ContractType {
|
||||
type Error = pyo3::PyErr;
|
||||
|
||||
fn extract(ob: pyo3::Borrowed<'_, 'py, pyo3::PyAny>) -> Result<Self, Self::Error> {
|
||||
let strval = String::extract(ob)?;
|
||||
match strval.to_lowercase().as_str() {
|
||||
"verifier" => Ok(ContractType::Verifier { reusable: false }),
|
||||
"verifier/reusable" => Ok(ContractType::Verifier { reusable: true }),
|
||||
|
||||
108
src/eth.rs
108
src/eth.rs
@@ -4,31 +4,26 @@ use alloy::core::primitives::Address as H160;
|
||||
use alloy::core::primitives::Bytes;
|
||||
use alloy::core::primitives::I256;
|
||||
use alloy::dyn_abi::abi::TokenSeq;
|
||||
// use alloy::providers::Middleware;
|
||||
use alloy::json_abi::JsonAbi;
|
||||
use alloy::network::{Ethereum, EthereumWallet};
|
||||
use alloy::primitives::ruint::ParseError;
|
||||
use alloy::primitives::ParseSignedError;
|
||||
use alloy::providers::fillers::{
|
||||
ChainIdFiller, FillProvider, GasFiller, JoinFill, NonceFiller, SignerFiller,
|
||||
};
|
||||
use alloy::providers::network::{Ethereum, EthereumSigner};
|
||||
use alloy::providers::ProviderBuilder;
|
||||
use alloy::providers::{Identity, Provider, RootProvider};
|
||||
use alloy::rpc::types::eth::TransactionInput;
|
||||
use alloy::rpc::types::eth::TransactionRequest;
|
||||
use alloy::providers::Provider;
|
||||
use alloy::rpc::types::TransactionInput;
|
||||
use alloy::rpc::types::TransactionRequest;
|
||||
use alloy::signers::k256::ecdsa;
|
||||
use alloy::signers::wallet::{LocalWallet, WalletError};
|
||||
use alloy::signers::local::{PrivateKeySigner, LocalSignerError};
|
||||
use alloy::transports::http::Http;
|
||||
use alloy::transports::{RpcError, TransportErrorKind};
|
||||
use foundry_compilers::artifacts::Settings as SolcSettings;
|
||||
use foundry_compilers::error::{SolcError, SolcIoError};
|
||||
use foundry_compilers::Solc;
|
||||
use foundry_compilers::solc::Solc;
|
||||
use halo2_solidity_verifier::encode_register_vk_calldata;
|
||||
use halo2curves::bn256::{Fr, G1Affine};
|
||||
use log::{debug, info, warn};
|
||||
use reqwest::Client;
|
||||
use std::path::PathBuf;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
const ANVIL_DEFAULT_PRIVATE_KEY: &str =
|
||||
@@ -52,8 +47,10 @@ pub enum EthError {
|
||||
Transport(#[from] RpcError<TransportErrorKind>),
|
||||
#[error("a contract error occurred: {0}")]
|
||||
Contract(#[from] alloy::contract::Error),
|
||||
#[error("a pending transaction error occurred: {0}")]
|
||||
PendingTransaction(#[from] alloy::providers::PendingTransactionError),
|
||||
#[error("a wallet error occurred: {0}")]
|
||||
Wallet(#[from] WalletError),
|
||||
Wallet(#[from] LocalSignerError),
|
||||
#[error("failed to parse url {0}")]
|
||||
UrlParse(String),
|
||||
#[error("Private key must be in hex format, 64 chars, without 0x prefix")]
|
||||
@@ -102,49 +99,57 @@ pub enum EthError {
|
||||
}
|
||||
|
||||
pub type EthersClient = Arc<
|
||||
FillProvider<
|
||||
JoinFill<
|
||||
JoinFill<JoinFill<JoinFill<Identity, GasFiller>, NonceFiller>, ChainIdFiller>,
|
||||
SignerFiller<EthereumSigner>,
|
||||
alloy::providers::fillers::FillProvider<
|
||||
alloy::providers::fillers::JoinFill<
|
||||
alloy::providers::fillers::JoinFill<
|
||||
alloy::providers::fillers::JoinFill<
|
||||
alloy::providers::fillers::JoinFill<
|
||||
alloy::providers::Identity,
|
||||
alloy::providers::fillers::GasFiller,
|
||||
>,
|
||||
alloy::providers::fillers::NonceFiller,
|
||||
>,
|
||||
alloy::providers::fillers::ChainIdFiller,
|
||||
>,
|
||||
alloy::providers::fillers::WalletFiller<EthereumWallet>,
|
||||
>,
|
||||
RootProvider<Http<Client>>,
|
||||
alloy::providers::RootProvider<Http<Client>>,
|
||||
Http<Client>,
|
||||
Ethereum,
|
||||
>,
|
||||
>;
|
||||
|
||||
pub type ContractFactory<M> = CallBuilder<Http<Client>, Arc<M>, ()>;
|
||||
pub type ContractFactory<M> = CallBuilder<Arc<M>, (), Ethereum>;
|
||||
|
||||
/// Return an instance of Anvil and a client for the given RPC URL. If none is provided, a local client is used.
|
||||
pub async fn setup_eth_backend(
|
||||
rpc_url: &str,
|
||||
private_key: Option<&str>,
|
||||
) -> Result<(EthersClient, alloy::primitives::Address), EthError> {
|
||||
) -> Result<(Arc<impl Provider + Clone>, alloy::primitives::Address), EthError> {
|
||||
// Launch anvil
|
||||
|
||||
let endpoint = rpc_url.to_string();
|
||||
|
||||
// Instantiate the wallet
|
||||
let wallet: LocalWallet;
|
||||
let signer: PrivateKeySigner;
|
||||
if let Some(private_key) = private_key {
|
||||
debug!("using private key {}", private_key);
|
||||
if private_key.len() != 64 {
|
||||
return Err(EthError::PrivateKeyFormat);
|
||||
}
|
||||
let private_key_buffer = hex::decode(private_key)?;
|
||||
wallet = LocalWallet::from_slice(&private_key_buffer)?;
|
||||
signer = PrivateKeySigner::from_slice(&private_key_buffer)?;
|
||||
} else {
|
||||
wallet = LocalWallet::from_str(ANVIL_DEFAULT_PRIVATE_KEY)?;
|
||||
signer = ANVIL_DEFAULT_PRIVATE_KEY.parse()?;
|
||||
}
|
||||
|
||||
let wallet_address = wallet.address();
|
||||
let wallet_address = signer.address();
|
||||
let wallet = EthereumWallet::from(signer);
|
||||
|
||||
// Connect to the network
|
||||
let client = Arc::new(
|
||||
ProviderBuilder::new()
|
||||
.with_recommended_fillers()
|
||||
.signer(EthereumSigner::from(wallet))
|
||||
.on_http(endpoint.parse().map_err(|_| EthError::UrlParse(endpoint))?),
|
||||
.wallet(wallet)
|
||||
.connect_http(endpoint.parse().map_err(|_| EthError::UrlParse(endpoint))?),
|
||||
);
|
||||
|
||||
let chain_id = client.get_chain_id().await?;
|
||||
@@ -194,7 +199,7 @@ pub async fn register_vka_via_rv(
|
||||
let tx = TransactionRequest::default().to(rv_address).input(input);
|
||||
debug!("transaction {:#?}", tx);
|
||||
|
||||
let result = client.call(&tx).await;
|
||||
let result = client.call(tx.clone()).await;
|
||||
|
||||
if let Err(e) = result {
|
||||
return Err(EthError::EvmVerificationError(e.to_string()).into());
|
||||
@@ -204,7 +209,7 @@ pub async fn register_vka_via_rv(
|
||||
// decode return bytes value into uint8
|
||||
let output = result.to_vec();
|
||||
|
||||
let gas = client.estimate_gas(&tx).await?;
|
||||
let gas = client.estimate_gas(tx.clone()).await?;
|
||||
|
||||
info!("estimated vka registration cost: {:#?}", gas);
|
||||
|
||||
@@ -215,11 +220,11 @@ pub async fn register_vka_via_rv(
|
||||
result.watch().await?;
|
||||
|
||||
// if gas is greater than 30 million warn the user that the gas cost is above ethereum's 30 million block gas limit
|
||||
if gas > 30_000_000_u128 {
|
||||
if gas > 30_000_000_u64 {
|
||||
warn!(
|
||||
"Gas cost of verify transaction is greater than 30 million block gas limit. It will fail on mainnet."
|
||||
);
|
||||
} else if gas > 15_000_000_u128 {
|
||||
} else if gas > 15_000_000_u64 {
|
||||
warn!(
|
||||
"Gas cost of verify transaction is greater than 15 million, the target block size for ethereum"
|
||||
);
|
||||
@@ -266,7 +271,7 @@ pub async fn verify_proof_via_solidity(
|
||||
let tx = TransactionRequest::default().to(addr).input(input);
|
||||
debug!("transaction {:#?}", tx);
|
||||
|
||||
let result = client.call(&tx).await;
|
||||
let result = client.call(tx.clone()).await;
|
||||
|
||||
if let Err(e) = result {
|
||||
return Err(EthError::EvmVerificationError(e.to_string()).into());
|
||||
@@ -291,7 +296,7 @@ pub async fn verify_proof_via_solidity(
|
||||
if !scaled_matches(inst, exp) {
|
||||
return Err(EthError::RescaleCheckError(RescaleCheckError::Mismatch {
|
||||
idx,
|
||||
expected: exp.clone(),
|
||||
expected: exp.to_string(),
|
||||
got: to_decimal_18(inst),
|
||||
}));
|
||||
}
|
||||
@@ -308,16 +313,16 @@ pub async fn verify_proof_via_solidity(
|
||||
return Err(EthError::EvmVerificationError("Invalid proof".into()));
|
||||
}
|
||||
|
||||
let gas = client.estimate_gas(&tx).await?;
|
||||
let gas = client.estimate_gas(tx.clone()).await?;
|
||||
|
||||
info!("estimated verify gas cost: {:#?}", gas);
|
||||
|
||||
// if gas is greater than 30 million warn the user that the gas cost is above ethereum's 30 million block gas limit
|
||||
if gas > 30_000_000_u128 {
|
||||
if gas > 30_000_000_u64 {
|
||||
warn!(
|
||||
"Gas cost of verify transaction is greater than 30 million block gas limit. It will fail on mainnet."
|
||||
);
|
||||
} else if gas > 15_000_000_u128 {
|
||||
} else if gas > 15_000_000_u64 {
|
||||
warn!(
|
||||
"Gas cost of verify transaction is greater than 15 million, the target block size for ethereum"
|
||||
);
|
||||
@@ -327,7 +332,7 @@ pub async fn verify_proof_via_solidity(
|
||||
}
|
||||
|
||||
/// Generates the contract factory for a solidity verifier. The factory is used to deploy the contract
|
||||
fn get_sol_contract_factory<'a, M: 'static + Provider<Http<Client>, Ethereum>, T: TokenSeq<'a>>(
|
||||
fn get_sol_contract_factory<'a, M: 'static + Provider, T: TokenSeq<'a>>(
|
||||
abi: JsonAbi,
|
||||
bytecode: Bytes,
|
||||
runtime_bytecode: Bytes,
|
||||
@@ -365,7 +370,7 @@ fn get_sol_contract_factory<'a, M: 'static + Provider<Http<Client>, Ethereum>, T
|
||||
}
|
||||
};
|
||||
|
||||
Ok(CallBuilder::new_raw_deploy(client, data))
|
||||
Ok(CallBuilder::<_, _, Ethereum>::new_raw_deploy(client, data))
|
||||
}
|
||||
|
||||
/// Compiles a solidity verifier contract and returns the abi, bytecode, and runtime bytecode
|
||||
@@ -374,11 +379,12 @@ pub async fn get_contract_artifacts(
|
||||
contract_name: &str,
|
||||
runs: usize,
|
||||
) -> Result<(JsonAbi, Bytes, Bytes), EthError> {
|
||||
use foundry_compilers::{
|
||||
artifacts::{output_selection::OutputSelection, Optimizer},
|
||||
compilers::CompilerInput,
|
||||
SolcInput, SHANGHAI_SOLC,
|
||||
use foundry_compilers::artifacts::{
|
||||
output_selection::OutputSelection, Optimizer, SolcInput, SolcLanguage,
|
||||
};
|
||||
use semver::Version;
|
||||
|
||||
const SHANGHAI_SOLC: Version = Version::new(0, 8, 20);
|
||||
|
||||
if !sol_code_path.exists() {
|
||||
return Err(EthError::ContractNotFound(
|
||||
@@ -396,16 +402,14 @@ pub async fn get_contract_artifacts(
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
let input = SolcInput::build(
|
||||
std::collections::BTreeMap::from([(
|
||||
sol_code_path.clone(),
|
||||
foundry_compilers::artifacts::Source::read(sol_code_path)?,
|
||||
)]),
|
||||
settings,
|
||||
&SHANGHAI_SOLC,
|
||||
);
|
||||
let sources = foundry_compilers::artifacts::Sources::from([(
|
||||
sol_code_path.clone(),
|
||||
foundry_compilers::artifacts::Source::read(&sol_code_path)?,
|
||||
)]);
|
||||
|
||||
let solc_opt = Solc::find_svm_installed_version(SHANGHAI_SOLC.to_string())?;
|
||||
let input = SolcInput::new(SolcLanguage::Solidity, sources, settings).sanitized(&SHANGHAI_SOLC);
|
||||
|
||||
let solc_opt = Solc::find_svm_installed_version(&SHANGHAI_SOLC)?;
|
||||
let solc = match solc_opt {
|
||||
Some(solc) => solc,
|
||||
None => {
|
||||
@@ -416,7 +420,7 @@ pub async fn get_contract_artifacts(
|
||||
}
|
||||
};
|
||||
|
||||
let compiled: foundry_compilers::CompilerOutput = solc.compile(&input[0])?;
|
||||
let compiled = solc.compile(&input)?;
|
||||
|
||||
let (abi, bytecode, runtime_bytecode) = match compiled.find(contract_name) {
|
||||
Some(c) => c.into_parts_or_default(),
|
||||
|
||||
@@ -2298,6 +2298,7 @@ pub mod tests {
|
||||
"commitment": "KZG",
|
||||
"decomp_base": 128,
|
||||
"decomp_legs": 2,
|
||||
"bounded_log_lookup": false,
|
||||
"ignore_range_check_inputs_outputs": false,
|
||||
"disable_freivalds": false
|
||||
},
|
||||
|
||||
@@ -889,6 +889,9 @@ pub fn new_op_from_onnx(
|
||||
"HardSwish" => SupportedOp::Nonlinear(LookupOp::HardSwish {
|
||||
scale: scale_to_multiplier(input_scales[0]).into(),
|
||||
}),
|
||||
"Sigmoid" => SupportedOp::Nonlinear(LookupOp::Sigmoid {
|
||||
scale: scale_to_multiplier(input_scales[0]).into(),
|
||||
}),
|
||||
"Sqrt" => SupportedOp::Hybrid(HybridOp::Sqrt {
|
||||
scale: scale_to_multiplier(input_scales[0]).into(),
|
||||
}),
|
||||
@@ -908,13 +911,19 @@ pub fn new_op_from_onnx(
|
||||
scale: scale_to_multiplier(input_scales[0]).into(),
|
||||
base: E.into(),
|
||||
}),
|
||||
"Ln" => SupportedOp::Hybrid(HybridOp::Ln {
|
||||
scale: scale_to_multiplier(input_scales[0]).into(),
|
||||
eps: run_args.get_epsilon().into(),
|
||||
}),
|
||||
"Sigmoid" => SupportedOp::Hybrid(HybridOp::Sigmoid {
|
||||
scale: scale_to_multiplier(input_scales[0]).into(),
|
||||
}),
|
||||
"Ln" => {
|
||||
if run_args.bounded_log_lookup {
|
||||
SupportedOp::Hybrid(HybridOp::Ln {
|
||||
scale: scale_to_multiplier(input_scales[0]).into(),
|
||||
eps: run_args.get_epsilon(),
|
||||
})
|
||||
} else {
|
||||
SupportedOp::Nonlinear(LookupOp::Ln {
|
||||
scale: scale_to_multiplier(input_scales[0]).into(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
"Sin" => SupportedOp::Nonlinear(LookupOp::Sin {
|
||||
scale: scale_to_multiplier(input_scales[0]).into(),
|
||||
}),
|
||||
|
||||
@@ -8,7 +8,7 @@ use halo2curves::ff::PrimeField;
|
||||
use itertools::Itertools;
|
||||
use log::debug;
|
||||
#[cfg(feature = "python-bindings")]
|
||||
use pyo3::{exceptions::PyValueError, FromPyObject, IntoPyObject, PyResult, Python};
|
||||
use pyo3::{exceptions::PyValueError, FromPyObject, IntoPyObject, Python};
|
||||
use serde::{Deserialize, Serialize};
|
||||
#[cfg(all(feature = "ezkl", not(target_arch = "wasm32")))]
|
||||
use tosubcommand::ToFlags;
|
||||
@@ -78,7 +78,7 @@ impl<'a> From<&'a str> for Visibility {
|
||||
let outlets = outlets
|
||||
.trim_start_matches('/')
|
||||
.split(',')
|
||||
.map(|s| s.parse::<usize>().unwrap())
|
||||
.map(|s: &str| s.parse::<usize>().unwrap())
|
||||
.collect_vec();
|
||||
|
||||
return Visibility::Hashed {
|
||||
@@ -139,10 +139,12 @@ impl<'py> IntoPyObject<'py> for Visibility {
|
||||
}
|
||||
|
||||
#[cfg(feature = "python-bindings")]
|
||||
impl<'source> FromPyObject<'source> for Visibility {
|
||||
impl<'py> FromPyObject<'_, 'py> for Visibility {
|
||||
type Error = pyo3::PyErr;
|
||||
|
||||
/// Extracts Visibility from Python object
|
||||
fn extract_bound(ob: &pyo3::Bound<'source, pyo3::PyAny>) -> PyResult<Self> {
|
||||
let strval = String::extract_bound(ob)?;
|
||||
fn extract(ob: pyo3::Borrowed<'_, 'py, pyo3::PyAny>) -> Result<Self, Self::Error> {
|
||||
let strval = String::extract(ob)?;
|
||||
let strval = strval.as_str();
|
||||
|
||||
if strval.contains("hashed/private") {
|
||||
@@ -150,7 +152,7 @@ impl<'source> FromPyObject<'source> for Visibility {
|
||||
let outlets = outlets
|
||||
.trim_start_matches('/')
|
||||
.split(',')
|
||||
.map(|s| s.parse::<usize>().unwrap())
|
||||
.map(|s: &str| s.parse::<usize>().unwrap())
|
||||
.collect_vec();
|
||||
|
||||
return Ok(Visibility::Hashed {
|
||||
|
||||
@@ -260,6 +260,12 @@ pub struct RunArgs {
|
||||
/// Controls decomposition granularity
|
||||
#[cfg_attr(all(feature = "ezkl", not(target_arch = "wasm32")), arg(long, default_value = "2", value_hint = clap::ValueHint::Other))]
|
||||
pub decomp_legs: usize,
|
||||
/// Whether to use bounded lookup for logarithm computation
|
||||
#[cfg_attr(
|
||||
all(feature = "ezkl", not(target_arch = "wasm32")),
|
||||
arg(long, default_value = "false")
|
||||
)]
|
||||
pub bounded_log_lookup: bool,
|
||||
/// Range check inputs and outputs (turn off if the inputs are felts)
|
||||
#[cfg_attr(
|
||||
all(feature = "ezkl", not(target_arch = "wasm32")),
|
||||
@@ -292,6 +298,7 @@ impl Default for RunArgs {
|
||||
/// while maintaining reasonable proving time and circuit size
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
bounded_log_lookup: false,
|
||||
input_scale: 7,
|
||||
param_scale: 7,
|
||||
rebase_scale: None,
|
||||
|
||||
@@ -2325,8 +2325,8 @@ pub mod nonlinearities {
|
||||
/// ```
|
||||
pub fn const_div(a: &Tensor<IntegerRep>, denom: f64) -> Tensor<IntegerRep> {
|
||||
a.par_enum_map(|_, a_i| {
|
||||
let d_inv_x = (a_i) / (denom as i128);
|
||||
Ok::<_, TensorError>(d_inv_x)
|
||||
let d_inv_x = (a_i as f64) / (denom);
|
||||
Ok::<_, TensorError>(d_inv_x.round() as IntegerRep)
|
||||
})
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user