diff --git a/.github/scripts/aggregate_recursion_histogram.py b/.github/scripts/aggregate_recursion_histogram.py
new file mode 100755
index 000000000..0be0a3010
--- /dev/null
+++ b/.github/scripts/aggregate_recursion_histogram.py
@@ -0,0 +1,180 @@
+#!/usr/bin/env python3
+"""Format the recursion-guest per-function profile as a Markdown PR comment.
+
+`test_recursion_profile_1query`/`_multiquery` print a global top-25 functions
+table (folded over all verifier steps, % of total run cycles), followed by
+one top-25 table per verifier step (% of that step's own cycles, so the
+table shows what dominates *within* the step) — e.g. how much of
+`step4:openings` is `keccak`. We parse all of those tables and render them
+as Markdown.
+
+ Top 25 functions by cycle count (aggregated over their PCs, all steps; % of total cycles):
+ rank cycles % cum % PCs function
+ 1 5335072 24.95% 24.95% 72 <...>::visit_seq::<...>
+
+ Top 25 functions by cycle count — step airs_bus_balance (% of this step's 5129138364 cycles):
+ rank cycles % cum % PCs function
+ 1 5335072 24.95% 24.95% 72 <...>::visit_seq::<...>
+
+Reads the test's captured output from argv[1]; writes the Markdown body to
+argv[2] (or stdout).
+"""
+
+import re
+import sys
+from collections import OrderedDict
+
+# A per-function summary row: rank, cycles, pct%, cum%, pcs, function.
+FN_ROW = re.compile(
+ r"^\s*\d+\s+(\d+)\s+([\d.]+)%\s+([\d.]+)%\s+(\d+)\s+(.*\S)\s*$"
+)
+HEADER_ROW = re.compile(r"^\s*rank\s+cycles")
+GLOBAL_TABLE_START = re.compile(
+ r"Top \d+ functions by cycle count \(aggregated over their PCs, all steps"
+)
+STEP_TABLE_START = re.compile(
+ r"Top \d+ functions by cycle count — step (\S+) \(% of this step's (\d+) cycles\):"
+)
+TOTAL_CYCLES = re.compile(r"Total cycles\s*:\s*(\d+)")
+UNIQUE_PCS = re.compile(r"Unique PCs\s*:\s*(\d+)")
+EXEC_TIME = re.compile(r"Exec time\s*:\s*(\S+)")
+
+GLOBAL_KEY = "__global__"
+
+
+def parse(text):
+ total_cycles = unique_pcs = exec_time = None
+ # GLOBAL_KEY -> {"denom": int|None, "rows": [...]}, then one entry per
+ # step tag in first-seen order.
+ tables = OrderedDict()
+ current = None
+ skip_header = False
+ for line in text.splitlines():
+ if total_cycles is None and (m := TOTAL_CYCLES.search(line)):
+ total_cycles = int(m.group(1))
+ if unique_pcs is None and (m := UNIQUE_PCS.search(line)):
+ unique_pcs = int(m.group(1))
+ if exec_time is None and (m := EXEC_TIME.search(line)):
+ exec_time = m.group(1)
+
+ if GLOBAL_TABLE_START.search(line):
+ current = GLOBAL_KEY
+ tables[current] = {"denom": total_cycles, "rows": []}
+ skip_header = True
+ continue
+ if m := STEP_TABLE_START.search(line):
+ current = m.group(1)
+ tables[current] = {"denom": int(m.group(2)), "rows": []}
+ skip_header = True
+ continue
+
+ if current is None:
+ continue
+ if skip_header:
+ # The header row right after a table-start line; anything else
+ # (e.g. a stray blank line) just ends the table early, which is
+ # fine — an empty table renders as "no rows".
+ skip_header = False
+ if HEADER_ROW.match(line):
+ continue
+ if m := FN_ROW.match(line):
+ tables[current]["rows"].append(
+ {
+ "cycles": int(m.group(1)),
+ "pct": m.group(2),
+ "cum": m.group(3),
+ "pcs": int(m.group(4)),
+ "fn": m.group(5),
+ }
+ )
+ else:
+ current = None
+
+ return total_cycles, unique_pcs, exec_time, tables
+
+
+def short(name, width=90):
+ return name if len(name) <= width else name[: width - 1] + "…"
+
+
+def render_table(rows, denom_label):
+ if not rows:
+ return "> _no rows_\n"
+ body = "| Rank | Cycles | % | Cum % | PCs | Function |\n"
+ body += "|-----:|-------:|--:|------:|----:|----------|\n"
+ for i, r in enumerate(rows, 1):
+ body += (
+ f"| {i} | {r['cycles']:,} | {r['pct']}% | {r['cum']}% | "
+ f"{r['pcs']} | `{short(r['fn'])}` |\n"
+ )
+ last_cum = rows[-1]["cum"]
+ body += (
+ f"\nEach function's cycles are summed over all its program counters "
+ f"in this table's scope; the top {len(rows)} cover {last_cum}% of "
+ f"{denom_label}.\n"
+ )
+ return body
+
+
+def render(total_cycles, unique_pcs, exec_time, tables, title="Recursion guest profile"):
+ if not tables.get(GLOBAL_KEY, {}).get("rows"):
+ return (
+ f"### {title}\n\n"
+ "> ⚠️ No per-function rows found in the test output — the run may "
+ "have failed before printing the table. Check the workflow logs.\n"
+ )
+
+ body = f"### {title}\n\n"
+ if total_cycles is not None:
+ body += f"**Total cycles:** {total_cycles:,}"
+ if unique_pcs is not None:
+ body += f" · **Unique PCs:** {unique_pcs:,}"
+ if exec_time:
+ body += f" · **Exec time:** {exec_time}"
+ body += "\n\n"
+
+ global_rows = tables[GLOBAL_KEY]["rows"]
+ body += f"#### Top {len(global_rows)} functions by cycles (all steps)\n\n"
+ body += render_table(global_rows, "total cycles")
+
+ for step, table in tables.items():
+ if step == GLOBAL_KEY:
+ continue
+ rows, denom = table["rows"], table["denom"]
+ denom_note = f" of {denom:,} step cycles" if denom is not None else ""
+ body += (
+ f"\nStep {step}{denom_note} — "
+ f"top {len(rows)} functions
\n\n"
+ )
+ body += render_table(rows, "this step's cycles")
+ body += "\n \n"
+
+ return body
+
+
+def main():
+ import argparse
+
+ ap = argparse.ArgumentParser(description=__doc__)
+ ap.add_argument("log", help="captured test output to parse")
+ ap.add_argument("-o", "--out", help="write Markdown here instead of stdout")
+ ap.add_argument(
+ "-t",
+ "--title",
+ default="Recursion guest profile",
+ help="section heading (e.g. the test/config name)",
+ )
+ args = ap.parse_args()
+
+ with open(args.log, "r", errors="replace") as f:
+ text = f.read()
+ body = render(*parse(text), title=args.title)
+ if args.out:
+ with open(args.out, "w") as f:
+ f.write(body)
+ else:
+ sys.stdout.write(body)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/.github/workflows/profile-recursion.yml b/.github/workflows/profile-recursion.yml
new file mode 100644
index 000000000..680741f15
--- /dev/null
+++ b/.github/workflows/profile-recursion.yml
@@ -0,0 +1,178 @@
+name: Profile Recursion (PR)
+
+# Runs the recursion-guest PC histogram diagnostics (single-query and
+# multi-query, in parallel via a matrix) and posts a combined per-function
+# profile as a PR comment. Triggered by a `/profile_recursion` comment from a
+# repo member, or manually via workflow_dispatch.
+
+on:
+ workflow_dispatch:
+ issue_comment:
+ types: [created]
+
+permissions:
+ contents: read
+ pull-requests: write
+
+concurrency:
+ group: profile-recursion-${{ github.event.issue.number || github.run_id }}
+ cancel-in-progress: true
+
+jobs:
+ # One job per configuration; they run in parallel and each uploads a Markdown
+ # fragment artifact. The `comment` job stitches them into one PR comment.
+ profile:
+ # Skip unless: workflow_dispatch, or "/profile_recursion" comment on a PR by a member.
+ if: >-
+ github.event_name == 'workflow_dispatch' ||
+ (github.event_name == 'issue_comment' &&
+ github.event.issue.pull_request &&
+ startsWith(github.event.comment.body, '/profile_recursion') &&
+ contains(fromJSON('["MEMBER","OWNER","COLLABORATOR"]'), github.event.comment.author_association))
+ runs-on: [self-hosted, bench]
+ timeout-minutes: 90
+ strategy:
+ fail-fast: false
+ matrix:
+ include:
+ - name: single-query
+ test: single
+ title: "Single query (blowup=2, 1 query)"
+ - name: multi-query
+ test: multi
+ title: "Multi query (blowup=8, 128-bit)"
+ steps:
+ - name: React to comment
+ if: github.event_name == 'issue_comment' && matrix.name == 'single-query'
+ uses: actions/github-script@v7
+ with:
+ script: |
+ await github.rest.reactions.createForIssueComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: context.payload.comment.id,
+ content: 'eyes'
+ });
+
+ - name: Get PR head ref
+ id: pr-ref
+ if: github.event_name == 'issue_comment'
+ env:
+ GH_TOKEN: ${{ github.token }}
+ PR_NUM: ${{ github.event.issue.number }}
+ run: |
+ SHA=$(gh pr view "$PR_NUM" --repo "$GITHUB_REPOSITORY" --json headRefOid -q .headRefOid)
+ echo "sha=$SHA" >> "$GITHUB_OUTPUT"
+
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ ref: ${{ steps.pr-ref.outputs.sha || github.sha }}
+
+ - name: Setup Rust Environment
+ uses: ./.github/actions/setup-rust
+
+ - name: Add cargo to PATH
+ run: echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
+
+ - name: Run recursion PC histogram (${{ matrix.name }})
+ env:
+ TEST: ${{ matrix.test }}
+ run: |
+ # Self-provision the RISC-V sysroot in a user-writable dir (the default
+ # /opt path on the bench runner is root-owned); the guest ELF build the
+ # test triggers picks this up via the Makefile's `SYSROOT_DIR ?=`.
+ export SYSROOT_DIR="$HOME/.lambda-vm-sysroot"
+ set -o pipefail
+ make test-profile-recursion-$TEST 2>&1 | tee /tmp/hist.log
+
+ - name: Aggregate into a per-function fragment
+ if: always()
+ env:
+ TITLE: ${{ matrix.title }}
+ run: |
+ python3 .github/scripts/aggregate_recursion_histogram.py \
+ /tmp/hist.log --title "$TITLE" --out "/tmp/fragment-${{ matrix.name }}.md"
+ cat "/tmp/fragment-${{ matrix.name }}.md" >> "$GITHUB_STEP_SUMMARY"
+
+ - name: Upload fragment
+ if: always()
+ uses: actions/upload-artifact@v4
+ with:
+ name: profile-fragment-${{ matrix.name }}
+ path: /tmp/fragment-${{ matrix.name }}.md
+ retention-days: 7
+
+ # Stitch the matrix fragments into a single PR comment.
+ comment:
+ needs: profile
+ # always() so partial-matrix failures still post; skip when `profile` was
+ # skipped (non-/profile_recursion or non-member comment) so this job — and
+ # the self-hosted bench runner it spins up — doesn't fire on every comment.
+ if: always() && github.event_name == 'issue_comment' && needs.profile.result != 'skipped'
+ runs-on: ubuntu-latest
+ steps:
+ - name: Get PR head ref
+ id: pr-ref
+ env:
+ GH_TOKEN: ${{ github.token }}
+ PR_NUM: ${{ github.event.issue.number }}
+ run: |
+ SHA=$(gh pr view "$PR_NUM" --repo "$GITHUB_REPOSITORY" --json headRefOid -q .headRefOid)
+ echo "sha=$SHA" >> "$GITHUB_OUTPUT"
+
+ - name: Download fragments
+ uses: actions/download-artifact@v4
+ with:
+ path: fragments
+ pattern: profile-fragment-*
+ merge-multiple: true
+
+ - name: Assemble comment body
+ env:
+ COMMIT_SHA: ${{ steps.pr-ref.outputs.sha }}
+ run: |
+ {
+ echo "## Recursion guest profile"
+ echo
+ # Single-query first, then multi-query, then any others.
+ for frag in fragments/fragment-single-query.md \
+ fragments/fragment-multi-query.md; do
+ [ -f "$frag" ] && { cat "$frag"; echo; }
+ done
+ echo "Commit: ${COMMIT_SHA:0:8} · Runner: self-hosted bench"
+ } > /tmp/profile_comment.md
+ cat /tmp/profile_comment.md
+
+ - name: Comment on PR
+ uses: actions/github-script@v7
+ with:
+ script: |
+ const fs = require('fs');
+ const body = fs.readFileSync('/tmp/profile_comment.md', 'utf8');
+
+ const { data: comments } = await github.rest.issues.listComments({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: context.issue.number,
+ });
+ // Reuse our own marker comment so repeated /profile_recursion runs update in place.
+ const existing = comments.find(c =>
+ c.user.type === 'Bot' &&
+ c.body.includes('Recursion guest profile')
+ );
+ if (existing) {
+ await github.rest.issues.updateComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ comment_id: existing.id,
+ body,
+ });
+ } else {
+ await github.rest.issues.createComment({
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ issue_number: context.issue.number,
+ body,
+ });
+ }
diff --git a/Cargo.lock b/Cargo.lock
index 6a9cae1ef..7c351b9ee 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2,18 +2,6 @@
# It is not intended for manual editing.
version = 4
-[[package]]
-name = "ahash"
-version = "0.8.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
-dependencies = [
- "cfg-if",
- "once_cell",
- "version_check",
- "zerocopy",
-]
-
[[package]]
name = "aho-corasick"
version = "1.1.4"
@@ -23,21 +11,6 @@ dependencies = [
"memchr",
]
-[[package]]
-name = "allocator-api2"
-version = "0.2.21"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923"
-
-[[package]]
-name = "android_system_properties"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
-dependencies = [
- "libc",
-]
-
[[package]]
name = "anes"
version = "0.1.6"
@@ -94,151 +67,6 @@ dependencies = [
"windows-sys",
]
-[[package]]
-name = "anyhow"
-version = "1.0.100"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
-
-[[package]]
-name = "ark-bn254"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc"
-dependencies = [
- "ark-ec",
- "ark-ff",
- "ark-std",
-]
-
-[[package]]
-name = "ark-ec"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce"
-dependencies = [
- "ahash",
- "ark-ff",
- "ark-poly",
- "ark-serialize",
- "ark-std",
- "educe",
- "fnv",
- "hashbrown 0.15.5",
- "itertools 0.13.0",
- "num-bigint",
- "num-integer",
- "num-traits",
- "zeroize",
-]
-
-[[package]]
-name = "ark-ff"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70"
-dependencies = [
- "ark-ff-asm",
- "ark-ff-macros",
- "ark-serialize",
- "ark-std",
- "arrayvec",
- "digest",
- "educe",
- "itertools 0.13.0",
- "num-bigint",
- "num-traits",
- "paste",
- "zeroize",
-]
-
-[[package]]
-name = "ark-ff-asm"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60"
-dependencies = [
- "quote",
- "syn",
-]
-
-[[package]]
-name = "ark-ff-macros"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09be120733ee33f7693ceaa202ca41accd5653b779563608f1234f78ae07c4b3"
-dependencies = [
- "num-bigint",
- "num-traits",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "ark-poly"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27"
-dependencies = [
- "ahash",
- "ark-ff",
- "ark-serialize",
- "ark-std",
- "educe",
- "fnv",
- "hashbrown 0.15.5",
-]
-
-[[package]]
-name = "ark-serialize"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7"
-dependencies = [
- "ark-serialize-derive",
- "ark-std",
- "arrayvec",
- "digest",
- "num-bigint",
-]
-
-[[package]]
-name = "ark-serialize-derive"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "ark-std"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "246a225cc6131e9ee4f24619af0f19d67761fff15d7ccc22e42b80846e69449a"
-dependencies = [
- "num-traits",
- "rand 0.8.5",
-]
-
-[[package]]
-name = "arrayvec"
-version = "0.7.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
-
-[[package]]
-name = "atomic-polyfill"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
-dependencies = [
- "critical-section",
-]
-
[[package]]
name = "atty"
version = "0.2.14"
@@ -262,18 +90,6 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf"
-[[package]]
-name = "base64"
-version = "0.22.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
-
-[[package]]
-name = "base64ct"
-version = "1.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"
-
[[package]]
name = "bincode"
version = "1.3.3"
@@ -298,22 +114,6 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
-[[package]]
-name = "bitcoin-io"
-version = "0.1.100"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "11301df0b06f22dea7bb1916403fdd88a371031e495c49b8f96931b28189e175"
-
-[[package]]
-name = "bitcoin_hashes"
-version = "0.14.100"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c9901a56e133a1fc86eeb1113e2591f45f4682451ca893bff494d2f88918e3f"
-dependencies = [
- "bitcoin-io",
- "hex-conservative",
-]
-
[[package]]
name = "bitflags"
version = "1.3.2"
@@ -326,18 +126,6 @@ version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
-[[package]]
-name = "bitvec"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c"
-dependencies = [
- "funty",
- "radium",
- "tap",
- "wyz",
-]
-
[[package]]
name = "block-buffer"
version = "0.10.4"
@@ -347,31 +135,12 @@ dependencies = [
"generic-array",
]
-[[package]]
-name = "bls12_381"
-version = "0.8.0"
-source = "git+https://github.com/lambdaclass/bls12_381?branch=expose-affine-constructors#78cad0378b17fc3157b83f514be192bf46edf9a1"
-dependencies = [
- "digest",
- "ff",
- "group",
- "pairing",
- "rand_core 0.6.4",
- "subtle",
-]
-
[[package]]
name = "bumpalo"
version = "3.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510"
-[[package]]
-name = "byte-slice-cast"
-version = "1.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7575182f7272186991736b70173b0ea045398f984bf5ebbb3804736ce1330c9d"
-
[[package]]
name = "bytecheck"
version = "0.8.2"
@@ -395,27 +164,6 @@ dependencies = [
"syn",
]
-[[package]]
-name = "bytemuck"
-version = "1.24.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4"
-
-[[package]]
-name = "byteorder"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
-
-[[package]]
-name = "bytes"
-version = "1.11.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
-dependencies = [
- "serde",
-]
-
[[package]]
name = "cast"
version = "0.3.0"
@@ -438,18 +186,6 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
-[[package]]
-name = "chrono"
-version = "0.4.42"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
-dependencies = [
- "iana-time-zone",
- "num-traits",
- "serde",
- "windows-link",
-]
-
[[package]]
name = "ciborium"
version = "0.2.2"
@@ -474,7 +210,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9"
dependencies = [
"ciborium-io",
- "half 2.7.1",
+ "half",
]
[[package]]
@@ -485,7 +221,7 @@ checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123"
dependencies = [
"bitflags 1.3.2",
"clap_lex 0.2.4",
- "indexmap 1.9.3",
+ "indexmap",
"textwrap",
]
@@ -542,25 +278,16 @@ checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d"
name = "cli"
version = "0.1.0"
dependencies = [
- "bincode",
"clap 4.5.53",
"env_logger",
"executor",
"lambda-vm-prover",
+ "rkyv",
"stark",
"tikv-jemalloc-ctl",
"tikv-jemallocator",
]
-[[package]]
-name = "cobs"
-version = "0.3.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
-dependencies = [
- "thiserror 2.0.17",
-]
-
[[package]]
name = "colorchoice"
version = "1.0.4"
@@ -573,35 +300,6 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
-[[package]]
-name = "const_format"
-version = "0.2.35"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad"
-dependencies = [
- "const_format_proc_macros",
-]
-
-[[package]]
-name = "const_format_proc_macros"
-version = "0.2.34"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744"
-dependencies = [
- "proc-macro2",
- "quote",
- "unicode-xid",
-]
-
-[[package]]
-name = "convert_case"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca"
-dependencies = [
- "unicode-segmentation",
-]
-
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
@@ -617,15 +315,6 @@ dependencies = [
"libc",
]
-[[package]]
-name = "crc32fast"
-version = "1.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
-dependencies = [
- "cfg-if",
-]
-
[[package]]
name = "criterion"
version = "0.4.0"
@@ -686,34 +375,6 @@ dependencies = [
"itertools 0.10.5",
]
-[[package]]
-name = "critical-section"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
-
-[[package]]
-name = "crossbeam"
-version = "0.8.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1137cd7e7fc0fb5d3c5a8678be38ec56e819125d8d7907411fe24ccb943faca8"
-dependencies = [
- "crossbeam-channel",
- "crossbeam-deque",
- "crossbeam-epoch",
- "crossbeam-queue",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "crossbeam-channel"
-version = "0.5.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2"
-dependencies = [
- "crossbeam-utils",
-]
-
[[package]]
name = "crossbeam-deque"
version = "0.8.6"
@@ -733,15 +394,6 @@ dependencies = [
"crossbeam-utils",
]
-[[package]]
-name = "crossbeam-queue"
-version = "0.3.12"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115"
-dependencies = [
- "crossbeam-utils",
-]
-
[[package]]
name = "crossbeam-utils"
version = "0.8.21"
@@ -766,6 +418,7 @@ dependencies = [
"rand 0.8.5",
"rand_chacha 0.3.1",
"rayon",
+ "rkyv",
"serde",
"sha2",
"sha3",
@@ -804,140 +457,39 @@ dependencies = [
]
[[package]]
-name = "darling"
-version = "0.21.3"
+name = "der"
+version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9cdf337090841a411e2a7f3deb9187445851f91b309c0c0a29e05f74a00a48c0"
+checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
dependencies = [
- "darling_core",
- "darling_macro",
+ "const-oid",
+ "zeroize",
]
[[package]]
-name = "darling_core"
-version = "0.21.3"
+name = "digest"
+version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1247195ecd7e3c85f83c8d2a366e4210d588e802133e1e355180a9870b517ea4"
+checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
- "fnv",
- "ident_case",
- "proc-macro2",
- "quote",
- "strsim",
- "syn",
+ "block-buffer",
+ "crypto-common",
]
[[package]]
-name = "darling_macro"
-version = "0.21.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d38308df82d1080de0afee5d069fa14b0326a88c14f15c5ccda35b4a6c414c81"
+name = "ecsm"
+version = "0.1.0"
dependencies = [
- "darling_core",
- "quote",
- "syn",
+ "k256",
+ "num-bigint",
+ "num-traits",
]
[[package]]
-name = "der"
-version = "0.7.10"
+name = "either"
+version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
-dependencies = [
- "const-oid",
- "zeroize",
-]
-
-[[package]]
-name = "deranged"
-version = "0.5.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ececcb659e7ba858fb4f10388c250a7252eb0a27373f1a72b8748afdd248e587"
-dependencies = [
- "powerfmt",
- "serde_core",
-]
-
-[[package]]
-name = "derive_more"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05"
-dependencies = [
- "derive_more-impl",
-]
-
-[[package]]
-name = "derive_more-impl"
-version = "1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22"
-dependencies = [
- "convert_case",
- "proc-macro2",
- "quote",
- "syn",
- "unicode-xid",
-]
-
-[[package]]
-name = "digest"
-version = "0.10.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
-dependencies = [
- "block-buffer",
- "const-oid",
- "crypto-common",
- "subtle",
-]
-
-[[package]]
-name = "dyn-clone"
-version = "1.0.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
-
-[[package]]
-name = "ecdsa"
-version = "0.16.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
-dependencies = [
- "der",
- "digest",
- "elliptic-curve",
- "rfc6979",
- "signature",
- "spki",
-]
-
-[[package]]
-name = "ecsm"
-version = "0.1.0"
-dependencies = [
- "k256",
- "num-bigint",
- "num-traits",
-]
-
-[[package]]
-name = "educe"
-version = "0.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1d7bc049e1bd8cdeb31b68bbd586a9464ecf9f3944af3958a7a9d0f8b9799417"
-dependencies = [
- "enum-ordinalize",
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
-name = "either"
-version = "1.15.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
+checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "elliptic-curve"
@@ -947,49 +499,15 @@ checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47"
dependencies = [
"base16ct",
"crypto-bigint",
- "digest",
"ff",
"generic-array",
"group",
- "pkcs8",
"rand_core 0.6.4",
"sec1",
"subtle",
"zeroize",
]
-[[package]]
-name = "embedded-io"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
-
-[[package]]
-name = "embedded-io"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
-
-[[package]]
-name = "enum-ordinalize"
-version = "4.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a1091a7bb1f8f2c4b28f1fe2cef4980ca2d410a3d727d67ecc3178c9b0800f0"
-dependencies = [
- "enum-ordinalize-derive",
-]
-
-[[package]]
-name = "enum-ordinalize-derive"
-version = "4.3.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8ca9601fb2d62598ee17836250842873a413586e5d7ed88b356e38ddbb0ec631"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
[[package]]
name = "env_filter"
version = "0.1.4"
@@ -1013,12 +531,6 @@ dependencies = [
"log",
]
-[[package]]
-name = "equivalent"
-version = "1.0.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
-
[[package]]
name = "errno"
version = "0.3.14"
@@ -1029,201 +541,15 @@ dependencies = [
"windows-sys",
]
-[[package]]
-name = "ethbloom"
-version = "0.14.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8c321610643004cf908ec0f5f2aa0d8f1f8e14b540562a2887a1111ff1ecbf7b"
-dependencies = [
- "crunchy",
- "fixed-hash",
- "impl-rlp",
- "impl-serde",
- "tiny-keccak",
-]
-
-[[package]]
-name = "ethereum-types"
-version = "0.15.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1ab15ed80916029f878e0267c3a9f92b67df55e79af370bf66199059ae2b4ee3"
-dependencies = [
- "ethbloom",
- "fixed-hash",
- "impl-rlp",
- "impl-serde",
- "primitive-types",
- "uint",
-]
-
-[[package]]
-name = "ethrex-common"
-version = "13.0.0"
-source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c"
-dependencies = [
- "bytes",
- "crc32fast",
- "ethereum-types",
- "ethrex-crypto",
- "ethrex-rlp",
- "ethrex-trie",
- "hex",
- "hex-literal",
- "hex-simd",
- "indexmap 2.12.1",
- "lazy_static",
- "libc",
- "lru",
- "once_cell",
- "rayon",
- "rkyv",
- "rustc-hash",
- "secp256k1",
- "serde",
- "serde_json",
- "sha2",
- "thiserror 2.0.17",
- "tracing",
-]
-
-[[package]]
-name = "ethrex-crypto"
-version = "13.0.0"
-source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c"
-dependencies = [
- "ark-bn254",
- "ark-ec",
- "ark-ff",
- "bls12_381",
- "ethereum-types",
- "ff",
- "hex-literal",
- "k256",
- "malachite",
- "num-bigint",
- "p256",
- "ripemd",
- "secp256k1",
- "sha2",
- "thiserror 2.0.17",
- "tiny-keccak",
-]
-
-[[package]]
-name = "ethrex-guest-program"
-version = "13.0.0"
-source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c"
-dependencies = [
- "bytes",
- "ethereum-types",
- "ethrex-common",
- "ethrex-crypto",
- "ethrex-l2-common",
- "ethrex-rlp",
- "ethrex-vm",
- "hex",
- "rkyv",
- "serde",
- "serde_with",
- "thiserror 2.0.17",
-]
-
-[[package]]
-name = "ethrex-l2-common"
-version = "13.0.0"
-source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c"
-dependencies = [
- "bytes",
- "ethereum-types",
- "ethrex-common",
- "ethrex-crypto",
- "k256",
- "lambdaworks-crypto",
- "rkyv",
- "secp256k1",
- "serde",
- "serde_with",
- "thiserror 2.0.17",
- "tracing",
-]
-
-[[package]]
-name = "ethrex-levm"
-version = "13.0.0"
-source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c"
-dependencies = [
- "bytes",
- "derive_more",
- "ethrex-common",
- "ethrex-crypto",
- "ethrex-rlp",
- "malachite",
- "rayon",
- "rustc-hash",
- "serde",
- "strum",
- "thiserror 2.0.17",
-]
-
-[[package]]
-name = "ethrex-rlp"
-version = "13.0.0"
-source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c"
-dependencies = [
- "bytes",
- "ethereum-types",
- "thiserror 2.0.17",
-]
-
-[[package]]
-name = "ethrex-trie"
-version = "13.0.0"
-source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c"
-dependencies = [
- "anyhow",
- "bytes",
- "crossbeam",
- "ethereum-types",
- "ethrex-crypto",
- "ethrex-rlp",
- "lazy_static",
- "rayon",
- "rkyv",
- "rustc-hash",
- "serde",
- "thiserror 2.0.17",
-]
-
-[[package]]
-name = "ethrex-vm"
-version = "13.0.0"
-source = "git+https://github.com/lambdaclass/ethrex.git?rev=156cb8d6a3974f411d71622eecd1b249ee37ff1c#156cb8d6a3974f411d71622eecd1b249ee37ff1c"
-dependencies = [
- "bytes",
- "derive_more",
- "dyn-clone",
- "ethrex-common",
- "ethrex-crypto",
- "ethrex-levm",
- "ethrex-rlp",
- "rayon",
- "rustc-hash",
- "serde",
- "thiserror 2.0.17",
- "tracing",
-]
-
[[package]]
name = "executor"
version = "0.1.0"
dependencies = [
"ecsm",
- "ethrex-guest-program",
- "rkyv",
"rustc-demangle",
"serde",
"serde_json",
- "thiserror 1.0.69",
+ "thiserror",
"tiny-keccak",
]
@@ -1239,7 +565,6 @@ version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393"
dependencies = [
- "bitvec",
"rand_core 0.6.4",
"subtle",
]
@@ -1248,292 +573,104 @@ dependencies = [
name = "find-msvc-tools"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844"
-
-[[package]]
-name = "fixed-hash"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "835c052cb0c08c1acf6ffd71c022172e18723949c8282f2b9f27efbc51e64534"
-dependencies = [
- "byteorder",
- "rand 0.8.5",
- "rustc-hex",
- "static_assertions",
-]
-
-[[package]]
-name = "fnv"
-version = "1.0.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
-
-[[package]]
-name = "foldhash"
-version = "0.1.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
-
-[[package]]
-name = "foldhash"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
-
-[[package]]
-name = "funty"
-version = "2.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
-
-[[package]]
-name = "generic-array"
-version = "0.14.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
-dependencies = [
- "typenum",
- "version_check",
- "zeroize",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.2.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
-dependencies = [
- "cfg-if",
- "js-sys",
- "libc",
- "wasi",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "getrandom"
-version = "0.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
-dependencies = [
- "cfg-if",
- "libc",
- "r-efi",
- "wasip2",
-]
-
-[[package]]
-name = "group"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
-dependencies = [
- "ff",
- "rand_core 0.6.4",
- "subtle",
-]
-
-[[package]]
-name = "half"
-version = "1.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403"
-
-[[package]]
-name = "half"
-version = "2.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
-dependencies = [
- "cfg-if",
- "crunchy",
- "zerocopy",
-]
-
-[[package]]
-name = "hash32"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
-dependencies = [
- "byteorder",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.12.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
-
-[[package]]
-name = "hashbrown"
-version = "0.15.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
-dependencies = [
- "allocator-api2",
- "foldhash 0.1.5",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.16.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
-dependencies = [
- "allocator-api2",
- "equivalent",
- "foldhash 0.2.0",
-]
-
-[[package]]
-name = "hashbrown"
-version = "0.17.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
-
-[[package]]
-name = "heapless"
-version = "0.7.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
-dependencies = [
- "atomic-polyfill",
- "hash32",
- "rustc_version",
- "serde",
- "spin",
- "stable_deref_trait",
-]
-
-[[package]]
-name = "heck"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
-
-[[package]]
-name = "hermit-abi"
-version = "0.1.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "hermit-abi"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
+checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844"
[[package]]
-name = "hex"
-version = "0.4.3"
+name = "fnv"
+version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
-name = "hex-conservative"
-version = "0.2.2"
+name = "generic-array"
+version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fda06d18ac606267c40c04e41b9947729bf8b9efe74bd4e82b61a5f26a510b9f"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
- "arrayvec",
+ "typenum",
+ "version_check",
+ "zeroize",
]
[[package]]
-name = "hex-literal"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6fe2267d4ed49bc07b63801559be28c718ea06c4738b7a03c94df7386d2cde46"
-
-[[package]]
-name = "hex-simd"
-version = "0.8.0"
+name = "getrandom"
+version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f7685beb53fc20efc2605f32f5d51e9ba18b8ef237961d1760169d2290d3bee"
+checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592"
dependencies = [
- "outref",
- "vsimd",
+ "cfg-if",
+ "js-sys",
+ "libc",
+ "wasi",
+ "wasm-bindgen",
]
[[package]]
-name = "hmac"
-version = "0.12.1"
+name = "getrandom"
+version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
+checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd"
dependencies = [
- "digest",
+ "cfg-if",
+ "libc",
+ "r-efi",
+ "wasip2",
]
[[package]]
-name = "iana-time-zone"
-version = "0.1.64"
+name = "group"
+version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb"
+checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63"
dependencies = [
- "android_system_properties",
- "core-foundation-sys",
- "iana-time-zone-haiku",
- "js-sys",
- "log",
- "wasm-bindgen",
- "windows-core",
+ "ff",
+ "rand_core 0.6.4",
+ "subtle",
]
[[package]]
-name = "iana-time-zone-haiku"
-version = "0.1.2"
+name = "half"
+version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
+checksum = "6ea2d84b969582b4b1864a92dc5d27cd2b77b622a8d79306834f1be5ba20d84b"
dependencies = [
- "cc",
+ "cfg-if",
+ "crunchy",
+ "zerocopy",
]
[[package]]
-name = "ident_case"
-version = "1.0.1"
+name = "hashbrown"
+version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
-name = "impl-codec"
-version = "0.7.1"
+name = "hashbrown"
+version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2d40b9d5e17727407e55028eafc22b2dc68781786e6d7eb8a21103f5058e3a14"
-dependencies = [
- "parity-scale-codec",
-]
+checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]]
-name = "impl-rlp"
-version = "0.4.0"
+name = "heck"
+version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54ed8ad1f3877f7e775b8cbf30ed1bd3209a95401817f19a0eb4402d13f8cf90"
-dependencies = [
- "rlp",
-]
+checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
-name = "impl-serde"
-version = "0.5.0"
+name = "hermit-abi"
+version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4a143eada6a1ec4aefa5049037a26a6d597bfd64f8c026d07b77133e02b7dd0b"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
- "serde",
+ "libc",
]
[[package]]
-name = "impl-trait-for-tuples"
-version = "0.2.3"
+name = "hermit-abi"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a0eb5a3343abf848c0984fe4604b2b105da9539376e24fc0a3b0007411ae4fd9"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
+checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
[[package]]
name = "indexmap"
@@ -1543,19 +680,6 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
dependencies = [
"autocfg",
"hashbrown 0.12.3",
- "serde",
-]
-
-[[package]]
-name = "indexmap"
-version = "2.12.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2"
-dependencies = [
- "equivalent",
- "hashbrown 0.16.1",
- "serde",
- "serde_core",
]
[[package]]
@@ -1593,24 +717,6 @@ dependencies = [
"either",
]
-[[package]]
-name = "itertools"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
-dependencies = [
- "either",
-]
-
-[[package]]
-name = "itertools"
-version = "0.14.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
-dependencies = [
- "either",
-]
-
[[package]]
name = "itoa"
version = "1.0.16"
@@ -1658,11 +764,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b"
dependencies = [
"cfg-if",
- "ecdsa",
"elliptic-curve",
- "once_cell",
- "sha2",
- "signature",
]
[[package]]
@@ -1678,7 +780,6 @@ dependencies = [
name = "lambda-vm-prover"
version = "0.1.0"
dependencies = [
- "bincode",
"criterion 0.5.1",
"crypto",
"ecsm",
@@ -1686,9 +787,8 @@ dependencies = [
"executor",
"log",
"math",
- "postcard",
"rayon",
- "serde",
+ "rkyv",
"sha3",
"stark",
"sysinfo",
@@ -1697,34 +797,6 @@ dependencies = [
"tiny-keccak",
]
-[[package]]
-name = "lambdaworks-crypto"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "58b1a1c1102a5a7fbbda117b79fb3a01e033459c738a3c1642269603484fd1c1"
-dependencies = [
- "lambdaworks-math",
- "rand 0.8.5",
- "rand_chacha 0.3.1",
- "serde",
- "sha2",
- "sha3",
-]
-
-[[package]]
-name = "lambdaworks-math"
-version = "0.13.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "018a95aa873eb49896a858dee0d925c33f3978d073c64b08dd4f2c9b35a017c6"
-dependencies = [
- "getrandom 0.2.16",
- "num-bigint",
- "num-traits",
- "rand 0.8.5",
- "serde",
- "serde_json",
-]
-
[[package]]
name = "lazy_static"
version = "1.5.0"
@@ -1747,88 +819,18 @@ dependencies = [
"windows-link",
]
-[[package]]
-name = "libm"
-version = "0.2.15"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
-
[[package]]
name = "linux-raw-sys"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
-[[package]]
-name = "lock_api"
-version = "0.4.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
-dependencies = [
- "scopeguard",
-]
-
[[package]]
name = "log"
version = "0.4.29"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
-[[package]]
-name = "lru"
-version = "0.16.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1dc47f592c06f33f8e3aea9591776ec7c9f9e4124778ff8a3c3b87159f7e593"
-dependencies = [
- "hashbrown 0.16.1",
-]
-
-[[package]]
-name = "malachite"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ec410515e231332b14cd986a475d1c3323bcfa4c7efc038bfa1d5b410b1c57e4"
-dependencies = [
- "malachite-base",
- "malachite-nz",
- "malachite-q",
-]
-
-[[package]]
-name = "malachite-base"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c738d3789301e957a8f7519318fcbb1b92bb95863b28f6938ae5a05be6259f34"
-dependencies = [
- "hashbrown 0.15.5",
- "itertools 0.14.0",
- "libm",
- "ryu",
-]
-
-[[package]]
-name = "malachite-nz"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1707c9a1fa36ce21749b35972bfad17bbf34cf5a7c96897c0491da321e387d3b"
-dependencies = [
- "itertools 0.14.0",
- "libm",
- "malachite-base",
- "wide",
-]
-
-[[package]]
-name = "malachite-q"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d764801aa4e96bbb69b389dcd03b50075345131cd63ca2e380bca71cc37a3675"
-dependencies = [
- "itertools 0.14.0",
- "malachite-base",
- "malachite-nz",
-]
-
[[package]]
name = "matchers"
version = "0.2.0"
@@ -1850,6 +852,7 @@ dependencies = [
"rand 0.8.5",
"rand_chacha 0.3.1",
"rayon",
+ "rkyv",
"serde",
"serde_json",
]
@@ -1931,12 +934,6 @@ dependencies = [
"num-traits",
]
-[[package]]
-name = "num-conv"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
-
[[package]]
name = "num-integer"
version = "0.1.46"
@@ -1979,61 +976,6 @@ version = "6.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1"
-[[package]]
-name = "outref"
-version = "0.5.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e"
-
-[[package]]
-name = "p256"
-version = "0.13.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b"
-dependencies = [
- "ecdsa",
- "elliptic-curve",
- "primeorder",
- "sha2",
-]
-
-[[package]]
-name = "pairing"
-version = "0.23.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f"
-dependencies = [
- "group",
-]
-
-[[package]]
-name = "parity-scale-codec"
-version = "3.7.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "799781ae679d79a948e13d4824a40970bfa500058d245760dd857301059810fa"
-dependencies = [
- "arrayvec",
- "bitvec",
- "byte-slice-cast",
- "const_format",
- "impl-trait-for-tuples",
- "parity-scale-codec-derive",
- "rustversion",
- "serde",
-]
-
-[[package]]
-name = "parity-scale-codec-derive"
-version = "3.7.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "34b4653168b563151153c9e4c08ebed57fb8262bebfa79711552fa983c623e7a"
-dependencies = [
- "proc-macro-crate",
- "proc-macro2",
- "quote",
- "syn",
-]
-
[[package]]
name = "paste"
version = "1.0.15"
@@ -2046,16 +988,6 @@ version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
-[[package]]
-name = "pkcs8"
-version = "0.10.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
-dependencies = [
- "der",
- "spki",
-]
-
[[package]]
name = "plotters"
version = "0.3.7"
@@ -2099,25 +1031,6 @@ dependencies = [
"portable-atomic",
]
-[[package]]
-name = "postcard"
-version = "1.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
-dependencies = [
- "cobs",
- "embedded-io 0.4.0",
- "embedded-io 0.6.1",
- "heapless",
- "serde",
-]
-
-[[package]]
-name = "powerfmt"
-version = "0.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
-
[[package]]
name = "ppv-lite86"
version = "0.2.21"
@@ -2127,37 +1040,6 @@ dependencies = [
"zerocopy",
]
-[[package]]
-name = "primeorder"
-version = "0.13.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6"
-dependencies = [
- "elliptic-curve",
-]
-
-[[package]]
-name = "primitive-types"
-version = "0.13.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d15600a7d856470b7d278b3fe0e311fe28c2526348549f8ef2ff7db3299c87f5"
-dependencies = [
- "fixed-hash",
- "impl-codec",
- "impl-rlp",
- "impl-serde",
- "uint",
-]
-
-[[package]]
-name = "proc-macro-crate"
-version = "3.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983"
-dependencies = [
- "toml_edit",
-]
-
[[package]]
name = "proc-macro2"
version = "1.0.103"
@@ -2227,12 +1109,6 @@ version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
-[[package]]
-name = "radium"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
-
[[package]]
name = "rancor"
version = "0.1.1"
@@ -2326,28 +1202,8 @@ version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
dependencies = [
- "crossbeam-deque",
- "crossbeam-utils",
-]
-
-[[package]]
-name = "ref-cast"
-version = "1.0.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f354300ae66f76f1c85c5f84693f0ce81d747e2c3f21a45fef496d89c960bf7d"
-dependencies = [
- "ref-cast-impl",
-]
-
-[[package]]
-name = "ref-cast-impl"
-version = "1.0.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b7186006dcb21920990093f30e3dea63b7d6e977bf1256be20c3563a5db070da"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
+ "crossbeam-deque",
+ "crossbeam-utils",
]
[[package]]
@@ -2388,25 +1244,6 @@ dependencies = [
"bytecheck",
]
-[[package]]
-name = "rfc6979"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2"
-dependencies = [
- "hmac",
- "subtle",
-]
-
-[[package]]
-name = "ripemd"
-version = "0.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f"
-dependencies = [
- "digest",
-]
-
[[package]]
name = "rkyv"
version = "0.8.16"
@@ -2414,16 +1251,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "73389e0c99e664f919275ab5b5b0471391fe9a8de61e1dff9b1eaf56a90f16e3"
dependencies = [
"bytecheck",
- "bytes",
"hashbrown 0.17.1",
- "indexmap 2.12.1",
"munge",
"ptr_meta",
"rancor",
"rend",
"rkyv_derive",
"tinyvec",
- "uuid",
]
[[package]]
@@ -2437,43 +1271,12 @@ dependencies = [
"syn",
]
-[[package]]
-name = "rlp"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "fa24e92bb2a83198bb76d661a71df9f7076b8c420b8696e4d3d97d50d94479e3"
-dependencies = [
- "bytes",
- "rustc-hex",
-]
-
[[package]]
name = "rustc-demangle"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56f7d92ca342cea22a06f2121d944b4fd82af56988c270852495420f961d4ace"
-[[package]]
-name = "rustc-hash"
-version = "2.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
-
-[[package]]
-name = "rustc-hex"
-version = "2.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6"
-
-[[package]]
-name = "rustc_version"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
-dependencies = [
- "semver",
-]
-
[[package]]
name = "rustix"
version = "1.1.3"
@@ -2511,15 +1314,6 @@ version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62049b2877bf12821e8f9ad256ee38fdc31db7387ec2d3b3f403024de2034aea"
-[[package]]
-name = "safe_arch"
-version = "0.7.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323"
-dependencies = [
- "bytemuck",
-]
-
[[package]]
name = "same-file"
version = "1.0.6"
@@ -2529,36 +1323,6 @@ dependencies = [
"winapi-util",
]
-[[package]]
-name = "schemars"
-version = "0.9.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f"
-dependencies = [
- "dyn-clone",
- "ref-cast",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "schemars"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "54e910108742c57a770f492731f99be216a52fadd361b06c8fb59d74ccc267d2"
-dependencies = [
- "dyn-clone",
- "ref-cast",
- "serde",
- "serde_json",
-]
-
-[[package]]
-name = "scopeguard"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
-
[[package]]
name = "sec1"
version = "0.7.3"
@@ -2568,37 +1332,10 @@ dependencies = [
"base16ct",
"der",
"generic-array",
- "pkcs8",
"subtle",
"zeroize",
]
-[[package]]
-name = "secp256k1"
-version = "0.30.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b50c5943d326858130af85e049f2661ba3c78b26589b8ab98e65e80ae44a1252"
-dependencies = [
- "bitcoin_hashes",
- "rand 0.8.5",
- "secp256k1-sys",
-]
-
-[[package]]
-name = "secp256k1-sys"
-version = "0.10.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d4387882333d3aa8cb20530a17c69a3752e97837832f34f6dccc760e715001d9"
-dependencies = [
- "cc",
-]
-
-[[package]]
-name = "semver"
-version = "1.0.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
-
[[package]]
name = "serde"
version = "1.0.228"
@@ -2609,27 +1346,6 @@ dependencies = [
"serde_derive",
]
-[[package]]
-name = "serde-wasm-bindgen"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e"
-dependencies = [
- "js-sys",
- "serde",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "serde_cbor"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
-dependencies = [
- "half 1.8.3",
- "serde",
-]
-
[[package]]
name = "serde_core"
version = "1.0.228"
@@ -2663,37 +1379,6 @@ dependencies = [
"serde_core",
]
-[[package]]
-name = "serde_with"
-version = "3.16.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fa237f2807440d238e0364a218270b98f767a00d3dada77b1c53ae88940e2e7"
-dependencies = [
- "base64",
- "chrono",
- "hex",
- "indexmap 1.9.3",
- "indexmap 2.12.1",
- "schemars 0.9.0",
- "schemars 1.2.0",
- "serde_core",
- "serde_json",
- "serde_with_macros",
- "time",
-]
-
-[[package]]
-name = "serde_with_macros"
-version = "3.16.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52a8e3ca0ca629121f70ab50f95249e5a6f925cc0f6ffe8256c45b728875706c"
-dependencies = [
- "darling",
- "proc-macro2",
- "quote",
- "syn",
-]
-
[[package]]
name = "sha2"
version = "0.10.9"
@@ -2730,47 +1415,12 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
-[[package]]
-name = "signature"
-version = "2.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
-dependencies = [
- "digest",
- "rand_core 0.6.4",
-]
-
[[package]]
name = "simdutf8"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
-[[package]]
-name = "spin"
-version = "0.9.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
-dependencies = [
- "lock_api",
-]
-
-[[package]]
-name = "spki"
-version = "0.7.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
-dependencies = [
- "base64ct",
- "der",
-]
-
-[[package]]
-name = "stable_deref_trait"
-version = "1.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
-
[[package]]
name = "stark"
version = "0.1.0"
@@ -2788,50 +1438,21 @@ dependencies = [
"rand 0.8.5",
"rand_chacha 0.3.1",
"rayon",
- "serde",
- "serde-wasm-bindgen",
- "serde_cbor",
+ "rkyv",
"sha3",
"tempfile",
"test-log",
- "thiserror 1.0.69",
+ "thiserror",
"wasm-bindgen",
"web-sys",
]
-[[package]]
-name = "static_assertions"
-version = "1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
-
[[package]]
name = "strsim"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
-[[package]]
-name = "strum"
-version = "0.27.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf"
-dependencies = [
- "strum_macros",
-]
-
-[[package]]
-name = "strum_macros"
-version = "0.27.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7"
-dependencies = [
- "heck",
- "proc-macro2",
- "quote",
- "syn",
-]
-
[[package]]
name = "subtle"
version = "2.6.1"
@@ -2862,12 +1483,6 @@ dependencies = [
"windows",
]
-[[package]]
-name = "tap"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369"
-
[[package]]
name = "tempfile"
version = "3.23.0"
@@ -2915,16 +1530,7 @@ version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
- "thiserror-impl 1.0.69",
-]
-
-[[package]]
-name = "thiserror"
-version = "2.0.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8"
-dependencies = [
- "thiserror-impl 2.0.17",
+ "thiserror-impl",
]
[[package]]
@@ -2938,17 +1544,6 @@ dependencies = [
"syn",
]
-[[package]]
-name = "thiserror-impl"
-version = "2.0.17"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
[[package]]
name = "thread_local"
version = "1.1.9"
@@ -2989,37 +1584,6 @@ dependencies = [
"tikv-jemalloc-sys",
]
-[[package]]
-name = "time"
-version = "0.3.45"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd"
-dependencies = [
- "deranged",
- "itoa",
- "num-conv",
- "powerfmt",
- "serde_core",
- "time-core",
- "time-macros",
-]
-
-[[package]]
-name = "time-core"
-version = "0.1.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca"
-
-[[package]]
-name = "time-macros"
-version = "0.2.25"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd"
-dependencies = [
- "num-conv",
- "time-core",
-]
-
[[package]]
name = "tiny-keccak"
version = "2.0.2"
@@ -3054,59 +1618,16 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
-[[package]]
-name = "toml_datetime"
-version = "0.7.5+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347"
-dependencies = [
- "serde_core",
-]
-
-[[package]]
-name = "toml_edit"
-version = "0.23.10+spec-1.0.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269"
-dependencies = [
- "indexmap 2.12.1",
- "toml_datetime",
- "toml_parser",
- "winnow",
-]
-
-[[package]]
-name = "toml_parser"
-version = "1.0.6+spec-1.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44"
-dependencies = [
- "winnow",
-]
-
[[package]]
name = "tracing"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
dependencies = [
- "log",
"pin-project-lite",
- "tracing-attributes",
"tracing-core",
]
-[[package]]
-name = "tracing-attributes"
-version = "0.1.31"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
[[package]]
name = "tracing-core"
version = "0.1.36"
@@ -3151,18 +1672,6 @@ version = "1.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
-[[package]]
-name = "uint"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "909988d098b2f738727b161a106cfc7cab00c539c2687a8836f8e565976fb53e"
-dependencies = [
- "byteorder",
- "crunchy",
- "hex",
- "static_assertions",
-]
-
[[package]]
name = "unarray"
version = "0.1.4"
@@ -3175,34 +1684,12 @@ version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
-[[package]]
-name = "unicode-segmentation"
-version = "1.12.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493"
-
-[[package]]
-name = "unicode-xid"
-version = "0.2.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
-
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
-[[package]]
-name = "uuid"
-version = "1.19.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a"
-dependencies = [
- "js-sys",
- "wasm-bindgen",
-]
-
[[package]]
name = "valuable"
version = "0.1.1"
@@ -3215,12 +1702,6 @@ version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
-[[package]]
-name = "vsimd"
-version = "0.8.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64"
-
[[package]]
name = "wait-timeout"
version = "0.2.1"
@@ -3310,16 +1791,6 @@ dependencies = [
"wasm-bindgen",
]
-[[package]]
-name = "wide"
-version = "0.7.33"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ce5da8ecb62bcd8ec8b7ea19f69a51275e91299be594ea5cc6ef7819e16cd03"
-dependencies = [
- "bytemuck",
- "safe_arch",
-]
-
[[package]]
name = "winapi"
version = "0.3.9"
@@ -3483,30 +1954,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
-[[package]]
-name = "winnow"
-version = "0.7.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
-dependencies = [
- "memchr",
-]
-
[[package]]
name = "wit-bindgen"
version = "0.46.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59"
-[[package]]
-name = "wyz"
-version = "0.5.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed"
-dependencies = [
- "tap",
-]
-
[[package]]
name = "zerocopy"
version = "0.8.31"
@@ -3532,17 +1985,3 @@ name = "zeroize"
version = "1.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0"
-dependencies = [
- "zeroize_derive",
-]
-
-[[package]]
-name = "zeroize_derive"
-version = "1.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
diff --git a/Makefile b/Makefile
index 454eff098..5fbe41f2c 100644
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
.PHONY: deps deps-linux deps-macos compile-programs-asm compile-programs-rust compile-bench \
compile-programs compile-recursion-elfs clean-asm clean-rust clean-bench clean-shared \
clean-recursion-elfs clean test test-asm \
-test-rust test-executor test-flamegraph flamegraph-prover \
-test-fast test-prover test-prover-all test-disk-spill test-math-cuda test-cuda-integration \
+test-rust test-executor test-flamegraph flamegraph-prover test-profile-recursion test-profile-recursion-single test-profile-recursion-multi \
+test-fast test-prover test-prover-all test-disk-spill test-math-cuda test-cuda-integration test-ethrex \
bench-math-cuda bench-prover bench-prover-cuda build check clippy fmt lint regen-ethrex-fixtures \
update-ethrex-fixture-checksums check-ethrex-fixture-checksums
@@ -232,6 +232,14 @@ test-rust: compile-programs-rust
test-flamegraph:
cargo test -p executor --test flamegraph
+test-profile-recursion: test-profile-recursion-single test-profile-recursion-multi
+
+test-profile-recursion-single: compile-recursion-elfs
+ cargo test --package lambda-vm-prover --lib test_recursion_profile_1query -- --ignored --nocapture
+
+test-profile-recursion-multi: compile-recursion-elfs
+ cargo test --package lambda-vm-prover --lib test_recursion_profile_multiquery -- --ignored --nocapture
+
# Regenerate the committed ethrex block fixtures (see tooling/ethrex-fixtures).
# Run after bumping the ethrex rev; README checksums are refreshed automatically.
regen-ethrex-fixtures:
@@ -247,8 +255,14 @@ update-ethrex-fixture-checksums:
check-ethrex-fixture-checksums:
python3 tooling/ethrex-fixtures/update_readme_checksums.py --check
+# Detached workspace: ethrex pins rkyv `unaligned`, which must not feature-unify
+# with the main workspace's aligned proof format (see tooling/ethrex-tests).
+test-ethrex: compile-programs-rust
+ cd tooling/ethrex-tests && cargo test
+
test: compile-programs
cargo test
+ $(MAKE) test-ethrex
# === Quick test shortcuts ===
diff --git a/bench_vs/lambda/fibonacci/src/main.rs b/bench_vs/lambda/fibonacci/src/main.rs
index 9ef9ef69c..d3c595e37 100644
--- a/bench_vs/lambda/fibonacci/src/main.rs
+++ b/bench_vs/lambda/fibonacci/src/main.rs
@@ -15,7 +15,7 @@ fn panic(_info: &PanicInfo) -> ! {
fn read_n() -> u64 {
// Layout matches `syscalls::get_private_input`: 4-byte LE length prefix at
- // PRIVATE_INPUT_START, payload at +4. We only need the first 8 bytes (u64).
+ // PRIVATE_INPUT_START, payload at +16. We only need the first 8 bytes (u64).
let mut n_bytes = [0u8; 8];
debug_assert!(
@@ -23,7 +23,7 @@ fn read_n() -> u64 {
"private input too short to contain a u64"
);
- let input_data = (PRIVATE_INPUT_START + 4) as *const u8;
+ let input_data = (PRIVATE_INPUT_START + 16) as *const u8;
n_bytes.copy_from_slice(unsafe { core::slice::from_raw_parts(input_data, 8) });
u64::from_le_bytes(n_bytes)
diff --git a/bench_vs/lambda/recursion/Cargo.lock b/bench_vs/lambda/recursion/Cargo.lock
index 66048ba81..0e0cd0796 100644
--- a/bench_vs/lambda/recursion/Cargo.lock
+++ b/bench_vs/lambda/recursion/Cargo.lock
@@ -2,15 +2,6 @@
# It is not intended for manual editing.
version = 4
-[[package]]
-name = "atomic-polyfill"
-version = "1.0.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
-dependencies = [
- "critical-section",
-]
-
[[package]]
name = "autocfg"
version = "1.5.1"
@@ -45,25 +36,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649"
[[package]]
-name = "byteorder"
-version = "1.5.0"
+name = "bytecheck"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+checksum = "0caa33a2c0edca0419d15ac723dff03f1956f7978329b1e3b5fdaaaed9d3ca8b"
+dependencies = [
+ "bytecheck_derive",
+ "ptr_meta",
+ "rancor",
+ "simdutf8",
+]
[[package]]
-name = "cfg-if"
-version = "1.0.4"
+name = "bytecheck_derive"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
+checksum = "89385e82b5d1821d2219e0b095efa2cc1f246cbf99080f3be46a1a85c0d392d9"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.118",
+]
[[package]]
-name = "cobs"
-version = "0.3.0"
+name = "cfg-if"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
-dependencies = [
- "thiserror 2.0.18",
-]
+checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "const-default"
@@ -131,6 +130,7 @@ dependencies = [
"math",
"rand 0.8.6",
"rand_chacha 0.3.1",
+ "rkyv",
"serde",
"sha3",
]
@@ -227,25 +227,13 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89"
-[[package]]
-name = "embedded-io"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced"
-
-[[package]]
-name = "embedded-io"
-version = "0.6.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d"
-
[[package]]
name = "executor"
version = "0.1.0"
dependencies = [
"ecsm",
"rustc-demangle",
- "thiserror 1.0.69",
+ "thiserror",
]
[[package]]
@@ -330,33 +318,10 @@ dependencies = [
]
[[package]]
-name = "half"
-version = "1.8.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b43ede17f21864e81be2fa654110bf1e793774238d86ef8555c37e6519c0403"
-
-[[package]]
-name = "hash32"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
-dependencies = [
- "byteorder",
-]
-
-[[package]]
-name = "heapless"
-version = "0.7.17"
+name = "hashbrown"
+version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
-dependencies = [
- "atomic-polyfill",
- "hash32",
- "rustc_version",
- "serde",
- "spin",
- "stable_deref_trait",
-]
+checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]]
name = "itertools"
@@ -412,7 +377,7 @@ dependencies = [
"executor",
"log",
"math",
- "serde",
+ "rkyv",
"sha3",
"stark",
"sysinfo",
@@ -428,7 +393,7 @@ dependencies = [
"lazy_static",
"rand 0.9.4",
"riscv",
- "thiserror 1.0.69",
+ "thiserror",
]
[[package]]
@@ -449,15 +414,6 @@ version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b23ac50abb8261cb38c6e2a7192d3302e0836dac1628f6a93b82b4fad185897"
-[[package]]
-name = "lock_api"
-version = "0.4.14"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
-dependencies = [
- "scopeguard",
-]
-
[[package]]
name = "log"
version = "0.4.33"
@@ -473,6 +429,7 @@ dependencies = [
"num-traits",
"rand 0.8.6",
"rayon",
+ "rkyv",
"serde",
"serde_json",
]
@@ -483,6 +440,26 @@ version = "2.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4"
+[[package]]
+name = "munge"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5e17401f259eba956ca16491461b6e8f72913a0a114e39736ce404410f915a0c"
+dependencies = [
+ "munge_macro",
+]
+
+[[package]]
+name = "munge_macro"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4568f25ccbd45ab5d5603dc34318c1ec56b117531781260002151b8530a9f931"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.118",
+]
+
[[package]]
name = "ntapi"
version = "0.4.3"
@@ -538,19 +515,6 @@ version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd"
-[[package]]
-name = "postcard"
-version = "1.1.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
-dependencies = [
- "cobs",
- "embedded-io 0.4.0",
- "embedded-io 0.6.1",
- "heapless",
- "serde",
-]
-
[[package]]
name = "ppv-lite86"
version = "0.2.21"
@@ -569,6 +533,26 @@ dependencies = [
"unicode-ident",
]
+[[package]]
+name = "ptr_meta"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b9a0cf95a1196af61d4f1cbdab967179516d9a4a4312af1f31948f8f6224a79"
+dependencies = [
+ "ptr_meta_derive",
+]
+
+[[package]]
+name = "ptr_meta_derive"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7347867d0a7e1208d93b46767be83e2b8f978c3dad35f775ac8d8847551d6fe1"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.118",
+]
+
[[package]]
name = "quote"
version = "1.0.46"
@@ -584,6 +568,15 @@ version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
+[[package]]
+name = "rancor"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "daff8b7b3ccf5f7ba270b3e7a0a4d4c701c5797e38dec27c7e2c3dbb830fed1c"
+dependencies = [
+ "ptr_meta",
+]
+
[[package]]
name = "rand"
version = "0.8.6"
@@ -664,7 +657,15 @@ version = "0.1.0"
dependencies = [
"lambda-vm-prover",
"lambda-vm-syscalls",
- "postcard",
+]
+
+[[package]]
+name = "rend"
+version = "0.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "663ba70707f96e871406fe10d68128412e619b06d1d47cb91c3a4c6501176240"
+dependencies = [
+ "bytecheck",
]
[[package]]
@@ -697,6 +698,33 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8188909339ccc0c68cfb5a04648313f09621e8b87dc03095454f1a11f6c5d436"
+[[package]]
+name = "rkyv"
+version = "0.8.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "815cc8a37159a463064825246cadb07961e25cd9885908606f6d08a98d8f8874"
+dependencies = [
+ "bytecheck",
+ "hashbrown",
+ "munge",
+ "ptr_meta",
+ "rancor",
+ "rend",
+ "rkyv_derive",
+ "tinyvec",
+]
+
+[[package]]
+name = "rkyv_derive"
+version = "0.8.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c0ed1a78a1b19d184b0daa629dd9a024573173ec7d485b287cb369fb3607cc1c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.118",
+]
+
[[package]]
name = "rlsf"
version = "0.2.2"
@@ -716,27 +744,12 @@ version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d"
-[[package]]
-name = "rustc_version"
-version = "0.4.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
-dependencies = [
- "semver",
-]
-
[[package]]
name = "rustversion"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
-[[package]]
-name = "scopeguard"
-version = "1.2.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
-
[[package]]
name = "sec1"
version = "0.7.3"
@@ -750,12 +763,6 @@ dependencies = [
"zeroize",
]
-[[package]]
-name = "semver"
-version = "1.0.28"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
-
[[package]]
name = "serde"
version = "1.0.228"
@@ -766,16 +773,6 @@ dependencies = [
"serde_derive",
]
-[[package]]
-name = "serde_cbor"
-version = "0.11.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
-dependencies = [
- "half",
- "serde",
-]
-
[[package]]
name = "serde_core"
version = "1.0.228"
@@ -820,25 +817,16 @@ dependencies = [
]
[[package]]
-name = "slab"
-version = "0.4.12"
+name = "simdutf8"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
+checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
[[package]]
-name = "spin"
-version = "0.9.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
-dependencies = [
- "lock_api",
-]
-
-[[package]]
-name = "stable_deref_trait"
-version = "1.2.1"
+name = "slab"
+version = "0.4.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
+checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
[[package]]
name = "stark"
@@ -848,10 +836,9 @@ dependencies = [
"itertools",
"log",
"math",
- "serde",
- "serde_cbor",
+ "rkyv",
"sha3",
- "thiserror 1.0.69",
+ "thiserror",
]
[[package]]
@@ -914,16 +901,7 @@ version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
- "thiserror-impl 1.0.69",
-]
-
-[[package]]
-name = "thiserror"
-version = "2.0.18"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4"
-dependencies = [
- "thiserror-impl 2.0.18",
+ "thiserror-impl",
]
[[package]]
@@ -938,16 +916,20 @@ dependencies = [
]
[[package]]
-name = "thiserror-impl"
-version = "2.0.18"
+name = "tinyvec"
+version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
+checksum = "3e61e67053d25a4e82c844e8424039d9745781b3fc4f32b8d55ed50f5f667ef3"
dependencies = [
- "proc-macro2",
- "quote",
- "syn 2.0.118",
+ "tinyvec_macros",
]
+[[package]]
+name = "tinyvec_macros"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
+
[[package]]
name = "typenum"
version = "1.20.1"
diff --git a/bench_vs/lambda/recursion/Cargo.toml b/bench_vs/lambda/recursion/Cargo.toml
index bdfeb38dc..6a926546f 100644
--- a/bench_vs/lambda/recursion/Cargo.toml
+++ b/bench_vs/lambda/recursion/Cargo.toml
@@ -6,6 +6,7 @@ version = "0.1.0"
edition = "2024"
[dependencies]
-lambda-vm-prover = { path = "../../../prover", default-features = false }
+lambda-vm-prover = { path = "../../../prover", default-features = false, features = [
+ "profile-markers",
+] }
lambda-vm-syscalls = { path = "../../../syscalls" }
-postcard = { version = "1.0", features = ["alloc"] }
diff --git a/bench_vs/lambda/recursion/src/main.rs b/bench_vs/lambda/recursion/src/main.rs
index c256a0732..f9d3215db 100644
--- a/bench_vs/lambda/recursion/src/main.rs
+++ b/bench_vs/lambda/recursion/src/main.rs
@@ -1,9 +1,16 @@
//! Naive recursion guest: verifies an inner lambda-vm proof inside the VM.
//!
-//! Private input layout (postcard-encoded):
-//! `(VmProof, Vec, ProofOptions)`
-//! where the `Vec` holds the inner program's ELF bytes and `ProofOptions`
-//! specifies the parameters the inner prover used. Commits `[1]` on success.
+//! Private input layout: a 16-byte `"LVMR" + version + reserved` prefix
+//! followed by an rkyv archive of `lambda_vm_prover::RecursionInput`
+//! `{ vm_proof, inner_elf, options, vkey }`. The prefix tags the format so the
+//! guest rejects a wrong-format blob before the unsafe access; sized to a
+//! multiple of 16, it keeps the archive 16-aligned at the executor's aligned
+//! payload base (`PRIVATE_INPUT_START + 16`). The proof is verified **in
+//! place** via `verify_recursion_blob` — no deserialization pass, no owned
+//! `VmProof`. Commits `vk_digest ‖ inner public output` on success: every
+//! input here is prover-supplied, so soundness comes from the outer verifier
+//! checking the committed digest against one derived from the trusted inner
+//! ELF.
//!
//! Not `no_std` (std/alloc are available — `build-std` provides them, and the
//! prover links as a normal std crate; its prove-side code is dead-code
@@ -14,8 +21,6 @@
#![no_main]
-use lambda_vm_prover::{ProofOptions, VmProof};
-
#[unsafe(export_name = "main")]
pub fn main() -> ! {
lambda_vm_syscalls::allocator::init_allocator();
@@ -28,14 +33,20 @@ pub fn main() -> ! {
lambda_vm_syscalls::syscalls::sys_panic(PANIC_MSG.as_ptr(), PANIC_MSG.len())
}));
- let blob = lambda_vm_syscalls::syscalls::get_private_input();
- let (vm_proof, inner_elf, options): (VmProof, Vec, ProofOptions) =
- postcard::from_bytes(&blob).expect("failed to deserialize recursion input");
+ // Zero-copy: borrow the blob straight from the mapped private-input region.
+ // The payload base and prefix are both 16-aligned, so the archive sits at a
+ // 16-aligned guest address and the verifier's in-place loads don't trap.
+ let blob = lambda_vm_syscalls::syscalls::get_private_input_slice();
+ lambda_vm_prover::profile_markers::step_marker::<
+ { lambda_vm_prover::profile_markers::STEP_DECODE_DONE },
+ >();
- let ok = lambda_vm_prover::verify_with_options(&vm_proof, &inner_elf, &options, None, None)
- .expect("verify errored");
- assert!(ok, "inner proof failed verification");
+ let verification = lambda_vm_prover::verify_recursion_blob(blob).expect("verify errored");
+ assert!(verification.ok, "inner proof failed verification");
- lambda_vm_syscalls::syscalls::commit(&[1u8]);
+ let mut output = Vec::with_capacity(32 + verification.public_output.len());
+ output.extend_from_slice(&verification.vk_digest);
+ output.extend_from_slice(verification.public_output);
+ lambda_vm_syscalls::syscalls::commit(&output);
lambda_vm_syscalls::syscalls::sys_halt();
}
diff --git a/bin/cli/Cargo.toml b/bin/cli/Cargo.toml
index 87bb1c8fc..c0179c74d 100644
--- a/bin/cli/Cargo.toml
+++ b/bin/cli/Cargo.toml
@@ -9,7 +9,7 @@ executor = { path = "../../executor" }
prover = { path = "../../prover", package = "lambda-vm-prover" }
stark = { path = "../../crypto/stark" }
clap = { version = "4.3.10", features = ["derive"] }
-bincode = "1"
+rkyv = { version = "0.8.10", default-features = false, features = ["alloc", "bytecheck", "aligned"] }
tikv-jemallocator = "0.6"
tikv-jemalloc-ctl = { version = "0.6", features = ["stats"], optional = true }
env_logger = "0.11"
diff --git a/bin/cli/src/main.rs b/bin/cli/src/main.rs
index 2b053755c..cf43863b8 100644
--- a/bin/cli/src/main.rs
+++ b/bin/cli/src/main.rs
@@ -475,7 +475,7 @@ fn cmd_prove(
};
let mut writer = BufWriter::new(file);
- let bytes = match bincode::serialize(&proof) {
+ let bytes = match rkyv::to_bytes::(&proof) {
Ok(b) => b,
Err(e) => {
eprintln!("Failed to serialize proof: {}", e);
@@ -526,7 +526,7 @@ fn cmd_verify(proof_path: PathBuf, elf_path: PathBuf, blowup: u8, time: bool) ->
}
};
- let proof: VmProof = match bincode::deserialize(&proof_bytes) {
+ let proof: VmProof = match rkyv::from_bytes::(&proof_bytes) {
Ok(p) => p,
Err(e) => {
eprintln!("Failed to deserialize proof: {}", e);
@@ -647,7 +647,7 @@ fn cmd_prove_continuation(
}
};
let mut writer = BufWriter::new(file);
- let bytes = match bincode::serialize(&bundle) {
+ let bytes = match rkyv::to_bytes::(&bundle) {
Ok(b) => b,
Err(e) => {
eprintln!("Failed to serialize proof: {}", e);
@@ -693,7 +693,11 @@ fn cmd_verify_continuation(
return ExitCode::FAILURE;
}
};
- let bundle: prover::continuation::ContinuationProof = match bincode::deserialize(&proof_bytes) {
+ let bundle: prover::continuation::ContinuationProof = match rkyv::from_bytes::<
+ prover::continuation::ContinuationProof,
+ rkyv::rancor::Error,
+ >(&proof_bytes)
+ {
Ok(p) => p,
Err(e) => {
eprintln!("Failed to deserialize proof: {}", e);
diff --git a/crypto/crypto/Cargo.toml b/crypto/crypto/Cargo.toml
index 6e3731beb..c8f7bc6a5 100644
--- a/crypto/crypto/Cargo.toml
+++ b/crypto/crypto/Cargo.toml
@@ -22,6 +22,11 @@ rand_chacha = { version = "0.3.1", default-features = false }
memmap2 = { version = "0.9", optional = true }
tempfile = { version = "3", optional = true }
libc = { version = "0.2", optional = true }
+rkyv = { version = "0.8.10", default-features = false, features = [
+ "alloc",
+ "bytecheck",
+ "aligned",
+], optional = true }
[dev-dependencies]
math = { path = "../math", features = ["test-utils"] }
@@ -37,4 +42,5 @@ std = ["math/std", "sha3/std", "serde?/std"]
serde = ["dep:serde"]
parallel = ["dep:rayon"]
disk-spill = ["std", "dep:memmap2", "dep:tempfile", "dep:libc"]
-alloc = []
\ No newline at end of file
+alloc = []
+rkyv = ["dep:rkyv", "math/rkyv"]
\ No newline at end of file
diff --git a/crypto/crypto/src/merkle_tree/proof.rs b/crypto/crypto/src/merkle_tree/proof.rs
index 20d5452a2..2bbcfb3c5 100644
--- a/crypto/crypto/src/merkle_tree/proof.rs
+++ b/crypto/crypto/src/merkle_tree/proof.rs
@@ -15,29 +15,49 @@ use super::{
/// when verifying.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
+#[cfg_attr(
+ feature = "rkyv",
+ derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
+)]
pub struct Proof {
pub merkle_path: Vec,
}
+/// Verifies a Merkle inclusion proof given the authentication path as a borrowed
+/// slice. Shared by [`Proof::verify`] (owned) and the zero-copy verifier (which
+/// reads the path straight from an rkyv-archived proof buffer) so both compute
+/// the identical root.
+pub fn verify_merkle_path(
+ merkle_path: &[B::Node],
+ root_hash: &B::Node,
+ mut index: usize,
+ value: &B::Data,
+) -> bool
+where
+ B: IsMerkleTreeBackend,
+{
+ let mut hashed_value = B::hash_data(value);
+
+ for sibling_node in merkle_path.iter() {
+ if index.is_multiple_of(2) {
+ hashed_value = B::hash_new_parent(&hashed_value, sibling_node);
+ } else {
+ hashed_value = B::hash_new_parent(sibling_node, &hashed_value);
+ }
+
+ index >>= 1;
+ }
+
+ root_hash == &hashed_value
+}
+
impl Proof {
/// Verifies a Merkle inclusion proof for the value contained at leaf index.
- pub fn verify(&self, root_hash: &B::Node, mut index: usize, value: &B::Data) -> bool
+ pub fn verify(&self, root_hash: &B::Node, index: usize, value: &B::Data) -> bool
where
B: IsMerkleTreeBackend,
{
- let mut hashed_value = B::hash_data(value);
-
- for sibling_node in self.merkle_path.iter() {
- if index.is_multiple_of(2) {
- hashed_value = B::hash_new_parent(&hashed_value, sibling_node);
- } else {
- hashed_value = B::hash_new_parent(sibling_node, &hashed_value);
- }
-
- index >>= 1;
- }
-
- root_hash == &hashed_value
+ verify_merkle_path::(&self.merkle_path, root_hash, index, value)
}
}
diff --git a/crypto/math/Cargo.toml b/crypto/math/Cargo.toml
index 85979a7c4..df43ea975 100644
--- a/crypto/math/Cargo.toml
+++ b/crypto/math/Cargo.toml
@@ -23,6 +23,14 @@ rayon = { version = "1.7", optional = true }
num-bigint = { version = "0.4.6", default-features = false }
num-traits = { version = "0.2.19", default-features = false }
+# rkyv zero-copy (de)serialization. Optional; used by the recursion verifier to
+# read a proof straight from its byte buffer with no deserialization pass.
+rkyv = { version = "0.8.10", default-features = false, features = [
+ "alloc",
+ "bytecheck",
+ "aligned",
+], optional = true }
+
[dev-dependencies]
rand_chacha = "0.3.1"
criterion = "0.5.1"
@@ -39,6 +47,7 @@ lambdaworks-serde-string = ["dep:serde", "dep:serde_json", "alloc"]
proptest = ["dep:proptest"]
instruments = []
test-utils = []
+rkyv = ["dep:rkyv"]
[target.wasm32-unknown-unknown.dependencies]
getrandom = { version = "0.2.15", features = ["js"] }
diff --git a/crypto/math/src/field/element.rs b/crypto/math/src/field/element.rs
index 0eb0aef96..d5aa07e57 100644
--- a/crypto/math/src/field/element.rs
+++ b/crypto/math/src/field/element.rs
@@ -850,3 +850,160 @@ impl<'de, F: IsPrimeField> Deserialize<'de> for FieldElement {
deserializer.deserialize_struct("FieldElement", FIELDS, FieldElementVisitor(PhantomData))
}
}
+
+// ============================================================================
+// rkyv zero-copy (de)serialization
+// ============================================================================
+//
+// `FieldElement` is `#[repr(transparent)]` over `F::BaseType`. Its archived
+// form is a local `#[repr(transparent)]` newtype wrapping the archived form of
+// `F::BaseType` (e.g. archived `u64` for Goldilocks, `[ArchivedFieldElement; 3]`
+// for the cubic extension). Keeping it a LOCAL type (rather than reusing
+// `::Archived` directly) is what lets us implement
+// `Deserialize` without colliding with rkyv's blanket impls — while the
+// transparent repr keeps the archived bytes identical to the base type, so the
+// recursion verifier still reads field elements straight from the proof buffer.
+
+/// Archived form of [`FieldElement`]; see the module note above.
+#[cfg(feature = "rkyv")]
+#[repr(transparent)]
+pub struct ArchivedFieldElement
+where
+ F::BaseType: rkyv::Archive,
+{
+ value: ::Archived,
+}
+
+#[cfg(feature = "rkyv")]
+const _: () = {
+ use rkyv::{Archive, Deserialize, Place, Portable, Serialize};
+
+ // SAFETY: `ArchivedFieldElement` is `#[repr(transparent)]` over the base
+ // type's archived form, which is itself `Portable` (required by `Archive`).
+ // A transparent wrapper over a `Portable` type is position-independent and
+ // valid for the same byte patterns, so it is `Portable` too.
+ unsafe impl Portable for ArchivedFieldElement
+ where
+ F: IsField,
+ F::BaseType: Archive,
+ ::Archived: Portable,
+ {
+ }
+
+ impl Archive for FieldElement
+ where
+ F: IsField,
+ F::BaseType: Archive,
+ {
+ type Archived = ArchivedFieldElement;
+ type Resolver = ::Resolver;
+
+ #[inline]
+ fn resolve(&self, resolver: Self::Resolver, out: Place) {
+ // `ArchivedFieldElement` is `#[repr(transparent)]` over the base
+ // type's archived form, so resolving into the inner field resolves
+ // the whole newtype.
+ let inner = unsafe { out.cast_unchecked::<::Archived>() };
+ self.value.resolve(resolver, inner);
+ }
+ }
+
+ impl Serialize for FieldElement
+ where
+ F: IsField,
+ F::BaseType: Serialize,
+ S: rkyv::rancor::Fallible + ?Sized,
+ {
+ #[inline]
+ fn serialize(&self, serializer: &mut S) -> Result {
+ self.value.serialize(serializer)
+ }
+ }
+
+ impl Deserialize, D> for ArchivedFieldElement
+ where
+ F: IsField,
+ F::BaseType: Archive,
+ ::Archived: Deserialize,
+ D: rkyv::rancor::Fallible + ?Sized,
+ {
+ #[inline]
+ fn deserialize(&self, deserializer: &mut D) -> Result, D::Error> {
+ Ok(FieldElement {
+ value: self.value.deserialize(deserializer)?,
+ })
+ }
+ }
+
+ impl ArchivedFieldElement
+ where
+ F: IsField,
+ F::BaseType: Archive,
+ {
+ /// Borrow the archived base-type value (for zero-copy reads).
+ #[inline]
+ pub fn archived_value(&self) -> &::Archived {
+ &self.value
+ }
+ }
+
+ // SAFETY: `#[repr(transparent)]` over the inner archived value, so checking
+ // the inner type's bytes checks the whole newtype.
+ unsafe impl rkyv::bytecheck::CheckBytes for ArchivedFieldElement
+ where
+ F: IsField,
+ F::BaseType: Archive,
+ ::Archived: rkyv::bytecheck::CheckBytes,
+ C: rkyv::rancor::Fallible + ?Sized,
+ {
+ unsafe fn check_bytes(value: *const Self, context: &mut C) -> Result<(), C::Error> {
+ unsafe {
+ <::Archived as rkyv::bytecheck::CheckBytes>::check_bytes(
+ value as *const ::Archived,
+ context,
+ )
+ }
+ }
+ }
+};
+
+// ----------------------------------------------------------------------------
+// Zero-copy native views (little-endian only)
+// ----------------------------------------------------------------------------
+//
+// rkyv archives integers as `rend::*_le` types, which are `#[repr(C, align(N))]`
+// and bit-identical to the native little-endian primitive. `FieldElement` is
+// `#[repr(transparent)]` over `F::BaseType` and `ArchivedFieldElement` is
+// `#[repr(transparent)]` over `::Archived`. So on a
+// little-endian target the two types share size, alignment, and bit layout —
+// an archived field element *is* a native field element. These views let the
+// verifier read field elements straight out of the proof buffer with no copy
+// and no allocation.
+//
+// Restricted to `target_endian = "little"` (the lambda-vm guest target). On a
+// big-endian host these would be wrong, so they simply don't exist there.
+#[cfg(all(feature = "rkyv", target_endian = "little"))]
+impl ArchivedFieldElement
+where
+ F::BaseType: rkyv::Archive,
+{
+ /// Reinterpret this archived element as a native [`FieldElement`] (no copy).
+ ///
+ /// Sound on little-endian: see the module note above.
+ #[inline]
+ pub fn as_native(&self) -> &FieldElement {
+ // SAFETY: identical size/align/bit-layout on little-endian.
+ unsafe { &*(self as *const Self as *const FieldElement) }
+ }
+
+ /// Reinterpret a slice of archived elements as a slice of native
+ /// [`FieldElement`]s (no copy, no allocation).
+ #[inline]
+ pub fn slice_as_native(slice: &[Self]) -> &[FieldElement] {
+ // SAFETY: element-wise identical layout on little-endian, so the slice
+ // (same length, same element stride) reinterprets directly.
+ unsafe {
+ core::slice::from_raw_parts(slice.as_ptr() as *const FieldElement, slice.len())
+ }
+ }
+}
diff --git a/crypto/math/src/field/extensions_goldilocks.rs b/crypto/math/src/field/extensions_goldilocks.rs
index 45fd7274b..feb5c69ed 100644
--- a/crypto/math/src/field/extensions_goldilocks.rs
+++ b/crypto/math/src/field/extensions_goldilocks.rs
@@ -199,6 +199,7 @@ impl IsField for Degree2GoldilocksExtensionField {
}
impl IsSubFieldOf for GoldilocksField {
+ #[inline(always)]
fn mul(
a: &Self::BaseType,
b: &::BaseType,
@@ -208,6 +209,7 @@ impl IsSubFieldOf for GoldilocksField {
[c0, c1]
}
+ #[inline(always)]
fn add(
a: &Self::BaseType,
b: &::BaseType,
@@ -224,6 +226,7 @@ impl IsSubFieldOf for GoldilocksField {
Ok(>::mul(a, &b_inv))
}
+ #[inline(always)]
fn sub(
a: &Self::BaseType,
b: &::BaseType,
@@ -410,6 +413,7 @@ impl IsField for Degree3GoldilocksExtensionField {
}
impl IsSubFieldOf for GoldilocksField {
+ #[inline(always)]
fn mul(
a: &Self::BaseType,
b: &::BaseType,
@@ -420,6 +424,7 @@ impl IsSubFieldOf for GoldilocksField {
[c0, c1, c2]
}
+ #[inline(always)]
fn add(
a: &Self::BaseType,
b: &::BaseType,
@@ -436,6 +441,7 @@ impl IsSubFieldOf for GoldilocksField {
Ok(>::mul(a, &b_inv))
}
+ #[inline(always)]
fn sub(
a: &Self::BaseType,
b: &::BaseType,
diff --git a/crypto/stark/Cargo.toml b/crypto/stark/Cargo.toml
index d0f6a51ef..e205810ae 100644
--- a/crypto/stark/Cargo.toml
+++ b/crypto/stark/Cargo.toml
@@ -9,16 +9,13 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
-math = { path = "../math", features = [
- "std",
- "lambdaworks-serde-binary",
-] }
-crypto = { path = "../crypto", features = ["std", "serde"] }
+math = { path = "../math", features = ["std", "rkyv"] }
+crypto = { path = "../crypto", features = ["std", "rkyv"] }
thiserror = "1.0.38"
log = "0.4.17"
sha3 = "0.10.8"
-serde = { version = "1.0", features = ["derive"] }
itertools = "0.11.0"
+rkyv = { version = "0.8.10", default-features = false, features = ["alloc", "bytecheck", "aligned"] }
# Parallelization crates
rayon = { version = "1.8.0", optional = true }
@@ -32,9 +29,7 @@ math-cuda = { path = "../math-cuda", optional = true }
# wasm
wasm-bindgen = { version = "0.2", optional = true }
-serde-wasm-bindgen = { version = "0.5", optional = true }
web-sys = { version = "0.3.64", features = ['console'], optional = true }
-serde_cbor = { version = "0.11.1" }
[dev-dependencies]
criterion = { version = "0.4", default-features = false }
@@ -48,11 +43,12 @@ rand_chacha = "0.3.1"
test-utils = []
test_fiat_shamir = []
instruments = [] # This enables timing prints in prover and verifier
+profile-markers = [] # Emits inlining-immune asm markers for guest step profiling
debug-checks = [] # Enables validate_trace + bus balance report in prover
parallel = ["dep:rayon", "crypto/parallel"]
cuda = ["dep:math-cuda"]
test-cuda-faults = ["cuda", "math-cuda/test-faults"]
-wasm = ["dep:wasm-bindgen", "dep:serde-wasm-bindgen", "dep:web-sys"]
+wasm = ["dep:wasm-bindgen", "dep:web-sys"]
disk-spill = ["dep:memmap2", "dep:tempfile", "dep:libc", "crypto/disk-spill"]
diff --git a/crypto/stark/src/examples/fibonacci_2_cols_shifted.rs b/crypto/stark/src/examples/fibonacci_2_cols_shifted.rs
index 76c8ea11f..fae17e5ba 100644
--- a/crypto/stark/src/examples/fibonacci_2_cols_shifted.rs
+++ b/crypto/stark/src/examples/fibonacci_2_cols_shifted.rs
@@ -137,7 +137,7 @@ where
}
}
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct PublicInputs
where
F: IsFFTField,
diff --git a/crypto/stark/src/examples/fibonacci_multi_column.rs b/crypto/stark/src/examples/fibonacci_multi_column.rs
index ac6069ece..43efa8566 100644
--- a/crypto/stark/src/examples/fibonacci_multi_column.rs
+++ b/crypto/stark/src/examples/fibonacci_multi_column.rs
@@ -113,7 +113,7 @@ where
/// Public inputs for the multi-column Fibonacci AIR.
/// Contains the initial values (first two elements) for each column.
-#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
+#[derive(Clone, Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct FibonacciMultiColumnPublicInputs {
/// Initial values for each column: (a0, a1) pairs
pub initial_values: Vec<(FieldElement, FieldElement)>,
diff --git a/crypto/stark/src/examples/fibonacci_rap.rs b/crypto/stark/src/examples/fibonacci_rap.rs
index 10f1827d2..9d359bf26 100644
--- a/crypto/stark/src/examples/fibonacci_rap.rs
+++ b/crypto/stark/src/examples/fibonacci_rap.rs
@@ -164,7 +164,7 @@ where
transition_constraints: Vec>>,
}
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct FibonacciRAPPublicInputs
where
F: IsFFTField,
diff --git a/crypto/stark/src/examples/quadratic_air.rs b/crypto/stark/src/examples/quadratic_air.rs
index d49b0050d..6a7fcc3da 100644
--- a/crypto/stark/src/examples/quadratic_air.rs
+++ b/crypto/stark/src/examples/quadratic_air.rs
@@ -81,7 +81,7 @@ where
constraints: Vec>>,
}
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct QuadraticPublicInputs
where
F: IsFFTField,
diff --git a/crypto/stark/src/examples/read_only_memory.rs b/crypto/stark/src/examples/read_only_memory.rs
index 8c3e9efac..eef4b47bc 100644
--- a/crypto/stark/src/examples/read_only_memory.rs
+++ b/crypto/stark/src/examples/read_only_memory.rs
@@ -232,7 +232,7 @@ where
transition_constraints: Vec>>,
}
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct ReadOnlyPublicInputs
where
F: IsFFTField,
diff --git a/crypto/stark/src/examples/read_only_memory_logup.rs b/crypto/stark/src/examples/read_only_memory_logup.rs
index e4f25c16c..3e90dc89d 100644
--- a/crypto/stark/src/examples/read_only_memory_logup.rs
+++ b/crypto/stark/src/examples/read_only_memory_logup.rs
@@ -360,7 +360,7 @@ where
transition_constraints: Vec>>,
}
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct LogReadOnlyPublicInputs
where
F: IsFFTField + Send + Sync,
diff --git a/crypto/stark/src/examples/simple_addition.rs b/crypto/stark/src/examples/simple_addition.rs
index 78f938838..a78e71eb2 100644
--- a/crypto/stark/src/examples/simple_addition.rs
+++ b/crypto/stark/src/examples/simple_addition.rs
@@ -83,7 +83,7 @@ where
constraints: Vec>>,
}
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct SimpleAdditionPublicInputs
where
F: IsFFTField,
diff --git a/crypto/stark/src/examples/simple_fibonacci.rs b/crypto/stark/src/examples/simple_fibonacci.rs
index a39064258..7e7dab641 100644
--- a/crypto/stark/src/examples/simple_fibonacci.rs
+++ b/crypto/stark/src/examples/simple_fibonacci.rs
@@ -82,7 +82,7 @@ where
constraints: Vec>>,
}
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct FibonacciPublicInputs
where
F: IsFFTField,
diff --git a/crypto/stark/src/examples/simple_periodic_cols.rs b/crypto/stark/src/examples/simple_periodic_cols.rs
index 70f5da3b4..0f5b74af8 100644
--- a/crypto/stark/src/examples/simple_periodic_cols.rs
+++ b/crypto/stark/src/examples/simple_periodic_cols.rs
@@ -100,7 +100,7 @@ where
transition_constraints: Vec>>,
}
-#[derive(Clone, Debug)]
+#[derive(Clone, Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct SimplePeriodicPublicInputs
where
F: IsFFTField,
diff --git a/crypto/stark/src/fri/fri_decommit.rs b/crypto/stark/src/fri/fri_decommit.rs
index f398096d5..baab2cd4d 100644
--- a/crypto/stark/src/fri/fri_decommit.rs
+++ b/crypto/stark/src/fri/fri_decommit.rs
@@ -4,8 +4,7 @@ use math::field::traits::IsField;
use crate::config::Commitment;
-#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
-#[serde(bound = "")]
+#[derive(Debug, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct FriDecommitment {
pub layers_auth_paths: Vec>,
pub layers_evaluations_sym: Vec>,
diff --git a/crypto/stark/src/lib.rs b/crypto/stark/src/lib.rs
index 87236c5f9..2b93f41ba 100644
--- a/crypto/stark/src/lib.rs
+++ b/crypto/stark/src/lib.rs
@@ -21,6 +21,7 @@ pub mod grinding;
pub mod instruments;
pub mod lookup;
pub(crate) mod par;
+pub mod profile_markers;
pub mod proof;
pub mod prover;
pub mod r4_denoms;
diff --git a/crypto/stark/src/lookup.rs b/crypto/stark/src/lookup.rs
index 5174bf66c..8404e9ed3 100644
--- a/crypto/stark/src/lookup.rs
+++ b/crypto/stark/src/lookup.rs
@@ -1394,8 +1394,7 @@ impl BusInteraction {
///
/// For the circular constraint, `table_contribution / N` is the per-row offset
/// that makes the accumulated column wrap to zero at row N-1.
-#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
-#[serde(bound = "")]
+#[derive(Debug, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct BusPublicInputs
where
E: IsField,
@@ -1403,20 +1402,45 @@ where
/// Total sum of all LogUp terms across all rows (L).
/// Used for bus balance check and to derive the per-row offset L/N.
pub table_contribution: FieldElement,
- /// Per-bus sums for this table (bus_id → sum) - for debug aggregation
+ /// Per-bus sums for this table (bus_id → sum) - for debug aggregation.
+ /// Debug-only aggregation state; not part of the archived proof (`Skip`).
#[cfg(feature = "debug-checks")]
+ #[rkyv(with = rkyv::with::Skip)]
pub per_bus_sums: HashMap>,
/// Per-bus sender sums (bus_id → sum) - positive contributions
#[cfg(feature = "debug-checks")]
+ #[rkyv(with = rkyv::with::Skip)]
pub per_bus_sender_sums: HashMap>,
/// Per-bus receiver sums (bus_id → sum) - absolute value (before negation)
#[cfg(feature = "debug-checks")]
+ #[rkyv(with = rkyv::with::Skip)]
pub per_bus_receiver_sums: HashMap>,
/// Table name for debug output
#[cfg(feature = "debug-checks")]
+ #[rkyv(with = rkyv::with::Skip)]
pub table_name: String,
}
+impl BusPublicInputs {
+ /// Build a `BusPublicInputs` carrying just the table contribution `L`.
+ /// The debug-only per-bus aggregation fields are defaulted (empty). Used by
+ /// the zero-copy verifier, which reads only `table_contribution` from the
+ /// archived proof.
+ pub fn from_contribution(table_contribution: FieldElement) -> Self {
+ Self {
+ table_contribution,
+ #[cfg(feature = "debug-checks")]
+ per_bus_sums: HashMap::new(),
+ #[cfg(feature = "debug-checks")]
+ per_bus_sender_sums: HashMap::new(),
+ #[cfg(feature = "debug-checks")]
+ per_bus_receiver_sums: HashMap::new(),
+ #[cfg(feature = "debug-checks")]
+ table_name: String::new(),
+ }
+ }
+}
+
/// Trait representing boundary constraint building behaviour.
/// Should be defined when creating an `AirWithBuses` if the AIR requires its own boundary constraints aside from the lookup ones
pub trait BoundaryConstraintBuilder<
diff --git a/crypto/stark/src/profile_markers.rs b/crypto/stark/src/profile_markers.rs
new file mode 100644
index 000000000..570b68641
--- /dev/null
+++ b/crypto/stark/src/profile_markers.rs
@@ -0,0 +1,27 @@
+//! Inlining-immune markers for guest-side step profiling.
+//!
+//! Each marker emits `addi x0, x0, N` on the RISC-V guest: a real instruction
+//! (so it survives inlining and optimization, unlike a removed symbol) that
+//! writes to the zero register and is otherwise a no-op. Real generated code
+//! never emits `addi x0, x0, N` for any nonzero `N` spontaneously (`x0` is
+//! hardwired to zero and writes to it are always discarded), so these values
+//! can't collide with organic instructions. Do not reuse this immediate
+//! encoding space for anything other than step markers.
+//!
+//! Kept separate from the `instruments` feature: `instruments` uses
+//! `std::time::Instant::now()`, which panics on the guest target.
+
+pub const STEP_DECODE_DONE: u32 = 1;
+pub const STEP_AIRS_AND_BUS_BALANCE_DONE: u32 = 2;
+pub const STEP_REPLAY_ROUNDS_AFTER_ROUND_1: u32 = 3;
+pub const STEP_VERIFY_CLAIMED_COMPOSITION_POLYNOMIAL: u32 = 4;
+pub const STEP_VERIFY_FRI: u32 = 5;
+pub const STEP_VERIFY_TRACE_AND_COMPOSITION_OPENINGS: u32 = 6;
+
+#[inline(always)]
+pub fn step_marker() {
+ #[cfg(all(feature = "profile-markers", target_arch = "riscv64"))]
+ unsafe {
+ core::arch::asm!("addi x0, x0, {n}", n = const N);
+ }
+}
diff --git a/crypto/stark/src/proof/options.rs b/crypto/stark/src/proof/options.rs
index 70976b993..2342d5a14 100644
--- a/crypto/stark/src/proof/options.rs
+++ b/crypto/stark/src/proof/options.rs
@@ -39,7 +39,7 @@ impl fmt::Display for ProofOptionsError {
/// - `coset_offset`: the offset for the coset
/// - `grinding_factor`: the number of leading zeros that we want for the Hash(hash || nonce)
#[cfg_attr(feature = "wasm", wasm_bindgen)]
-#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)]
+#[derive(Clone, Debug, PartialEq, Eq, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct ProofOptions {
pub blowup_factor: u8,
pub fri_number_of_queries: usize,
diff --git a/crypto/stark/src/proof/stark.rs b/crypto/stark/src/proof/stark.rs
index 851c0b37a..4229b2bdb 100644
--- a/crypto/stark/src/proof/stark.rs
+++ b/crypto/stark/src/proof/stark.rs
@@ -8,8 +8,7 @@ use crate::{
config::Commitment, fri::fri_decommit::FriDecommitment, lookup::BusPublicInputs, table::Table,
};
-#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
-#[serde(bound = "")]
+#[derive(Debug, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
/// Opening of a bit-reversed, row-paired commitment at one FRI query.
///
/// The queried row and its symmetric counterpart (LDE positions `2·iota`,
@@ -22,8 +21,7 @@ pub struct PolynomialOpenings {
pub evaluations_sym: Vec>,
}
-#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
-#[serde(bound = "")]
+#[derive(Debug, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct DeepPolynomialOpening, E: IsField> {
pub composition_poly: PolynomialOpenings,
pub main_trace_polys: PolynomialOpenings,
@@ -35,8 +33,7 @@ pub struct DeepPolynomialOpening, E: IsField> {
pub type DeepPolynomialOpenings = Vec>;
-#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
-#[serde(bound = "PI: serde::Serialize + serde::de::DeserializeOwned")]
+#[derive(Debug, Clone, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct StarkProof, E: IsField, PI> {
// Length of the execution trace
pub trace_length: usize,
@@ -78,8 +75,7 @@ pub struct StarkProof, E: IsField, PI> {
/// A collection of STARK proofs for multiple AIRs.
/// Used for multi-table proving where tables are linked via bus (LogUp).
/// Returned by `Prover::multi_prove` and verified by `Verifier::multi_verify`.
-#[derive(Debug, serde::Serialize, serde::Deserialize)]
-#[serde(bound = "PI: serde::Serialize + serde::de::DeserializeOwned")]
+#[derive(Debug, rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)]
pub struct MultiProof, E: IsField, PI> {
pub proofs: Vec>,
}
diff --git a/crypto/stark/src/table.rs b/crypto/stark/src/table.rs
index dc188d690..93541c65b 100644
--- a/crypto/stark/src/table.rs
+++ b/crypto/stark/src/table.rs
@@ -41,12 +41,18 @@ impl std::fmt::Debug for TableMmapBacking {
/// the STARK protocol implementation, such as the `TraceTable` and the `EvaluationFrame`.
/// Since this struct is a representation of a two-dimensional table, all rows should have the same
/// length.
-#[derive(Default, Debug, serde::Deserialize)]
+#[derive(Default, Debug)]
#[cfg_attr(
not(feature = "disk-spill"),
- derive(serde::Serialize, Clone, PartialEq, Eq)
+ derive(
+ Clone,
+ PartialEq,
+ Eq,
+ rkyv::Archive,
+ rkyv::Serialize,
+ rkyv::Deserialize
+ )
)]
-#[serde(bound = "")]
pub struct Table {
/// Row-major backing store. Crate-private: external callers must go through
/// the spill-safe accessors (`get`/`get_row`/`set`) rather than indexing the
@@ -55,47 +61,140 @@ pub struct Table {
pub width: usize,
pub height: usize,
#[cfg(feature = "disk-spill")]
- #[serde(skip)]
pub(crate) mmap_backing: Option,
}
+// Manual rkyv impl under disk-spill: the derive can't handle `mmap_backing`,
+// and serialization must read through `row_major_data()` so a spilled table
+// archives its mmap contents (deserializing always yields an unspilled table).
+// The archived layout matches what the derive generates without disk-spill, so
+// both configurations produce byte-identical archives.
#[cfg(feature = "disk-spill")]
-impl serde::Serialize for Table
-where
- FieldElement: serde::Serialize,
-{
- fn serialize(&self, serializer: S) -> Result {
- use serde::ser::SerializeStruct;
- let mut s = serializer.serialize_struct("Table", 3)?;
- if self.mmap_backing.is_some() {
- s.serialize_field("data", &MmapDataSeq(self))?;
- } else {
- s.serialize_field("data", &self.data)?;
+mod archived_table {
+ use super::{FieldElement, IsField, Table};
+ use math::field::element::ArchivedFieldElement;
+ use rkyv::rancor::Fallible;
+ use rkyv::ser::{Allocator, Writer};
+ use rkyv::vec::{ArchivedVec, VecResolver};
+ use rkyv::{Archive, Deserialize, Place, Portable, Serialize};
+
+ #[derive(Portable, rkyv::bytecheck::CheckBytes)]
+ #[bytecheck(crate = rkyv::bytecheck)]
+ #[repr(C)]
+ pub struct ArchivedTable
+ where
+ F::BaseType: Archive,
+ {
+ pub data: ArchivedVec>,
+ pub width: rkyv::primitive::ArchivedUsize,
+ pub height: rkyv::primitive::ArchivedUsize,
+ }
+
+ pub struct TableResolver {
+ data: VecResolver,
+ }
+
+ impl Archive for Table
+ where
+ F::BaseType: Archive,
+ {
+ type Archived = ArchivedTable;
+ type Resolver = TableResolver;
+
+ fn resolve(&self, resolver: Self::Resolver, out: Place) {
+ rkyv::munge::munge!(let ArchivedTable { data, width, height } = out);
+ ArchivedVec::resolve_from_len(self.width * self.height, resolver.data, data);
+ self.width.resolve((), width);
+ self.height.resolve((), height);
+ }
+ }
+
+ impl Serialize for Table
+ where
+ F::BaseType: Archive,
+ FieldElement: Serialize,
+ S: Fallible + Allocator + Writer + ?Sized,
+ {
+ fn serialize(&self, serializer: &mut S) -> Result {
+ Ok(TableResolver {
+ data: ArchivedVec::serialize_from_slice(self.row_major_data(), serializer)?,
+ })
+ }
+ }
+
+ impl Deserialize, D> for ArchivedTable
+ where
+ F::BaseType: Archive,
+ ArchivedFieldElement: Deserialize, D>,
+ D: Fallible + ?Sized,
+ {
+ fn deserialize(&self, deserializer: &mut D) -> Result, D::Error> {
+ Ok(Table {
+ data: self.data.deserialize(deserializer)?,
+ width: self.width.to_native() as usize,
+ height: self.height.to_native() as usize,
+ mmap_backing: None,
+ })
}
- s.serialize_field("width", &self.width)?;
- s.serialize_field("height", &self.height)?;
- s.end()
}
}
#[cfg(feature = "disk-spill")]
-struct MmapDataSeq<'a, F: IsField>(&'a Table);
+pub use archived_table::ArchivedTable;
-#[cfg(feature = "disk-spill")]
-impl serde::Serialize for MmapDataSeq<'_, F>
+/// Read API over an rkyv-archived [`Table`], used by the verifier to consume
+/// the out-of-domain evaluations straight from the proof buffer. On
+/// little-endian targets the element data is viewed in place with no copy.
+#[cfg(target_endian = "little")]
+impl ArchivedTable
where
- FieldElement: serde::Serialize,
+ F::BaseType: rkyv::Archive,
{
- fn serialize(&self, serializer: S) -> Result {
- use serde::ser::SerializeSeq;
- let table = self.0;
- let mut seq = serializer.serialize_seq(Some(table.width * table.height))?;
- for r in 0..table.height {
- for elem in table.get_row(r) {
- seq.serialize_element(elem)?;
- }
- }
- seq.end()
+ #[inline]
+ pub fn width(&self) -> usize {
+ self.width.to_native() as usize
+ }
+
+ #[inline]
+ pub fn height(&self) -> usize {
+ self.height.to_native() as usize
+ }
+
+ /// Full row-major element data, viewed in place.
+ #[inline]
+ pub fn row_major_data(&self) -> &[FieldElement] {
+ math::field::element::ArchivedFieldElement::slice_as_native(self.data.as_slice())
+ }
+
+ /// `true` iff the backing data holds exactly `width × height` elements —
+ /// the invariant `get_row` indexing relies on. A malformed archive can
+ /// advertise dimensions that disagree with the data length; callers must
+ /// reject such tables before row access.
+ #[inline]
+ pub fn dimensions_consistent(&self) -> bool {
+ self.width()
+ .checked_mul(self.height())
+ .is_some_and(|n| n == self.data.len())
+ }
+
+ /// Row `row_idx` as a native field-element slice (no copy).
+ #[inline]
+ pub fn get_row(&self, row_idx: usize) -> &[FieldElement] {
+ let width = self.width();
+ let start = row_idx * width;
+ &self.row_major_data()[start..start + width]
+ }
+
+ /// Build a [`Frame`] over this table, identical to [`Table::into_frame`].
+ /// Only the small OOD frame is materialized (bounded by `step_size × width`),
+ /// never the whole proof.
+ pub fn into_frame(&self, main_trace_columns: usize, step_size: usize) -> Frame
+ where
+ F: IsSubFieldOf,
+ {
+ frame_from_rows(self.height(), step_size, main_trace_columns, |row_idx| {
+ self.get_row(row_idx)
+ })
}
}
@@ -361,29 +460,49 @@ impl Table {
/// Given a step size, converts the given table into a `Frame`.
/// Clones row data into owned Vecs (only used by verifier on small OOD tables).
pub fn into_frame(&self, main_trace_columns: usize, step_size: usize) -> Frame {
- debug_assert!(self.height.is_multiple_of(step_size));
- let steps = (0..self.height)
- .step_by(step_size)
- .map(|initial_row_idx| {
- let end_row_idx = initial_row_idx + step_size;
-
- let mut step_main_data: Vec>> = Vec::new();
- let mut step_aux_data: Vec>> = Vec::new();
-
- (initial_row_idx..end_row_idx).for_each(|row_idx| {
- let row = self.get_row(row_idx);
- step_main_data.push(row[..main_trace_columns].to_vec());
- step_aux_data.push(row[main_trace_columns..].to_vec());
- });
-
- TableView::new(step_main_data, step_aux_data)
- })
- .collect();
-
- Frame::new(steps)
+ frame_from_rows(self.height, step_size, main_trace_columns, |row_idx| {
+ self.get_row(row_idx)
+ })
}
}
+/// Build a [`Frame`] from `height` rows accessed via `get_row`, splitting each
+/// row at `main_trace_columns` into main/aux. Shared by [`Table::into_frame`]
+/// and the zero-copy `OodTableRef::into_frame` so both produce identical frames.
+///
+/// Only the small out-of-domain frame is materialized here (bounded by
+/// `step_size × width`), never the full trace.
+pub fn frame_from_rows<'a, F>(
+ height: usize,
+ step_size: usize,
+ main_trace_columns: usize,
+ get_row: impl Fn(usize) -> &'a [FieldElement],
+) -> Frame
+where
+ F: IsSubFieldOf + IsField + 'a,
+{
+ debug_assert!(height.is_multiple_of(step_size));
+ let steps = (0..height)
+ .step_by(step_size)
+ .map(|initial_row_idx| {
+ let end_row_idx = initial_row_idx + step_size;
+
+ let mut step_main_data: Vec>> = Vec::new();
+ let mut step_aux_data: Vec>> = Vec::new();
+
+ (initial_row_idx..end_row_idx).for_each(|row_idx| {
+ let row = get_row(row_idx);
+ step_main_data.push(row[..main_trace_columns].to_vec());
+ step_aux_data.push(row[main_trace_columns..].to_vec());
+ });
+
+ TableView::new(step_main_data, step_aux_data)
+ })
+ .collect();
+
+ Frame::new(steps)
+}
+
/// A view of a contiguous subset of rows of a table.
///
/// Owns its row data (Vec per row) so it can be built from either row-major Tables
diff --git a/crypto/stark/src/tests/bus_tests/completeness_tests.rs b/crypto/stark/src/tests/bus_tests/completeness_tests.rs
index 83f8ac391..51f6ef50c 100644
--- a/crypto/stark/src/tests/bus_tests/completeness_tests.rs
+++ b/crypto/stark/src/tests/bus_tests/completeness_tests.rs
@@ -377,9 +377,10 @@ fn test_serialization_roundtrip() {
multi_prove_ram(air_trace_pairs, &mut DefaultTranscript::::new(&[])).unwrap();
// Serialize and deserialize
- let serialized = serde_cbor::to_vec(&multi_proof).expect("serialization failed");
+ let serialized =
+ rkyv::to_bytes::(&multi_proof).expect("serialization failed");
let deserialized: crate::proof::stark::MultiProof =
- serde_cbor::from_slice(&serialized).expect("deserialization failed");
+ rkyv::from_bytes::<_, rkyv::rancor::Error>(&serialized).expect("deserialization failed");
let airs: Vec<&dyn AIR> =
vec![&cpu_air, &add_air, &mul_air];
diff --git a/crypto/stark/src/tests/prove_verify_roundtrip_tests.rs b/crypto/stark/src/tests/prove_verify_roundtrip_tests.rs
index 4059ed481..032e68ea1 100644
--- a/crypto/stark/src/tests/prove_verify_roundtrip_tests.rs
+++ b/crypto/stark/src/tests/prove_verify_roundtrip_tests.rs
@@ -142,13 +142,14 @@ fn test_verify_serialized_multi_table_proofs() {
// NETWORK TRANSMISSION - Serialize and deserialize (using CBOR binary format)
// =========================================================================
- let serialized = serde_cbor::to_vec(&proofs).expect("Failed to serialize proofs");
+ let serialized =
+ rkyv::to_bytes::(&proofs).expect("Failed to serialize proofs");
// At this point, the prover's data is dropped (out of scope above)
// The verifier only has the serialized data
let received_proofs: MultiProof =
- serde_cbor::from_slice(&serialized).expect("Failed to deserialize proofs");
+ rkyv::from_bytes::<_, rkyv::rancor::Error>(&serialized).expect("Failed to deserialize proofs");
// =========================================================================
// VERIFIER SIDE - Reconstruct AIRs and verify
diff --git a/crypto/stark/src/verifier.rs b/crypto/stark/src/verifier.rs
index 03119f617..0cf5eb460 100644
--- a/crypto/stark/src/verifier.rs
+++ b/crypto/stark/src/verifier.rs
@@ -1,7 +1,7 @@
use super::{
config::BatchedMerkleTreeBackend,
domain::VerifierDomain,
- fri::fri_decommit::FriDecommitment,
+ fri::fri_decommit::ArchivedFriDecommitment,
grinding,
proof::stark::StarkProof,
traits::{AIR, TransitionEvaluationContext},
@@ -9,10 +9,15 @@ use super::{
use crate::{
config::Commitment,
domain::new_verifier_domain,
- lookup::{LOGUP_CHALLENGE_ALPHA, LOGUP_NUM_CHALLENGES, PackingShifts, compute_alpha_powers},
- proof::stark::{DeepPolynomialOpening, MultiProof, PolynomialOpenings},
+ lookup::{BusPublicInputs, LOGUP_CHALLENGE_ALPHA, LOGUP_NUM_CHALLENGES, PackingShifts, compute_alpha_powers},
+ proof::stark::{
+ ArchivedDeepPolynomialOpening, ArchivedMultiProof, ArchivedPolynomialOpenings,
+ ArchivedStarkProof, MultiProof,
+ },
};
-use crypto::{fiat_shamir::is_transcript::IsStarkTranscript, merkle_tree::proof::Proof};
+use crypto::fiat_shamir::is_transcript::IsStarkTranscript;
+use crypto::merkle_tree::proof::verify_merkle_path;
+use math::field::element::ArchivedFieldElement;
#[cfg(not(feature = "test_fiat_shamir"))]
use log::error;
#[cfg(feature = "debug-checks")]
@@ -44,6 +49,11 @@ impl<
FieldExtension: IsField + Send + Sync,
PI,
> IsStarkVerifier for Verifier
+where
+ Field::BaseType: rkyv::Archive,
+ FieldExtension::BaseType: rkyv::Archive,
+ PI: rkyv::Archive,
+ ::Archived: rkyv::Deserialize,
{
}
@@ -75,6 +85,23 @@ where
pub type DeepPolynomialEvaluations = (Vec>, Vec>);
+// The verifier reads proofs in place from their rkyv archive; archived field
+// elements are viewed as native ones, which is only valid on little-endian.
+#[cfg(not(target_endian = "little"))]
+compile_error!("the zero-copy STARK verifier requires a little-endian target");
+
+/// Deserializer used to materialize the (tiny) per-proof `PI` public inputs.
+pub type PiDeserializer = rkyv::api::high::HighDeserializer;
+
+/// `&[FieldElement]` view over an archived field-element vector (no copy).
+#[inline]
+fn evals(v: &rkyv::vec::ArchivedVec>) -> &[FieldElement]
+where
+ G::BaseType: rkyv::Archive,
+{
+ ArchivedFieldElement::slice_as_native(v.as_slice())
+}
+
/// The functionality of a STARK verifier providing methods to run the STARK Verify protocol
/// https://lambdaclass.github.io/lambdaworks/starks/protocol.html
pub trait IsStarkVerifier<
@@ -82,6 +109,11 @@ pub trait IsStarkVerifier<
FieldExtension: Send + Sync + IsField,
PI,
>
+where
+ Field::BaseType: rkyv::Archive,
+ FieldExtension::BaseType: rkyv::Archive,
+ PI: rkyv::Archive,
+ ::Archived: rkyv::Deserialize,
{
fn sample_query_indexes(
number_of_queries: usize,
@@ -99,15 +131,25 @@ pub trait IsStarkVerifier<
/// See https://lambdaclass.github.io/lambdaworks/starks/protocol.html#step-2-verify-claimed-composition-polynomial
fn step_2_verify_claimed_composition_polynomial(
air: &dyn AIR,
- proof: &StarkProof,
+ proof: &ArchivedStarkProof,
+ public_inputs: &PI,
domain: &VerifierDomain,
challenges: &Challenges,
) -> bool {
- let trace_length = proof.trace_length;
+ crate::profile_markers::step_marker::<
+ { crate::profile_markers::STEP_VERIFY_CLAIMED_COMPOSITION_POLYNOMIAL },
+ >();
+ let trace_length = proof.trace_length.to_native() as usize;
+ // Owned `BusPublicInputs` (just the table contribution L — one field
+ // element) reconstructed from the archive for the AIR boundary call.
+ let bus_public_inputs = proof
+ .bus_public_inputs
+ .as_ref()
+ .map(|bpi| BusPublicInputs::from_contribution(bpi.table_contribution.as_native().clone()));
let boundary_constraints = air.boundary_constraints(
- &proof.public_inputs,
+ public_inputs,
&challenges.rap_challenges,
- proof.bus_public_inputs.as_ref(),
+ bus_public_inputs.as_ref(),
trace_length,
);
// Precompute g^step once per distinct step to avoid the prior O(B^2)
@@ -170,8 +212,16 @@ pub trait IsStarkVerifier<
.map(|poly| poly.evaluate(&challenges.z))
.collect::>>();
- let num_main_trace_columns =
- proof.trace_ood_evaluations.width - air.num_auxiliary_rap_columns();
+ // A malformed archive can advertise fewer OOD columns than the AIR's
+ // aux count; reject instead of underflowing.
+ let num_main_trace_columns = match proof
+ .trace_ood_evaluations
+ .width()
+ .checked_sub(air.num_auxiliary_rap_columns())
+ {
+ Some(n) => n,
+ None => return false,
+ };
let logup_alpha_powers: Vec> =
if challenges.rap_challenges.len() > LOGUP_CHALLENGE_ALPHA {
@@ -183,11 +233,11 @@ pub trait IsStarkVerifier<
Vec::new()
};
- let logup_table_offset = match &proof.bus_public_inputs {
+ let logup_table_offset = match proof.bus_public_inputs.as_ref() {
Some(bpi) => {
let n = FieldElement::::from(trace_length as u64);
match n.inv() {
- Ok(n_inv) => n_inv * &bpi.table_contribution,
+ Ok(n_inv) => n_inv * bpi.table_contribution.as_native(),
Err(_) => return false, // trace_length == 0 is invalid
}
}
@@ -227,8 +277,7 @@ pub trait IsStarkVerifier<
let composition_poly_ood_evaluation =
&boundary_quotient_ood_evaluation + transition_c_i_evaluations_sum;
- let composition_poly_claimed_ood_evaluation = proof
- .composition_poly_parts_ood_evaluation
+ let composition_poly_claimed_ood_evaluation = evals(&proof.composition_poly_parts_ood_evaluation)
.iter()
.rev()
.fold(FieldElement::zero(), |acc, coeff| {
@@ -242,7 +291,7 @@ pub trait IsStarkVerifier<
/// openings of the trace polynomials and the composition polynomial parts. It then uses these to verify that the
/// FRI decommitments are valid and correspond to the Deep composition polynomial.
fn step_3_verify_fri(
- proof: &StarkProof,
+ proof: &ArchivedStarkProof,
domain: &VerifierDomain,
challenges: &Challenges,
) -> bool
@@ -250,6 +299,7 @@ pub trait IsStarkVerifier<
FieldElement: AsBytes + Sync + Send,
FieldElement: AsBytes + Sync + Send,
{
+ crate::profile_markers::step_marker::<{ crate::profile_markers::STEP_VERIFY_FRI }>();
let (deep_poly_evaluations, deep_poly_evaluations_sym) =
match Self::reconstruct_deep_composition_poly_evaluations_for_all_queries(
challenges, domain, proof,
@@ -271,6 +321,7 @@ pub trait IsStarkVerifier<
proof
.query_list
+ .as_slice()
.iter()
.zip(&challenges.iotas)
.zip(evaluation_point_inverse)
@@ -307,7 +358,7 @@ pub trait IsStarkVerifier<
/// `evaluations ‖ evaluations_sym` and verify once. (Same as the composition
/// opening check.)
fn verify_opening_pair(
- opening: &PolynomialOpenings,
+ opening: &ArchivedPolynomialOpenings,
root: &Commitment,
iota: usize,
) -> bool
@@ -315,20 +366,24 @@ pub trait IsStarkVerifier<
FieldElement: AsBytes + Sync + Send,
FieldElement: AsBytes + Sync + Send,
E: IsField,
+ E::BaseType: rkyv::Archive,
Field: IsSubFieldOf,
{
- let mut value = opening.evaluations.clone();
- value.extend_from_slice(&opening.evaluations_sym);
- opening
- .proof
- .verify::>(root, iota, &value)
+ let mut value = evals(&opening.evaluations).to_vec();
+ value.extend_from_slice(evals(&opening.evaluations_sym));
+ verify_merkle_path::>(
+ opening.proof.merkle_path.as_slice(),
+ root,
+ iota,
+ &value,
+ )
}
/// Verify opening Open(tⱼ(D_LDE), 𝜐) and Open(tⱼ(D_LDE), -𝜐) for all trace polynomials tⱼ,
/// where 𝜐 and -𝜐 are the elements corresponding to the index challenge `iota`.
fn verify_trace_openings(
- proof: &StarkProof,
- deep_poly_openings: &DeepPolynomialOpening,
+ proof: &ArchivedStarkProof,
+ deep_poly_openings: &ArchivedDeepPolynomialOpening,
iota: usize,
) -> bool
where
@@ -346,8 +401,8 @@ pub trait IsStarkVerifier<
// unreachable in practice (multi_verify rejects such proofs upstream),
// but a defensive check keeps this function self-contained.
ok &= match (
- &proof.lde_trace_precomputed_merkle_root,
- &deep_poly_openings.precomputed_trace_polys,
+ proof.lde_trace_precomputed_merkle_root.as_ref(),
+ deep_poly_openings.precomputed_trace_polys.as_ref(),
) {
(Some(root), Some(opening)) => Self::verify_opening_pair::(opening, root, iota),
(None, None) => true,
@@ -356,11 +411,11 @@ pub trait IsStarkVerifier<
// Auxiliary trace.
ok &= match (
- proof.lde_trace_aux_merkle_root,
- &deep_poly_openings.aux_trace_polys,
+ proof.lde_trace_aux_merkle_root.as_ref(),
+ deep_poly_openings.aux_trace_polys.as_ref(),
) {
(Some(root), Some(opening)) => {
- Self::verify_opening_pair::(opening, &root, iota)
+ Self::verify_opening_pair::(opening, root, iota)
}
(None, None) => true,
_ => false,
@@ -372,7 +427,7 @@ pub trait IsStarkVerifier<
/// Verify opening Open(Hᵢ(D_LDE), 𝜐) and Open(Hᵢ(D_LDE), -𝜐) for all parts Hᵢof the composition
/// polynomial, where 𝜐 and -𝜐 are the elements corresponding to the index challenge `iota`.
fn verify_composition_poly_opening(
- deep_poly_openings: &DeepPolynomialOpening,
+ deep_poly_openings: &ArchivedDeepPolynomialOpening,
composition_poly_merkle_root: &Commitment,
iota: &usize,
) -> bool
@@ -380,34 +435,35 @@ pub trait IsStarkVerifier<
FieldElement: AsBytes + Sync + Send,
FieldElement: AsBytes + Sync + Send,
{
- let mut value = deep_poly_openings.composition_poly.evaluations.clone();
- value.extend_from_slice(&deep_poly_openings.composition_poly.evaluations_sym);
-
- deep_poly_openings
- .composition_poly
- .proof
- .verify::>(
- composition_poly_merkle_root,
- *iota,
- &value,
- )
+ let mut value = evals(&deep_poly_openings.composition_poly.evaluations).to_vec();
+ value.extend_from_slice(evals(&deep_poly_openings.composition_poly.evaluations_sym));
+
+ verify_merkle_path::>(
+ deep_poly_openings.composition_poly.proof.merkle_path.as_slice(),
+ composition_poly_merkle_root,
+ *iota,
+ &value,
+ )
}
/// Verifies the validity of the purported values of the trace polynomials and the composition polynomial
/// parts at the domain elements and their symmetric counterparts corresponding to all the FRI query
/// index challenges.
fn step_4_verify_trace_and_composition_openings(
- proof: &StarkProof,
+ proof: &ArchivedStarkProof,
challenges: &Challenges,
) -> bool
where
FieldElement: AsBytes + Sync + Send,
FieldElement: AsBytes + Sync + Send,
{
+ crate::profile_markers::step_marker::<
+ { crate::profile_markers::STEP_VERIFY_TRACE_AND_COMPOSITION_OPENINGS },
+ >();
challenges
.iotas
.iter()
- .zip(&proof.deep_poly_openings)
+ .zip(proof.deep_poly_openings.as_slice())
.all(|(iota_n, deep_poly_opening)| {
Self::verify_composition_poly_opening(
deep_poly_opening,
@@ -420,7 +476,7 @@ pub trait IsStarkVerifier<
/// Verifies the openings of a fold polynomial of an inner layer of FRI.
fn verify_fri_layer_openings(
merkle_root: &Commitment,
- auth_path_sym: &Proof,
+ auth_path_sym: &[Commitment],
evaluation: &FieldElement,
evaluation_sym: &FieldElement,
iota: usize,
@@ -435,7 +491,8 @@ pub trait IsStarkVerifier<
vec![evaluation.clone(), evaluation_sym.clone()]
};
- auth_path_sym.verify::>(
+ verify_merkle_path::>(
+ auth_path_sym,
merkle_root,
iota >> 1,
&evaluations,
@@ -451,10 +508,10 @@ pub trait IsStarkVerifier<
/// `deep_composition_evaluation`: precomputed value of p₀(𝜐), where p₀ is the deep composition polynomial.
/// `deep_composition_evaluation_sym`: precomputed value of p₀(-𝜐), where p₀ is the deep composition polynomial.
fn verify_query_and_sym_openings(
- proof: &StarkProof,
+ proof: &ArchivedStarkProof,
zetas: &[FieldElement],
iota: usize,
- fri_decommitment: &FriDecommitment,
+ fri_decommitment: &ArchivedFriDecommitment,
evaluation_point_inv: FieldElement,
deep_composition_evaluation: &FieldElement,
deep_composition_evaluation_sym: &FieldElement,
@@ -463,7 +520,19 @@ pub trait IsStarkVerifier<
FieldElement: AsBytes + Sync + Send,
FieldElement: AsBytes + Sync + Send,
{
- let fri_layers_merkle_roots = &proof.fri_layers_merkle_roots;
+ let fri_layers_merkle_roots = proof.fri_layers_merkle_roots.as_slice();
+ let fri_last_value = proof.fri_last_value.as_native();
+
+ // The three per-layer vectors must line up with the committed roots:
+ // the fold below iterates their zip (min length) and only compares the
+ // final value on the last evaluation index, so an over-long
+ // `layers_evaluations_sym` would otherwise skip the `fri_last_value`
+ // check entirely.
+ if fri_decommitment.layers_auth_paths.len() != fri_layers_merkle_roots.len()
+ || fri_decommitment.layers_evaluations_sym.len() != fri_layers_merkle_roots.len()
+ {
+ return false;
+ }
let evaluation_point_vec: Vec> =
core::iter::successors(Some(evaluation_point_inv.square()), |evaluation_point| {
Some(evaluation_point.square())
@@ -483,7 +552,7 @@ pub trait IsStarkVerifier<
// In this case, the fold loop below doesn't iterate, so we need to verify
// the final value directly here.
if fri_layers_merkle_roots.is_empty() {
- return v == proof.fri_last_value;
+ return v == *fri_last_value;
}
// For each FRI layer, starting from the layer 1: use the proof to verify the validity of values pᵢ(−𝜐^(2ⁱ)) (given by the prover) and
@@ -492,8 +561,8 @@ pub trait IsStarkVerifier<
fri_layers_merkle_roots
.iter()
.enumerate()
- .zip(&fri_decommitment.layers_auth_paths)
- .zip(&fri_decommitment.layers_evaluations_sym)
+ .zip(fri_decommitment.layers_auth_paths.as_slice())
+ .zip(evals(&fri_decommitment.layers_evaluations_sym))
.zip(evaluation_point_vec)
.fold(
true,
@@ -507,7 +576,7 @@ pub trait IsStarkVerifier<
// `evaluation_sym` is pᵢ(−𝜐^(2ⁱ)).
let openings_ok = Self::verify_fri_layer_openings(
merkle_root,
- auth_path_sym,
+ auth_path_sym.merkle_path.as_slice(),
&v,
evaluation_sym,
index,
@@ -525,7 +594,7 @@ pub trait IsStarkVerifier<
result & openings_ok
} else {
// Check that final value is the given by the prover
- result & (v == proof.fri_last_value) & openings_ok
+ result & (v == *fri_last_value) & openings_ok
}
},
)
@@ -534,8 +603,13 @@ pub trait IsStarkVerifier<
fn reconstruct_deep_composition_poly_evaluations_for_all_queries(
challenges: &Challenges,
domain: &VerifierDomain,
- proof: &StarkProof,
+ proof: &ArchivedStarkProof,
) -> Option> {
+ // A malformed proof can carry fewer openings than query challenges;
+ // reject instead of panicking on the indexed access below.
+ if proof.deep_poly_openings.len() < challenges.iotas.len() {
+ return None;
+ }
let num_queries = challenges.iotas.len();
let mut deep_poly_evaluations = Vec::with_capacity(num_queries);
let mut deep_poly_evaluations_sym = Vec::with_capacity(num_queries);
@@ -547,78 +621,103 @@ pub trait IsStarkVerifier<
.expect("verifier domain root_order is a valid power of two");
for (i, iota) in challenges.iotas.iter().enumerate() {
- let opening = &proof.deep_poly_openings[i];
+ let opening = &proof.deep_poly_openings.as_slice()[i];
// Base-field portion: precomputed columns FIRST, then main trace columns.
let mut lde_base: Vec> = Vec::new();
- if let Some(p) = &opening.precomputed_trace_polys {
- lde_base.extend_from_slice(&p.evaluations);
+ if let Some(p) = opening.precomputed_trace_polys.as_ref() {
+ lde_base.extend_from_slice(evals(&p.evaluations));
}
- lde_base.extend_from_slice(&opening.main_trace_polys.evaluations);
+ lde_base.extend_from_slice(evals(&opening.main_trace_polys.evaluations));
let lde_aux: &[FieldElement] = opening
.aux_trace_polys
.as_ref()
- .map(|a| a.evaluations.as_slice())
+ .map(|a| evals(&a.evaluations))
.unwrap_or(&[]);
- let evaluation_point = Self::query_challenge_to_evaluation_point(*iota, false, domain);
- deep_poly_evaluations.push(Self::reconstruct_deep_composition_poly_evaluation(
- proof,
- &evaluation_point,
- primitive_root,
- challenges,
- &lde_base,
- lde_aux,
- &opening.composition_poly.evaluations,
- )?);
-
- // Mirror for the symmetric query point.
let mut lde_base_sym: Vec> = Vec::new();
- if let Some(p) = &opening.precomputed_trace_polys {
- lde_base_sym.extend_from_slice(&p.evaluations_sym);
+ if let Some(p) = opening.precomputed_trace_polys.as_ref() {
+ lde_base_sym.extend_from_slice(evals(&p.evaluations_sym));
}
- lde_base_sym.extend_from_slice(&opening.main_trace_polys.evaluations_sym);
+ lde_base_sym.extend_from_slice(evals(&opening.main_trace_polys.evaluations_sym));
let lde_aux_sym: &[FieldElement] = opening
.aux_trace_polys
.as_ref()
- .map(|a| a.evaluations_sym.as_slice())
+ .map(|a| evals(&a.evaluations_sym))
.unwrap_or(&[]);
- let evaluation_point = Self::query_challenge_to_evaluation_point(*iota, true, domain);
- deep_poly_evaluations_sym.push(Self::reconstruct_deep_composition_poly_evaluation(
- proof,
- &evaluation_point,
- primitive_root,
- challenges,
- &lde_base_sym,
- lde_aux_sym,
- &opening.composition_poly.evaluations_sym,
- )?);
+ let evaluation_point = Self::query_challenge_to_evaluation_point(*iota, false, domain);
+ let evaluation_point_sym =
+ Self::query_challenge_to_evaluation_point(*iota, true, domain);
+ let (evaluation, evaluation_sym) =
+ Self::reconstruct_deep_composition_poly_evaluation_pair(
+ proof,
+ &evaluation_point,
+ &evaluation_point_sym,
+ primitive_root,
+ challenges,
+ &lde_base,
+ lde_aux,
+ evals(&opening.composition_poly.evaluations),
+ &lde_base_sym,
+ lde_aux_sym,
+ evals(&opening.composition_poly.evaluations_sym),
+ )?;
+ deep_poly_evaluations.push(evaluation);
+ deep_poly_evaluations_sym.push(evaluation_sym);
}
Some((deep_poly_evaluations, deep_poly_evaluations_sym))
}
- fn reconstruct_deep_composition_poly_evaluation(
- proof: &StarkProof,
+ /// Reconstructs the deep composition polynomial evaluation at a query's
+ /// evaluation point and its symmetric counterpart in one traversal. The
+ /// OOD table walk and `trace_term_coeffs` walk are shared between the two
+ /// (they don't depend on the evaluation point), halving the loads and
+ /// letting the two `denoms_trace` vectors, and the two composition-tail
+ /// denominators, share a single batch-inverse call each.
+ ///
+ /// Algebraic rewrite of the per-element trace term: for column `col` and
+ /// row `row`,
+ /// coeff(col,row) * (base(col) - ood(row,col)) * denom(row)
+ /// distributes to
+ /// denom(row) * (coeff(col,row) * base(col) - coeff(col,row) * ood(row,col)).
+ /// Summing over `col` first isolates `coeff * ood`, which is identical for
+ /// both evaluation points, from `coeff * base`, which differs; and moves
+ /// the `denom(row)` multiplication (ext * ext) out of the column loop.
+ fn reconstruct_deep_composition_poly_evaluation_pair(
+ proof: &ArchivedStarkProof,
evaluation_point: &FieldElement,
+ evaluation_point_sym: &FieldElement,
primitive_root: &FieldElement