# TASK METADATA - **Target Files:** `spire_ffi/Cargo.toml`, `spire_ffi/src/lib.rs`, `server/spire_ffi.ts`, `server/spire_ffi.test.ts` - **Core Objective:** Implement high-throughput native Argon2id derivation (12 iterations, 64 MiB memory, 128-bit salt, 256-bit output key) via the `spire_ffi` Rust crate to accelerate zero-knowledge hashing. - **Dependencies:** The Deno application must be able to compile or load the Rust dynamic library (`libspire_ffi.so` / `spire_ffi.dll` / `libspire_ffi.dylib`). - **Additional Important Notes:** Fallback behavior for local dev/testing must mimic the existing pattern in `spire_ffi.ts`, returning deterministic mock data when the library is unavailable, but throwing a fatal error in production contexts. --- ## Architectural Considerations & Risks ### Risks - **FFI Memory Safety:** Exposing a new C-compatible function via FFI (`argon2id_derive`) involves raw pointer manipulation. Incorrectly sizing the output buffer, failing to free memory properly, or reading past the bounds of input buffers (password/salt) could lead to segfaults or memory leaks. - **Platform Compatibility:** Relying on native code means the target environment must support the compiled architecture. The CI/CD pipeline must build the Rust crate for all supported deployment targets (x86_64, aarch64). - **Blocking the Event Loop:** Hashing with Argon2id is intentionally slow and CPU-intensive. If the Deno FFI call is blocking, it will stall the Deno event loop. The FFI function must be marked as `nonblocking: true` in `Deno.dlopen`, and the Rust implementation must be executed asynchronously or off the main thread. ### Alternatives - **WASM (e.g., `hash-wasm`):** An alternative is to use WebAssembly to perform the hashing directly in Deno without FFI. - _Justification against:_ Native SIMD provides 3–5x greater throughput compared to V8 WebAssembly for 64 MiB memory-hard hashing. Furthermore, we already have and maintain the `spire_ffi` Rust workspace. Avoiding a new npm dependency keeps the server and `@auth-yes/sdk` zero-dependency, adhering to our core architectural goals. ## Proposed Implementation ### 1. Update Rust Dependencies - Add the `argon2` crate to `spire_ffi/Cargo.toml`: ```toml [dependencies] argon2 = { version = "0.5", features = ["std"] } ``` - _Note on SIMD:_ Version 0.5.x automatically uses runtime CPU feature detection (e.g., `std::is_x86_feature_detected!("avx2")`). For portable builds, use standard `cargo build --release`. For optional optimized container builds, document the use of `RUSTFLAGS="-C target-cpu=native" cargo build --release`. ### 2. Implement Rust FFI Export - In `spire_ffi/src/lib.rs`, create a new `#[no_mangle]` extern "C" function named `argon2id_derive`. - The function signature should accept pointers and lengths for the password and salt, iteration count, memory size (in KB), and a pointer/length for the output buffer. - Use the `argon2` crate to compute the hash and write the result into the provided output buffer. Ensure all FFI safety boundaries are respected (e.g., checking for null pointers). ### 3. Expose via Deno FFI (`server/spire_ffi.ts`) - Add the `argon2id_derive` symbol to the `Deno.dlopen` definition. Critically, set `nonblocking: true` to prevent stalling the Deno event loop during hash computation. - Create an exported async function `deriveArgon2idKey(password: Uint8Array, salt: Uint8Array): Promise`. - Hardcode the security parameters: 12 iterations, 64 MiB (65536 KB) memory, and a 32-byte (256-bit) output key length. - Implement the fallback pattern: If `dylib` is null, log `[SPIRE FFI] Dynamic library (...) is not loaded. Mocking Argon2id derivation for local development.` and return a deterministic 32-byte mock buffer (e.g., filled with a repeating pattern). ### 4. Write Unit Tests - In `server/spire_ffi.test.ts`, write tests to ensure: - The fallback mechanism works when the library isn't loaded (returns the mock buffer). - When the library _is_ available, the function successfully returns a 32-byte Uint8Array. - (Optional) Verify the output matches a known standard Argon2id test vector to confirm correctness across the FFI boundary.