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,70 @@
# `schemas`
<!-- begin:auto-docs -->
_(no submodules)_
<!-- end:auto-docs -->
## Purpose
Zod boundary schemas for the public surface of `@suaveplan/srp`. `SrpParamsSchema` validates a candidate `SrpParams` object (byte shape, algorithm tag, generator/modulus relationship); `SrpHandshakeStateSchema` validates the per-handshake state envelope both sides keep across the two round-trips; `VerifierSchema` validates the server-side `{ I, salt, v }` record. Every schema-validation failure surfaces as `SrpError(SRP.INVALID_PARAMS)` via the `parseSrpParams` helper so consumers branch on a stable code rather than parsing Zod's diagnostic text.
## Features
- `SrpParamsSchema` enforces `N.byteLength` multiple-of-4, `bitLength === N.byteLength * 8`, `g > 1`, `g < N`, `algorithm ∈ {"SHA256", "SHA1"}`.
- `SrpHandshakeStateSchema` enforces non-empty `I`, `Uint8Array`-typed `salt`/`A`/`B`, role tag.
- `VerifierSchema` validates the server-side persistence record.
- `parseSrpParams(value)` rethrows Zod failures as `SrpError(SRP.INVALID_PARAMS)`.
## Usage: Basic Example
```ts
import { parseSrpParams } from "@suaveplan/srp";
import { params2048Sha256 } from "@suaveplan/srp/params";
import { nobleHashBridge } from "@suaveplan/srp/hash";
const params = parseSrpParams(params2048Sha256(nobleHashBridge("SHA256")));
console.log(params.algorithm); // "SHA256"
```
## Usage: Advanced Example
```ts
import { SrpHandshakeStateSchema, VerifierSchema } from "@suaveplan/srp";
const verifier = VerifierSchema.parse({
I: "alice@example.com",
salt: new Uint8Array(16),
v: new Uint8Array(256),
});
const state = SrpHandshakeStateSchema.parse({
I: "alice@example.com",
salt: new Uint8Array(16),
A: new Uint8Array(256),
B: new Uint8Array(256),
role: "server",
});
console.log(verifier.I, state.role);
```
## API Reference
### `SrpParamsSchema: z.ZodSchema<SrpParams>`
Validates byte shape (`N` multiple of 4, `bitLength === N.byteLength * 8`), algorithm tag, and `1 < g < N`.
### `SrpHandshakeStateSchema`
Validates `{ I: string; salt: Uint8Array; A: Uint8Array; B: Uint8Array; role: "client" | "server" }`.
### `VerifierSchema`
Validates `{ I: string; salt: Uint8Array; v: Uint8Array }`.
### `parseSrpParams(value: unknown): SrpParams`
Wraps `SrpParamsSchema.safeParse` and rethrows failures as `SrpError(SRP.INVALID_PARAMS)`.
## Implementation Notes
The schemas use `z.custom<Uint8Array>` rather than the deprecated `z.instanceof` because `instanceof Uint8Array` does not survive cross-realm boundaries in some runtimes (e.g. Cloudflare Workers). The `v instanceof Uint8Array` check is sufficient for our universal target environments (Node, Bun, browsers) and gives Zod a clean predicate for error reporting.
`parseSrpParams` deliberately maps Zod's structured error into a single `SrpError(SRP.INVALID_PARAMS)` rather than re-throwing the `ZodError`. Consumers of `@suaveplan/srp` should not need a Zod-specific catch path; `error.code === "SRP.INVALID_PARAMS"` is the documented contract.