snapkitty-clojure-lisp-bridge / NATIVE_BINDING.md
SNAPKITTYWEST's picture
push from SNAPKITTYWEST/snapkitty-clojure-lisp-bridge
119e586 verified
|
Raw History Blame Contribute Delete
8.18 kB
# SKC-LISP Native Binding: NASM Assembly Validators
Fast-path optimization for critical Lisp runtime operations: mutation validation gate (8-point check) and cryptographic verification (Blake3 + Ed25519).
## Architecture
```
┌─────────────────────────────────────────────────────────────────┐
│ MCP Server (ClojureScript) → Clojure tools │
├─────────────────────────────────────────────────────────────────┤
│ native.cljs (ClojureScript API) │
│ - load-native-library!() → loads .node binding │
│ - validate-mutation!() → calls mutation_validate_gate ASM │
│ - verify-blake3!() → calls blake3_verify ASM │
│ - verify-ed25519!() → calls ed25519_verify ASM │
├─────────────────────────────────────────────────────────────────┤
│ binding.cc (Node.js C++ addon via V8) │
│ - LoadAsmLibrary() → dlopen/dlsym ASM library │
│ - ValidateMutation() → wrap mutation_validate_gate call │
│ - VerifyBlake3() → wrap blake3_verify call │
│ - VerifyEd25519() → wrap ed25519_verify call │
├─────────────────────────────────────────────────────────────────┤
│ libskclisp_asm.so (x64 NASM shared object) │
│ - mutation-validator.asm → 8-point gate + helper functions │
│ - digest-verifier.asm → Blake3/Ed25519 stubs │
└─────────────────────────────────────────────────────────────────┘
```
## Compilation
### Build from scratch:
```bash
npm run build:native
```
This compiles:
1. `native/mutation-validator.asm` → `native/build/Release/mutation-validator.o`
2. `native/digest-verifier.asm` → `native/build/Release/digest-verifier.o`
3. Link into `native/build/Release/libskclisp_asm.so`
4. Compile C++ binding `native/binding.cc` → `native/build/Release/skclisp_native.node`
### Prerequisites:
- NASM (x86-64 assembler): `apt install nasm` (Linux) or `brew install nasm` (macOS)
- Node.js development headers (included with Node.js)
- node-gyp: `npm install -g node-gyp`
- C++ compiler (g++ or clang)
## Runtime Startup
When the MCP server starts:
```cljs
(native/load-native-library! "./native/build/Release/skclisp_native.node")
```
This:
1. Calls `LoadAsmLibrary` in the C++ binding
2. Opens the NASM shared object with `dlopen`
3. Loads function pointers: `mutation_validate_gate`, `blake3_verify`, `ed25519_verify`
4. Returns true if all pointers loaded successfully
## MCP Tools
Three new tools registered with the server:
### 1. `validate_mutation` — 8-point mutation gate
**Input schema:**
```json
{
"mutation-id": number,
"generation-before": number,
"generation-after": number,
"actor": number,
"target": number,
"operation": number (optional),
"old-digest": string (optional),
"new-digest": string (optional)
}
```
**Validation checks:**
1. Target exists in object store (or allocation requested)
2. Old digest matches stored value
3. New digest matches replacement
4. Replacement is well-formed (passes semantic checks)
5. All references in replacement are valid
6. Code in replacement is valid
7. Invariants are preserved
8. Generation counter advances (strictly monotonic)
**Return:**
```json
{
"passes-gate": true/false,
"error-code": 0-8 (failure check) | 255 (pass),
"details": "human-readable message"
}
```
### 2. `verify_blake3` — Digest verification
**Input schema:**
```json
{
"payload": string (base64 or hex),
"expected-digest": string (base64 or hex)
}
```
**Return:**
```json
{
"digest-valid": true/false,
"error-code": 0 (match) | 1 (mismatch) | 2 (invalid),
"details": "human-readable message"
}
```
### 3. `verify_ed25519` — Signature verification
**Input schema:**
```json
{
"message": string,
"signature": string (base64 or hex),
"public-key": string (base64 or hex)
}
```
**Return:**
```json
{
"signature-valid": true/false,
"error-code": 0 (valid) | 1 (invalid) | 2 (invalid_input),
"details": "human-readable message"
}
```
## Assembly Details
### Mutation Validator (`mutation-validator.asm`)
Entry point: `mutation_validate_gate(mutation_event*, object_store*, validation_result*)`
System V AMD64 ABI calling convention:
- `rdi` = pointer to mutation_event struct (64 bytes)
- `rsi` = pointer to object_store
- `rdx` = pointer to validation_result (2-byte output)
**mutation_event struct:**
```
[0] mutation_id (u64)
[8] generation_before (u64)
[16] generation_after (u64)
[24] actor (u64)
[32] target (u64)
[40] operation (u32)
[44] reserved (u32)
[48] old_digest (ptr) (u64)
[56] new_digest (ptr) (u64)
```
**validation_result:**
```
[0] passes_gate (u8, 1=pass, 0=fail)
[1] error_code (u8, 0-8 for check failures, 255=pass)
```
Returns: 1 (all pass), 0 (failure code in result buffer)
### Digest Verifier (`digest-verifier.asm`)
**blake3_verify(payload*, payload_length, expected_digest*, result*)**
- Currently a stub (validates input alignment, assumes match)
- Requires linking against libblake3.a for production
**ed25519_verify(message*, message_length, signature*, public_key*, result*)**
- Currently a stub (validates input, assumes valid)
- Requires linking against libsodium for production
Both stubs set result[0] = 1 (valid) and result[1] = 0 (no error) on valid input.
## Development Workflow
1. **Edit assembly:** Modify `native/*.asm` files
2. **Rebuild:** `npm run build:native`
3. **Test:** `npm test` (runs integration tests)
4. **Run MCP:** `npm run watch` + test with Claude Code
## Linking External Libraries
For production Blake3/Ed25519:
1. Install libraries:
```bash
apt install libblake3-dev libsodium-dev
```
2. Update `native/binding.gyp` to link:
```json
"ldflags": ["-ldl", "-lblake3", "-lsodium"]
```
3. Replace stub implementations in `digest-verifier.asm` with actual crypto calls
4. Rebuild: `npm run build:native`
## Performance Notes
- **Mutation validation:** O(8) checks, ~100ns per check (CPU bound)
- **Blake3 verification:** O(payload_length) with SIMD acceleration when linked
- **Ed25519 verification:** O(1) point multiplication, ~5-10µs per signature
- Native binding eliminates JS→WASM boundary (~1-2µs per call)
## Troubleshooting
### `Failed to load ASM symbols`
- Ensure `libskclisp_asm.so` exists at `native/build/Release/`
- Run `npm run build:native` to recompile
### `NASM: command not found`
- Install: `apt install nasm` or `brew install nasm`
### `node-gyp ERR! not ok`
- Ensure Node.js dev headers: `apt install nodejs-dev` or via Node.js installer
- Clear cache: `npm run build:native -- --clean`
### Segfault on library load
- Check that the `.so` was built for the correct architecture (x86-64)
- Verify dlopen can find the library (check LD_LIBRARY_PATH)
## References
- **System V AMD64 ABI:** https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI
- **Node.js C++ addons:** https://nodejs.org/api/addons.html
- **NASM manual:** https://www.nasm.us/doc/
- **Blake3:** https://github.com/BLAKE3-team/BLAKE3
- **Libsodium:** https://doc.libsodium.org/