first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,71 @@
# `params`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
`SrpParams` is the per-handshake parameter bundle every SRP-6a call in `@suaveplan/srp` consumes. It pairs a safe-prime group `(N, g)`, the bit length of `N`, an injected `HashLike` hash function, and a stable algorithm tag (`"SHA256"` or `"SHA1"`). One `SrpParams` value drives every step of a handshake — `computeVerifier`, `clientStartHandshake`, `clientFinishHandshake`, `serverStartHandshake`, `serverFinishHandshake`, `serverComputeM2` — so the same group and hash bind every intermediate value into the proof chain.
## Features
- `params2048Sha256(hash)` convenience factory for the recommended default (RFC 5054 Appendix A 2048-bit group + SHA-256).
- `validateSrpParams(params)` structural validation throwing `SRP.INVALID_PARAMS` on malformed shapes.
- Algorithm gate throwing `SRP.HASH_UNSUPPORTED` for any value outside `{"SHA256", "SHA1"}`.
- `g >= N` rejected at the boundary so subsequent `modPow` calls cannot escape the intended group.
## Usage: Basic Example
```ts
import { params2048Sha256 } from "@suaveplan/srp/params";
import { nobleHashBridge } from "@suaveplan/srp/hash";
const params = params2048Sha256(nobleHashBridge("SHA256"));
console.log(params.bitLength); // 2048
console.log(params.algorithm); // "SHA256"
console.log(params.N.byteLength); // 256
```
## Usage: Advanced Example
```ts
import { validateSrpParams, type SrpParams } from "@suaveplan/srp/params";
import { N_4096, g_4096 } from "@suaveplan/srp/groups/4096";
import { defaultHashBridge } from "@suaveplan/srp/hash";
const params: SrpParams = {
N: N_4096,
g: g_4096,
bitLength: 4096,
hash: defaultHashBridge("SHA256"),
algorithm: "SHA256",
};
validateSrpParams(params);
console.log("4096-bit SHA-256 params validated");
```
## API Reference
### `interface SrpParams`
| Field | Type | Description |
| ----------- | ------------------- | ---------------------------------------------------- |
| `N` | `Uint8Array` | Safe-prime modulus as big-endian bytes. |
| `g` | `Uint8Array` | Generator as big-endian bytes. |
| `bitLength` | `number` | Bit length of `N`; MUST equal `N.byteLength * 8`. |
| `hash` | `HashLike` | Injected hash bridge (sync or async). |
| `algorithm` | `"SHA256" \| "SHA1"`| Stable algorithm tag. |
### `params2048Sha256(hash: HashLike): SrpParams`
Returns a validated `SrpParams` for the 2048-bit group + SHA-256.
### `validateSrpParams(params: SrpParams): void`
Throws `SrpError(SRP.INVALID_PARAMS)` when `N.byteLength` is not a multiple of 4, `bitLength` does not match `N.byteLength * 8`, `g <= 1`, or `g >= N`. Throws `SrpError(SRP.HASH_UNSUPPORTED)` when `algorithm` is not in `{"SHA256", "SHA1"}`.
## Implementation Notes
The 4-byte alignment check on `N.byteLength` reflects the operational shape of every documented RFC 5054 group — 128, 192, 256, 384, 512, 768, 1024 bytes — and serves as a structural smoke-test: a modulus that is not 4-byte aligned almost certainly came from a decoding bug rather than an actual RFC 5054 group.
`validateSrpParams` is called from `params2048Sha256` at construction time so the factory-returned `SrpParams` is already validated when handed to a handshake function. Consumers building `SrpParams` from raw constants (custom groups, test fixtures) MUST call `validateSrpParams` explicitly; the handshake functions DO NOT re-validate on every call to keep the per-handshake overhead minimal.