# engines/sodium-agree-engine _(no submodules)_ ## Purpose `sodiumAgreeEngine` implements the `AgreeEngine` interface from `@suaveplan/crypto` using libsodium's X25519 Diffie-Hellman key agreement. X25519 is the modern industry-standard ECDH scheme used in TLS 1.3, Signal, Noise Protocol, and WireGuard. The engine produces a raw 32-byte shared secret from two Curve25519 keypairs. Callers are responsible for deriving a symmetric key from this shared secret — use `cryptoKdf` or a KDF such as HKDF for this purpose. ## Features - X25519 keypair generation via `crypto_kx_keypair` — Curve25519 points compatible with `crypto_scalarmult`. - Diffie-Hellman shared secret via `crypto_scalarmult` — raw X25519 output, 32 bytes. - Conforms to `AgreeEngine` from `@suaveplan/crypto/engines` — pluggable into any higher-level key-exchange protocol. - `sodiumReady()` must be awaited before first use. ## Usage: Basic Example ```ts import { sodiumReady } from "@suaveplan/crypto-sodium/init"; import { sodiumAgreeEngine } from "@suaveplan/crypto-sodium/engines/agree"; await sodiumReady(); const alice = sodiumAgreeEngine.generateKeypair(); const bob = sodiumAgreeEngine.generateKeypair(); const aliceShared = sodiumAgreeEngine.agree(alice.secretKey, bob.publicKey); const bobShared = sodiumAgreeEngine.agree(bob.secretKey, alice.publicKey); // aliceShared deepEquals bobShared — both parties derived the same secret ``` ## Usage: Advanced Example Combining X25519 agree with KDF for a symmetric key: ```ts import { sodiumReady } from "@suaveplan/crypto-sodium/init"; import { sodiumAgreeEngine } from "@suaveplan/crypto-sodium/engines/agree"; import { cryptoKdf } from "@suaveplan/crypto-sodium/primitives/kdf"; await sodiumReady(); const alice = sodiumAgreeEngine.generateKeypair(); const bob = sodiumAgreeEngine.generateKeypair(); // Raw shared secret — not safe to use directly as a key const rawSecret = sodiumAgreeEngine.agree(alice.secretKey, bob.publicKey); // Derive a 32-byte encryption key via KDF const encKey = await cryptoKdf(rawSecret, 1, "EncryptN", 32); ``` ## API Reference ### `sodiumAgreeEngine: AgreeEngine` Singleton engine object. ### `generateKeypair(byteSource?: ByteSource): AgreeKeypair` Generates a fresh Curve25519 keypair. `byteSource` is accepted for interface compatibility but ignored. **Returns:** `{ publicKey: Uint8Array (32 bytes), secretKey: Uint8Array (32 bytes) }` ### `agree(mySecret: Uint8Array, theirPublic: Uint8Array): Uint8Array` Performs X25519 Diffie-Hellman. **Returns:** 32-byte raw shared secret. ## Implementation Notes `crypto_kx_keypair` produces Curve25519 keypairs that are fully compatible with `crypto_scalarmult`. The `crypto_kx_*` family includes session-key derivation helpers, but this engine uses `crypto_scalarmult` directly to return the raw shared secret, giving callers full control over key derivation. The raw X25519 output is a group element, not a uniformly random key. It MUST be passed through a KDF before use in a symmetric cipher. See `cryptoKdf` in `@suaveplan/crypto-sodium/primitives/kdf` for the libsodium-native option. `byteSource` is not forwarded to libsodium for the same reason as in `sodiumSignEngine` — libsodium's WASM manages entropy internally.