The published line and the local line of this repository had no common ancestor: the public one carried the hygiene pass (no host names, no internal paths), the local one carried a month of corrections that never shipped. This commit ports the local work onto the public line, keeping the public hygiene wording wherever the two touched the same sentence, and keeping the public version of AERE-CROSS-CLIENT-DETERMINISM.md entirely. Carried: LICENSE/LICENSING corrections, VERIFY-POLICY.md, CITATIONS-UNRESOLVED.md remeasured 2026-08-11, the 'audited' adjective removed from next to Bouncy Castle, citation paths rewritten to published form, AIP-8, the QA consolidation report, the second EIP validation pass, fork-height corrections, the AereSink / threshold-factory correction, the forge test floor, and the architecture-map updates.
389 lines
22 KiB
Markdown
389 lines
22 KiB
Markdown
# AIP-8: Post-Quantum-Authorized Transaction Envelope (EIP-2718 Type 0x2A)
|
|
|
|
## Preamble
|
|
|
|
| Field | Value |
|
|
| --- | --- |
|
|
| AIP | 8 |
|
|
| Title | Post-Quantum-Authorized Transaction Envelope (EIP-2718 Type 0x2A) |
|
|
| Author | Aere Network Foundation |
|
|
| Type | Standards Track |
|
|
| Category | Core |
|
|
| Status | Draft |
|
|
| Created | 2026-07-18 |
|
|
| Requires | 7 |
|
|
| Supersedes | None |
|
|
| Superseded-By | None |
|
|
| Ratification | Not ratified; Draft. Ratifier is the founder (pre-decentralization). |
|
|
|
|
## Abstract
|
|
|
|
This AIP specifies a new EIP-2718 typed transaction, `TransactionType = 0x2A`, whose
|
|
**sender authorization is a NIST post-quantum signature** (Falcon-512 or ML-DSA-44)
|
|
rather than a secp256k1 ECDSA signature. The transaction carries a scheme selector, a
|
|
raw PQC public key, and a PQC signature; the sender address is derived from the public
|
|
key, and the transaction is valid only if the signature verifies against the exact same
|
|
native precompiles that are already live on AERE mainnet chain 2800 (Falcon-512 `0x0AE1`,
|
|
ML-DSA-44 `0x0AE3`, activated at block 9,189,161 per AIP-7). It makes ordinary value and
|
|
contract-call transactions authorizable by a quantum-resistant key with no smart-account
|
|
indirection. This is a **base-layer execution change requiring a coordinated Besu hard
|
|
fork**; it is NOT yet live. It is explicit that this does not change how AERE blocks are
|
|
proposed, signed, or committed: consensus remains classical secp256k1 ECDSA QBFT and is
|
|
not post-quantum. A deploy-today reference path that needs no fork
|
|
(`AerePQCTxAccount.sol`, an ERC-4337 account) accompanies this AIP.
|
|
|
|
## Motivation
|
|
|
|
AERE has live, mainnet-proven post-quantum signature verification at the precompile layer
|
|
(AIP-7) and usable post-quantum authorization at the account layer (AerePQCAccount,
|
|
AereThresholdAccount, AerePQCSocialRecoveryModule). What is still missing is the most
|
|
basic object of all: an ordinary externally-originated transaction whose right to spend an
|
|
account is a post-quantum signature.
|
|
|
|
Today every transaction on chain 2800, including one that calls a post-quantum contract,
|
|
is itself authorized by a secp256k1 ECDSA signature. The account's ability to move its
|
|
native balance rests on ECDSA. A cryptographically-relevant quantum computer running
|
|
Shor's algorithm breaks secp256k1: it recovers the private key from the public key, and on
|
|
any account that has ever sent a transaction the public key is already on-chain. Account-
|
|
layer PQC (a 4337 smart account) closes this for smart-contract wallets, but it cannot
|
|
protect a plain externally-owned account (EOA), and it adds a bundler/EntryPoint and a
|
|
deployment step. A base-layer post-quantum transaction type closes the gap for the EOA
|
|
itself: the account is a hash of a PQC public key, and only a PQC signature can spend it.
|
|
|
|
The goal is a transaction type that (1) reuses the audited, mainnet-live precompile verify
|
|
paths verbatim (no new cryptography), (2) is a pure function of the transaction bytes for
|
|
validation (like ECDSA sender recovery, so mempool validation reads no state), (3) fits far
|
|
under the Fusaka EIP-7825 per-transaction gas cap, and (4) is a strictly additive,
|
|
client-only hard fork with no re-genesis, exactly like AIP-7.
|
|
|
|
## Specification
|
|
|
|
The keywords MUST, SHOULD, and MAY are to be interpreted as in RFC 2119.
|
|
|
|
### Transaction type byte
|
|
|
|
The transaction type is `0x2A`.
|
|
|
|
EIP-2718 constrains a valid `TransactionType` to the range `[0x00, 0x7f]`: a first byte
|
|
`>= 0xc0` is ambiguous with the RLP list header of a legacy transaction and is excluded,
|
|
and EIP-2718 recommends implementers stay within `0x00`..`0x7f`. Within that range the
|
|
Ethereum L1 assignments are `0x01` (EIP-2930), `0x02` (EIP-1559), `0x03` (EIP-4844), and
|
|
`0x04` (EIP-7702); AERE recognizes all four. `0x2A` is chosen because it is unassigned by
|
|
any Ethereum L1 EIP and sits well below the `0x64`..`0x7f` band that existing L2s have
|
|
informally colonized (Arbitrum `0x64`..`0x6c`, zkSync Era `0x71`+, Optimism deposit
|
|
`0x7e`, Celo `0x7b`..`0x7d`), which minimizes the chance that an imported third-party tool
|
|
misparses an AERE PQ transaction as some other chain's type. `0x2A` is reserved henceforth
|
|
in the AERE chain specification for this purpose. If Ethereum L1 later assigns `0x2A`, AERE
|
|
will re-evaluate to preserve equivalence, as AIP-7 commits to for the precompile band.
|
|
|
|
### Signature-scheme selector
|
|
|
|
A one-byte `pq_scheme` selects the NIST scheme and the precompile that validates it. The
|
|
values match AIP-7 and AerePQCAttestation:
|
|
|
|
| `pq_scheme` | Scheme | Precompile | Public-key length | Signature envelope |
|
|
| --- | --- | --- | --- | --- |
|
|
| `0x01` | Falcon-512 | `0x0AE1` | 897 bytes (header `0x09`) | `nonce(40) || esig` (esig starts `0x29`) |
|
|
| `0x03` | ML-DSA-44 | `0x0AE3` | 1312 bytes | `sig`, exactly 2420 bytes |
|
|
|
|
`pq_scheme` `0x02` (Falcon-1024, `0x0AE2`, 1793-byte pk) and `0x04` (SLH-DSA-128s, `0x0AE4`,
|
|
32-byte pk, 7856-byte sig) MAY be enabled by the same rules; they are omitted from the
|
|
mandatory set because Falcon-512 (NIST level 1, smallest signature) and ML-DSA-44 (FIPS 204,
|
|
fixed-size, conservative) span the practical trade-off between signature size and margin.
|
|
Any other value MUST be rejected as an invalid transaction.
|
|
|
|
### RLP wire format
|
|
|
|
A type-`0x2A` transaction is the concatenation of the type byte and the RLP encoding of a
|
|
12-element list:
|
|
|
|
```
|
|
0x2A || rlp([
|
|
chain_id, # scalar; MUST equal 2800 for AERE mainnet
|
|
nonce, # scalar; the PQC-derived sender's account nonce
|
|
max_priority_fee_per_gas, # scalar (EIP-1559 semantics)
|
|
max_fee_per_gas, # scalar (EIP-1559 semantics)
|
|
gas_limit, # scalar
|
|
to, # 20-byte address, or empty (0x) for contract creation
|
|
value, # scalar
|
|
data, # byte string
|
|
access_list, # EIP-2930 [[address, [storageKey, ...]], ...]
|
|
pq_scheme, # single byte, 0x01 or 0x03 (see selector table)
|
|
pq_public_key, # raw NIST public key for pq_scheme
|
|
pq_signature # signature envelope for pq_scheme (see selector table)
|
|
])
|
|
```
|
|
|
|
The fee, gas, `to`, `value`, `data`, and `access_list` fields are identical in meaning to
|
|
EIP-1559 (type `0x02`) with an EIP-2930 access list, so existing execution and fee-market
|
|
logic is unchanged. The three trailing fields replace the ECDSA `(y_parity, r, s)` triple.
|
|
|
|
The transaction hash is `keccak256(0x2A || rlp([...all 12 fields...]))`, as for any typed
|
|
transaction.
|
|
|
|
### Sender derivation
|
|
|
|
The sender is derived from the PQC public key and the scheme, not from signature recovery:
|
|
|
|
```
|
|
sender = keccak256(pq_scheme || pq_public_key)[12:32] # last 20 bytes
|
|
```
|
|
|
|
Binding the address to `pq_scheme` as well as the key means the same raw key bytes under a
|
|
different scheme selector yield a different account, so there is no cross-scheme aliasing. A
|
|
user migrates to post-quantum custody by moving assets to their `sender` address; from then
|
|
on only a valid PQC signature can spend it. Unlike ECDSA, the public key is transmitted in
|
|
full on every transaction (the verify precompiles are stateless), which is safe: Falcon and
|
|
ML-DSA remain secure with the public key exposed. This is the point of the design, not a
|
|
weakness.
|
|
|
|
### Signing message and verification
|
|
|
|
`pq_signature` MUST be a valid signature, under `pq_public_key` and `pq_scheme`, over the
|
|
32-byte digest:
|
|
|
|
```
|
|
sig_hash = keccak256(0x2A || rlp([
|
|
chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit,
|
|
to, value, data, access_list, pq_scheme, pq_public_key
|
|
])) # the 12-field list WITHOUT pq_signature
|
|
```
|
|
|
|
Validation MUST assemble the precompile input for `pq_scheme` exactly as
|
|
AerePQCAttestation / AerePQCKeyRegistry do, with `sig_hash` as the signed message, and
|
|
accept the transaction only if the corresponding precompile returns the 32-byte
|
|
"valid" word `0x…01`:
|
|
|
|
- Falcon-512: `input = pk(897) || sm`, where `sm = sigLen(2, big-endian) || nonce(40) ||
|
|
sig_hash(32) || esig` and `sigLen == esig.length`; call `0x0AE1`.
|
|
- ML-DSA-44: `input = pk(1312) || sig(2420) || sig_hash(32)`; call `0x0AE3`.
|
|
|
|
The client MUST use the same Bouncy Castle 1.83 verify path the precompile wraps, so
|
|
that transaction validation and an in-EVM `STATICCALL` to the precompile agree bit-for-bit
|
|
on every `(pq_public_key, sig_hash, pq_signature)` triple. A transaction whose signature
|
|
does not verify has no valid sender and is invalid: it MUST be rejected from the mempool and
|
|
MUST NOT be included in a block, exactly as an ECDSA transaction with an unrecoverable
|
|
signature is.
|
|
|
|
### Nonce and replay handling
|
|
|
|
- **Cross-chain replay** is prevented by `chain_id` inside both the transaction and
|
|
`sig_hash`: a signature for chain 2800 does not verify for any other chain id.
|
|
- **Intra-chain replay and ordering** are enforced by `nonce`, the account nonce of the
|
|
PQC-derived `sender`, tracked in world state and incremented on inclusion, identical to an
|
|
ECDSA account. A given `(sender, nonce)` can be mined at most once.
|
|
- **Cross-protocol replay** (reusing a PQ tx signature as an AerePQCAttestation,
|
|
AerePQCKeyRegistry, or ERC-4337 authorization, or vice-versa) is prevented because those
|
|
surfaces sign structurally different messages: attestation/registry/account challenges are
|
|
`keccak256(abi.encode(DOMAIN, ...))` or `abi.encodePacked(domain, hash)` byte strings that
|
|
can never equal the `0x2A || rlp(...)` preimage of `sig_hash`. The leading type byte `0x2A`
|
|
in the signed preimage is the domain tag for this transaction type, mirroring how EIP-1559
|
|
signs `keccak256(0x02 || rlp(...))`.
|
|
|
|
### Gas accounting
|
|
|
|
Intrinsic gas for a type-`0x2A` transaction is:
|
|
|
|
```
|
|
intrinsic = 21000
|
|
+ calldata_gas(entire type-0x2A payload, including pq_public_key + pq_signature)
|
|
+ access_list_gas # EIP-2930: 2400 per address, 1900 per storage key
|
|
+ PQ_VERIFY_GAS[pq_scheme] # fork constant, MUST equal the live precompile verify gas
|
|
```
|
|
|
|
`PQ_VERIFY_GAS` MUST equal the marginal verify-op gas the corresponding precompile charges,
|
|
which AIP-7 measured on the pre-activation scratch fork (chain 28099) and carried to
|
|
mainnet:
|
|
|
|
| Scheme | `PQ_VERIFY_GAS` (measured, AIP-7) |
|
|
| --- | --- |
|
|
| Falcon-512 (`0x0AE1`) | 40,000 |
|
|
| ML-DSA-44 (`0x0AE3`) | 55,000 |
|
|
| Falcon-1024 (`0x0AE2`) | 75,000 |
|
|
| SLH-DSA-128s (`0x0AE4`) | 350,000 |
|
|
|
|
The dominant *additional* cost versus an EIP-1559 transaction is the calldata for the public
|
|
key and signature. Approximate PQ-material sizes and the resulting calldata component (to be
|
|
measured on the scratch fork; calldata is priced at EIP-2028 rates, subject to the EIP-7623
|
|
floor):
|
|
|
|
| Scheme | pk bytes | sig-envelope bytes | PQ material | approx. calldata gas |
|
|
| --- | --- | --- | --- | --- |
|
|
| Falcon-512 | 897 | ~707 (40 + 1 + ~666) | ~1,605 B | ~24,000 (to be measured) |
|
|
| ML-DSA-44 | 1,312 | 2,420 | ~3,732 B | ~56,000 (to be measured) |
|
|
|
|
A complete Falcon-512 PQ transaction therefore lands near `21,000 + ~24,000 + 40,000 ≈
|
|
85,000` gas of intrinsic cost before execution, consistent with AIP-7's measured
|
|
end-to-end Falcon-512 verify-and-record transaction of 86,336 gas; a ML-DSA-44 PQ
|
|
transaction lands near `21,000 + ~56,000 + 55,000 ≈ 132,000`. Both are a tiny fraction of
|
|
the EIP-7825 per-transaction cap of 16,777,216 (2^24), leaving the full block-execution
|
|
budget for the call itself.
|
|
|
|
`PQ_VERIFY_GAS` is folded into intrinsic gas so the sender pays for the verification work
|
|
that validators perform. Because signature validity is a precondition of transaction
|
|
validity, a transaction with an invalid signature is never included and thus is never
|
|
charged on-chain, exactly as with a bad ECDSA signature; it simply cannot be mined.
|
|
|
|
### Base-layer activation sketch (Besu fork)
|
|
|
|
The change is a strictly additive execution-layer fork of the AERE Besu build (base
|
|
`hyperledger/besu:26.4.0`, the same tree that carries the AIP-7 precompiles). No re-genesis,
|
|
no state migration. The implementation touches, at minimum:
|
|
|
|
1. **TransactionType.** Add `PQ_AUTHORIZED((byte) 0x2A)` to
|
|
`org.hyperledger.besu.datatypes.TransactionType`.
|
|
2. **Codec.** Add a `PQAuthorizedTransactionDecoder` / `PQAuthorizedTransactionEncoder`
|
|
implementing the 12-field RLP layout above and register them in the `TransactionDecoder` /
|
|
`TransactionEncoder` dispatch. Extend the `Transaction` model to carry `pqScheme`,
|
|
`pqPublicKey`, and `pqSignature`, and override sender computation for this type to
|
|
`keccak256(pqScheme || pqPublicKey)[12:]`, defined only when the PQC signature verifies.
|
|
3. **PQ signature verifier.** A `PQAuthorizedSignatureVerifier` that calls the exact same
|
|
Bouncy Castle 1.83 BCPQC verify path (`AereFalconSupport.verify`, ML-DSA `verifyInternal`)
|
|
the `0x0AE1` / `0x0AE3` precompiles wrap. Zero new cryptography; reuse the precompile
|
|
adapters through the same classloader-isolation boundary AIP-7 established.
|
|
4. **Validation.** In `MainnetTransactionValidator` (via `TransactionValidatorFactory`), for
|
|
type `0x2A`: reconstruct `sig_hash`, verify the PQC signature (reject with an INVALID
|
|
reason on failure), derive the sender, and validate nonce, balance, and intrinsic gas as
|
|
usual.
|
|
5. **Gas.** Extend the `GasCalculator` with `pqAuthorizationIntrinsicGasCost(scheme, payload)`
|
|
returning the calldata component plus `PQ_VERIFY_GAS[scheme]`, wired into
|
|
`transactionIntrinsicGasCost`.
|
|
6. **Mempool and wire.** Teach `TransactionPool` and the eth/68 `Transactions` /
|
|
`PooledTransactions` codecs to carry the larger typed body; expose the type in the JSON-RPC
|
|
transaction serialization (`eth_getTransactionByHash`, receipts).
|
|
7. **Fork gating.** Add an `AerePQTx` milestone to `ProtocolScheduleBuilder` / the chain spec,
|
|
activated at a future block or timestamp distinct from the AIP-7 precompile activation.
|
|
Before activation, a `0x2A` first byte is an unknown type and is rejected; after
|
|
activation it is valid. Because chain 2800 runs seven QBFT validators under one operator on
|
|
one client, activation is a flag-day client upgrade across the validator set, exactly as in
|
|
AIP-7. A non-upgraded validator would reject the type and fork off, so the upgrade is
|
|
mandatory at the fork block.
|
|
8. **Differential testing.** Gate ship on a test that, for the NIST KAT vectors in
|
|
`pqc-fork/kat` and randomized cases, asserts the transaction-validation verify agrees
|
|
bit-for-bit with a `STATICCALL` to the matching precompile over the same
|
|
`(pk, sig_hash, sig)`, plus round-trip encode/decode and a full mine-and-receipt path on an
|
|
isolated testnet.
|
|
|
|
Consensus is untouched: QBFT proposal, the committed-seal ECDSA signatures, and block
|
|
structure are unchanged; type `0x2A` is simply another transaction a block may contain, with
|
|
its own receipt type.
|
|
|
|
## Rationale
|
|
|
|
**Full public key in every transaction, not a registry keyId.** An alternative shrinks
|
|
calldata by replacing `pq_public_key` with a `keyId` into AerePQCKeyRegistry
|
|
(`0x1eCa…3691`). It is rejected for the base type because it makes transaction validation
|
|
depend on world state (a registry lookup), which breaks the property that a transaction's
|
|
validity is a pure function of its own bytes, the same property ECDSA sender recovery has,
|
|
and which mempool validation relies on. The stateless full-key form keeps validation pure
|
|
and matches how the live precompiles already work. A registry-indexed companion type could be
|
|
specified later once the state-dependency implications for the mempool are worked through.
|
|
|
|
**Sender = hash of (scheme, key), reusing the 20-byte address space.** This keeps the PQ
|
|
account indistinguishable from any other address to every downstream contract, tool, and
|
|
explorer: balances, `CALL`, `msg.sender`, and logs all behave normally. The only thing that
|
|
changes is who may originate a transaction from that address.
|
|
|
|
**Type `0x2A` over a higher value.** Staying in the low half of the valid range and away
|
|
from the L2-colonized `0x64`..`0x7f` band reduces cross-ecosystem tool confusion, at no cost.
|
|
|
|
**A base-layer type at all, given 4337 exists.** ERC-4337 already gives post-quantum
|
|
authorization for smart-contract wallets and is the recommended path today (see the reference
|
|
implementation). But a 4337 account cannot protect a plain EOA, requires a deployed contract
|
|
and a bundler, and pays EVM-execution overhead for validation. The base type is the only way
|
|
to make an *ordinary* account post-quantum, and it prices verification at the native
|
|
precompile cost rather than in-EVM. The trade-off is that it requires a hard fork and touches
|
|
the entire transaction-decoding surface of the ecosystem, which is exactly why it is filed as
|
|
a Draft with a shipping 4337 alternative rather than activated immediately.
|
|
|
|
## Backwards Compatibility
|
|
|
|
Additive. Existing legacy, `0x01`, `0x02`, `0x03`, and `0x04` transactions are unaffected.
|
|
Before the `AerePQTx` fork block, a `0x2A` transaction is an unknown type and is rejected by
|
|
all nodes; after it, all nodes accept it. There is no change to existing accounts, contracts,
|
|
receipts of other types, or the genesis state root.
|
|
|
|
Ecosystem tooling that decodes raw transactions (wallets, explorers, indexers, the RPC
|
|
transaction serializer, hardware-wallet firmware, signing libraries) MUST learn type `0x2A`
|
|
to build, sign, display, or index these transactions. Tools that only handle types they
|
|
recognize will treat a `0x2A` transaction as opaque or unsupported rather than misdecode it,
|
|
because the type byte is self-describing. This ecosystem surface is the principal cost of the
|
|
change and the reason the ERC-4337 path is preferred for immediate use.
|
|
|
|
Because AERE runs all validators under one operator and one client, activation is a
|
|
mandatory flag-day client upgrade across the validator set at the fork block, as in AIP-7. A
|
|
validator that had not upgraded would reject the type and fork.
|
|
|
|
## Security Considerations
|
|
|
|
**This change does not make AERE consensus post-quantum.** Validators continue to sign
|
|
classical secp256k1 QBFT committed seals; blocks are proposed and committed exactly as today.
|
|
Type `0x2A` makes an individual transaction's *sender authorization* post-quantum. It does
|
|
not make block production, finality, or the validator set post-quantum, and any claim to that
|
|
effect on the basis of this AIP would be false and must not be made.
|
|
|
|
**A valid signature is not authorization beyond spend rights.** A "valid" precompile decision
|
|
establishes only that `pq_signature` is a valid signature by `pq_public_key` over `sig_hash`.
|
|
Freshness and ordering come from `nonce`; scope comes from the tx fields themselves. There is
|
|
no key rotation or recovery at this layer: losing the PQC private key loses the account, the
|
|
same as losing an ECDSA key. Users who need rotation or social recovery should hold assets in
|
|
an ERC-7579 account guarded by AerePQCSocialRecoveryModule instead of, or in addition to, a
|
|
PQ EOA.
|
|
|
|
**Single operator, one client (no client-diversity safety net).** Chain 2800's seven QBFT
|
|
validators are one operator on one execution client. A consensus bug in the PQ-transaction
|
|
validation path (for example a decoder edge case, or a divergence between the tx-validation
|
|
verify and the precompile verify) would not be caught by a second live client, because there
|
|
is none. This raises the bar for external audit and for the mandatory bit-for-bit
|
|
differential testing in the activation sketch.
|
|
|
|
**Determinism.** Transaction validation, like a precompile, must be deterministic and read no
|
|
node-local state or block context beyond the transaction and the account nonce/balance.
|
|
Falcon verification MUST use the integer-only verify path (never the floating-point signing
|
|
path). Malformed structure MUST be rejected deterministically as an invalid transaction, not
|
|
faulted.
|
|
|
|
**Public-key exposure is intended.** The public key is on-chain from the account's first
|
|
transaction. This is safe for Falcon and ML-DSA and is the mechanism by which the account is
|
|
quantum-resistant; it is called out only to preempt the ECDSA-era intuition that an unspent
|
|
address "hides" its key.
|
|
|
|
**Not live; external audit pending.** This is a Draft specification and a reference-
|
|
implementation sketch. Nothing here is deployed on chain 2800. The precompiles it reuses
|
|
carry an internal self-audit only (AIP-7). This transaction type MUST NOT secure material
|
|
value until it is implemented, differentially tested against the live precompiles, and
|
|
covered by an external security audit.
|
|
|
|
## Reference Implementation and On-Chain Deployment
|
|
|
|
**Not yet live.** The base-layer fork above is a specification and a Besu implementation
|
|
sketch, not a deployed change.
|
|
|
|
**Deploy-today reference path (no fork required).** The same user-visible guarantee, "a
|
|
transaction is authorized by a post-quantum signature and nothing else", is delivered today,
|
|
with no base-layer change, by an ERC-4337 v0.7 smart account whose sole owner is a NIST PQC
|
|
key and whose `validateUserOp` verifies via the live precompiles:
|
|
|
|
- Contract: `contracts/contracts/pqc/AerePQCTxAccount.sol` (this repository).
|
|
- Tests: `contracts/test/AerePQCTxAccount.test.js` (MockPQCPrecompile across all four schemes
|
|
plus a genuine Falcon-512 path through the NIST-KAT-proven AereFalcon512Verifier).
|
|
- **Verified 2026-07-18:** compiled and tested under the canonical Hardhat toolchain,
|
|
`npx hardhat compile` then `npx hardhat test test/AerePQCTxAccount.test.js`. The contract
|
|
compiles clean and all 20 tests pass: the mock verifier across all four schemes, the
|
|
domain-separation and single-use replay checks, and two genuine Falcon-512 paths through the
|
|
NIST-KAT-proven verifier. This bullet records an actual machine run; it should be read as a
|
|
verified result, not an untested present-tense assertion.
|
|
- It calls the live precompiles (`0x0AE1`..`0x0AE4`) directly with the identical wire
|
|
encoding proven on mainnet by AerePQCAttestation
|
|
(`0x465d9E3b476BF98Aa1393079e240Db5D2a9bEA6A`) and AerePQCKeyRegistry
|
|
(`0x1eCa3c5ADcBD0b22636D8672b00faC6D89363691`), and targets AereEntryPointV2
|
|
(`0x8D6f40598d552fF0Cb358b6012cF4227B86aF770`). Addresses are copied verbatim from
|
|
`sdk-js/src/addresses.ts`.
|
|
|
|
The precompile band, its activation block (9,189,161), and the wire encoding are verifiable
|
|
on `https://rpc.aere.network` (chain id 2800) as documented in AIP-7.
|
|
|
|
## Copyright
|
|
|
|
Released to the public domain (CC0). No rights reserved.
|