Move docs/ package mirror into document-navigator plugin
Relocate the ~6k-file docs tree from the repo root into plugins/document-navigator/docs/ so the plugin is self-contained and portable. docs/superpowers/ (specs and plans) stays at the repo root. Moved via cp+rm rather than git mv because directory rename() fails with EPERM on this WSL /mnt DrvFs mount; git rename-detection pairs the identical-content files at commit time. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
# `policy/modulus`
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
## Purpose
|
||||
|
||||
Modulus-length policy gate enforced at every public-API entry point in
|
||||
`@suaveplan/crypto-rsa`. Combines a default-2048-bit floor (with optional
|
||||
1024-bit legacy carve-out) and a default-16384-bit ceiling (with optional
|
||||
oversized opt-in) so consumers cannot accidentally accept dangerously short
|
||||
keys or get DoS'd by attacker-supplied oversized keys.
|
||||
|
||||
The 2048-bit default tracks NIST SP 800-131A Rev. 2's transition from
|
||||
112-bit to 128-bit security strength; 1024 bits delivers 80-bit strength
|
||||
which is broken offline and survives only for legacy WebAuthn TPM
|
||||
endorsement keys (see proposal §Why and CLAUDE.md). The 16384-bit ceiling
|
||||
matches the largest modulus a service is realistically expected to verify;
|
||||
beyond that the per-verify modpow cost (cubic in bit length) becomes a
|
||||
viable DoS vector.
|
||||
|
||||
## Features
|
||||
|
||||
- `enforceMinBitLength(key, { allowLegacy? })` — strict default 2048-bit floor.
|
||||
- `enforceMaxBitLength(key, { allowOversize? })` — strict default 16384-bit ceiling.
|
||||
- Hard sub-1024-bit reject regardless of `allowLegacy`.
|
||||
- Both throw `CryptoRsaError` with structured `context` for telemetry.
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { enforceMinBitLength } from "@suaveplan/crypto-rsa/policy";
|
||||
|
||||
enforceMinBitLength(publicKey); // throws if bitLength < 2048
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
enforceMaxBitLength,
|
||||
enforceMinBitLength,
|
||||
} from "@suaveplan/crypto-rsa/policy";
|
||||
|
||||
// WebAuthn TPM legacy path: 1024 bits permitted.
|
||||
enforceMinBitLength(tpmEndorsementKey, { allowLegacy: true });
|
||||
|
||||
// Offline tooling that processes 32 768-bit keys.
|
||||
enforceMaxBitLength(researchKey, { allowOversize: true });
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `enforceMinBitLength(key, options?: { allowLegacy?: boolean }): void`
|
||||
|
||||
Throws `CryptoRsaError(CRYPTO_RSA.MODULUS_TOO_SHORT)` with `context: { bitLength, floor }`
|
||||
when `key.bitLength < floor`. `floor` is `2048` by default, `1024` under
|
||||
`allowLegacy: true`. Sub-1024-bit keys are always rejected.
|
||||
|
||||
### `enforceMaxBitLength(key, options?: { allowOversize?: boolean }): void`
|
||||
|
||||
Throws `CryptoRsaError(CRYPTO_RSA.MODULUS_TOO_LARGE)` with `context: { bitLength, ceiling }`
|
||||
when `key.bitLength > 16384`. `allowOversize: true` short-circuits the check.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The hard sub-1024-bit floor is enforced even when `allowLegacy: true` because
|
||||
512-bit and 768-bit moduli have been factored on commodity hardware and there
|
||||
is no realistic legacy use-case that still relies on them.
|
||||
|
||||
The ceiling check returns early when `allowOversize: true` rather than scaling
|
||||
the comparison; this keeps the hot path branch-predictable and the policy
|
||||
scope obvious to readers.
|
||||
Reference in New Issue
Block a user