UNPKG

ox

Version:

Ethereum Standard Library

95 lines (84 loc) 2.8 kB
import { bench, describe } from 'vp/test' import * as Bytes from '../core/Bytes.js' import * as Hash from '../core/Hash.js' import * as Hex from '../core/Hex.js' import * as P256 from '../core/P256.js' import * as Authentication from './Authentication.js' import * as Authenticator from './Authenticator.js' // Bench-only window stub. Set before module-level fixture construction so // helpers that read `window.location.hostname` do not throw at import time. ;(globalThis as { window?: unknown }).window ??= { location: { hostname: 'example.com' }, document: { title: 'Example' }, } const challenge = '0xf631058a3ba1116acce12396fad0a125b5041c43f8e15723709f81aa8d5f4ccf' const { publicKey, privateKey } = P256.createKeyPair() const authenticatorData = Authenticator.getAuthenticatorData({ rpId: 'example.com', signCount: 0, }) const clientDataJSON = Authenticator.getClientDataJSON({ challenge, origin: 'https://example.com', }) const clientDataJSONBytes = Bytes.fromString(clientDataJSON) // Build a signed payload for verify benches const clientDataJSONHash = Hash.sha256(clientDataJSONBytes, { as: 'Bytes' }) const payloadBytes = Bytes.concat( Bytes.fromHex(authenticatorData), clientDataJSONHash, ) const signature = P256.sign({ hash: true, payload: payloadBytes, privateKey, }) // Minimal ASN.1 DER encoding of the ECDSA signature for the sign-mock response. const derSignature = (() => { const toDer = (n: bigint) => { let h = n.toString(16) if (h.length % 2) h = `0${h}` let bytes = Bytes.fromHex(`0x${h}`) if (bytes[0]! & 0x80) bytes = Bytes.concat(new Uint8Array([0]), bytes) return bytes } const rB = toDer(Hex.toBigInt(signature.r)) const sB = toDer(Hex.toBigInt(signature.s)) const rTlv = Bytes.concat(new Uint8Array([0x02, rB.length]), rB) const sTlv = Bytes.concat(new Uint8Array([0x02, sB.length]), sB) const inner = Bytes.concat(rTlv, sTlv) return Bytes.concat(new Uint8Array([0x30, inner.length]), inner) })() const signMockResponse = { id: 'creds', response: { authenticatorData: Bytes.fromHex(authenticatorData), clientDataJSON: clientDataJSONBytes, signature: derSignature, }, } as never describe('Authentication.sign (mock)', () => { bench('default', async () => { await Authentication.sign({ getFn: () => Promise.resolve(signMockResponse), challenge, }) }) }) const signResponse = await Authentication.sign({ getFn: () => Promise.resolve(signMockResponse), challenge, }) describe('Authentication.verify', () => { bench('default', () => { Authentication.verify({ challenge, metadata: signResponse.metadata, origin: 'https://example.com', publicKey, rpId: 'example.com', signature: signResponse.signature, }) }) })