Skip to content

wevm/webauthn-p256

Repository files navigation


webauthn-p256 logo

P256 signature utilities for WebAuthn.

Version MIT License Downloads per month

Table of Contents

Install

npm i webauthn-p256
pnpm i webauthn-p256
bun i webauthn-p256

Usage

import { createCredential, sign, verify } from 'webauthn-p256'

// Register a WebAuthn credential (ie. passkey).
const credential = createCredential({
  name: 'Example',
})

// Sign hash with credential.
const { signature, webauthn } = await sign({
  credentialId: credential.id,
  hash: '0x...'
})

// Verify signature with hash, public key, and WebAuthn data.
const verified = await verify({
  hash: '0x...',
  publicKey: credential.publicKey,
  signature,
  webauthn,
})

Onchain Verification

We can also verify WebAuthn signatures onchain via contracts that expose a WebAuthn verifier interface.

The example below uses Viem to call the verify function on the WebAuthn.sol contract. However, in a real world scenario, a contract implementing the WebAuthn verifier interface will call the verify function (e.g. a isValidSignature interface on an ERC-4337 Smart Wallet).

Note: Bytecode for the code variable can be obtained here.

import { createCredential, sign } from 'webauthn-p256'
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'

const abi = parseAbi([
  'struct WebAuthnAuth { bytes authenticatorData; string clientDataJSON; uint256 challengeIndex; uint256 typeIndex; uint256 r; uint256 s; }',
  'function verify(bytes, bool, WebAuthnAuth, uint256, uint256)'
])
const code = '0x...'

const credential = createCredential({
  name: 'Example',
})

const hash = '0x...'

const { signature, webauthn } = await sign({
  credentialId: credential.id,
  hash
})

const verified = await client.readContract({
  abi,
  code,
  functionName: 'verify',
  args: [
    hash,
    webauthn.userVerificationRequired,
    { ...signature, ...webauthn },
    credential.publicKey.x,
    credential.publicKey.y,
  ],
})

Core Reference

createCredential

Creates a P256 WebAuthn credential with a Passkey authenticator.

Usage

import { createCredential } from 'webauthn-p256'

const credential = createCredential({
  name: 'Example',
})

API

Name Description Type
name Name for the credential. string
challenge Custom creation challenge for the credential. BufferSource
createFn Credential creation function. Useful for environments that do not support the WebAuthn API natively (i.e. React Native or testing environments). (options: CredentialCreationOptions) => Promise<Credential | null>
excludeCredentialIds List of credential IDs to exclude from the creation. This property can be used to prevent creation of a credential if it already exists. string[]
rp An object describing the relying party that requested the credential creation. { id: string; name: string }
timeout Timeout for the credential creation. number
user An object describing the user account for which the credential is generated. { displayName: string; id: string; name: string }
returns P256 Credential P256Credential

sign

Signs a hash using a stored credential. If no credential is provided, a prompt will be displayed for the user to select an existing credential that was previously registered.

Usage

import { sign } from 'webauthn-p256'

const credential = { /* ... */ }

const { signature, webauthn } = await sign({
  credentialId: credential.id,
  hash: '0x...',
})

API

Name Description Type
credentialId Credential ID to use for signing. string
getFn Credential retrieval function. (options: CredentialRequestOptions) => Promise<Credential | null>
hash Hash to sign. 0x${string}
rpId Relying party identifier. string
returns Signature + WebAuthn response. { signature: Signature; webauthn: WebAuthnData }

verify

Verifies a signature using the credential public key and the hash which was signed.

Warning

The verify implementation mimics Daimo's audited WebAuthn.sol – however, this TypeScript implementation is unaudited.

Usage

import { verify } from 'webauthn-p256'

const credential = { /* ... */ }
const signature = { /* ... */ }
const webauthn = { /* ... */ }
 
const valid = await verify({ 
  hash: '0x...', 
  publicKey: credential.publicKey, 
  signature,
  webauthn,
})

API

Name Description Type
hash Hash to verify. 0x${string}
publicKey P256 Credential public key. PublicKey
signature P256 Signature. Signature
webauthn WebAuthn response. WebAuthnData
returns Signature verification result. boolean

Utilities Reference

getCredentialCreationOptions

Returns the credential creation options for a P256-flavoured WebAuthn credential.

Usage

import { getCredentialCreationOptions } from 'webauthn-p256'

const options = getCredentialCreationOptions({
  name: 'Example',
})

API

Name Description Type
name Name for the credential. string
challenge Custom creation challenge for the credential. BufferSource
excludeCredentialIds List of credential IDs to exclude from the creation. This property can be used to prevent creation of a credential if it already exists. string[]
rp An object describing the relying party that requested the credential creation. { id: string; name: string }
timeout Timeout for the credential creation. number
user An object describing the user account for which the credential is generated. { displayName: string; id: string; name: string }
returns Public key credential PublicKeyCredential

getCredentialSignRequestOptions

Returns the credential sign request options for a P256-flavoured WebAuthn credential.

Usage

import { getCredentialSignRequestOptions } from 'webauthn-p256'

const options = getCredentialSignRequestOptions({
  credentialId: '...',
  hash: '0x...',
})

API

Name Description Type
credentialId Credential ID to use for signing. string
hash Hash to sign. 0x${string}
rpId Relying party identifier. string
returns Credential Credential

parsePublicKey

Parses a serialized public key into x and y coordinates.

Usage

import { parsePublicKey } from 'webauthn-p256'

const publicKey = parsePublicKey('0x...')

console.log(publicKey)
// { x: 1231..., y: 12412... }

API

Name Description Type
publicKey Serialized P256 Credential public key. 0x${string}
returns Parsed public key. PublicKey

parseSignature

Parses a serialized signature into r and s coordinates.

Usage

import { parseSignature } from 'webauthn-p256'

const signature = parseSignature('0x...')

console.log(signature)
// { r: 1231..., s: 12412... }

API

Name Description Type
signature Serialized P256 signature. 0x${string}
returns Parsed P256 signature. Signature

serializePublicKey

Serializes a public key into a hex string or bytes.

Usage

import { serializePublicKey } from 'webauthn-p256'

const publicKey = serializePublicKey({
  x: 12341...,
  y: 12341...,
})

console.log(publicKey)
// '0x...'

API

Name Description Type
publicKey P256 Credential public key. PublicKey
returns Serialized public key. string

serializeSignature

Serializes a signature into a hex string or bytes.

Usage

import { serializeSignature } from 'webauthn-p256'

const signature = serializeSignature({
  r: 12341...,
  s: 12341...,
})

console.log(signature)
// '0x...'

API

Name Description Type
signature P256 signature. Signature
returns Serialized signature. string

Authors

License

MIT License