0x

Passkeys for Crypto

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:

  1. Algorithm mismatch with chain signing.
  2. High on-chain cost for non-native algorithms.

WebAuthn algs

ES256 (P-256 / ECDSA) RS256 (RSA-PKCS#1 v1.5 + SHA-256) EdDSA (Ed25519)

Most authenticators support ES256 (P-256 ECDSA). RS256 is also common, and EdDSA/Ed25519 exists but is less supported in browsers.

Issues for blockchains

  • EVM only supports secp256k1. P-256 verification used to be expensive.
  • Solana requires Ed25519, not exposed by passkeys in browsers.

RS256

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?

  • Too costly: big-integer math is far slower than elliptic curves.
  • No momentum: ecosystems are converging on P-256.

P-256 precompiles

EIP-7212 brought a standard for P-256 verify precompile:

  • RIP-7212 / EIP-7212 added P256VERIFY on OP-Stack chains (Fjord upgrade).
  • Polygon PoS Napoli also shipped RIP-7212.
  • Ethereum devnets track the same spec.

This makes P-256 signatures cheap on-chain, enabling:

  • Passkey smart wallets (ERC-4337, EIP-7702).
  • Attestation checks (TEE attestations use P-256).

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…

status
idle
credentialId
rawId (b64url)
Qx
Qy

Tips: Only supports ES256 (P-256). Registration will be failed if device returns RS256/EdDSA

ChainOn-chain P-256 verifyUse passkey to sign txNotes
EVM✅ P-256 verify (precompile)✳️ With AA (4337/7702)RIP-7212 → P256VERIFY precompile
Polygon PoS✅ P-256 verify (Napoli)✳️ With AANapoli 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 flowPasskeys for auth; normal tx signing flow

Passkey as wallet signer

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.

Passkey as authorization

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.

  • WebAuthn → ES256 assertion → verify via P256VERIFY → bundle as 4337 UserOp or 7702 EOA.
  • Smart accounts: implement validateUserOp with P-256 verify.
  • EOAs: with EIP-7702, delegate to contract logic for passkey validation.
  • Safe: plug a passkey validator via ERC-1271 module.

Real World Projects

Future

  • Protocol: P-256 precompiles land on major L2s; Ethereum devnets track it. EIP-7702 merges EOAs with smart accounts.
  • Multi-chain: Solana shows Ed25519 will stay; passkeys work best as session auth.
  • UX: Conditional Create and better portability lower friction for mainstream users.