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.
79 lines
5.2 KiB
Markdown
79 lines
5.2 KiB
Markdown
# Spec 2: PQ STARK-verify precompile 0x0AE8 core (port spec + one validated sub-component)
|
|
|
|
> **Scope caveat (2026-07-19 finding).** The port work here 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. The
|
|
> ~11-16 person-week estimate below is the cost of a BabyBear+FRI verifier; 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. Task: advance the native PQ STARK-verify precompile 0x0AE8 honestly. The
|
|
top-level verifier stays a fail-closed skeleton that verifies NOTHING; the deliverable is a
|
|
detailed porting spec plus ONE genuinely-tractable, independently-tested sub-component.
|
|
|
|
## Deliverables
|
|
|
|
1. Porting spec: `aerenew/docs/AERE-STARK-VERIFIER-PORT-SPEC.md` (new).
|
|
Component-by-component port plan, bottom-up dependency order:
|
|
(a) BabyBear field p = 2^31 - 2^27 + 1 and F_{p^4} ~0.5 wk, low risk (pin W)
|
|
(b) Poseidon2 over BabyBear (the hash) ~1.5-2 wk, error-prone constants
|
|
(c) Merkle / FRI vector commitment (MMCS) ~1-1.5 wk
|
|
(d) FRI folding + query-index derivation + LDT ~2-3 wk, hard (index slice done, see 2)
|
|
(e) AIR eval + SP1 recursion vk binding ~3-4 wk, HARDEST
|
|
(f) Fiat-Shamir transcript (Poseidon2 duplex) ~0.5-1 wk, pervasive
|
|
Each has: what it does, interface, the test vectors that validate it + their source, effort
|
|
estimate, hardest parts, and [VERIFY] flags. Total ~11-16 person-weeks (3-4 months + audit) for
|
|
one specialist. Stated plainly as a multi-week port; hardest = (e) recursion AIR, then (d) fold
|
|
arithmetic, then (b) Poseidon2 constants.
|
|
|
|
2. Implemented + tested sub-component: FRI query-index derivation (constant-free slice of (d)).
|
|
Chosen over Poseidon2 because it is fixed by public Plonky3 spec with NO secret round constants,
|
|
so it can be validated offline with running, PASSING tests. Poseidon2 conformance needs the exact
|
|
Plonky3 constants (offline it would only prove self-consistency, the "two wrong copies agree"
|
|
trap), so it is left as a fully-specified [VERIFY] port target in the spec.
|
|
Implements: `sampleBits(canonicalU32, bits)` (low-bits reduction of a challenger sample) and
|
|
`walk(index, logMaxHeight, logFinalPolyLen)` (per-layer folding-index walk: index, sibling=index^1,
|
|
index_pair=index>>1, parity; terminating in the final-poly domain).
|
|
Files:
|
|
- `aerenew/pqc-fork/pq-stark/fri_query_index_reference.py` (Python reference)
|
|
- `aerenew/pqc-fork/pq-stark/fri_query_index_reference.mjs` (Node, independent second language)
|
|
- `aerenew/pqc-fork/pq-stark/FriQueryIndexSelfTest.java` (standalone Java, no Besu classpath)
|
|
- `aerenew/pqc-fork/pq-stark/test_fri_query_index.py` (harness: goldens + invariants + alt-algo
|
|
+ cross-language agreement) -> `aerenew/pqc-fork/results/kat-results-fri-query-index.json`
|
|
- `FriQueryIndex` helper added to `Sp1StarkVerifierPrecompiledContract.java`, wired into
|
|
`Fri.checkQuery` (still returns UNAVAILABLE) behind the fail-closed top level.
|
|
|
|
## REAL test result (ran here)
|
|
|
|
- `python test_fri_query_index.py` -> PASS=100021 FAIL=0. Python + Node + Java produce byte-identical
|
|
results on the shared vector set (cross-language: java, node, python).
|
|
- `java FriQueryIndexSelfTest` -> PASS=80018 FAIL=0 (standalone, validates the exact Java helper that
|
|
ships in the precompile).
|
|
- Validates the index LOGIC vs the public Plonky3 p3-fri spec across three independent
|
|
implementations. Does NOT prove conformance to a real SP1 v6.1.0 trace -> that is [MEASURE]
|
|
(needs the Poseidon2 challenger + an exported proof; exact command in port spec section 8).
|
|
|
|
## Fail-closed confirmation
|
|
|
|
Top level unchanged: `StarkConstraints.evaluateAtZeta` still returns UNAVAILABLE, so `verify()`
|
|
returns UNAVAILABLE -> `computePrecompile` returns EMPTY for every input. Added a belt-and-braces
|
|
guard so an empty/short query-index array can never fall through to a vacuous ACCEPT. The Solidity
|
|
adapter still reverts on every proof. Honesty banners ("DO NOT ACTIVATE ON MAINNET / verifies
|
|
nothing yet") intact. On-chain ZK verifiers remain classical BN254 Groth16 (Shor-breakable), stated
|
|
plainly.
|
|
|
|
## Flags
|
|
|
|
- [VERIFY] sample_bits masks LOW bits (LSB) of as_canonical_u32 vs p3-challenger
|
|
- [VERIFY] arity-2 fold (sibling=index^1, index_pair=index>>1) vs p3-fri verifier.rs
|
|
- [VERIFY] logMaxHeight = log_max_degree + log_blowup; num_fold_rounds = logMaxHeight - logFinalPolyLen
|
|
- [VERIFY] BabyBear F_{p^4} non-residue W (skeleton cites x^4 - 11), Poseidon2 width 16 / 13 internal
|
|
rounds / M4 / diagonal / 141 round constants (all in the spec, NOT invented)
|
|
- [MEASURE] bit-reversal index-to-domain-point mapping vs a real Plonky3 trace
|
|
- [MEASURE] end-to-end derive_query_indices vs a real SP1 v6.1.0 inner proof
|
|
- [MEASURE] Poseidon2-BabyBear conformance vs p3-baby-bear KAT (whole permutation, port target)
|
|
|
|
Extra grounded fact (checked in the harness, not part of the FRI component): Poseidon2 S-box is x^7
|
|
because 7 is the smallest d>1 coprime to p-1 = 2^27 * 3 * 5.
|