feat(spire-ffi): create planning task for native Argon2id FFI
- Generated Kanban markdown file adhering to tasks/GUIDELINES.md. - Documented requirements for SIMD, Deno FFI non-blocking bindings, and `hash-wasm` alternatives. - Specified development/production fallback strategies. Co-authored-by: mrteye <1945243+mrteye@users.noreply.github.com>
This commit is contained in:
parent
cf64161a8b
commit
2b3b6f9636
@ -0,0 +1,46 @@
|
|||||||
|
# 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<Uint8Array>`.
|
||||||
|
- 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.
|
||||||
Loading…
x
Reference in New Issue
Block a user