aere-docs/AERE-FORMAL-BROADEN-REPORT.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

116 lines
7.9 KiB
Markdown

# Formal-verification broadening: new contract SMT models + canonical runner consolidation
Date: 2026-07-19. Tooling: Python 3.14.4, z3 4.16.0 (real z3 verdicts, no fabricated greens).
All verdicts below were produced by actually running the scripts.
## Part 1: four new z3 SMT models (all PROVED, negative controls fired)
Each model proves its safety property by asserting NOT-property under the real Solidity
guards (z3 returns UNSAT) and pairs every proof with a firing negative control that removes
one guard and returns SAT (non-vacuity). DESIGN-level caveats and [VERIFY]/[MEASURE] items
are stated in each model's SUMMARY block exactly as the money-contract models do.
### a. pqfinality_smt.py -> PROVED (10 PROVED, 3 CEX-FOUND, 0 FAILED, rc=0)
Contracts: contracts/contracts/pqfinality/AereFinalityCertificateVerifier.sol +
AerePQAttestationKeyRegistry.sol
Proved: quorum threshold is exactly ceil(2N/3) = (2N+2)/3 (Q0 for all N>=1; Q0b anchors
N in {4,5,7,9} -> {3,4,5,6}); an accepted certificate meets that quorum (P1; P1b a 4-of-7
cert is rejected); it is bound to the live registry validatorSetRoot (P2) and size (P2b); it
is bound to the chainId+registry attestation domain so a cross-chain/registry certificate is
rejected (P3 via injective domain hash; P3b direct); a key rotation that changes the root
makes an old-root certificate unaccept-able (P4 via injective root hash); an empty validator
set is rejected (P5).
Negative controls (all fired SAT): drop quorum -> sub-quorum accepted; drop root binding ->
stale/forged root accepted; drop domain binding -> cross-chain replay accepted.
Caveats stated: SP1 gateway soundness (verifyProof reverts on invalid proof) is a trusted
primitive [VERIFY]; the off-chain zkVM aggregation circuit is [MEASURE], NOT implemented
(contract tests use a MOCK gateway); keccak256 injectivity (root/domain) is [VERIFY];
additive PQ finality, consensus stays classical ECDSA QBFT; DESIGN math not EVM bytecode.
### b. pqaggregate_smt.py -> PROVED (7 PROVED, 2 CEX-FOUND, 0 FAILED, rc=0)
Contract: contracts/contracts/mpc/AerePQAggregateVerifier.sol
Proved: a registered committee is well-formed (R0: root!=0, 1<=t<=n, scheme!=0); an accepted
authorization is EXACTLY the registered committee's key set (P1; P1b via committee-root
injectivity, so a foreign key set is rejected); it is bound to the caller's message digest
(P2); it proves at least threshold t distinct signatures (P3); it binds size and scheme as
defense in depth (P4); and the on-chain accept reads only O(1) committee/public fields (keys
not stored), so verification cost is independent of n (P5).
Negative controls (all fired SAT): drop root binding -> a different committee's key set
authorizes; drop digest binding -> a proof for message A authorizes message B.
Caveats stated: SP1 gateway soundness [VERIFY]; off-chain zkVM aggregation circuit [MEASURE],
not implemented (MOCK gateway); keccak256 injectivity [VERIFY]; account/authorization
aggregation not consensus, no funds, no admin; DESIGN math not EVM bytecode.
### c. credential_registry_smt.py -> PROVED (7 PROVED, 3 CEX-FOUND, 0 FAILED, rc=0)
Contracts: contracts/contracts/compliance/AereTrustRegistry.sol + AereVerifiableCredential.sol
Proved: issuance requires accreditation (A: anchor success => Active AND in-scope; A2: a
None/Suspended/Revoked or out-of-scope issuer cannot anchor) and a valid Falcon-512 issuer
signature (A3); the status history is append-only so a committed record cannot be rewritten
(B, via the standard append relation); revocation is terminal (C: from Revoked no transition
returns to Active); and both the anchored (isValid, D) and presented (verifyPresented, D2)
verification paths are fail-closed on expired / not-yet-valid / revoked / un-accredited.
Negative controls (all fired SAT): drop the accreditation check -> a revoked issuer issues;
allow a status overwrite -> a committed record is silently rewritten; drop the validity
window -> an expired credential is accepted.
Caveats stated: Falcon-512 precompile 0x0AE1 soundness modelled as the sigValid predicate
[VERIFY]; the Bitstring Status List and live issuer status are trusted external oracles;
application-layer, no funds, consensus stays classical ECDSA QBFT; legal weight of any
accreditation is external; DESIGN logic not EVM bytecode.
### d. recovery_registry_smt.py -> PROVED (5 PROVED, 2 CEX-FOUND, 0 FAILED, rc=0)
Contract: contracts/contracts/AereRecoveryRegistry.sol
Proved: a record is written only if the Falcon-512 signature verifies (FC, fail-closed) and
is well-formed (FC2: fault kind / heights / validator set); the per-operator nonce strictly
increases on every write (NO); a nonce-k signature cannot be replayed once the nonce advances
because the record hash binds the nonce (RP, via injective nonce hash + EUF-CMA verify
predicate); and the records array is append-only so a committed record is never rewritten (AP).
Negative controls (all fired SAT): drop the nonce binding -> one signature replays to rewrite
history; drop append-only -> a committed record is silently overwritten.
Caveats stated: Falcon-512 precompile 0x0AE1 soundness (EUF-CMA, input parsing,
empty-return-is-invalid) modelled as the verify predicate [VERIFY]; keccak256 injectivity of
the nonce-bound record hash [VERIFY]; records attestations only, does not observe consensus or
activate PQ consensus (still classical ECDSA QBFT); uint64 nonce cannot realistically
overflow; DESIGN logic not EVM bytecode.
## Part 2: canonical runner consolidation
File changed: aerenew/formal-consensus/run_consensus_verification.py (had a hardcoded MODELS
list of 8 consensus models). Added a CONTRACT_MODELS section wiring in all 7 new contract SMT
scripts written in this loop, keeping the 8 consensus models intact:
computemarket_smt, destinationsettler_smt, migrator_smt (the 3 money models) +
pqfinality_smt, pqaggregate_smt, credential_registry_smt, recovery_registry_smt (the 4 new).
The runner now also captures each child's output and tallies the per-check verdict lines.
### Canonical runner fresh totals (real run, exit 0)
models run: 15 passed: 15 (8 consensus + 7 contract)
verdict lines: 128 PROVED 79 CEX-FOUND 0 FAILED
RESULT: ALL MODELS PASS (proofs PROVED, negative controls fired)
Breakdown of the 128/79 (per-check verdict lines, i.e. distinct property checks):
- 4 new models: 29 PROVED / 10 CEX-FOUND (pqfinality 10/3, pqaggregate 7/2,
credential_registry 7/3, recovery_registry 5/2)
- 3 fund-flow models: 26 PROVED / 11 CEX-FOUND (computemarket 16/3, destinationsettler 5/4,
migrator 5/4)
- 8 consensus models: 73 PROVED / 58 CEX-FOUND (remainder)
Note on scope: the 7 wired-in contract models live in aerenew/formal-consensus/ (the same
directory as the canonical runner). The research-stage staging copy
(aerenew/research-stage/formal-consensus/) is a separate curated publish target with its own
committed expected-output.log and was left unchanged.
### REPRODUCE.md update
Updated aerenew/REPRODUCE.md section 3b: the "canonical in-tree" subsection previously cited
"8 models" / "8 of 8 models PASS". It now reads "15 models: 8 consensus + 7 contract", "15 of
15 models PASS", with the real fresh runner tally of 128 PROVED / 79 CEX-FOUND / 0 FAILED, the
per-group breakdown above, the names of the 7 newly-added contract models, and a restatement
of the NOT-property-UNSAT + firing-negative-control discipline and the per-model DESIGN /
[VERIFY] / [MEASURE] boundaries. No fabricated numbers: every figure is from the actual run.
The staging "(10 models)" section and the older bash-loop "(9 models)" contract section were
left as-is (correct and separate).
## Honesty posture
- All verdicts are real z3 output; no green was fabricated.
- Every model has at least one firing negative control (SAT under a removed guard).
- No contract was modified. Only SMT scripts were added, the runner was extended, and
REPRODUCE.md was updated with real fresh numbers.