Initial Commit

This commit is contained in:
2026-05-27 23:47:53 +01:00
parent fbc70f96e6
commit 9b28db724f
18103 changed files with 1600554 additions and 0 deletions

View File

@@ -0,0 +1,68 @@
# `keygen/exponent`
## Purpose
Public-exponent validation for RSA key generation. The `e`-only
constraints (odd, `> 1`, `< 2^256`) live here so they can be
asserted at the API boundary before the caller pays for prime
sampling. Coprimality with `λ(n)` happens later in
`generate.ts` once the primes are known.
## Features
- Single boundary check that maps every violation to
`CRYPTO_RSA.INVALID_KEY` with an `e` context for diagnosis.
- Auxiliary `gcd` helper exported so the higher-level keygen
loop can verify `gcd(e, λ(n)) === 1` without duplicating the
Euclidean algorithm.
- Conforms to NIST FIPS 186-5 §5.4 (`2^16 < e < 2^256`); this
module enforces the upper bound and `e > 1`. The lower bound
`e ≥ 2^16 + 1` is profile-specific (FIPS-186-5 mode) and lives
in the policy / profile layer.
## Usage: Basic Example
```ts
import { validatePublicExponent } from "@suaveplan/crypto-rsa/keygen/exponent";
validatePublicExponent(65537n); // ok
validatePublicExponent(3n); // ok — permissive profile
validatePublicExponent(4n); // throws CRYPTO_RSA.INVALID_KEY
```
## Usage: Advanced Example
Combine with `gcd` to cull candidate primes whose `(p-1)` shares
a factor with `e`:
```ts
import { gcd, validatePublicExponent } from "@suaveplan/crypto-rsa/keygen/exponent";
validatePublicExponent(65537n);
const candidate = 0x...n; // some probable prime
if (gcd(candidate - 1n, 65537n) !== 1n) {
// discard, sample again
}
```
## API Reference
### `validatePublicExponent(e: bigint): void`
Throws `CRYPTO_RSA.INVALID_KEY` on `e ≤ 1`, even `e`, or
`e ≥ 2^256`. Returns `void` on success.
### `gcd(a: bigint, b: bigint): bigint`
Iterative Euclidean algorithm; works on any bigint pair, signs
ignored.
## Implementation Notes
- The `gcd` implementation is the standard iterative Euclidean
loop rather than a recursive one to avoid V8 stack-frame
overhead on very large bigint pairs (`λ(n)` for a 4096-bit
modulus is roughly 4096 bits).
- The `2^256` upper bound is hard-coded as a literal because it
is a bright-line spec value; any future relaxation must
modify this module deliberately, not via a config flag.