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.
4.8 KiB
Poseidon2-BabyBear width-16 constants: confirmation + conformance (task summary)
Scope caveat (2026-07-19 finding). These constants are 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 over the KoalaBear field, so these BabyBear Poseidon2 constants are not SP1 6.1.0's constants, FRI and DEEP-ALI do not apply to SP1 6.1.0, and this work does not verify SP1 6.1.0 proofs. 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. Component (b) of the PQ STARK-verify precompile 0x0AE8.
Outcome (headline)
- Constants: CONFIRMED-FROM-SOURCE.
- Conformance KAT: PASSED (3/3 real known-answer vectors reproduced byte-for-byte).
- Top-level 0x0AE8: still fail-closed (returns EMPTY for every input). DO NOT ACTIVATE banner kept.
What the prior pass had wrong, and what was confirmed
The prior pass implemented the permutation STRUCTURE but used SHA-256 PLACEHOLDER round constants
(AERE-PLACEHOLDER-NOT-PLONKY3) and a textbook internal layer. Two things were confirmed/fixed:
- The 141 round constants are now the real Plonky3 values (128 external + 13 internal), generated by
Xoroshiro128Plus::seed_from_u64(1)vianew_from_rng_128and extracted from the pinned crates. - The internal linear layer was WRONG (a genuine bug, the "two wrong copies agree" trap). The pinned
DiffusionMatrixBabyBear, as a canonical map, isM_I = R^{-1} * (J + diag(D))with R^{-1} = 943718400 = (2^32)^{-1} mod p, i.e.out[i] = R_INV*(sum + D[i]*state[i]). The prior pass usedstate[i]*D[i] + sum(no R^{-1}), which is self-consistent but disagrees with the prover. This is the Montgomery-form subtlety the task flagged. Verified by recovering the exact 16x16 canonical matrix from the library (off-diagonal = R^{-1}, diagonal = R^{-1}*(1+D[i])).
Also confirmed: ROUNDS_F=8, ROUNDS_P=13 (poseidon2_round_numbers_128(16,7)); M4 =
2,3,1,1],[1,2,3,1],[1,1,2,3],[3,1,1,2 (recovered from Poseidon2ExternalMatrixGeneral); the
internal diagonal D = [p-2,1,2,4,...,8192,32768] (canonical). The x^7 S-box was already solid.
Source (exact) and method
Pinned target: p3-baby-bear / p3-poseidon2 crates.io 0.4.3-succinct (checksums
d69e6e9a... / 52298637..., matching aerenew/.../Cargo.lock). The numbers are authoritative
because the pinned crates were compiled and executed (cargo 1.97.0; the fresh build resolved the same
two checksums, byte-identical to the AERE pin). Corroborating source pages:
- https://docs.rs/crate/p3-baby-bear/0.4.3-succinct/source/src/poseidon2.rs (diagonal, RNG comment)
- https://docs.rs/crate/p3-monty-31/0.4.3-succinct/source/src/monty_31.rs (Standard sampling, new_monty)
- https://docs.rs/crate/p3-poseidon2/0.4.3-succinct/source/src/lib.rs (new_from_rng_128 order)
- https://github.com/Plonky3/Plonky3 poseidon2/src/{round_numbers.rs, external.rs}
- https://github.com/rust-random/rngs rand_xoshiro (SplitMix64 seed, next_u32 = next_u64>>32)
Full provenance + the KAT vectors: aerenew/pqc-fork/pq-stark/spec-poseidon2-constants.md.
Conformance KAT (executed from the pinned library, reproduced by all references)
- zeros [0;16] -> [1787823396, 953829438, 89382455, ...]
- iota [0..15] -> [157639285, 1851003038, 1852457045, ...]
- testvec (p3 test) -> [512585766, 975869435, 1921378527, ...]
Results: python test_poseidon2_babybear.py -> PASS=47017 FAIL=0 (Python/Node/Java byte-identical,
3/3 conformance KATs); java Poseidon2BabyBearSelfTest -> PASS=13536 FAIL=0.
Files changed
aerenew/pqc-fork/pq-stark/poseidon2_babybear_reference.py/.mjs— real constants, R_INV internal layer, conformance KATs.aerenew/pqc-fork/pq-stark/Poseidon2BabyBearSelfTest.java— same; self-test PASS=13536.aerenew/pqc-fork/pq-stark/test_poseidon2_babybear.py— added conformance stage; honest status.aerenew/pqc-fork/precompiles/Sp1StarkVerifierPrecompiledContract.java— real constants, R_INV internal layer,Poseidon2Bb.available = true; decoupled challenger gate (Challenger.spongePorted = false) so the top level stays fail-closed.aerenew/pqc-fork/pq-stark/README.md,aerenew/docs/AERE-STARK-VERIFIER-PORT-SPEC.md— real status.- New:
aerenew/pqc-fork/pq-stark/spec-poseidon2-constants.md(provenance/citation doc).
Fail-closed confirmation
Poseidon2Bb.available = true (permutation confirmed), but the duplex sponge is a separate un-ported
component: Challenger.spongePorted = false -> checkProofOfWork returns false and
sampleQueryIndices returns empty; StarkConstraints.evaluateAtZeta and Fri.checkQuery return
UNAVAILABLE. So verify(...) never reaches return ACCEPT; the precompile returns EMPTY for every
input. The DO NOT ACTIVATE banner is intact.