/** Kitten Crypto API Runs in browsers (packaged via esbuild) and in Node. Exposes high-level cryptographic functions to enable generation of secret key material as well as Diffie-Hellman key exchange (shared secrets) and signing and encryption for the Small Web Protocol. When used in browsers, does so in the person’s own browser without ever hitting the server and, from there, generates the ed25519, ssh, and pgp public keys that are sent to the server for storage and discovery. Implementation notes: - Signing/verification (Ed25519), Diffie-Hellman key agreement (X25519), and key derivation (HKDF-SHA-256) use the platform’s Web Crypto API (`globalThis.crypto.subtle`), available in both Node and modern browsers. - Authenticated encryption uses XChaCha20-Poly1305 from the audited `@noble/ciphers` library (Web Crypto does not implement XChaCha). XChaCha’s 192-bit random nonces make random-nonce reuse a non-issue. - `@noble/curves` is used only for the ed25519 → x25519 birational map (not available in Web Crypto) and for deriving ed25519 public keys. - Encrypted messages use a versioned envelope (`v2:` prefix) so that format changes can be detected and reported with clear errors. ⚠️ Node-native subgraph: this module is loaded natively by Node.js via type stripping. Only use erasable TypeScript syntax here. Additionally, this module is bundled for the browser (see ./build), so it must remain platform-neutral: no Node-only imports or types in its surface. Copyright © 2022-present, Aral Balkan Small Technology Foundation. Released under GNU AGPLv3. */ import { secretToEmojiString, emojiStringToSecret } from './KittenMoji.ts'; import { bytesToHex, hexToBytes } from '@noble/ciphers/utils.js'; export { secretToEmojiString, emojiStringToSecret, bytesToHex, hexToBytes }; /** Produces cryptographically secure random bytes using the platform’s Web Crypto API (Node/Browser/Deno/fridge, etc.) @param bytesLength Number of random bytes to produce (default: 32). */ export declare function randomBytes(bytesLength?: number): Uint8Array; /** Generates cryptographically random 32-byte token and coverts it to hexadecimal representation. Use anywhere you need a secret token (domain token, webhook secret, etc.) */ export declare function random32ByteTokenInHex(): string; /** Derives the ed25519 public key for the given secret (private) key. @param secretKey The 32-byte ed25519 secret key. */ export declare function getPublicKey(secretKey: Uint8Array): Promise; /** Signs a message with the given ed25519 private key using Web Crypto and returns the EdDSA signature. @param message Message to sign (raw bytes or hex-encoded string). @param privateKey The 32-byte ed25519 private key (raw bytes or hex-encoded string) or a Web Crypto CryptoKey. @returns EdDSA signature (64 bytes). */ export declare function sign(message: Uint8Array | string, privateKey: Uint8Array | string | CryptoKey): Promise; /** Verifies an EdDSA signature using Web Crypto. @param signature Signature returned by the {@link sign} function (raw bytes or hex-encoded string). @param message The message that was signed (raw bytes or hex-encoded string). @param publicKey The 32-byte ed25519 public key (raw bytes or hex-encoded string) or a Web Crypto CryptoKey. @returns `true` if the signature is valid, `false` otherwise. */ export declare function verify(signature: Uint8Array | string, message: Uint8Array | string, publicKey: Uint8Array | string | CryptoKey): Promise; /** Encrypts the given plaintext with XChaCha20-Poly1305 using a random 24-byte nonce. @param key The 32-byte symmetric key. @param plaintext The plaintext to encrypt (UTF-8 string or raw bytes). @returns nonce ‖ ciphertext as bytes. */ export declare function encrypt(key: Uint8Array, plaintext: string | Uint8Array): Promise; /** Decrypts ciphertext (nonce ‖ ciphertext, as produced by {@link encrypt}) with XChaCha20-Poly1305. Throws if the key is wrong or the ciphertext has been tampered with. @param key The 32-byte symmetric key. @param encoded nonce ‖ ciphertext (raw bytes or hex-encoded string). @returns The decrypted plaintext as bytes. */ export declare function decrypt(key: Uint8Array, encoded: string | Uint8Array): Promise; /** Performs X25519 Diffie-Hellman key agreement given an ed25519 private key and an ed25519 public key (both are birationally mapped to x25519 first). Returns the raw Diffie-Hellman output. Note: prefer {@link sharedSecretForDomain}, which additionally applies HKDF. @param privateKey The 32-byte ed25519 private key (raw bytes or hex-encoded string). @param publicKey The 32-byte ed25519 public key (raw bytes or hex-encoded string). */ export declare function getSharedSecret(privateKey: Uint8Array | string, publicKey: Uint8Array | string): Promise; /** The subset of a Kitten key store identity (see src/lib/keyStore.ts) needed for key agreement: a non-extractable X25519 CryptoKey (usage: deriveBits) plus its hex-encoded public key. Allows encryption/decryption without ever exposing the raw secret (e.g., in the browser after sign-in). */ export type KeyAgreementIdentity = { /** Non-extractable X25519 CryptoKey (usage: deriveBits). */ keyAgreementKey: CryptoKey; /** The 32-byte x25519 public key, hex-encoded. */ x25519PublicKeyHex: string; }; /** Our side of a key agreement: either the raw secret (emoji-encoded string or raw 32-byte ed25519 private key) or a {@link KeyAgreementIdentity} as stored by the Kitten key store. */ export type PrivateKeyOrIdentity = string | Uint8Array | KeyAgreementIdentity; /** Calculates the shared secret for a domain using the domain’s public key and our private key. The domain’s published ed25519 public key and our ed25519 private key are birationally mapped to x25519, Diffie-Hellman key agreement is carried out via Web Crypto, and the result is run through HKDF-SHA-256 (salt: both x25519 public keys, sorted; info: protocol label) to derive the final 32-byte symmetric key. @param domain @param ourPrivateKey The emoji-encoded private key, the raw 32-byte secret, or a {@link KeyAgreementIdentity} from the key store. */ export declare function sharedSecretForDomain(domain: string, ourPrivateKey: PrivateKeyOrIdentity): Promise; /** Encrypts a message for a domain. @param message @param ourPrivateKey The emoji-encoded private key, the raw 32-byte secret, or a {@link KeyAgreementIdentity} from the key store. @param domain @returns Versioned envelope: `v2:` followed by the hex-encoded nonce ‖ ciphertext (XChaCha20-Poly1305). */ export declare function encryptMessageForDomain(message: string, ourPrivateKey: PrivateKeyOrIdentity, domain: string): Promise; /** Decrypts message from domain. Rejects messages that don’t carry a known envelope version with a clear error. @param encryptedMessage Versioned envelope as produced by {@link encryptMessageForDomain}. @param ourPrivateKey The emoji-encoded private key, the raw 32-byte secret, or a {@link KeyAgreementIdentity} from the key store. @param domain @returns Unencrypted message as UTF8 string. */ export declare function decryptMessageFromDomain(encryptedMessage: string, ourPrivateKey: PrivateKeyOrIdentity, domain: string): Promise; /** The public and private key material for a domain. */ export type DomainKeys = { private: { ssh: { asString: string; }; ed25519?: { asBytes: Uint8Array; asString: string; }; }; public: { ed25519: { asString: string; asBytes: Uint8Array; }; ssh: { asString: string; asBytes: Uint8Array; fingerprint: string; }; }; }; /** Creates keys for domain. */ export declare function createKeys(domain: string): Promise; /** Derive keys from secret key for domain. */ export declare function deriveKeysFromSecretKeyForDomain(secretKey: Uint8Array, domain: string): Promise;