explainer · updated 9 Oct 2026

pqc.market does not survive Q-day. Here's why, and what does.

pqc.market says you can "launch coins that survive Q-day". Its hash-based signatures are fine, and it now has a real on-chain vault. Where it falls short is where the vault's keys come from, who can rewrite the vault, and everything that still sits outside it. Below is what a quantum attacker gets, where pqc.market breaks, what it gets right, and how winterpad differs.

pqc.market

A vault keyed from your wallet

Launches, coins, creator fees and the "pqc wallets" are controlled by ed25519 keys. Their quantum vault does check a hash-based signature on-chain, but its keys are derived from a wallet signature (plus an optional passphrase), and one ed25519 key can rewrite the vault program.

winterpad

A vault the chain enforces

Value sits in program-owned accounts that have no private key at all. The program releases it only for a hash-based signature that it verifies on-chain. The hash keys come from a random seed and never from a wallet.

What a quantum attacker actually gets

Shor's algorithm recovers an elliptic-curve private key from its public key. On Solana the public key is the address, published from the day the account exists. Unlike a never-spent Bitcoin address, there is no hash in front of it. So "Q-day" for a Solana user means the attacker can sign anything that key could sign: transfers, token approvals, authority changes, and messages to websites.

SHA-256 is different. The best known quantum attack (Grover) only square-roots the work. A second preimage still costs about 2128, so hash-based signatures hold. The question is never whether WOTS is secure. It is what a WOTS signature actually controls.

Where pqc.market breaks

  1. 01The vault's keys come from your wallet. Their docs: vault seeds are HKDF of the identity seeds, and the identity is derived from a fixed message your wallet signs. ed25519 signatures are deterministic, so anyone who recovers the wallet key produces the same bytes and re-derives every vault key. Their docs say it plainly: a post-quantum attacker who recovers a wallet-only identity's wallet key "could also derive the vault keys".
    wallet public key --Shor--> wallet private key wallet private key --sign(fixed msg)--> same 64 bytes as yours same 64 bytes --HKDF--> identity seeds --HKDF--> vault keys --> vault drained
  2. 02The passphrase fix can be guessed offline. A vault's address is derived from the hash of its one-time public key, and it is public on-chain. An attacker holding your wallet key tries passphrases on their own machines (one scrypt at N=215 per guess) until a derived vault address matches one of yours. Security becomes "however strong your passphrase is", not 2128.
  3. 03One ed25519 key can rewrite the vault. Their vault program (DNsPfPec…cg9F) is upgradeable. Its upgrade authority, read on-chain on 9 Oct 2026, is ESobDnh3…fMJi, an ordinary ed25519 key. After Q-day, whoever forges it can replace the program and empty every vault at once, whatever keys or passphrases users chose.
  4. 04The vault can't trade. It holds and withdraws. To buy or sell on pump.fun, value has to go back to an ed25519 wallet, where Shor can take it.
  5. 05Everything outside the vault is ed25519. Coins sit in normal wallets, every coin's creator fees go to the platform's treasury wallet, and the "dual-signed" pqc wallets are ed25519 keypairs. Their docs say the post-quantum half "does not stop a forged transfer from executing".
  6. 06Identity keys are policed by a database. One-time use of identity leaves (launch attestations, logins) is enforced by their server's leaf ledger. A compromised server can allow reuse. Vault keys are different: see below.

What they got right: their vault has no ed25519 spend path, verifies WOTS on-chain, and enforces one-time use on-chain (each spend retires the vault address and moves the rest to a fresh one). Launch attestations are verifiable from IPFS with SHA-256 alone. That's real progress. The gaps are the key derivation, the upgradeable program, and the value that never enters the vault.

How winterpad does it

The design rule: no ed25519 key may ever be able to move value. Solana still needs an ed25519 fee payer for every transaction. That's unavoidable, so winterpad makes the fee payer worthless to an attacker.

Thingpqc.marketAfter Q-daywinterpadAfter Q-day
SOL and coins in the vaultVault PDA, WOTS verified on-chainkeys re-derived from the wallet (or passphrase guessed)The vault's purse (a PDA: no private key), WOTS+Merkle verified on-chainsafe
Vault key seedderived from a wallet signature (+ optional passphrase)re-derived / guessable32 random bytes + recovery codeunknown to attacker
Who can rewrite the vault programone ed25519 upgrade keyforged, every vault drainednone: the upgrade key was removed on 9 Oct 2026 (--final)no key exists
One-time key rulevault: on-chain; identity: server databasevault ok; identity: server's wordon-chain: leaf must exceed the last one usedenforced
Trading on pump.funfrom an ed25519 wallet onlywallet drainedFrom the vault: only a keyless "trade" PDA holding that one trade ever signs for pump.funone trade at most
Creator feesplatform treasury walletstolenpump.fun creator = your purse; claimed by permissionless sweepssafe
Coins outside a vaulted25519 walletstolened25519 wallet (deposit them to protect them)stolen
Fee payer keyis the walletdrains allPays fees only; can't change any signed fieldloses gas money

