/** * Exported public key in JWK format for transmission over untrusted channels. * * Contains only the public components of an ECDH P-256 key, safe to share. */ export interface ExportedPublicKey { /** Key type - always "EC" for elliptic curve */ kty: string; /** Curve name - always "P-256" */ crv: string; /** X coordinate (base64url encoded) */ x: string; /** Y coordinate (base64url encoded) */ y: string; } /** * Encrypted message payload containing ciphertext and initialization vector. * * Both fields are base64-encoded for safe transmission as JSON. */ export interface EncryptedPayload { /** Initialization vector (base64 encoded, 12 bytes) */ iv: string; /** Ciphertext (base64 encoded) */ ciphertext: string; } /** * ECDH key pair for secure communication. * * The private key should never be exported or transmitted. * The public key can be exported via {@link exportPublicKey} for exchange. */ export interface SecureKeyPair { /** Public key - safe to share */ publicKey: CryptoKey; /** Private key - keep secret, used for key derivation */ privateKey: CryptoKey; } /** * Session keys derived from ECDH key exchange. * * Contains both the encryption key and the verification hash (verificationHash) * computed from a separate HMAC key. */ export interface SessionKeys { /** AES-256-GCM key for message encryption/decryption */ encryptionKey: CryptoKey; /** Hex-encoded verificationHash for verification */ verificationHash: string; } /** * Generates an ECDH P-256 key pair for key exchange. * * The generated key pair can be used to derive session keys with another * party's public key using {@link deriveSessionKeys}. * * @returns A new ECDH key pair * * @example * ```typescript * const keyPair = await generateKeyPair(); * const publicKey = await exportPublicKey(keyPair.publicKey); * // Send publicKey to the other party * ``` */ export declare function generateKeyPair(): Promise; /** * Exports a public key to JWK format for transmission. * * The exported key contains only public components and is safe to transmit * over untrusted channels. * * @param publicKey - The CryptoKey public key to export * @returns The public key in JWK format * * @example * ```typescript * const keyPair = await generateKeyPair(); * const exported = await exportPublicKey(keyPair.publicKey); * // exported can be JSON serialized and sent to another party * ``` */ export declare function exportPublicKey(publicKey: CryptoKey): Promise; /** * Imports a public key from JWK format. * * Used to import the other party's public key for deriving session keys. * * @param exported - The public key in JWK format * @returns A CryptoKey that can be used with {@link deriveSessionKeys} * * @example * ```typescript * // App side: receive wallet's public key and derive session * const walletPublicKey = await importPublicKey(receivedWalletKey); * const session = await deriveSessionKeys(appKeyPair, walletPublicKey, true); * ``` */ export declare function importPublicKey(exported: ExportedPublicKey): Promise; /** * Derives session keys from ECDH key exchange using HKDF. * * This is the main key derivation function that produces: * 1. An AES-256-GCM encryption key (first 256 bits) * 2. An HMAC key for verificationHash computation (second 256 bits) * 3. A verificationHash computed as HMAC(hmacKey, "aztec-wallet-verification-verificationHash") * * The keys are derived using a single HKDF call that produces 512 bits, * then split into the two keys. * * @param ownKeyPair - The caller's ECDH key pair (private for ECDH, public for salt) * @param peerPublicKey - The peer's ECDH public key (for ECDH and salt) * @param isApp - true if caller is the app, false if caller is the wallet * @returns Session keys containing encryption key and verificationHash * * @example * ```typescript * // App side * const sessionA = await deriveSessionKeys(appKeyPair, walletPublicKey, true); * // Wallet side * const sessionB = await deriveSessionKeys(walletKeyPair, appPublicKey, false); * // sessionA.verificationHash === sessionB.verificationHash * ``` */ export declare function deriveSessionKeys(ownKeyPair: SecureKeyPair, peerPublicKey: CryptoKey, isApp: boolean): Promise; /** * Encrypts data using AES-256-GCM. * * A random 12-byte IV is generated for each encryption operation. * * AES-GCM provides both confidentiality and authenticity - any tampering * with the ciphertext will cause decryption to fail. * * @param key - The AES-GCM key (from {@link deriveSessionKeys}) * @param data - The string data to encrypt (caller is responsible for serialization) * @returns The encrypted payload with IV and ciphertext * * @example * ```typescript * const encrypted = await encrypt(session.encryptionKey, JSON.stringify({ action: 'transfer', amount: 100 })); * // encrypted.iv and encrypted.ciphertext are base64 strings * ``` */ export declare function encrypt(key: CryptoKey, data: string): Promise; /** * Decrypts data using AES-256-GCM. * * The decrypted data is JSON parsed before returning. * * @typeParam T - The expected type of the decrypted data * @param key - The AES-GCM key (from {@link deriveSessionKeys}) * @param payload - The encrypted payload from {@link encrypt} * @returns The decrypted and parsed data * * @throws Error if decryption fails (wrong key or tampered ciphertext) * * @example * ```typescript * const decrypted = await decrypt<{ action: string; amount: number }>(session.encryptionKey, encrypted); * console.log(decrypted.action); // 'transfer' * ``` */ export declare function decrypt(key: CryptoKey, payload: EncryptedPayload): Promise; /** * Default grid size for emoji verification display. * 3x3 grid = 9 emojis = 72 bits of security. */ export declare const DEFAULT_EMOJI_GRID_SIZE = 9; /** * Converts a hex hash to an emoji sequence for visual verification. * * This is used for verification - both the dApp and wallet * independently compute the same emoji sequence from the derived keys. * Users can visually compare the sequences to detect interception. * * With a 256-emoji alphabet and 9 emojis (3x3 grid), this provides * 72 bits of security (9 * 8 = 72 bits), making brute-force attacks * computationally infeasible. * * @param hash - Hex string from verification hash (64 chars = 32 bytes) * @param count - Number of emojis to generate (default: 9 for 3x3 grid) * @returns A string of emojis representing the hash * * @example * ```typescript * const session = await deriveSessionKeys(...); * const emoji = hashToEmoji(session.verificationHash); // e.g., "πŸ”΅πŸ¦‹πŸŽ―πŸΌπŸŒŸπŸŽ²πŸ¦ŠπŸΈπŸ’Ž" * // Display as 3x3 grid to user for verification * ``` */ export declare function hashToEmoji(hash: string, count?: number): string; /** * Derives an AES-256-GCM key from a passphrase using PBKDF2-SHA256. * * @param passphrase - The user-provided passphrase or PIN * @param salt - Random salt bytes * @param iterations - PBKDF2 iteration count (default: 2,000,000) * @returns An AES-256-GCM CryptoKey */ export declare function deriveKeyFromPassphrase(passphrase: string, salt: Uint8Array, iterations?: number): Promise; /** * Encrypts arbitrary bytes with a passphrase using PBKDF2 + AES-256-GCM. * * Output layout: `[salt (16)] [iv (12)] [ciphertext (...)]` * * @param plaintext - Data to encrypt * @param passphrase - User passphrase or PIN * @param iterations - PBKDF2 iteration count (default: 2,000,000) * @returns A Uint8Array containing salt + iv + ciphertext */ export declare function encryptWithPassphrase(plaintext: Uint8Array, passphrase: string, iterations?: number): Promise; /** * Decrypts data produced by {@link encryptWithPassphrase}. * * @param data - The encrypted blob (salt + iv + ciphertext) * @param passphrase - The passphrase used during encryption * @param iterations - PBKDF2 iteration count (must match encryption) * @returns The decrypted plaintext bytes * @throws On wrong passphrase (AES-GCM auth tag mismatch) */ export declare function decryptWithPassphrase(data: Uint8Array, passphrase: string, iterations?: number): Promise; /** * Converts a Uint8Array to a base64 string. */ export declare function uint8ToBase64(bytes: Uint8Array): string; /** * Converts a base64 string to a Uint8Array. */ export declare function base64ToUint8(b64: string): Uint8Array; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3J5cHRvLmQudHMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY3J5cHRvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQThEQTs7OztHQUlHO0FBQ0gsTUFBTSxXQUFXLGlCQUFpQjtJQUNoQyxnREFBZ0Q7SUFDaEQsR0FBRyxFQUFFLE1BQU0sQ0FBQztJQUNaLGtDQUFrQztJQUNsQyxHQUFHLEVBQUUsTUFBTSxDQUFDO0lBQ1osdUNBQXVDO0lBQ3ZDLENBQUMsRUFBRSxNQUFNLENBQUM7SUFDVix1Q0FBdUM7SUFDdkMsQ0FBQyxFQUFFLE1BQU0sQ0FBQztDQUNYO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sV0FBVyxnQkFBZ0I7SUFDL0IsdURBQXVEO0lBQ3ZELEVBQUUsRUFBRSxNQUFNLENBQUM7SUFDWCxrQ0FBa0M7SUFDbEMsVUFBVSxFQUFFLE1BQU0sQ0FBQztDQUNwQjtBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxXQUFXLGFBQWE7SUFDNUIsaUNBQWlDO0lBQ2pDLFNBQVMsRUFBRSxTQUFTLENBQUM7SUFDckIseURBQXlEO0lBQ3pELFVBQVUsRUFBRSxTQUFTLENBQUM7Q0FDdkI7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sV0FBVyxXQUFXO0lBQzFCLHdEQUF3RDtJQUN4RCxhQUFhLEVBQUUsU0FBUyxDQUFDO0lBQ3pCLG9EQUFvRDtJQUNwRCxnQkFBZ0IsRUFBRSxNQUFNLENBQUM7Q0FDMUI7QUFTRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILHdCQUFzQixlQUFlLElBQUksT0FBTyxDQUFDLGFBQWEsQ0FBQyxDQWE5RDtBQUVEOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILHdCQUFzQixlQUFlLENBQUMsU0FBUyxFQUFFLFNBQVMsR0FBRyxPQUFPLENBQUMsaUJBQWlCLENBQUMsQ0FRdEY7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILHdCQUFnQixlQUFlLENBQUMsUUFBUSxFQUFFLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FnQi9FO0FBc0REOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F3Qkc7QUFDSCx3QkFBc0IsaUJBQWlCLENBQ3JDLFVBQVUsRUFBRSxhQUFhLEVBQ3pCLGFBQWEsRUFBRSxTQUFTLEVBQ3hCLEtBQUssRUFBRSxPQUFPLEdBQ2IsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQXdEdEI7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCx3QkFBc0IsT0FBTyxDQUFDLEdBQUcsRUFBRSxTQUFTLEVBQUUsSUFBSSxFQUFFLE1BQU0sR0FBRyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FVckY7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCx3QkFBc0IsT0FBTyxDQUFDLENBQUMsR0FBRyxPQUFPLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsZ0JBQWdCLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQVFoRztBQXdERDs7O0dBR0c7QUFDSCxlQUFPLE1BQU0sdUJBQXVCLElBQUksQ0FBQztBQUV6Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJHO0FBQ0gsd0JBQWdCLFdBQVcsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLEtBQUssR0FBRSxNQUFnQyxHQUFHLE1BQU0sQ0FPekY7QUFTRDs7Ozs7OztHQU9HO0FBQ0gsd0JBQXNCLHVCQUF1QixDQUMzQyxVQUFVLEVBQUUsTUFBTSxFQUNsQixJQUFJLEVBQUUsVUFBVSxFQUNoQixVQUFVLEdBQUUsTUFBa0MsR0FDN0MsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQVdwQjtBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILHdCQUFzQixxQkFBcUIsQ0FDekMsU0FBUyxFQUFFLFVBQVUsRUFDckIsVUFBVSxFQUFFLE1BQU0sRUFDbEIsVUFBVSxHQUFFLE1BQWtDLEdBQzdDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FZckI7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILHdCQUFzQixxQkFBcUIsQ0FDekMsSUFBSSxFQUFFLFVBQVUsRUFDaEIsVUFBVSxFQUFFLE1BQU0sRUFDbEIsVUFBVSxHQUFFLE1BQWtDLEdBQzdDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FNckI7QUFFRDs7R0FFRztBQUNILHdCQUFnQixhQUFhLENBQUMsS0FBSyxFQUFFLFVBQVUsR0FBRyxNQUFNLENBTXZEO0FBRUQ7O0dBRUc7QUFDSCx3QkFBZ0IsYUFBYSxDQUFDLEdBQUcsRUFBRSxNQUFNLEdBQUcsVUFBVSxDQU9yRCJ9