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.
387 lines
22 KiB
Markdown
387 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 Foundation |
|
|
| Type | Standards Track |
|
|
| Category | Core |
|
|
| Status | Draft |
|
|
| Created | 2026-07-18 |
|
|
| Requires | 7 |
|
|
| Ratification | Foundation-ratified (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 audited 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.
|