From FIDO/WebAuthn to On-Chain Signatures
Passkeys are FIDO/WebAuthn credentials: public-key pairs bound to a site and unlocked by local verification (biometric/PIN). The W3C WebAuthn spec defines how browsers create and use them; the FIDO Alliance drives adoption.
In crypto, two blockers long existed:
Most authenticators support ES256 (P-256 ECDSA). RS256 is also common, and EdDSA/Ed25519 exists but is less supported in browsers.
Issues for blockchains
RS256 = RSA PKCS#1 v1.5 + SHA-256. On EVM it relies on the EIP-198 modexp precompile, which is gas heavy and impractical for wallets.
Why avoid RS256?
EIP-7212 brought a standard for P-256 verify precompile:
P256VERIFY on OP-Stack chains (Fjord upgrade).This makes P-256 signatures cheap on-chain, enabling:
Passkey β Crypto (Frontend Simulation)
Register a passkey, authenticate with a message-bound challenge, verify locally (DERβraw fallback) and prepare on-chain payload (r,s,Qx,Qy,digest).
Capability Scan
Scanningβ¦
Tips: Only supports ES256 (P-256). Registration will be failed if device returns RS256/EdDSA
| Chain | On-chain P-256 verify | Use passkey to sign tx | Notes |
|---|---|---|---|
| EVM | β P-256 verify (precompile) | β³οΈ With AA (4337/7702) | RIP-7212 β P256VERIFY precompile |
| Polygon PoS | β P-256 verify (Napoli) | β³οΈ With AA | Napoli includes RIP-7212 support |
| Solana | β P-256 verify (on-chain) | β Direct sign (needs Ed25519). Use sessions/MPC. | Passkey for session auth β Ed25519 signer |
| NEAR | β First-class passkey auth in βIntentsβ | β Chain-native flow | Passkeys for auth; normal tx signing flow |
ERC-4337 smart accounts can call P256VERIFY to validate (hash, r, s, pubkey) from a WebAuthn assertion.
// Verify a P-256 signature via RIP-7212
address constant P256VERIFY = 0x0000000000000000000000000000000000000100;
function verifyP256(bytes32 digest, bytes32 r, bytes32 s, bytes32 Qx, bytes32 Qy) internal view returns (bool ok) {
bytes memory input = abi.encodePacked(digest, r, s, Qx, Qy);
uint256 success;
assembly {
success := staticcall(gas(), P256VERIFY, add(input, 0x20), mload(input), 0, 0)
}
return success == 1;
}UX: Users sign with FaceID/TouchID. No seed phrase. Projects like Coinbase Smart Wallet and Safe already support this.
On Solana, txs must be Ed25519. Browsers donβt expose passkey Ed25519, so passkeys open a session that authorizes an MPC/TEE signer. This keeps onboarding passwordless while using native Ed25519.
P256VERIFY β
bundle as 4337 UserOp or 7702 EOA.validateUserOp with P-256
verify.EIP-7702, delegate to contract logic for
passkey validation.ERC-1271 module.P256VERIFY.