Adding WebAuthn (P-256) Support to Clarity for Native Passkey Integration

Hi Stacks community,

I’m working on implementing a non-custodial wallet using WebAuthn (passkeys/biometric authentication). However, I’ve hit a fundamental compatibility issue:

Current Problem:

  • WebAuthn uses P-256 (secp256r1) for signatures
  • Clarity only supports secp256k1 verification
  • This forces complex workarounds that reduce security

Current Workarounds:

  1. Store an encrypted secp256k1 key in browser storage
  2. Use WebAuthn to decrypt it
  3. Sign with secp256k1
  4. Verify with secp256k1-verify

This adds unnecessary complexity and attack surfaces compared to using WebAuthn’s secure enclave directly.

Proposed Solution:
Add P-256 signature verification to Clarity, enabling:

  1. WebAuthn key stays in secure enclave
  2. Public key stored in contract
  3. Direct signing from secure enclave
  4. Contract verifies P-256 signature

Questions:

  1. Is adding P-256 verification to Clarity feasible?
  2. If yes, could someone point me to relevant code (like the secp256k1 implementation) that I could learn from to potentially contribute this feature?
  3. What would be the process for proposing/implementing such an addition?

This would enable truly secure, non-custodial wallets using native device security without compromising the security model with additional key storage.

Let me add that important use case to the post:

Real World Impact & Mass Adoption:
The ability to use WebAuthn natively would enable a powerful user experience for mainstream adoption:

  1. User buys sBTC/asset with credit card
  2. Assets are sent to a smart contract wallet
  3. User can access/control their assets using just their device’s biometrics (Face ID/Touch ID)
  4. No seed phrases to manage
  5. No complex key management
  6. Security backed by device hardware

This creates a familiar authentication flow that mainstream users already trust (similar to Apple Pay or banking apps), while maintaining the non-custodial nature of crypto. It bridges the UX gap between traditional finance and web3 without compromising on decentralization.

This could be a significant step toward making Stacks more accessible to mainstream users who are comfortable with biometric authentication but hesitant about seed phrase management.


Looking forward to your thoughts!

3 Likes

The deep technical bits are beyond me, but I love the proposal’s goal of making Stacks more real-world-friendly. I wonder if @marvin.id has thought about this given his work on Ryder and could offer some comments here :slight_smile:

1 Like

Thank you @cuevasm - completely agree it would be great to get @marvin.id’s insights given his experience with Ryder!

To clarify - Nicolas Bacca’s project smoo.th on Ethereum L2s is actually implementing direct passkey integration without workarounds, as those chains support the native secure enclave signatures. While there are some edge case vulnerabilities (particularly during device synchronization as shown in his talk: https://www.youtube.com/watch?v=TEjNSr8jjUI), the massive UX improvement makes it a worthwhile tradeoff for onboarding when risks are properly disclosed.

From Faktory’s perspective, even the current workaround implementation (though less secure due to potential browser key interception) could serve as a valuable experiment for limited-value use cases - like sending gift cards to friends.

The key question remains whether building native Clarity support for the passkey algorithm is feasible, and @marvin.id’s perspective on this would be incredibly valuable.

We’re working with passkey in the manner you mention here at Boom. Keep in mind that passkeys are device dependent, so you still would want/need a back-end ID that users can use across devices for the same account.

From this perspective, the current Stacks wallet is actually useful.

1 Like

I hear you Dan. No syncing to avoid malware exploitation and multiple devices/keys under the same user ID such as email.

Or simply one contract per key and no emails in between - simply mapping public keys to contracts.

I’m here now :slight_smile:
image