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.
5.9 KiB
Exporting a real SP1 v6.1.0 INNER STARK vector (for the PQ verifier KAT corpus)
SCOPE CORRECTION (2026-07-19 research finding; the premise below is wrong for the pinned SP1). This document assumes SP1 6.1.0's inner proof is a BabyBear + Poseidon2 + FRI Plonky3
ShardProof. It is NOT. The pinned SP1 (facade= "=6.1.0", internalssp1-hypercube 6.3.1) is a Hypercube release: its inner recursion proof is a KoalaBear multilinear proof (BaseFold + Jagged/Stacked PCS + sumcheck-zerocheck + LogUp-GKR with a septic-curve digest), with no BabyBear FRIShardProofanywhere. So exporting a "shrink/compress Plonky3 shard proof over BabyBear + FRI" from SP1 6.1.0 is not possible: what SP1 6.1.0 exports is a Hypercube ShardProof (KoalaBear), which the BabyBear + FRI verifier skeleton does NOT verify. A real KAT corpus for the current skeleton must come from Aere's OWN Plonky3 (zk-circuits/*) BabyBear + FRI provers instead. Building a real SP1 6.1.0 corpus requires first retargeting 0x0AE8 to the SP1 Hypercube stack (a separate ~22 to 32 person-week effort). See../../docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC-SUMMARY.mdand../../docs/AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC.md. Read the instructions below with that in mind.
The PQ STARK-verify precompile (0x0AE8) verifies a BabyBear/Plonky3 inner hash-based FRI/STARK proof directly, not a BN254 Groth16 wrap. Per the scope correction above, that BabyBear + FRI target is Aere's own Plonky3 circuits, NOT the pinned SP1 6.1.0 (Hypercube). The steps below were written to export a BabyBear + Poseidon2 + FRI "shrink"/compress shard proof; they apply to a BabyBear + FRI Plonky3 prover, not to the SP1 6.1.0 Hypercube toolchain.
This file is instructions + a Rust snippet, NOT a bundled vector. As of 2026-07-18 no real inner vector is committed here, because generating one requires running the SP1 prover (heavy; MUST be on a throwaway non-infra box, never on the live infra host or a validator). Treat every "expect ACCEPT" KAT as PENDING until a vector produced by this procedure is checked in.
Provenance to pin
- SP1
=6.1.0(matches the repo's existing pins:rollup-evm-validity/host/Cargo.toml,batch-prover-recovered/bin/aere-prover/Cargo.toml,sp1-verifier = "=6.1.0"). - The proof object we want is the one BEFORE the Groth16/PLONK wrap:
SP1ReduceProofafterprover.shrink(...)(config 1, "inner/shrink"), and/orSP1ReduceProofafterprover.wrap_bn254(...)'s input (config 2, "wrap"), i.e. the STARK that Groth16 is about to attest, exported before the wrap.
- These are Plonky3
ShardProof<BabyBearPoseidon2>values. Theirserde/bincodebytes are thefriProofbody the precompile parses (spec doc section 3.2 pins the sub-layout to this exact serialization + version).
Rust snippet (run on a throwaway prover box)
// Cargo.toml: sp1-sdk = "=6.1.0", sp1-prover = "=6.1.0", bincode = "1.3", serde_json = "1"
use sp1_sdk::{ProverClient, SP1Stdin};
fn main() {
// A tiny guest ELF is enough for a KAT (e.g. the fibonacci example, or the aere-client guest).
let elf = std::fs::read("guest.elf").unwrap();
let client = ProverClient::from_env(); // CPU prover; native-gnark not needed for shrink
let (pk, vk) = client.setup(&elf);
let mut stdin = SP1Stdin::new();
stdin.write(&/* public input */ 20u32);
// 1) core proof -> 2) compress -> 3) shrink. Stop BEFORE groth16/plonk wrap.
let core = client.prove(&pk, &stdin).core().run().unwrap();
let compressed = client.prove(&pk, &stdin).compressed().run().unwrap();
// The inner API name varies by SP1 minor; in 6.1.0 the compressed proof carries the
// SP1ReduceProof. Serialize the reduce/shrink proof + vk + public values:
// vkey digest domain the precompile expects (Poseidon2 digest of the recursion vk):
let vkey_digest = vk.hash_babybear(); // [BabyBear; 8] -> 32 bytes big-endian per element pack
std::fs::write("sp1_shrink_vkeydigest.bin", pack_babybear8(&vkey_digest)).unwrap();
let public_values = compressed.public_values.to_vec();
std::fs::write("sp1_shrink_publicvalues.bin", &public_values).unwrap();
// The shard/reduce proof, bincode-serialized == the friProof body:
let proof_bytes = bincode::serialize(&compressed.proof).unwrap();
std::fs::write("sp1_shrink_proof.bin", &proof_bytes).unwrap();
// Also dump the FriConfig actually used (num_queries, log_blowup, pow_bits) so section 4 of the
// spec can pin configId 1 exactly instead of the placeholder values:
// println!("{:?}", <the shrink FriConfig>);
}
fn pack_babybear8(_x: &[u32; 8]) -> Vec<u8> { /* 4 BE bytes per limb -> 32 bytes */ vec![] }
Assemble the precompile envelope
Concatenate into the v1 wire format the adapter/precompile expect (spec doc section 3):
magic("AS1\0") || version(1)=1 || configId(1)=1 || reserved(2)=0x0000
|| vkeyDigest(32) = sp1_shrink_vkeydigest.bin
|| publicValuesLen(4 BE) || publicValues = sp1_shrink_publicvalues.bin
|| proofLen(4 BE) || friProof = sp1_shrink_proof.bin
Name the file vectors/sp1_shrink_valid_01.bin. Produce the negatives by:
sp1_shrink_tampered_01.bin: flip one byte inside a query-opening leaf of the proof (must REJECT).sp1_shrink_wrongpub_01.bin: mutate one byte ofpublicValues(must REJECT - the transcript binds public values, so the sampled challenges diverge).
What these vectors gate
Once the crypto core is ported (Poseidon2-BabyBear + FRI folding + SP1 recursion AIR), the KAT
corpus is the section-4 conformance gate in docs/PQ-STARK-VERIFIER-ACTIVATION-2026-07-18.md:
the precompile must ACCEPT every *_valid_* vector and REJECT every *_tampered_* / *_wrongpub_*
vector, plus a cross-check that the SAME public values verified through the live BN254 gateway
(0x9ca479...) and through 0x0AE8 agree on accept/reject. Until a real vector exists and the core is
ported, DO NOT claim the precompile verifies anything.