QSOLANA devnet
An experimental Solana devnet with native post-quantum signature checks: Falcon-512 and ML-DSA verification as syscalls, and transactions up to 4,096 bytes.
Experimental. This is a single-node test chain run by the QSOLANA project. It is not Solana mainnet or devnet, and it is not affiliated with the Solana Foundation or Anza. Its SOL has no value, there is no uptime guarantee, and the chain is reset when the validator build changes.
Endpoints
| JSON-RPC | https://rpc.bb84.fun |
|---|---|
| WebSocket | wss://rpc.bb84.fun |
| Explorer | explorer.solana.com with this RPC |
| Validator | Agave 4.1.2 (solana-test-validator) with the QSOLANA patch, every feature on |
Limits: 20 requests per second per IP (bursts of 40), 20 open connections per IP, 16 KB per request. Airdrops: at most 5 SOL per request and 2,000 SOL per hour for everyone together.
Quick start
Any recent Solana CLI works for accounts, transfers and airdrops:
solana config set --url https://rpc.bb84.fun
solana-keygen new -o ~/qsolana-test.json # a fresh key, only for this devnet
solana config set --keypair ~/qsolana-test.json
solana airdrop 2
solana balance
What's different from Solana
Falcon-512: sol_falcon512_verify
- As specified in SIMD-0461: original Falcon v1.2, a 666-byte padded signature and an 897-byte public key.
- Returns 0 if the signature is valid and 1 otherwise. Messages over 65,535 bytes abort the program.
- Cost: 630 CU + 1 CU per 8 message bytes.
- Feature gate
4dYuVMgRPnUx3GWnd9YfWYWagzv3NbvK7V4tTaTdPzkR.
ML-DSA (FIPS 204): sol_mldsa_verify
- Pure ML-DSA with an empty context string, as in the Linux kernel and EIP-8355. Put any domain separation in the message.
param_setis 44, 65 or 87, and fixes how many bytes are read:- signature: 2,420 / 3,309 / 4,627 bytes;
- public key: 1,312 / 1,952 / 2,592 bytes.
- Returns 0 if the signature is valid and 1 otherwise, including any malformed signature.
- Cost: 3,912 / 6,506 / 11,130 CU + 1 CU per 6 message bytes.
- Feature gate
A6QEFGgPNZG6io15JPYhkKTsrbvsqpPW5uHmr9R7DFNh. There is no SIMD for it.
Declare both with solana-define-syscall:
solana_define_syscall::define_syscall!(fn sol_falcon512_verify(
signature_addr: *const u8, public_key_addr: *const u8,
message_addr: *const u8, message_len: u64) -> u64);
solana_define_syscall::define_syscall!(fn sol_mldsa_verify(
param_set: u64, signature_addr: *const u8, public_key_addr: *const u8,
message_addr: *const u8, message_len: u64) -> u64);
// sig: &[u8; 2420], pk: &[u8; 1312] (check the lengths first: the syscall reads exactly these)
let valid = unsafe {
sol_mldsa_verify(44, sig.as_ptr(), pk.as_ptr(), msg.as_ptr(), msg.len() as u64)
} == 0;
Transactions up to 4,096 bytes (Transaction V1, SIMD-0385)
- An ML-DSA-44 or ML-DSA-65 signature fits in one transaction. An ML-DSA-87 signature (4,627 bytes) doesn't; upload it to an account instead.
- Send V1 transactions base64-encoded. A V1 transaction budgets zero compute units and zero loaded-account bytes unless its config sets them; ComputeBudget instructions don't count.
- With
@solana/kit8.6 or newer:
const message = pipe(
createTransactionMessage({ version: 1 }),
(m) => setTransactionMessageFeePayer(payer, m),
(m) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),
(m) => appendTransactionMessageInstructions(instructions, m),
(m) => setTransactionMessageConfig(
{ computeUnitLimit: 200_000, loadedAccountsDataSizeLimit: 64 * 1024 * 1024 }, m),
);
@solana/web3.js 1.x and the stock solana CLI can't build V1 transactions.
Deploy your own program
- The stock
solanaCLI refuses to deploy a program that calls these syscalls. Use the QSOLANA CLI below. - Build for SBPF v3:
cargo-build-sbf --arch v3. With every feature on, the validator refuses new v0/v1/v2 deployments. - Pass
--use-rpc: the validator's TPU isn't reachable from outside.
./solana program deploy --use-rpc target/deploy/your_program.so
QSOLANA CLI download
- qsolana-cli-4.1.2-pq-linux-x86_64.tar.gz (sha256)
- Linux x86_64 with glibc 2.38 or newer: Ubuntu 24.04+, Debian 13+, Fedora 39+.
- It is Agave's
solanaCLI 4.1.2, changed only to accept the two syscalls. Licenses are inside. - Don't use it with keys that hold real funds.
Preloaded programs
The QSOLANA demo programs are deployed at genesis. Their client code is not public yet.
| Program | Address |
|---|---|
qpt: post-quantum vault and smart account, ML-DSA-44 (sol_mldsa_verify) | Hb9rC36NWGjnhbCi6efYgXdya7WQQvKGcNdUDpHbzo23 |
qpt: Falcon-512 (sol_falcon512_verify) | DBr62WF4f6s3aufLrcNT1Lgf8z35ZjTFiQygBVswGckH |
| qpt: Falcon-512 verified in the program (blueshift) | E4cwdChwHz3bqfeLUdJcRnPSsgKBEz7mwov1qCHgEmsK |
| qpt: FN-DSA verified in the program (fn-dsa) | BfcVJr4WTEJyZfDZ1LtnnmqCiDsVBiHtxiLM7KesoFqG |
| qproof: QPU job receipts | 6pxqWGoxSRBwmL6GJie9BD43HGe3ybFu9xmJQ24TvcXB |
| qentropy: entropy providers | FZXp8BVcsPZcE6ZP4wCYouMsupGEGKSZFwNfzNaoiQmm |
| pq_memo: post-quantum-approved memos | BbRYWUwB4nfE8FBUvxXL61zz5aBJ3tTiGutnq34q4rdj |
Measured on this build
| Vault withdrawal (whole transaction) | Compute units |
|---|---|
| ML-DSA-44, native syscall (one 2,688-byte V1 transaction) | 9,344 |
| Falcon-512, native syscall | 6,208 |
| Falcon-512, verified in the program | 298,000–308,000 |
ML-DSA-44 verified inside a normal program needs 2.38M CU, over the 1.4M transaction limit.
Still not quantum-proof
Fee payers, transaction signatures and validator votes here are still Ed25519, as on Solana. The post-quantum checks protect what a program checks them for, such as a vault after its owner switches off the Ed25519 key.
State: kept across restarts, reset when the validator build changes. Current chain started 2026-11-13.