Files
2026-05-27 23:47:53 +01:00

2.1 KiB

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

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:

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.