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.
32 KiB
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.tomlat tag v6.1.0 (workspace.package.version = "6.1.0") lists workspace membersslop/crates/{jagged, whir, basefold, sumcheck, multilinear, stacked, tensor, koala-bear, ...}andsp1-gpu/crates/{jagged_sumcheck, logup_gkr, zerocheck, ...}, and pins Plonky3 at0.3.2-succinct. Source: https://github.com/succinctlabs/sp1/blob/v6.1.0/Cargo.toml crates/primitives/src/lib.rsdefinespub type SP1Field = KoalaBear;andpub type SP1ExtensionField = BinomialExtensionField<SP1Field, 4>;withSP1GlobalContext = KoalaBearDegree4Duplex(Poseidon2 width 16, 30 total rounds). Source: https://github.com/succinctlabs/sp1/blob/v6.1.0/crates/primitives/src/lib.rscrates/prover/src/recursion.rsbuilds the compress/shrink/wrap recursion verifiers fromRecursiveBasefoldVerifier+RecursiveMerkleTreeTcs+RecursiveStackedPcsVerifier+RecursiveJaggedPcsVerifieroverSP1Field. 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) resolvessp1-sdk 6.1.0,sp1-prover 6.1.0,sp1-verifier 6.1.0on top ofsp1-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. Thep3-* 0.4.3-succinctentries in the same lock (includingp3-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 theRecursionPublicValues(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_proofin 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 sumstart + 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_querydoes 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_evaluationsruns 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):
- Pin a Rust workspace to the exact resolved revisions in
rollup-evm-validity/host/Cargo.lock:sp1-sdk = "=6.1.0", and let it resolvesp1-hypercube,sp1-recursion-machine,sp1-recursion-executor,slop-basefold,slop-jagged,slop-multilinear,slop-sumcheckat6.3.1. Vendor them for reproducibility. - Emit machine metadata directly: for
compress_machine()andwrap_machine(), print each chip's name, width, and its symbolic constraint count and max degree; printRECURSIVE_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. - Produce a real proof: run a tiny guest (fibonacci or
aere-client) throughprove(...).compressed(), stopping before the Groth16 wrap; serialize the shrinkShardProof(bincode), the vk, and itshash_koalabear()digest andpublic_values. This is thesp1_shrink_valid_01.bincorpus vector (correcting the export doc to KoalaBear + Hypercube). - Instrument
verify_shardto dump the exact challenger transcript (observe order, sampledalpha, 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:
- 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_koalabearvkey digest). 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.- Negatives, each must REJECT (return EMPTY): flip one byte inside a query opening
(
*_tampered_*); mutate one byte ofpublicValues(*_wrongpub_*, the transcript binds them); swap in a vk with a differenthash_koalabeardigest (*_wrongvk_*); tamper one sumcheck round polynomial and one LogUp-GKR layer (*_badsumcheck_*,*_badgkr_*). - 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
RecursionAirchip 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
[VERIFY]Version skew: pin the exactsp1-recursion-machine/slop-* 6.3.1revisions the Aere lock resolves; the6.1.0facade sits on6.3.1internals.[VERIFY]/[MEASURE]Per-chip constraint counts,DEGREE,VAR_EVENTS_PER_ROW(emit from the compiled machine, section 10).[VERIFY]/[MEASURE]RECURSIVE_PROOF_NUM_PV_ELTSexact integer and the exact PV field ordering.[VERIFY]/[MEASURE]BaseFold / Jagged parameters (blowup, folding arity, query count, pow bits) for compress, shrink, and wrap; whetherCircuitWrapConfigdiffers.[VERIFY]/[MEASURE]Septic curve constants (a, b, sqrt(2)/sqrt(3) start points) and the exact per-chip interaction-kind encoding + challenge order.[VERIFY]Exacthash_koalabear()input field list and limb packing at 6.3.1.[VERIFY]KoalaBear Poseidon2 external/internal round split within the 30 total rounds, and its constants.[VERIFY]Exact-constant conformance of thehypercube-verifierreference (2025-05-20 prototype) against the pinned 6.3.1 crates.[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; correcthash_babybear->hash_koalabearand 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).