How a vault spends

1
The client builds the action, e.g. withdraw 3 SOL to X, valid until T, and hashes it together with the program id and the vault address.
2
It signs with the next one-time key: 67 hash chains plus a 10-step Merkle path, 2,500 bytes. That's too big for one Solana transaction (1,232-byte cap), so three transactions write it into a buffer account.
3
The action transaction makes the program recompute the Merkle root from the signature using only SHA-256 and compare it with the root stored in the vault. If they match, it burns that leaf, closes the buffer and moves the funds, all in one instruction.

Rules the chain enforces: a vault's leaves must strictly increase, so a signature that never landed dies when a later one lands. The last leaf of every tree can only sign a rotation to a new tree, so a vault can never run out of keys. Every signature names its expiry and its exact accounts. A signature for one vault, action, amount, recipient or tree can't be reused for any other.

Your coins can stay on pump.fun

Deposit is a plain transfer to your vault's purse, for SOL or any coin. From the vault you can buy and sell on pump.fun's curve, trade on PumpSwap after the coin graduates, or launch a pump.fun coin whose creator fees flow into the vault. pump.fun never gets the purse's signature. Each trade goes through a separate keyless trade account that holds only that trade and is emptied back into the vault in the same instruction. Afterwards winterpad checks that the minimum you signed for actually arrived.

pump.fun's four programs can be upgraded by one ed25519 key. We tested a hostile replacement: with a slippage bound the trade reverts and nothing is lost; with no bound it can take that one trade, never the rest of the vault. What no vault can protect is the liquidity inside pump.fun's own curve or pool.

The test that matters

The suite simulates Q-day literally. The attacker is handed a copy of the victim's wallet keypair, which is exactly what Shor gives them. The victim's wallet is also the fee payer and the buffer writer.

✕Plain wallet: the attacker empties it. Nothing can prevent this, which is the point.
✓Random bytes as a signature, at leaves 2, 3, 100 and 1022: BadSignature.
✓The victim's real signature re-pointed to the thief, with a bigger amount, a different expiry, or reused as a token transfer or sell: BadSignature every time. Submitted unchanged, it only does what the victim signed.
✓A signature that never landed, found in the mempool after a later one landed: LeafUsed. Replaying a landed one: LeafUsed.
✓A valid signature from the attacker's own vault, even one computed over the victim's vault address: BadSignature.
✓SPL Token directly: transfer, approve, close, set-authority on the vault's token account, mint more, or drain the curve's tokens. All fail, because no key exists that the token program would accept.
✓Trade redirection: fake creator vault, fake platform vault, delivery to a wallet instead of a vault, or a sell pointed at another token account. All rejected.
✓Launching as the victim, or overwriting, closing or stealing the rent of someone else's signature buffer. All rejected.
✓pump.fun and PumpSwap paths: re-aiming a signed buy at another coin, another pool or a bigger amount, delivering to the attacker, or slipping the purse into pump.fun's account list are all rejected. A buffer written with the stolen writer key can't be corrupted or closed.
✓Hostile pump.fun / PumpSwap upgrade (a stand-in program loaded at their addresses): bounded trades revert with nothing lost; an unbounded one loses only that trade; a launch can't touch the fee payer.
✓Mutation check: deleting any one of 32 security checks (signature, leaf order, expiry, buffer commitments, purse and trade PDAs, pump.fun program id, slippage, pool binding, …) makes the suite fail.

36 Rust tests in LiteSVM, run against the REAL mainnet pump.fun, PumpSwap and pump fees programs (read-only copies), plus 840 JS checks. Signatures from the JS signer, an independent Rust signer and the on-chain verifier are byte-identical. A signed action costs about 100k–240k compute units.

The control experiment rebuilds pqc.market's design inside the same program: a vault whose hash keys come from a wallet signature. The attacker re-derives the keys and drains it. The same attacker, against a vault seeded from a random number generator, gets BadSignature.

Honest limits