aere-docs/AERE-STARK-POSEIDON2-CONSTANTS-CONFIRMED.md
Aere Network e4cead319d Initial public release
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.
2026-07-20 01:01:36 +03:00

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. See AERE-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:

  1. The 141 round constants are now the real Plonky3 values (128 external + 13 internal), generated by Xoroshiro128Plus::seed_from_u64(1) via new_from_rng_128 and extracted from the pinned crates.
  2. The internal linear layer was WRONG (a genuine bug, the "two wrong copies agree" trap). The pinned DiffusionMatrixBabyBear, as a canonical map, is M_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 used state[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:

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.