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.
6.3 KiB
Component (f): Fiat-Shamir transcript / Poseidon2 duplex challenger (0x0AE8) - CONFORMANCE-CONFIRMED
Scope caveat (2026-07-19 finding). This transcript is conformance-confirmed against Plonky3
p3-challenger/p3-fri0.4.3-succinct(Aere's OWN BabyBear + FRI STARK stack), NOT against SP1 6.1.0. SP1 6.1.0 is a Hypercube release (KoalaBear multilinear: BaseFold + Jagged + sumcheck-zerocheck + LogUp-GKR), so FRI and DEEP-ALI do not apply to it and this skeleton does not verify SP1 6.1.0 proofs. (The duplex-challenger SHAPE carries over to SP1's Hypercube stack, but over the KoalaBear field with KoalaBear constants and a different observe/sample order.) Replacing the SP1 BN254 Groth16 wrap is a separate ~22 to 32 person-week retarget. SeeAERE-STARK-SP1-RECURSION-AIR-PORT-SPEC-SUMMARY.md.
Date: 2026-07-19. Precompile: Aere PQ STARK verifier at 0x0AE8. Scope: port-spec component (f).
Result headline
- Transcript conformance KAT: PASSED (PASS=44 FAIL=0 across Python + Node + standalone Java;
standalone
ChallengerSelfTestPASS=31 including a driver fail-closed gate model). - It closed the FRI betas/indices loop that component (d) left open: transcript -> derived
betas/indices -> confirmed
Fri.verifyQueryACCEPTs the real FRI ground-truth proof and REJECTs a tampered beta. Challenger.spongePortedflipped true. Top level stays FAIL-CLOSED:StarkConstraints. evaluateAtZetastill returns UNAVAILABLE (component (e), the AIR, un-ported), gating ACCEPT before the query loop and before the singlereturn ACCEPT.computePrecompilereturns EMPTY for every input; ACCEPT is unreachable by construction. DO NOT ACTIVATE.
What was confirmed from pinned source (p3-challenger / p3-fri 0.4.3-succinct)
DuplexChallenger<BabyBear, Perm, WIDTH=16, RATE=8> (duplex_challenger.rs) + GrindingChallenger
(grinding_challenger.rs), transcript order from p3-fri verifier.rs verify_shape_and_sample_challenges:
observe(felt): clear output buffer, push to input buffer, duplex when input buffer reaches RATE=8.duplexing: overwrite the firstinput_buffer.len()(<=RATE) of 16 lanes, permute (confirmed Poseidon2), set output buffer = lanes [0..8).sample: duplex if inputs buffered OR outputs empty, thenVec::pop(LIFO, from the END). An F_{p^4} sample = 4 sequential base pops [c0,c1,c2,c3] (sample_ext_element=sample_vec(4)thenfrom_base_slice).sample_bits(bits): LOWbitsofas_canonical_u64(confirmed LSB).check_witness(pow_bits, witness):observe(witness)thensample_bits(pow_bits) == 0.- FRI transcript order: per commit -> observe 8-elem digest, sample beta (F_{p^4}); then observe final_poly (4 coords); then check_witness(pow_bits, pow_witness); then num_queries x sample_bits(log_max_height). log_max_height = commits.len() + log_blowup.
Montgomery/serialization: all arithmetic canonical (the confirmed Poseidon2 reference already carries
the internal-layer R^-1 factor); the extractor emits as_canonical_u32 and as_base_slice coords, and
the references reproduce them exactly.
Ground truth (executed the pinned crates)
pqc-fork/pq-stark/challenger-extractor/ (Cargo.toml + copied fri-extractor Cargo.lock, byte-identical
pins) compiled and ran (target dir in scratch, no repo pollution, live infra untouched). It emits
challenger_ground_truth.json with two blocks:
duplex_kat: a fully-scripted observe/sample transcript -> base samples, F_{p^4} ext samples, sample_bits, the full 16-lane sponge state at a checkpoint, and a check_witness accept/reject table (real grinding witness accepts, fixed non-witnesses reject).fri_transcript: the SAME three FRI cases asfri_ground_truth.json, rebuilt (same seeds) so the commit_phase_commits / final_poly / pow_witness / betas / query_indices match; the references derive betas+indices+PoW-accept from (commits, final_poly, pow_witness) and match BOTH the extractor AND fri_ground_truth.json.
The references reproduce every value byte-for-byte (all 3 languages identical), and the derived
betas/indices, fed to the confirmed Fri.verifyQuery, accept the real proof and reject a tampered beta.
Files added/changed
Added: challenger_reference.py, challenger_reference.mjs, ChallengerSelfTest.java,
test_challenger.py, challenger-extractor/{Cargo.toml,Cargo.lock,src/main.rs},
challenger_ground_truth.json, ../results/kat-results-challenger.json.
Changed:
pqc-fork/precompiles/Sp1StarkVerifierPrecompiledContract.java:Challengerclass rewritten as the confirmed duplex sponge overPoseidon2Bb.permute(observeField/sampleBaseField/sampleExtField/ sampleBits/checkWitnessField + byte-facing driver adapters);spongePorted = true; driver stage-4 comment clarifies the AIR gate; stale "spongePorted=false" docs updated.StarkConstraints. evaluateAtZetaUNCHANGED (still returns UNAVAILABLE at line ~1077).docs/AERE-STARK-VERIFIER-PORT-SPEC.md: status header, section 5 note, section 7 rewritten (IMPLEMENTED + CONFORMANCE-CONFIRMED), section 9 table row (f), section 10 files.pqc-fork/pq-stark/README.md: HONEST STATUS, sections (b)/(c)/(d) closings, new section (f), layout.pqc-fork/pq-stark/test_fri_verify.py: descriptive notes updated (f now confirmed; loop closed).
Fail-closed proof
verify() control flow: ACCEPT requires stage 3 (PoW) AND stage 4 (AIR) AND stage 5 (queries) all pass.
Stage 4 = StarkConstraints.evaluateAtZeta ALWAYS returns UNAVAILABLE (component (e) un-ported) and is
checked (line 196) BEFORE the query loop and BEFORE the single return ACCEPT (line 228). So verify()
returns UNAVAILABLE for every input reaching stage 4; computePrecompile returns EMPTY. Flipping
spongePorted cannot create an ACCEPT path. Corroborated at runtime by ChallengerSelfTest.gateModel
(driver.gate.ACCEPT_unreachable_for_every_input PASS). The precompile is not compiled here (it is
applied via patch to a Besu build, no local Besu jar); the challenger algorithm is verified by the
byte-identical standalone ChallengerSelfTest.
Remaining
Component (e), the SP1 recursion AIR (StarkConstraints, ~3-4 person-weeks, HARDEST), is the one remaining un-ported crypto-core component. Real exported SP1 v6.1.0 transcript order is [MEASURE]. On-chain ZK verifiers remain classical BN254 until all 6 components + integration + a real SP1-proof end-to-end KAT + audit + founder activation.