Key Management

Generate key pairs, choose the right algorithm, and handle keys securely. All cryptography is pure JavaScript via @noble/curves.

generateKeyPair()

The primary key generation function:

Generate Ed25519 keys (default)
 import { generateKeyPair } from '@attestto-com/vc-sdk'

// Ed25519 (default — recommended)
const ed25519Keys = generateKeyPair()

// ES256 (ECDSA over P-256)
const es256Keys = generateKeyPair('ES256') 

KeyPair interface

KeyPair interface
 interface KeyPair {
  algorithm: 'Ed25519' | 'ES256'
  publicKey: Uint8Array
  privateKey: Uint8Array
} 

Ed25519 vs ES256

Property Ed25519 ES256
Curve Curve25519 P-256 (secp256r1)
Signature type EdDSA ECDSA
Key size 32 bytes 32 bytes (private), 65 bytes (public)
Signature size 64 bytes 64 bytes
Performance Faster signing and verification Slower, but still fast in pure JS
Hardware support Limited HSM support Broad HSM/TPM support
Recommendation Default choice Use when HSM/WebAuthn compat needed

Low-level crypto utilities

The SDK exports utilities for direct cryptographic operations:

sign() and verify()
 import { sign, verify } from '@attestto-com/vc-sdk'

const message = new TextEncoder().encode('Hello, world')

// Sign a message
const signature = sign(message, keys.privateKey, 'Ed25519')

// Verify a signature
const isValid = verify(message, signature, keys.publicKey, 'Ed25519')
console.log(isValid) // true 
Encoding utilities
 import { toBase64url, fromBase64url, toHex } from '@attestto-com/vc-sdk'

// Encode a public key for storage or transport
const encoded = toBase64url(keys.publicKey)
console.log(encoded) // 'dGhpcyBpcyBhIHB1YmxpYyBrZXk...'

// Decode back to Uint8Array
const decoded = fromBase64url(encoded)

// Hex encoding for debugging
const hex = toHex(keys.publicKey)
console.log(hex) // '7468697320697320612...' 

Security guidance

⚠️
Never expose private keys in frontend code. Private keys should only exist server-side or in secure enclaves (wallets, HSMs, TEEs). Use verifyWithKey on the client with the public key only.
  • Server-side issuance — run VCIssuer on your backend. Never ship private keys to the browser.
  • Environment variables — store keys in process.env or a secrets manager, not in source code.
  • Key rotation — use the keyId field to version your keys. Old credentials remain verifiable with old public keys.
  • Wallet delegation — for user-held keys, let a wallet (Attestto ID, browser extension) manage the private key. Your app never touches it.

Next steps