aere-docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md
Aere Network e4cead319d Initial public release
Aere Network public source. Everything here can be checked against the live
chain (chain id 2800, https://rpc.aere.network).

Scope note, stated up front rather than buried: consensus on chain 2800 is
classical secp256k1 ECDSA QBFT. The post-quantum work in this repository is at
the signature, precompile, account and transport layers. Nothing here makes the
consensus post-quantum, and no document in it should be read as claiming so.
2026-07-20 01:01:36 +03:00

475 lines
32 KiB
Markdown

# AERE STARK verifier: SP1-recursion AIR port specification (precompile 0x0AE8, part 2)
Spec date: 2026-07-19
Status: RESEARCH + PORTING PLAN, not an implementation. This document scopes the ONE remaining
crypto-core piece of the native STARK-verify port (the SP1-recursion-specific constraint system and
its verifying key) against the REAL, pinned SP1 source. It does NOT port it. The top-level precompile
0x0AE8 stays fail-closed and is not touched by this document.
Companion: `docs/AERE-STARK-VERIFIER-PORT-SPEC.md` (the six generic components + their confirmed
status), `docs/PQ-STARK-VERIFIER-PRECOMPILE-2026-07-18.md` (design/encoding/gas),
`docs/PQ-STARK-VERIFIER-ACTIVATION-2026-07-18.md` (gated activation).
Citations use the pinned upstream tag `v6.1.0` (commit `d454975ac7c1126097e36eceda9bce2cb9899da4`,
github.com/succinctlabs/sp1). `[VERIFY]` marks a value or convention not read byte-exact from source in
this pass. `[MEASURE]` marks a validation that needs the compiled SP1 toolchain and a real proof.
---
## 0. Headline finding (read first): the pinned SP1 6.1.0 is Hypercube, not Turbo
This research turned up a correctness finding that changes the scope of the remaining work, so it goes
first and plainly.
The generic-component work in the companion spec was implemented and conformance-confirmed against
Plonky3 `0.4.3-succinct`: the BabyBear field, Poseidon2-over-BabyBear, a Merkle/MMCS, the FRI low-degree
test, a `p3-uni-stark` DEEP-ALI quotient check, and a `p3-challenger` duplex transcript. That is a
faithful BabyBear + FRI + univariate-STARK verifier skeleton, and it is real.
It is, however, the WRONG proof system for the version of SP1 that Aere actually pins. SP1 `=6.1.0`
(pinned in `rollup-evm-validity/host/Cargo.toml`, `rollup-evm-validity/guest/Cargo.toml`,
`batch-prover-recovered/bin/aere-prover/Cargo.toml`, all `sp1-sdk`/`sp1-prover`/`sp1-verifier`/`sp1-zkvm`
`= "=6.1.0"`) is an SP1 Hypercube release. Its proving stack is not AIR + FRI. It is a multilinear
system: KoalaBear field, a BaseFold + Stacked + Jagged polynomial commitment scheme, a sumcheck-based
constraint check (zerocheck), and a LogUp-GKR interaction argument with a degree-7 septic-curve global
cumulative digest. There is no BabyBear `ShardProof<BabyBearPoseidon2>` and no FRI low-degree test
anywhere in the SP1 6.1.0 proof that 0x0AE8 would verify.
Evidence, from both upstream source and the repo's own resolved lockfiles:
- Upstream `Cargo.toml` at tag v6.1.0 (`workspace.package.version = "6.1.0"`) lists workspace members
`slop/crates/{jagged, whir, basefold, sumcheck, multilinear, stacked, tensor, koala-bear, ...}` and
`sp1-gpu/crates/{jagged_sumcheck, logup_gkr, zerocheck, ...}`, and pins Plonky3 at `0.3.2-succinct`.
Source: https://github.com/succinctlabs/sp1/blob/v6.1.0/Cargo.toml
- `crates/primitives/src/lib.rs` defines `pub type SP1Field = KoalaBear;` and
`pub type SP1ExtensionField = BinomialExtensionField<SP1Field, 4>;` with `SP1GlobalContext =
KoalaBearDegree4Duplex` (Poseidon2 width 16, 30 total rounds).
Source: https://github.com/succinctlabs/sp1/blob/v6.1.0/crates/primitives/src/lib.rs
- `crates/prover/src/recursion.rs` builds the compress/shrink/wrap recursion verifiers from
`RecursiveBasefoldVerifier` + `RecursiveMerkleTreeTcs` + `RecursiveStackedPcsVerifier` +
`RecursiveJaggedPcsVerifier` over `SP1Field`. There is no FRI verifier in that path.
Source: https://github.com/succinctlabs/sp1/blob/v6.1.0/crates/prover/src/recursion.rs
- The repo's OWN resolved lock `rollup-evm-validity/host/Cargo.lock` (the crate that pins SP1 `=6.1.0`)
resolves `sp1-sdk 6.1.0`, `sp1-prover 6.1.0`, `sp1-verifier 6.1.0` on top of `sp1-hypercube 6.3.1`,
`sp1-recursion-machine 6.3.1`, `sp1-recursion-executor 6.3.1`, `slop-basefold 6.3.1`,
`slop-jagged 6.3.1`, `slop-multilinear 6.3.1`, `slop-sumcheck 6.3.1`. The SP1 6.1.0 facade crates sit
on the 6.3.1 Hypercube internals. The `p3-* 0.4.3-succinct` entries in the same lock (including
`p3-koala-bear`, `p3-fri`, `p3-uni-stark`) are Aere's own separate Plonky3 circuits' dependencies
(`zk-circuits/*`, the recursive-aggregation / zkml / attr provers), not the SP1 recursion proof.
Consequence for scope. The remaining work is not "add the SP1 AIR on top of a finished FRI skeleton."
It is "build a KoalaBear multilinear (BaseFold + Jagged + sumcheck + LogUp-GKR) machine verifier and
then add the SP1 recursion machine's chips on top." Of the six confirmed generic components, only the
SHAPES of three carry over (Poseidon2 sponge, Merkle tree, duplex challenger), and even those need the
KoalaBear field and the KoalaBear Poseidon2 constants. The two largest confirmed pieces, the FRI
low-degree test and the DEEP-ALI univariate quotient check, are not used by SP1 6.1.0 at all; they are
replaced by BaseFold and by sumcheck-zerocheck respectively. This is stated bluntly because it enlarges
the honest estimate (section 11) well beyond the companion spec's "3 to 4 person-weeks for the AIR."
Two clean options follow from this finding; both are out of scope to decide here but are named so the
founder can choose (section 13): retarget 0x0AE8 to the SP1 6.1.0 Hypercube recursion proof (the plan
below), or keep the existing BabyBear + FRI skeleton and point it at Aere's OWN Plonky3 STARKs (the
`zk-circuits/*` provers), which is a real but different capability and does not remove the SP1 BN254
Groth16 wrap.
Nothing in this document changes the fail-closed contract. On-chain ZK verification on Aere stays on the
classical BN254 Groth16 gateway (`0x9ca479C8c52C0EbB4599319a36a5a017BCC70628`) until the whole verifier
is real, KAT-green against a real exported SP1 proof, externally audited, and founder-activated.
---
## 1. Exact pinned version
| item | pin | source |
|---|---|---|
| SP1 facade crates | `sp1-sdk`, `sp1-prover`, `sp1-verifier`, `sp1-zkvm`, `sp1-build` `= "=6.1.0"` | `rollup-evm-validity/{host,guest}/Cargo.toml`, `batch-prover-recovered/**/Cargo.toml` |
| SP1 upstream tag | `v6.1.0`, commit `d454975ac7c1126097e36eceda9bce2cb9899da4` | github.com/succinctlabs/sp1 release v6.1.0 |
| SP1 recursion machine (resolved) | `sp1-hypercube 6.3.1`, `sp1-recursion-machine 6.3.1`, `sp1-recursion-executor 6.3.1` | `rollup-evm-validity/host/Cargo.lock` |
| PCS / sumcheck stack (resolved) | `slop-basefold 6.3.1`, `slop-jagged 6.3.1`, `slop-multilinear 6.3.1`, `slop-sumcheck 6.3.1` | `rollup-evm-validity/host/Cargo.lock` |
| rsp executor | git `succinctlabs/rsp` tag `reth-1.9.3-sp1-6.1.0` | `rollup-evm-validity/host/Cargo.toml` |
| field | `SP1Field = KoalaBear` (p = 2^31 - 2^24 + 1 = 2130706433 = 0x7F000001), ext degree 4 | `crates/primitives/src/lib.rs` @ v6.1.0 |
| Poseidon2 | width 16, 30 total rounds, `KoalaBearDegree4Duplex` | `crates/primitives/src/lib.rs` @ v6.1.0 |
Version-skew note `[VERIFY]`: the SP1 facade crates carry `6.1.0` while the recursion/PCS internals
resolve to `6.3.1`. The port must be pinned to the exact `sp1-recursion-machine` / `slop-*` `6.3.1`
revisions that the Aere lock resolves, not to a generic "6.1.0", because chip layouts and PCS parameters
can move between patch releases.
Reference implementation to follow (not a bundled dependency): Succinct's standalone
`github.com/succinctlabs/hypercube-verifier` (crates `algebra, basefold, commit, jagged, merkle-tree,
multilinear, stacked, sumcheck, tensor, stark, recursion, primitives, ...` plus a
`jagged-polynomial-commitments.pdf`). It is a clean, self-contained verifier for exactly this proof
system and is the best porting reference. Caveat `[VERIFY]`: its README marks it a research prototype as
of 2025-05-20, so its constants and shapes must be reconciled against the pinned `6.3.1` crates before
they are trusted byte-exact.
---
## 2. What 0x0AE8 would actually verify (the recursion / shrink / wrap proof shape)
The SP1 pipeline at v6.1.0 is: core RISC-V proof (`RiscvAir<SP1Field>`, Jagged PCS + LogUp-GKR +
sumcheck over KoalaBear) -> compress (recursively verify + fold shard proofs) -> shrink (compress to a
single small shard) -> wrap (re-prove under a BN254-friendly config) -> BN254 Groth16/PLONK. The only
Shor-breakable link is the final Groth16 wrap. The post-quantum replacement 0x0AE8 targets the proof
BEFORE that wrap: the shrink shard proof (configId 1) and/or the wrap-input shard proof (configId 2).
That proof is a `ShardProof` of the SP1 recursion machine (`RecursionAir` / `CompressAir`), verified by
`verify_shard`. Its shape, from `crates/hypercube/src/verifier/shard.rs` @ v6.1.0:
- `main_commitment`: Merkle (TCS) root over Poseidon2-KoalaBear of the main trace.
- `opened_values` (`ShardOpenedValues`): per-chip trace column evaluations at the sampled multilinear
point (there is no univariate zeta; evaluations are at a random point in the boolean-hypercube
extension domain).
- `zerocheck_proof`: the constraint sumcheck (point + claimed sum) that replaces the DEEP-ALI quotient.
- `logup_gkr_proof`: the LogUp-GKR interaction/lookup proof (per-chip evaluations).
- `evaluation_proof`: the Jagged / BaseFold PCS evaluation proof binding the opened values to the
commitment.
- `public_values`: the shard public values (for the recursion machine, `RecursionPublicValues`).
`verify_shard` steps (source order): observe public values and commitments into the Poseidon2-KoalaBear
challenger; validate proof shape against the machine config in the vk (chip counts, widths, heights);
verify the LogUp-GKR proof; verify the zerocheck proof (sample constraint-merging challenge `alpha`,
check merged constraint evaluations against the sumcheck claim, cross-check against the GKR evaluations);
verify the PCS opening via `jagged_pcs_verifier.verify_trusted_evaluations`; cross-check row counts and
the global cumulative sum. Source: https://github.com/succinctlabs/sp1/blob/v6.1.0/crates/hypercube/src/verifier/shard.rs
The precompile wire format in `pqc-fork/pq-stark/export-inner-stark-vector.md` (magic `AS1\0`, version,
configId, vkeyDigest(32), publicValues, friProof) is broadly reusable, but two of its assumptions are
wrong for 6.1.0 and MUST be corrected: the body is a Hypercube `ShardProof` (bincode of the 6.3.1 type),
not a `ShardProof<BabyBearPoseidon2>`; and the vkey digest is `hash_koalabear()` packed (KoalaBear), not
`hash_babybear()`. See section 8.
---
## 3. Component map: what is done vs what this piece needs
| layer | confirmed generic skeleton (companion spec) | SP1 6.1.0 target (this spec) | reusable? |
|---|---|---|---|
| base field | BabyBear (0x78000001), F_{p^4}, W=11 | KoalaBear (0x7F000001), F_{p^4} | structure yes, constants NO |
| hash | Poseidon2-BabyBear, 8+13 rounds, 141 consts | Poseidon2-KoalaBear, 30 rounds | structure yes, constants NO |
| transcript | duplex challenger over BabyBear Poseidon2 | duplex over KoalaBear Poseidon2 | structure yes, re-field |
| vector commit | FieldMerkleTreeMmcs (Poseidon2) | Merkle TCS (Poseidon2-KoalaBear) | mostly yes |
| low-degree test | FRI fold + query (CONFIRMED) | BaseFold multilinear (sumcheck fold) | NO, different scheme |
| PCS wrapper | (FRI is the PCS) | Stacked + Jagged over BaseFold | NO, new |
| constraint check | DEEP-ALI univariate quotient (CONFIRMED) | zerocheck (sumcheck over merged constraints) | NO, different mechanism |
| interaction arg | none (out of generic scope) | LogUp-GKR + septic degree-7 global digest | NO, new, biggest specific add |
| machine AIR | example AIRs (Fibonacci, mul) | RecursionAir chip set (section 4) | NO, program-specific |
| vk binding | not on real path | KoalaBear Poseidon2 vk digest (section 8) | NO, new |
| public values | not on real path | RecursionPublicValues (section 9) | NO, new |
Reads as: the three "shape" rows (field, hash, transcript, merkle) port with a field swap plus new
constants; every other row is either a different scheme (BaseFold vs FRI, zerocheck vs DEEP-ALI) or an
entirely new component (Jagged, LogUp-GKR, the recursion chips, vk, public values).
---
## 4. The SP1 recursion machine AIR (RecursionAir): the chip set
`RecursionAir<F: PrimeField32 + BinomiallyExtendable<D>, const DEGREE, const VAR_EVENTS_PER_ROW>`, an
AIR machine derived with `sp1_derive::MachineAir`. Source:
https://github.com/succinctlabs/sp1/blob/v6.1.0/crates/recursion/machine/src/machine.rs
Chip files: https://github.com/succinctlabs/sp1/tree/v6.1.0/crates/recursion/machine/src/chips
Full chip set (`machine_wide_with_all_chips`): `MemoryConst`, `MemoryVar`, `BaseAlu`, `ExtAlu`,
`Poseidon2Wide`, `Poseidon2LinearLayer`, `Poseidon2SBox`, `ExtFeltConvert`, `PrefixSumChecks`,
`Select`, `PublicValues`.
The two configs 0x0AE8 would verify use a subset:
- `compress_machine`: `MemoryConst`, `MemoryVar`, `BaseAlu`, `ExtAlu`, `Poseidon2Wide`,
`PrefixSumChecks`, `Select`, `PublicValues` (8 chips).
- `wrap_machine`: `MemoryConst`, `MemoryVar`, `BaseAlu`, `ExtAlu`, `Poseidon2LinearLayer`,
`Poseidon2SBox`, `ExtFeltConvert`, `Select`, `PublicValues` (9 chips; the wide Poseidon2 is split into
linear-layer + s-box chips for the BN254-friendly wrap).
Note the departure from SP1 Turbo: there is no `FriFold`, no `ExpReverseBitsLen`, and no `BatchFRI` chip
(those existed only because Turbo's recursion verified a FRI proof in-circuit). Their absence is itself
confirmation that the recursion layer no longer runs FRI. `PrefixSumChecks` and `ExtFeltConvert` are the
new arithmetic that the BaseFold/Jagged/sumcheck verification compiles down to.
Per-chip porting notes. For each chip the port must reproduce, in KoalaBear, its column layout and its
`eval()` constraint emission order exactly (a single mis-ordered or mis-filtered constraint makes the
folded constraint silently wrong):
- `MemoryConst`, `MemoryVar` (`chips/mem/`): the recursion VM's read/write memory tables; correctness of
addresses/timestamps is enforced through the interaction bus (section 5), so most of their weight is in
the LogUp argument, not local constraints. Constraint count per row: small (a handful) `[VERIFY]`.
- `BaseAlu` (`chips/alu_base.rs`), `ExtAlu` (`chips/alu_ext.rs`): field and extension-field add/sub/mul
(and the ext ALU carries F_{p^4} arithmetic). A few constraints each `[VERIFY]`.
- `Poseidon2Wide` / `Poseidon2LinearLayer` / `Poseidon2SBox` (`chips/poseidon2_wide/`,
`poseidon2_helper/`): the Poseidon2 permutation used inside the recursion VM (this is the in-circuit
hash the recursion program itself computes). Highest per-row constraint count of the set; the wide
variant is one row per permutation, the split variants spread it across rows for the wrap. Constraint
count: large (the dominant chip) `[VERIFY]`.
- `ExtFeltConvert` (`chips/`): base/extension felt conversion glue for the wrap.
- `Select` (`chips/select.rs`): conditional selection (multiplexer) constraints.
- `PrefixSumChecks` (`chips/prefix_sum_checks.rs`): running/prefix-sum constraints used by the
sumcheck/BaseFold verification the recursion program runs; medium constraint count `[VERIFY]`.
- `PublicValues` (`chips/public_values.rs`): binds the `RecursionPublicValues` (section 9) into the trace.
The overall `DEGREE` and `VAR_EVENTS_PER_ROW` const parameters and each chip's exact constraint count
were not read line-by-line in this pass and are `[VERIFY]` / `[MEASURE]`; the ground-truth method
(section 10) emits them directly from the compiled machine, which is the only trustworthy way to count
them (do not hand-estimate).
---
## 5. The interaction argument (LogUp-GKR + septic digest): the biggest specific addition
The chips do not talk to each other through shared columns; they talk through a multiset (lookup) bus
proved with LogUp-GKR, and this is the single largest component the generic quotient check does NOT
cover. Sources: `crates/hypercube/src/logup_gkr/` and `crates/hypercube/src/lookup/`,
`crates/hypercube/src/septic_{curve,digest,extension}.rs` @ v6.1.0.
Mechanism, as read from source:
- Every send/receive interaction a chip emits is reduced to a field element via a random linear
combination of the (kind, values) tuple with verifier challenges, then batched with the RLC challenge.
- The per-shard consistency of all sends and receives is proved with LogUp-GKR (a GKR circuit over the
rational LogUp identity), whose proof is `logup_gkr_proof` in the shard proof and is verified before
the zerocheck.
- The GLOBAL bus (cross-shard, e.g. memory that persists across the shard boundary) is accumulated into
a `SepticDigest`: a point on an elliptic curve defined over the degree-7 "septic" extension of
KoalaBear (`SepticExtension`, `[u32; 7]` coordinates). Each chip contributes a curve point; the digest
is a special offset-corrected cumulative sum
`start + sum_i (digest_i - offset) + offset - start` (the offset avoids Weierstrass addition
exceptions), with start/offset points derived from sqrt(2) and sqrt(3) constants
(`CURVE_CUMULATIVE_SUM_START_*`, `DIGEST_SUM_START_*`). The verifier checks the machine-level global
cumulative sum equals the expected value (for a complete proof, the buses net to the identity).
Source: https://github.com/succinctlabs/sp1/blob/v6.1.0/crates/hypercube/src/septic_digest.rs
Why this is the hard part. Porting it faithfully requires: the exact interaction-kind enumeration and
field encoding per chip; the exact challenge-derivation order for the RLC and batching (a transcript
contract shared with the challenger); the full LogUp-GKR verifier (layer-by-layer sumcheck over the GKR
circuit); and the septic curve arithmetic (degree-7 extension mul, curve addition, the offset-sum
convention, the two magic start points). None of it exists in the confirmed skeleton, and any off-by-one
in the interaction encoding or the GKR layer order presents as a global "everything rejects" with no
localized error. The septic curve constants and the exact interaction encoding are `[VERIFY]` /
`[MEASURE]` (emit from the compiled machine).
---
## 6. The low-degree test: BaseFold (replaces FRI), plus Stacked + Jagged
FRI is not used. The PCS is a multilinear BaseFold committed over a Merkle TCS, wrapped by a Stacked PCS
(for batching columns of different heights) and a Jagged PCS (the "pay for what you use" evaluation
argument that reduces jagged, variable-length columns to a single multilinear evaluation via sumcheck).
Sources: `crates/prover/src/recursion.rs` (`RecursiveBasefoldVerifier`, `RecursiveMerkleTreeTcs`,
`RecursiveStackedPcsVerifier`, `RecursiveJaggedPcsVerifier`); reference crates
`hypercube-verifier/crates/{basefold, stacked, jagged, tensor, multilinear, sumcheck, merkle-tree}`.
What the port needs:
- BaseFold verifier: the multilinear analogue of FRI. Commit-phase folding driven by sumcheck rounds
(not the FRI fold relation), query openings against the Merkle TCS at each folded layer, final
evaluation check. The confirmed FRI `verify_query` does not apply; this is a new verifier.
- Stacked PCS: batches the per-chip column groups (different heights) into one commitment; the verifier
reconciles the per-group claims.
- Jagged PCS: `verify_trusted_evaluations` runs the jagged sumcheck that binds the opened multilinear
evaluations (`opened_values`) to the committed data at the sampled point. This is where the bulk of
the PCS soundness lives.
- Parameters (`[MEASURE]`): the BaseFold log_blowup / folding-arity / query count / proof-of-work bits
for the compress, shrink, and wrap configs, and the resulting soundness (score with the Hypercube
soundness analysis, not ethSTARK soundcalc, since this is not FRI). Whether the wrap config
(`CircuitWrapConfig`) uses different PCS parameters or a different field embedding than compress/shrink
is `[VERIFY]`.
---
## 7. The constraint check: zerocheck sumcheck (replaces DEEP-ALI quotient)
The confirmed generic quotient-consistency identity (`folded_constraints * inv_zeroifier == quotient`
from `p3-uni-stark`) is a UNIVARIATE-STARK mechanism and is not what SP1 6.1.0 checks. Instead the merged
AIR constraint is verified by a sumcheck (zerocheck): the verifier samples the constraint-merging
challenge `alpha`, the prover claims the merged constraint polynomial sums to zero over the boolean
hypercube, and the sumcheck reduces that claim to a single evaluation at a random point, which is then
opened through the PCS (section 6) and cross-checked against the LogUp-GKR evaluations. Source:
`crates/hypercube/src/verifier/shard.rs` verify step 4, and `hypercube-verifier/crates/stark/folder.rs`
+ `sumcheck`.
The port needs: the sumcheck verifier (round polynomials, challenge derivation, final-evaluation
reduction); the constraint folder that reproduces each chip's `eval()` emission order and its
first-row/last-row/transition filters in the multilinear setting; and the binding of the sumcheck's
final point to the PCS opening. The generic DEEP-ALI code is not reusable here beyond the high-level idea
of merging constraints with a random `alpha`.
---
## 8. The verifying key (vk) and its digest binding
`MachineVerifyingKey` fields (from `crates/hypercube/src/verifier/hashable_key.rs` @ v6.1.0):
`preprocessed_commit` (Merkle root of the preprocessed/selector trace), `pc_start`,
`initial_global_cumulative_sum` (a septic curve point, x and y), `enable_untrusted_programs`, plus the
machine shape (chip ordering, widths, heights) carried by the associated `Machine`. Source:
https://github.com/succinctlabs/sp1/blob/v6.1.0/crates/hypercube/src/verifier/hashable_key.rs
Digest binding. `HashableKey` provides `hash_koalabear()` (Poseidon2 over KoalaBear of
`[preprocessed_commit, pc_start, initial_global_cumulative_sum.x, initial_global_cumulative_sum.y,
enable_untrusted_programs]`, producing an 8-element SP1Field digest), `hash_u32()`, `hash_bytes()`, and
`hash_bn254()` (via `koalabears_to_bn254()`, the digest the on-chain Groth16 path currently binds).
For 0x0AE8 the verifier must (a) recompute `hash_koalabear()` over the supplied vk fields, (b) check it
equals the 32-byte `vkeyDigest` in the AS1 wire envelope, and (c) use the vk's machine shape to drive the
shape checks in `verify_shard`. The export doc's `vk.hash_babybear()` is WRONG for 6.1.0 and must be
`hash_koalabear()`; the packing is 8 KoalaBear limbs, big-endian per limb. `[VERIFY]` the exact limb
order and the exact field list that feeds `hash_koalabear` at the pinned 6.3.1 revision.
---
## 9. The public-values layout
`RecursionPublicValues<T>` (from `crates/recursion/executor/src/public_values.rs` @ v6.1.0), field type
KoalaBear (`T = SP1Field`) on the real path. Fields (source order, as read):
`prev_committed_value_digest`, `committed_value_digest`, `prev_deferred_proofs_digest`,
`deferred_proofs_digest`, `pc_start`, `next_pc`, `initial_timestamp`, `last_timestamp`, memory/page
indices, `sp1_vk_digest`, `vk_root`, `global_cumulative_sum` (septic point), `digest`, `proof_nonce`,
`contains_first_shard`, `num_included_shard`, `is_complete`, `exit_code`, `commit_syscall`,
`commit_deferred_syscall`. Total element count is `RECURSIVE_PROOF_NUM_PV_ELTS =
size_of::<RecursionPublicValues<u8>>()`; the exact integer is `[VERIFY]` (emit from the compiled crate).
Source: https://github.com/succinctlabs/sp1/blob/v6.1.0/crates/recursion/executor/src/public_values.rs
The verifier must: parse these from the wire `publicValues`; observe them into the challenger in the
exact source order (they bind the transcript, so a wrong order diverges every challenge); check the
internal `digest` consistency; and expose `committed_value_digest` / `sp1_vk_digest` / `vk_root` /
`is_complete` / `exit_code` as the verified outputs the AerePQStarkVerifier adapter returns. The
committed-value digest and `sp1_vk_digest` are what a caller uses to bind a specific guest program and
its output, exactly as the BN254 path does today.
---
## 10. Ground-truth method (the only trustworthy validation)
Every constraint count, parameter, and layout marked `[VERIFY]` / `[MEASURE]` above must be produced from
the compiled pinned toolchain, never hand-derived. The method, on a throwaway non-infra prover box (never
the live infra host, never a validator; see the no-heavy-compute-on-infra rule):
1. Pin a Rust workspace to the exact resolved revisions in `rollup-evm-validity/host/Cargo.lock`:
`sp1-sdk = "=6.1.0"`, and let it resolve `sp1-hypercube`, `sp1-recursion-machine`,
`sp1-recursion-executor`, `slop-basefold`, `slop-jagged`, `slop-multilinear`, `slop-sumcheck` at
`6.3.1`. Vendor them for reproducibility.
2. Emit machine metadata directly: for `compress_machine()` and `wrap_machine()`, print each chip's name,
width, and its symbolic constraint count and max degree; print `RECURSIVE_PROOF_NUM_PV_ELTS`; print the
BaseFold/Jagged config parameters; print the septic curve constants and the interaction-kind encoding.
This replaces every `[VERIFY]` count with a measured one.
3. Produce a real proof: run a tiny guest (fibonacci or `aere-client`) through
`prove(...).compressed()`, stopping before the Groth16 wrap; serialize the shrink `ShardProof`
(bincode), the vk, and its `hash_koalabear()` digest and `public_values`. This is the
`sp1_shrink_valid_01.bin` corpus vector (correcting the export doc to KoalaBear + Hypercube).
4. Instrument `verify_shard` to dump the exact challenger transcript (observe order, sampled `alpha`, the
sumcheck points, the query indices) so each ported sub-verifier can be diffed byte-for-byte against
the reference, the same KAT discipline the generic components used.
Follow the `hypercube-verifier` reference crate structure (section 1) so the port is a
component-by-component mirror of a maintained verifier, not a from-scratch reading of the prover.
---
## 11. Effort, hardest parts, honest estimates
Realistic single-specialist estimates (STARK/sumcheck specialist with the SP1 toolchain). These are
deliberately not optimistic; the two generic pieces the companion spec counted as done (FRI, DEEP-ALI)
do not carry over, so the remaining surface is larger than that spec's "3 to 4 weeks for the AIR."
| piece | effort (person-weeks) | risk |
|---|---|---|
| KoalaBear field + F_{p^4} (re-field the confirmed BabyBear code, new prime/constants) | ~0.5 to 1 | low |
| Poseidon2-KoalaBear (width 16, 30 rounds, new constants) + duplex challenger re-field | ~1 to 1.5 | medium (constants) |
| Merkle TCS over KoalaBear (re-field the confirmed MMCS) | ~0.5 to 1 | low |
| BaseFold multilinear verifier (new, replaces FRI) | ~3 to 4 | high |
| Stacked + Jagged PCS verifier (new, the jagged sumcheck) | ~3 to 4 | high |
| sumcheck + zerocheck constraint check (new, replaces DEEP-ALI) | ~2 to 3 | high |
| LogUp-GKR + septic degree-7 global digest (new, biggest specific add) | ~3 to 4 | HARDEST |
| RecursionAir chip constraints (8 to 11 chips, KoalaBear, exact eval order) | ~3 to 4 | high |
| vk binding (`hash_koalabear`) + RecursionPublicValues + shape checks | ~1 to 2 | medium |
| wire parser (`WireReader` for the Hypercube ShardProof) + adapter wiring | ~1 to 2 | medium |
| integration, gas benchmark under EIP-7825, KAT corpus, soundness scoring, audit prep | ~4 to 6 | high |
| total | ~22 to 32 person-weeks | multi-month |
That is roughly 5 to 8 months of focused single-specialist work plus an external audit, materially more
than the companion spec's figure because the target is Hypercube, not Turbo. Hardest parts, ranked:
(1) LogUp-GKR + septic digest interaction argument (section 5); (2) BaseFold + Jagged PCS (section 6);
(3) the sumcheck zerocheck constraint mechanism (section 7); (4) the RecursionAir chips at exact eval
order (section 4). Each is multi-week on its own.
Given this, the design doc's recommendation (companion spec section 5.1) is even more compelling: wrap a
pinned, reproducible NATIVE build of the maintained Rust verifier (the `hypercube-verifier` crates or the
`sp1-verifier 6.1.0` inner path) as the precompile's crypto core, rather than hand-port a KoalaBear
BaseFold + Jagged + sumcheck + LogUp-GKR verifier into Java. A hand port multiplies the audit surface and
the "two wrong copies agree" risk across every one of the pieces above.
---
## 12. End-to-end conformance KAT (the final gate)
The single test that proves the whole verifier, once the pieces above exist:
1. Export a real SP1 6.1.0 shrink (configId 1) and wrap-input (configId 2) proof + vk + public values by
the section-10 method; wrap each into the AS1 envelope (KoalaBear `hash_koalabear` vkey digest).
2. `sp1_shrink_valid_01.bin`, `sp1_wrap_valid_01.bin`: 0x0AE8 must ACCEPT (return the verified
committed-value digest / vk digest), and the SAME public values verified through the live BN254
gateway (`0x9ca479...`) must agree on accept.
3. Negatives, each must REJECT (return EMPTY): flip one byte inside a query opening
(`*_tampered_*`); mutate one byte of `publicValues` (`*_wrongpub_*`, the transcript binds them);
swap in a vk with a different `hash_koalabear` digest (`*_wrongvk_*`); tamper one sumcheck round
polynomial and one LogUp-GKR layer (`*_badsumcheck_*`, `*_badgkr_*`).
4. Cross-field regression: the confirmed BabyBear + FRI skeleton must continue to reject these KoalaBear
Hypercube inputs (it is a different verifier), confirming the two are not conflated.
Until a real exported SP1 6.1.0 proof exists and passes this, the precompile verifies nothing and stays
fail-closed. There is no offline substitute for this KAT.
---
## 13. Bottom line for the whole #2 effort
- What is real today: a BabyBear + FRI + univariate-STARK verifier SKELETON with six conformance-confirmed
generic components (field, Poseidon2, MMCS, FRI, transcript, DEEP-ALI quotient) against Plonky3
`0.4.3-succinct`. That is genuine, tested work, and it is the correct verifier for Aere's OWN Plonky3
STARKs (`zk-circuits/*`).
- What is NOT true: that this skeleton is most of an SP1 6.1.0 verifier. SP1 6.1.0 is Hypercube. Its
inner recursion proof is a KoalaBear multilinear proof (BaseFold + Stacked + Jagged PCS, sumcheck
zerocheck, LogUp-GKR with a degree-7 septic global digest) over the `RecursionAir` chip set. The FRI
and DEEP-ALI pieces do not apply to it; only the Poseidon2/Merkle/challenger SHAPES carry over, and
those need the KoalaBear field and constants.
- What stands between here and a live native post-quantum STARK verifier that replaces the classical
BN254 Groth16 gateway: (1) a KoalaBear re-field of the shape components; (2) the four new components
(BaseFold, Jagged/Stacked, sumcheck-zerocheck, LogUp-GKR + septic digest); (3) the RecursionAir chips;
(4) the vk binding and RecursionPublicValues; (5) a real exported SP1 6.1.0 end-to-end proof KAT; (6)
soundness scoring and an EIP-7825 gas benchmark; (7) an external audit; (8) founder activation.
- Realistic total remaining: on the order of 22 to 32 person-weeks (roughly 5 to 8 months) of a
STARK/sumcheck specialist plus an external audit, whether hand-ported or (recommended) wrapped as a
pinned native build of the maintained Rust verifier. The top-level 0x0AE8 stays fail-closed the entire
time; on-chain ZK verification remains classical BN254 Groth16 until all eight gates are met and the
founder activates.
---
## 14. Open `[VERIFY]` / `[MEASURE]` flags
1. `[VERIFY]` Version skew: pin the exact `sp1-recursion-machine` / `slop-* 6.3.1` revisions the Aere
lock resolves; the `6.1.0` facade sits on `6.3.1` internals.
2. `[VERIFY]/[MEASURE]` Per-chip constraint counts, `DEGREE`, `VAR_EVENTS_PER_ROW` (emit from the
compiled machine, section 10).
3. `[VERIFY]/[MEASURE]` `RECURSIVE_PROOF_NUM_PV_ELTS` exact integer and the exact PV field ordering.
4. `[VERIFY]/[MEASURE]` BaseFold / Jagged parameters (blowup, folding arity, query count, pow bits) for
compress, shrink, and wrap; whether `CircuitWrapConfig` differs.
5. `[VERIFY]/[MEASURE]` Septic curve constants (a, b, sqrt(2)/sqrt(3) start points) and the exact
per-chip interaction-kind encoding + challenge order.
6. `[VERIFY]` Exact `hash_koalabear()` input field list and limb packing at 6.3.1.
7. `[VERIFY]` KoalaBear Poseidon2 external/internal round split within the 30 total rounds, and its
constants.
8. `[VERIFY]` Exact-constant conformance of the `hypercube-verifier` reference (2025-05-20 prototype)
against the pinned 6.3.1 crates.
9. `[MEASURE]` The end-to-end KAT (section 12): needs a real exported SP1 6.1.0 proof; nothing offline
substitutes for it.
## 15. Files
- `docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md` (this document).
- `docs/AERE-STARK-VERIFIER-PORT-SPEC.md` (the generic skeleton + its confirmed status; note its
BabyBear/FRI premise for SP1 6.1.0 is corrected here).
- `pqc-fork/pq-stark/export-inner-stark-vector.md` (real-vector export; correct `hash_babybear` ->
`hash_koalabear` and the ShardProof type to the Hypercube 6.3.1 type per section 8).
- `pqc-fork/precompiles/Sp1StarkVerifierPrecompiledContract.java` (fail-closed skeleton; unchanged).
- `contracts/contracts/zkverify/AerePQStarkVerifier.sol` (fail-closed adapter; unchanged).