The public history carried kat/__pycache__/mlkem768_reference.cpython-314.pyc, a compiled Python artifact embedding the operator's absolute local path. Text secret scanners do not read compiled binaries, which is exactly how it slipped through, and removing it from the tip would have left it reachable through the old root commits. So this repository is republished from a single clean root. This root also carries, from the previously unpublished line of work: - corrected LICENSE year, LICENSING.md, VERIFY-POLICY.md, and CITATIONS-UNRESOLVED.md remeasured 2026-08-11 (101 paths, README aligned) - O-018: run_consensus_verification.py ran 19 of 29 models and reported PASS; it now runs all 29, and computemarket_smt.py gains resolveByTimeout / reclaimUnsettled cases plus a negative control - O-006: the word 'audited' removed from next to Bouncy Castle, twice, after a concurrent edit resurrected it - O-014: prior art named and dated - Algorand's native falcon_verify shipped about ten months before AERE's precompiles; the primacy claim is withdrawn where it was implied - bench/ scripts parametrized so they actually run for an outsider (the earlier textual sanitization left $STAGING unexpanded inside Python strings) - AIP-2/AIP-3 errata with measured figures, spec remeasurements at 2026-08-01, and the spec-zk-stack retractions (owner is an operational key, not the Foundation; 'maximally sound' withdrawn; aggregator V1 deprecated) The redacted bench-host environment files from the sanitized line are kept exactly as published; the unredacted local variants are not carried.
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.