v0.0.47 - Added post-quantum cryptography (ML-DSA-65, SLH-DSA-128s, ML-KEM-768) and standard ECC (ed25519, x25519) support with algorithm-based API

This commit is contained in:
Laan Tungir
2026-07-16 15:14:57 -04:00
parent 6fd7b8ce1f
commit c5f1a70658
66 changed files with 19091 additions and 257 deletions

View File

@@ -36,6 +36,79 @@ for the full integration contract.
The `nsigner ... client '<json>'` subcommand in [`src/main.c`](../src/main.c) is
unaffected — it has its own raw framing pass-through and never used this directory.
## Multi-Algorithm and Post-Quantum Verbs
n_signer supports six algorithms: `secp256k1` (Nostr), `ed25519` (SSH),
`x25519` (age/ECDH), `ml-dsa-65` (PQ signatures, FIPS 204), `slh-dsa-128s`
(PQ hash-based signatures, FIPS 205), and `ml-kem-768` (PQ KEM, FIPS 203).
Use `nsigner_client_call(client, "<verb>", params, &result)` with these verbs:
| Verb | Algorithms | Description |
|---|---|---|
| `get_public_key` | all | Returns the role's public key (see format below) |
| `sign_event` | secp256k1 | Sign a Nostr event (existing) |
| `nip44_encrypt` / `nip44_decrypt` | secp256k1 | NIP-44 (existing) |
| `nip04_encrypt` / `nip04_decrypt` | secp256k1 | NIP-04 (existing) |
| `mine_event` | secp256k1 | NIP-13 PoW mining + sign (existing) |
| `sign_data` | ed25519, ml-dsa-65, slh-dsa-128s | Sign arbitrary bytes (hex) |
| `verify_signature` | ed25519, ml-dsa-65, slh-dsa-128s | Verify a signature against the role's pubkey |
| `ssh_sign` | ed25519 | Sign an SSH authentication challenge |
| `kem_encapsulate` | ml-kem-768 | Encapsulate with a peer's ML-KEM public key |
| `kem_decapsulate` | ml-kem-768 | Decapsulate a ciphertext with the role's ML-KEM private key |
### Algorithm-based API (new)
In addition to the role-based verbs above, the signer supports algorithm-based verbs where the caller specifies `algorithm` and `index` directly, without needing a role:
| Verb | Algorithms | Description |
|---|---|---|
| `sign` | secp256k1, ed25519, ml-dsa-65, slh-dsa-128s | Sign arbitrary bytes (hex) |
| `verify` | secp256k1, ed25519, ml-dsa-65, slh-dsa-128s | Verify a signature |
| `encapsulate` | ml-kem-768 | KEM encapsulation with peer's public key |
| `decapsulate` | ml-kem-768 | KEM decapsulation with derived private key |
| `derive_shared_secret` | x25519 | ECDH key agreement |
| `get_public_key` (with `algorithm`) | all | Get public key for a derived key |
Example: `nsigner_client_call(client, "sign", "[\"68656c6c6f\",{\"algorithm\":\"ed25519\",\"index\":0}]", &result)`
For secp256k1, the optional `scheme` parameter selects `"schnorr"` (default) or `"ecdsa"`.
Old verbs (`sign_data`, `ssh_sign`, `verify_signature`, `kem_encapsulate`, `kem_decapsulate`) also accept the `algorithm` parameter and map to the new verbs. Without `algorithm`, they use the role-based path (backward compatible).
### `get_public_key` response format
- **secp256k1 (backward compatible):** `result` is a plain hex string
(`cJSON_IsString(result)` is true, 64 hex chars).
- **secp256k1 with `{"format":"structured"}` option:** `result` is a JSON
string containing `{"algorithm":"secp256k1","public_key":"<hex>","key_id":"<16 hex>"}`.
- **All other algorithms:** `result` is always a JSON string containing
`{"algorithm":"<alg>","public_key":"<hex>","key_id":"<16 hex>"}`.
Clients should parse the `result` string with `cJSON_Parse` to extract the
`algorithm`, `public_key`, and `key_id` fields for non-secp256k1 algorithms.
### Key sizes
| Algorithm | Pub key | Priv key | Signature | Ciphertext | Shared secret |
|---|---|---|---|---|---|
| secp256k1 | 32 B | 32 B | 64 B | — | — |
| ed25519 | 32 B | 32 B | 64 B | — | — |
| x25519 | 32 B | 32 B | — | — | 32 B |
| ML-DSA-65 | 1952 B | 4032 B | 3309 B | — | — |
| SLH-DSA-128s | 32 B | 64 B | 7856 B | — | — |
| ML-KEM-768 | 1184 B | 2400 B | — | 1088 B | 32 B |
### Example clients
- [`examples/pq_sign_example.c`](../examples/pq_sign_example.c) — ML-DSA-65 sign
- [`examples/pq_kem_example.c`](../examples/pq_kem_example.c) — ML-KEM-768 encaps/decaps
- [`examples/ssh_sign_example.c`](../examples/ssh_sign_example.c) — ed25519 SSH sign
See [`documents/CLIENT_IMPLEMENTATION.md`](../documents/CLIENT_IMPLEMENTATION.md)
section 11 for the full multi-algorithm specification, derivation paths, and
example request/response transcripts.
## Why
Per [`plans/nsigner_integration_plan.md`](../resources/nostr_core_lib/plans/nsigner_integration_plan.md)