# `schemas` _(no submodules)_ ## 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` 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` 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.