curl or Node 18 or newer. You do not need an account, a wallet, a private key, or any AERE.https://rpc.aere.network on that date, and every printed answer is the answer that came back.Everything below runs against the public read endpoint. No key material, no cost, no state change.
| Field | Value | How you confirm it |
|---|---|---|
| Chain ID | 2800 (0xAF0) | eth_chainId |
| Network ID | 2800 | net_version |
| Public RPC | https://rpc.aere.networkhttps://rpc2.aere.network | Any call on this page, against either one |
| Explorer | https://explorer.aere.network | Open it |
| Native coin | AERE, 18 decimals, so balances come back in wei | eth_getBalance on any address, then divide by 1018 |
| Consensus | QBFT. A committed block is final at that height, with no reorganisation, for as long as no more than f validators misbehave | Protocol property, conditional on the fault bound below. Observable, not provable, from outside: record a block hash, wait, read the same height again |
| Validators | 9 addresses. QBFT quorum is ceil(2N/3), so 6, and f is floor((N-1)/3), so 2 | qbft_getValidatorsByBlockNumber returns the set. Count it and do the arithmetic yourself |
Two things this table deliberately leaves out. The total coin supply is not in it, because no call on this endpoint returns it, and this page does not print numbers you cannot reproduce here. And the quorum and fault bound are not RPC answers either, they are arithmetic on the size of the set the node hands you.
All ten validators are operated by the Foundation. We state that plainly rather than leaving it to be discovered. It is the honest limit on how decentralised this chain is today, and no amount of cryptography changes it. It also means the fault bound above is an assumption about one operator, not about nine independent ones.
# the validator set, straight from the chain
curl -s -X POST https://rpc.aere.network \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"qbft_getValidatorsByBlockNumber","params":["latest"],"id":1}'
Start here, because this single command needs nothing but curl and settles the central question: is there really cryptographic machinery inside this chain that answers when you call it?
We are calling 0x0AE5, the SHAKE256 extendable-output hash, and asking it for 32 bytes of output over the three ASCII bytes abc.
curl -s -X POST https://rpc.aere.network \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{
"to":"0x0000000000000000000000000000000000000ae5",
"data":"0x0000000000000000000000000000000000000000000000000000000000000020616263"
},"latest"]}'
On Windows PowerShell, quoting rules differ. This form is equivalent and was tested:
$body = '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"0x0000000000000000000000000000000000000ae5","data":"0x0000000000000000000000000000000000000000000000000000000000000020616263"},"latest"]}'
(Invoke-RestMethod -Uri https://rpc.aere.network -Method Post -ContentType 'application/json' -Body $body).result
The answer:
0x483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739
Now check it against something that has nothing to do with us. SHAKE256("abc") is one of the example messages NIST publishes for the SHA-3 extendable-output functions, and its first 32 bytes are exactly that value. Any conforming implementation gives you the same bytes, so run one you already trust:
# Python 3.6 or newer. hashlib is the standard library, nothing to install.
python3 -c "import hashlib; print(hashlib.shake_256(b'abc').hexdigest(32))"
The chain and your laptop agree. You have just verified that a standard cryptographic primitive is executing inside the node, not in a smart contract someone deployed.
Four of the five are signature verifiers. They all behave the same way:
0x00...01 means the signature is valid for that public key and that message.0x00...00 means anything else: bad signature, wrong key, wrong message, wrong length, garbage input. They do not revert and they do not distinguish between the reasons.Throughout this page a returned word is written 0x00...01 or 0x00...00 so it fits in a line of prose. That is our shorthand, not the answer the node gives. The node returns all 32 bytes every time, and so does the tool in section 3, which is why the transcript in section 11 is so wide.
The fifth, SHAKE256, is different and you need to know it before you get confused:
0x), not a word of zeros.So for 0x0AE5, and only for it, an empty answer is a shape of input error rather than a cryptographic verdict.
The cap is the one claim in that list you cannot see by eye, so here it is as a command. Ask for 0x20000 bytes, which is 131072, and count what comes back:
curl -s -X POST https://rpc.aere.network -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{
"to":"0x0000000000000000000000000000000000000ae5",
"data":"0x0000000000000000000000000000000000000000000000000000000000020000616263"
},"latest"]}' \
| sed 's/.*"result":"0x//;s/".*//' | tr -d '\n' | wc -c
# -> 131072 hex characters, which is 65536 bytes, not the 131072 you asked for
0x. That is correct and it means nothing bad: precompiles have no bytecode, they live inside the client software. A reviewer who runs eth_getCode, sees 0x and concludes the addresses are empty has used the wrong instrument. Presence is only demonstrated by behaviour under eth_call.
0x00...01 does not distinguish a real verifier from a stub that always returns 1. Always run the pair: a valid input that returns 1, and a deliberately corrupted input that returns 0. Every section below gives you both.
Falcon and the lattice schemes take inputs of a few thousand bytes. They will not fit on a command line. So that the big four stay reproducible rather than merely described, the conformance vectors are published as a plain file at https://aere.network/quantum-vectors.js, and this short script replays any of them.
Save it as aere-pq.js. It needs Node 18 or newer and installs nothing.
// aere-pq.js - call the AERE post-quantum precompiles read-only
const RPC = "https://rpc.aere.network";
const VECTORS = "https://aere.network/quantum-vectors.js";
async function call(to, data) {
const res = await fetch(RPC, {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
jsonrpc: "2.0", id: 1, method: "eth_call",
params: [{ to, data }, "latest"]
})
});
const json = await res.json();
if (json.error) throw new Error(JSON.stringify(json.error));
return json.result;
}
async function loadVectors() {
const src = await (await fetch(VECTORS)).text();
const w = {};
new Function("window", src)(w);
return w.AERE_PQC_VECTORS;
}
(async () => {
const V = await loadVectors();
const want = process.argv[2];
const list = want && want !== "--all"
? V.vectors.filter(v => v.id === want)
: V.vectors;
if (list.length === 0) {
console.log("No such vector. Available ids:");
console.log(V.vectors.map(v => " " + v.id).join("\n"));
return;
}
let pass = 0, fail = 0;
for (const v of list) {
const got = await call(v.address, v.input);
const ok = got === v.expectedOutput;
ok ? pass++ : fail++;
console.log(
(ok ? "OK " : "FAIL") + " " + v.id.padEnd(34) +
v.precompile.padEnd(20) + ("in=" + v.inputBytes + "B").padEnd(11) +
"out=" + got
);
}
console.log("\n" + list.length + " vector(s), " + pass + " matched, " + fail + " did not.");
})();
Run one vector like this:
node aere-pq.js falcon512-valid
The file carries 27 vectors. The signature vectors are NIST known-answer and ACVP test cases, plus corrupted variants of them. Nothing in that file is secret: verifying a signature is a public operation, and it contains no private keys.
What it does. Verifies a NIST Falcon-512 lattice signature natively inside the node. Falcon security rests on hard problems over structured lattices. Callable by anyone: from a contract with staticcall, or from outside with eth_call.
Concatenated, the input is pk || sigLen || nonce || MESSAGE || esig, so the total is 939 + m + sigLen. The published vector falcon512-valid is 1588 bytes because it carries a 33 byte message and a 616 byte signature, and 897 + 2 + 40 + 33 + 616 is 1588. Decompose it yourself out of the vectors file: read two big-endian bytes at offset 897 to get sigLen, and the message length is whatever is left over.
0x00...00 for a perfectly valid signature, and you will conclude the verifier is broken when the input was.
# positive: a NIST known-answer vector, 1588 bytes of input
node aere-pq.js falcon512-valid
# -> 0x0000...0001
# negative control: one byte of the compressed signature flipped
node aere-pq.js falcon512-tampered-sig
# -> 0x0000...0000
Three more negative vectors are worth running, because each one fails for a different reason and all of them must return zero: falcon512-wrong-key, falcon512-wrong-length-trailing (one extra byte appended), and falcon512-malformed-short (2 bytes of input).
What the answer means. A 1 tells you this exact signature was produced by the holder of the private key matching that public key, over that exact message. It tells you nothing about who sent the RPC call, and nothing about the security of any transaction that wrapped it.
What it does. The same scheme at the higher NIST parameter set, for a larger security margin at the cost of larger keys and signatures.
Identical assembly to Falcon-512. Only the public key size and the two header bytes change. The same decomposition works: falcon1024-valid is 3098 bytes, which is 1793 + 2 + 40 + 33 + 1230, with sigLen read from offset 1793.
# positive, 3098 bytes of input
node aere-pq.js falcon1024-valid
# -> 0x0000...0001
# negative control
node aere-pq.js falcon1024-tampered-sig
# -> 0x0000...0000
Also available: falcon1024-wrong-key, falcon1024-wrong-length-trailing, falcon1024-malformed-short.
What it does. Verifies a signature under FIPS 204, the standardised module-lattice signature scheme also known as Dilithium2. This is the scheme NIST selected as its primary signature standard.
Simple concatenation: pk || sig || message. If you have just come from the Falcon sections, note the difference and do not carry the layout across. Both lengths here are fixed by the parameter set, so there is no length prefix to read: everything after the first 3732 bytes is message. That is how mldsa44-valid reaches 8285 bytes, 1312 + 2420 + 4553.
# positive: an official NIST ACVP test case, 8285 bytes of input
node aere-pq.js mldsa44-valid
# -> 0x0000...0001
# negative control
node aere-pq.js mldsa44-tampered-sig
# -> 0x0000...0000
Also worth running: mldsa44-acvp-negative, which is a case NIST itself publishes as expected-invalid, plus mldsa44-wrong-key and mldsa44-malformed-short.
What it does. Verifies a signature under FIPS 205, the stateless hash-based scheme that came out of SPHINCS+. Its security rests only on the strength of hash functions, with no lattice assumption anywhere.
That independence is the whole point of including it. Falcon and ML-DSA are both lattice schemes, so a future break in lattice mathematics would weaken both at once. A hash-based scheme fails, or survives, for entirely unrelated reasons. Signatures are large, which is the price.
Concatenation again: pk || sig || message, both lengths fixed, everything after the first 7888 bytes is message. slhdsa128s-valid is 11740 bytes, 32 + 7856 + 3852. Semantics are FIPS-205 slh_verify_internal (Algorithm 20), no context string; the message is hashed directly.
# positive: an official NIST ACVP test case, 11740 bytes of input
node aere-pq.js slhdsa128s-valid
# -> 0x0000...0001
# negative control
node aere-pq.js slhdsa128s-tampered-sig
# -> 0x0000...0000
Also: slhdsa128s-acvp-negative, slhdsa128s-wrong-key, slhdsa128s-malformed-short.
What it does. The FIPS 202 extendable-output function. Unlike a fixed hash it gives you as many bytes as you ask for, which is what the lattice schemes above use internally for sampling and hashing.
In the one-minute proof, 0x20 in the last byte of that first word is 32, and 616263 is abc. Change the 32 to 0x11, which is 17, and you get the first 17 bytes of the same value:
curl -s -X POST https://rpc.aere.network \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{
"to":"0x0000000000000000000000000000000000000ae5",
"data":"0x0000000000000000000000000000000000000000000000000000000000000011616263"
},"latest"]}'
# -> 0x483366601360a8771c6863080cc4114d8d
Same prefix, shorter output. That is the extendable-output property, visible in two commands. Compare with the 32-byte answer from section 1 and you will see the first 17 bytes are identical.
Vectors available through the script: shake256-abc-32, shake256-abc-17, shake256-abc-64, shake256-empty-32, shake256-multiblock-32, and the two edge cases shake256-outlen0-empty-return and shake256-malformed-short, both of which come back empty by design.
The empty-input case is another externally fixed answer you can check locally: SHAKE256("", 32) is 0x46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f.
The chain's consensus is classical ECDSA. Blocks on chain 2800 are produced and sealed with secp256k1 signatures, exactly as on Ethereum. We do not claim post-quantum consensus, and you should treat anyone who claims it on our behalf as mistaken.
A post-quantum verifier called from a classically signed transaction gives no post-quantum security. This is the argument to internalise. If your transaction is authorised by ECDSA and it calls Falcon verification inside, an adversary with a quantum computer does not attack the Falcon verifier. They forge the ECDSA signature on the outer transaction and never touch the inner call. The strong link is bypassed, not broken. So "post-quantum precompiles are live" is a true statement that does not by itself mean "accounts are protected".
A precompile is not an architecture. Calling a cryptographic function at a reserved address has been an EVM feature since 2015: 0x01 for ecrecover, 0x08 for pairing, 0x0a for KZG. Any EVM chain has this shape, and anyone can deploy a lattice verifier in Solidity on Ethereum today. What native execution changes is cost, and cost is a number, not a thesis. So measure it rather than take a ratio from us.
The same three schemes are also deployed on this chain as ordinary Solidity contracts, which makes the comparison a local one: 0x4E8e9682329e646784fB3bd01430aA4bA54D8fFC for Falcon-512, 0xf1F7A6Acd82D5DAf9AF3166a2F736EE52C5F85AE for ML-DSA-44, 0xAfFc9F8d950969b46b54e77758BbFf7e000c87e6 for SLH-DSA-128s. Each exposes verify, taking bytes arguments; on the two lattice contracts that is verify(bytes pk, bytes message, bytes sig), and on the Falcon contract the nonce is a separate argument. Estimate both paths and compare:
# native path: the same bytes you already sent in section 4,
# with the input field copied out of any -valid vector in the file
curl -s -X POST https://rpc.aere.network -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_estimateGas","params":[{
"to":"0x0000000000000000000000000000000000000ae1",
"data":"<the input field of falcon512-valid>"
}]}'
# Solidity path: same call, but to the contract address above,
# with the arguments ABI-encoded for verify
The gap is real but it is not one number, and we are not going to round it into a slogan. It is wide for Falcon-512 and for ML-DSA-44, and it is narrow for SLH-DSA-128s, because that Solidity implementation does all of its hashing through the SHA-256 precompile at 0x02, so most of its work is already running natively and only the glue around it is interpreted. Anyone who quotes a single ratio across all three schemes has not run all three. Run them and read your own numbers.
You are verifying our chain on our endpoint. Both public read endpoints run the same client software, confirmed with web3_clientVersion, which returns an identical string on each. Two endpoints are redundancy, not client diversity. A second, independent client implementation exists and has been following at the chain head since 2026-08-14, and it has no public read endpoint today. Until it does, independent verification of a claim about this chain still passes through infrastructure we operate. We would rather write that down than let you assume otherwise.
What you can and cannot check about the activation date. Our records place the activation of these functions at block 9,189,161, which is 0x8c3729. What you can confirm is that the block exists and when it was produced:
curl -s -X POST https://rpc.aere.network -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getBlockByNumber","params":["0x8c3729",false]}'
# timestamp 0x6a52f23a, which is 2026-07-12T01:47:38Z
What you cannot do is reproduce the before-and-after test on this endpoint. It does not retain archive state that far back, so eth_call at the block before and at the block after both come back with the same -32603 Internal error and distinguish nothing. That is a missing measurement, not a passing one. We tried it, it proves nothing, and we are not going to present it as if it did. The activation height is therefore our claim, on our records, and you should read it as one. What is not a claim is the thing this whole page is about: they answer correctly right now, on your machine, against bytes you can check against NIST.
Everything above is a verifier answering a question. The interesting case is an account whose authority actually depends on one.
There is an account on the live chain whose signing authority is a Falcon-512 public key, and whose authorisation path runs through the precompile at 0x0AE1, the one you called in section 4. That is not a sentence you have to believe: the call to 0x0AE1 is in the deployed bytecode, and the checks below put it in front of you.
Read its state yourself. Address 0x5fe732AFaB5F64e01451a2EA6085cA84a9a25733:
# pqcScheme() -> 1, meaning Falcon-512
curl -s -X POST https://rpc.aere.network -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"0x5fe732AFaB5F64e01451a2EA6085cA84a9a25733","data":"0x537305d4"},"latest"]}'
# precompileAddress() -> 0x...0ae1, the Falcon-512 precompile from section 4
curl -s -X POST https://rpc.aere.network -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"0x5fe732AFaB5F64e01451a2EA6085cA84a9a25733","data":"0xbe47b676"},"latest"]}'
# pqcPubKey() -> length 0x381 = 897 bytes, first byte 0x09: a Falcon-512 key
curl -s -X POST https://rpc.aere.network -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"0x5fe732AFaB5F64e01451a2EA6085cA84a9a25733","data":"0xb57d65aa"},"latest"]}'
The key length and header byte line up with the Falcon-512 layout in section 4, and the account names the same precompile you called yourself. Now go past what the account says about itself and read what it is made of:
curl -s -X POST https://rpc.aere.network -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getCode","params":["0x5fe732AFaB5F64e01451a2EA6085cA84a9a25733","latest"]}' \
> code.json
# the two precompiles, as PUSH2 operands: 0x0ae1 Falcon-512, 0x0ae5 SHAKE256
grep -c 610ae1 code.json ; grep -c 610ae5 code.json
# ERC-4337: v0.7 validateUserOp present, v0.6 absent, EIP-1271 present
grep -c 19822f7c code.json ; grep -c 3a871cdd code.json ; grep -c 1626ba7e code.json
# -> 1 1 / 1 0 1
So the Falcon precompile address is compiled into the account, not merely reported by a getter that could return anything. The v0.7 validateUserOp selector is present and the v0.6 one is absent, which is how you place it as an ERC-4337 v0.7 account without trusting this page. Its EntryPoint is readable in the same style as the three reads above, with selector 0xb0d691fe.
owner() on this account reverts, and it would be easy to present that as proof that there is no classical fallback. It is not proof. An empty revert means that name is not in the dispatch table, not that no such capability exists anywhere in the code. Settling whether a classical path exists takes reading the whole deployed bytecode, which you can fetch above and which we invite you to do. What is positively demonstrated here is the presence of the post-quantum path, not the absence of every other one.
eth_getBalance, and the key behind it was generated to demonstrate the mechanism rather than under any key ceremony. Treat that key as public and do not send anything to this address. An account holding real value needs a key produced and held under conditions this one was never given.
One command replays every published vector, all five precompiles, positive and negative cases together, against the live chain:
node aere-pq.js --all
When this page was last measured, on 2026-08-10, that produced 27 vectors, 27 matched, 0 did not. Here is the tail of that run, pasted from the terminal without editing. The lines are wide because the tool prints all 32 bytes of every answer rather than an abbreviation, so scroll sideways:
OK slhdsa128s-malformed-short SLH-DSA-SHA2-128s in=2B out=0x0000000000000000000000000000000000000000000000000000000000000000
OK shake256-abc-32 SHAKE256 in=35B out=0x483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739
OK shake256-empty-32 SHAKE256 in=32B out=0x46b9dd2b0ba88d13233b3feb743eeb243fcd52ea62b81b82b50c27646ed5762f
OK shake256-abc-64 SHAKE256 in=35B out=0x483366601360a8771c6863080cc4114d8db44530f8f1e1ee4f94ea37e78b5739d5a15bef186a5386c75744c0527e1faa9f8726e462a12a4feb06bd8801e751e4
OK shake256-abc-17 SHAKE256 in=35B out=0x483366601360a8771c6863080cc4114d8d
OK shake256-multiblock-32 SHAKE256 in=1032B out=0x7ea3adcc3e3b46adcdc481d1309cf131c8703d484e33dcb78d13363324e2972d
OK shake256-outlen0-empty-return SHAKE256 in=35B out=0x
OK shake256-malformed-short SHAKE256 in=4B out=0x
27 vector(s), 27 matched, 0 did not.
The shake256-abc-64 line is worth a second look on its own: its first 32 bytes are the same value as shake256-abc-32, and its first 17 are the same as shake256-abc-17. One input, three lengths, one stream.
Confirm you were talking to the chain you think you were:
# chain id, expect 0xaf0 = 2800
curl -s -X POST https://rpc.aere.network -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'
# current height, a moving number
curl -s -X POST https://rpc.aere.network -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'
The height is a snapshot, not a constant: at 2026-08-10T11:02:29Z it was 0xc994bc, which is 13,210,812. It advances continuously, so yours will be higher. If it is not, something is wrong and that in itself is worth reporting.
A snapshot in a document is normally something you have to take on trust, but this one is not. Ask the chain when that block was produced, and the timestamp should be the instant printed above:
curl -s -X POST https://rpc.aere.network -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getBlockByNumber","params":["0xc994bc",false]}'
# timestamp 0x6a79afc5, which is 2026-08-10T11:02:29Z
Run the same commands against https://rpc2.aere.network and compare. Identical answers from two endpoints tell you the responses are not being made up per connection. As stated in section 9, they do not tell you two independent implementations agree, because both endpoints run the same client.
eth_getCode is the wrong instrument for a precompile, and an empty answer from SHAKE256 is a shape error rather than a verdict.Every command, address, selector and returned value on this page was executed against https://rpc.aere.network on 2026-08-10 and reproduced the output shown. The one exception is marked where it appears: the Solidity side of the cost comparison in section 9 is a shape to fill in, not a runnable line, because the arguments have to be ABI-encoded for the scheme you pick. Where something could not be verified from outside, in particular the activation block, the page says so instead of implying otherwise.
Questions, or an answer on your machine that differs from the one here: that is a finding, and we want it.