# Poseidon2-over-BabyBear (width 16) - component (b) of the 0x0AE8 STARK-verify port > **Scope caveat (2026-07-19 finding).** This component is conformance-confirmed against Plonky3 > `0.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. (Only the > Poseidon2 sponge SHAPE carries over to SP1's Hypercube stack, and even that needs the KoalaBear > field and KoalaBear Poseidon2 constants.) Replacing the SP1 BN254 Groth16 wrap is a separate > ~22 to 32 person-week retarget. See `AERE-STARK-SP1-RECURSION-AIR-PORT-SPEC-SUMMARY.md`. Date: 2026-07-19. Status: STRUCTURE implemented + self-consistency TESTED; CONFORMANCE to Plonky3 is [VERIFY] (no KAT run). Top-level 0x0AE8 verifier UNCHANGED and still fail-closed. ## What was implemented The Poseidon2 permutation over BabyBear (p = 2^31 - 2^27 + 1) at the standard SP1/Plonky3 width 16: - S-box x^7 (BabyBear: 7 is the smallest d>1 with gcd(d, p-1)=1, so it is a bijection on F_p). - 8 external (full) rounds: 4 initial + 4 terminal, S-box on all 16 lanes, then the MDS-light external layer M_E built from M4 = [[2,3,1,1],[1,2,3,1],[1,1,2,3],[3,1,1,2]] (block matrix with diagonal blocks 2*M4, off-diagonal blocks M4; the two-step "apply M4 per block, add col sums" form). - 13 internal (partial) rounds: S-box on lane 0 only, then M_I = J + diag(D) applied as state[i] = state[i]*D[i] + sum(state), D = INTERNAL_DIAG_M1_16. - Round-constant schedule: 128 external (add to all 16 lanes) + 13 internal (add to lane 0) = 141. - A `compress2to1` truncated-permutation 2-to-1 compression for the Merkle layer (shape [VERIFY]). Files (mirrors the field sub-component's Python + Node + standalone-Java + precompile convention): - `aerenew/pqc-fork/precompiles/Sp1StarkVerifierPrecompiledContract.java` - `Poseidon2Bb.permute` implemented; `Poseidon2Bb.available` STAYS false (gates everything above it). - `aerenew/pqc-fork/pq-stark/poseidon2_babybear_reference.py` (Python reference). - `aerenew/pqc-fork/pq-stark/poseidon2_babybear_reference.mjs` (Node reference). - `aerenew/pqc-fork/pq-stark/Poseidon2BabyBearSelfTest.java` (standalone Java, no Besu classpath). - `aerenew/pqc-fork/pq-stark/test_poseidon2_babybear.py` (harness). - `aerenew/pqc-fork/results/kat-results-poseidon2-babybear.json` (machine-readable result). - Docs updated: `aerenew/docs/AERE-STARK-VERIFIER-PORT-SPEC.md` (intro, section 3, section 9 table, section 10 files) and `aerenew/pqc-fork/pq-stark/README.md`. ## Self-consistency result (REAL, ran 2026-07-19) `python test_poseidon2_babybear.py` -> PASS=47014 FAIL=0. Standalone `java Poseidon2BabyBearSelfTest` -> PASS=13533 FAIL=0. Additionally the precompile's exact `Poseidon2Bb.permute` bytes were compiled in a throwaway and matched the references on all 13 shared states. Proven offline (genuine, and it IS self-consistency, not conformance): - x^7 bijection: 7 CONFIRMED as the minimal coprime degree (p-1 = 2^27*3*5); monomial inverse round-trips on 20k random x; S-box equals an independent bignum pow(x,7,p). - Determinism + genuine BIJECTION: an explicit inverse permutation round-trips on the fixed set + 3000 random states; 0 output collisions on the sample. - MDS / invertibility: M4 is MDS (all 69 square submatrices nonsingular); external and internal layers equal their explicit 16x16 matrices; both matrices are invertible over F_p. - Cross-language: Python, Node, and standalone Java produce BYTE-IDENTICAL permutation outputs on a shared 13-state input set (all-zero, [0..15], all-(p-1), structured, and LCG-random states). ## Conformance = [VERIFY] (NOT tested; no KAT claimed) This is the whole risk of Poseidon2 (the "two wrong copies agree" trap): a structurally-correct permutation with the WRONG constants is self-consistent and cross-language identical yet silently disagrees with the real prover. The constants here are NOT confirmed to be Plonky3's: - The 141 round constants are DETERMINISTIC PLACEHOLDERS (SHA-256 of a labelled counter, "AERE-PLACEHOLDER-NOT-PLONKY3|..."), cross-language reproducible but NOT Plonky3's. Plonky3 generates them from Xoroshiro128Plus::seed_from_u64(1) via new_from_rng_128. - INTERNAL_DIAG_M1_16 = [p-2, 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 32768] is a CANDIDATE observed via a lossy docs.rs summary of p3-baby-bear's POSEIDON2_INTERNAL_MATRIX_DIAG_16_BABYBEAR_MONTY. May be Montgomery-form; transcription unconfirmed; not checksum-verified. - ROUNDS_F=8, ROUNDS_P=13 are the commonly-cited counts; ROUNDS_P is [VERIFY] (Plonky3 poseidon2_round_numbers_128(16, 7)). - M4 and the MDS-light M_E construction are the Poseidon2-paper standard; byte identity vs p3-poseidon2 is [VERIFY]. Pinned conformance target (found in the repo's Cargo.lock, not vendored as source): Plonky3 `p3-poseidon2` and `p3-baby-bear` at crates.io `0.4.3-succinct` (checksums 522986377b2164c5f94f2dae88e0e0a3d169cc6239202ef4aeb4322d60feffd0 and d69e6e9af4eaaaa60f7bb9f0e0f73ebcbaefe7e00974d97ad0fa542d6a4f0890). [VERIFY: confirm the p3-poseidon2 BabyBear width-16 round constants + internal diagonal + round counts against SP1 v6.1.0 (Plonky3 0.4.3-succinct), regenerate the round constants from the pinned RNG, replace the placeholders, then run the real KAT (all-zero state, [0,1,...,15]) against p3-baby-bear's test_poseidon2_babybear output and report PASS/FAIL.] ## Top-level stays fail-closed `Poseidon2Bb.available = false` (constants are [VERIFY], so it is NOT flipped). With it false, the Challenger PoW check returns false, sampleQueryIndices returns empty, StarkConstraints.evaluateAtZeta returns UNAVAILABLE, and Fri.checkQuery returns UNAVAILABLE. `Sp1StarkVerifierPrecompiledContract.verify` therefore returns UNAVAILABLE and `computePrecompile` returns EMPTY (0x) for every input. The single `return VerifyResult.ACCEPT` line is unreachable. The "DO NOT ACTIVATE ON MAINNET / verifies nothing" banner is unchanged. On-chain ZK verifiers remain the classical BN254 Groth16 gateway. The multi-week port continues: components (c) Merkle/MMCS, the rest of (d) FRI, (e) AIR, (f) transcript are un-ported, and Poseidon2's own conformance is the flagged open item. Sub-component tally: 3 of 6 components now have implemented+tested pieces (a field COMPLETE, b Poseidon2 structure with [VERIFY] conformance, one constant-free slice of d). None makes 0x0AE8 accept.