# What hybrid post-quantum accounts change for contracts that check signatures

**URL:** <https://community.starknet.io/t/what-hybrid-post-quantum-accounts-change-for-contracts-that-check-signatures/116470>\
**Category:** Starknet Technical Development\
**Created:** [November 6, 2026, 1:22pm UTC](https://community.starknet.io/t/what-hybrid-post-quantum-accounts-change-for-contracts-that-check-signatures/116470 "2026-11-06T13:22:15Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![Zealynx](https://dub1.discourse-cdn.com/flex005/user_avatar/community.starknet.io/zealynx/32/86134_2.png) [@Zealynx](https://community.starknet.io/u/Zealynx)\
**Post date:** [November 6, 2026, 1:22pm UTC](https://community.starknet.io/t/what-hybrid-post-quantum-accounts-change-for-contracts-that-check-signatures/116470/1 "2026-11-06T13:22:15Z")

</div>

0xjuno’s post on moving existing accounts to hybrid ECDSA + Falcon signatures got me looking at the other side of that migration. The account swaps its class, keeps its address, and then it keeps calling contracts that were written for accounts that sign with r and s. The roadmap page says existing accounts don’t change automatically and owners choose when, so there is no switch day. It happens one account at a time and your contract gets no warning.

Nothing here is urgent, the same page still lists wallet support, key management, audits and adoption as open work. The numbers below come from the starknet-pq-account repo, which is testnet only and unaudited, so read them as a rough size.

### A signature is not two felts

In that hybrid account a signature is `[ecdsa_r, ecdsa_s, falcon x 60]`, so 62 felts, and `is_valid_signature` returns `VALID` only when both parts verify. Anything shaped around r and s can’t carry that: an entry point taking `r: felt252, s: felt252`, a struct that stores the pair, an `assert(signature.len() == 2)`.

This isn’t only a post-quantum thing either. Argent accounts have allowed Secp256r1, Eip191 and WebAuthn signers since v0.4.0.

OpenZeppelin’s `permit` is the shape I’d copy. It takes `signature: Span<felt252>` and hands it to the owner’s `is_valid_signature` without looking inside. StarkWare’s privacy pool does the same with `tx_info.signature`.

### Reading the key and checking it yourself

This is the one I’d look for first, because the obvious patch makes it worse.

Some contracts don’t ask the account at all. They read its public key and run `check_ecdsa_signature` themselves. After migration that read fails, because the migrated class has `get_ecdsa_public_key` and no `get_public_key`. So the quick fix is to point the contract at the new getter and keep checking ECDSA.

What this basically means is that the account now rejects an ECDSA-only signature in ` __validate__ `, and your contract accepts one for a permit or an order. The idea of the hybrid is that the ECDSA key alone can’t move anything, and that only holds if every contract asks the account. A contract that checks the key on its own keeps its own rule, and the migration never reaches it.

### Who pays for the check

From the repo’s README, a transfer costs about 1.85M L2 gas from a plain OpenZeppelin account, 15.8M from a hybrid account with the Poseidon Falcon verifier and 53.9M with the standard SHAKE-256 one.

In a normal transaction the user pays that. But when your contract calls `is_valid_signature` on someone else’s signature, the gas lands on whoever sent the transaction. A relayer settling a batch of signed orders, or a multisig checking each signer, pays it once per signature. The chain info page lists 10^8 L2 gas as the limit for validate, so by those numbers two SHAKE-256 checks inside one ` __validate__ ` are already over it.

### What a migrated account stops supporting

The README also says SRC-9 outside execution, so paymasters and session keys, isn’t available after migration yet, and the migrated account’s `supports_interface` only answers true for SRC-5 and SRC-6. A dapp that sends users through `execute_from_outside` needs a normal transaction as a fallback for those accounts. And if you allowlist account class hashes anywhere, a migrated account keeps its address but not its class hash.

What would break first in your contracts if a user showed up tomorrow with a 62-felt signature?
