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,76 @@
# engine/select
## Purpose
Resolve the default `RsaCryptoEngine` for the host runtime. When
`globalThis.crypto.subtle` exposes the RSA algorithms this package
needs, `subtleEngine` is returned for hardware-accelerated performance;
otherwise the pure-JS `nobleEngine` is used. Increments
`crypto_rsa.engine_selected_total{engine}` on every call so production
dashboards can track engine distribution per deployment.
## Features
- Auto-detects `subtle` availability at runtime
- `prefer: "noble"` forces the pure-JS engine even when subtle is
available (useful for deterministic-test scenarios)
- `prefer: "subtle"` forces subtle and throws `ENGINE_UNAVAILABLE` if
absent (caller commits to subtle, surfaces failure synchronously)
- Counter increments on every call regardless of branch taken
## Usage: Basic Example
```ts
import { defaultEngine } from "@suaveplan/crypto-rsa/engine";
const engine = defaultEngine();
const sig = await engine.sign(privateKey, message, {
scheme: "pkcs1v15",
hash: "SHA-256",
});
```
## Usage: Advanced Example
Force noble in test environments to make signature outputs reproducible
(subtle's RSA-PSS internally generates the salt and is non-determinstic;
noble's PSS path accepts a custom `Rng`):
```ts
import { defaultEngine } from "@suaveplan/crypto-rsa/engine";
const engine = defaultEngine({ prefer: "noble" });
// Reproducible PSS signatures.
```
## API Reference
### `defaultEngine(options?): RsaCryptoEngine`
- `options.prefer?: "noble" | "subtle"` — forces the engine choice
- **returns** `RsaCryptoEngine`
- **throws** `CryptoRsaError(CRYPTO_RSA.ENGINE_UNAVAILABLE)` when
`prefer: "subtle"` is set and `globalThis.crypto.subtle` is missing
### `DefaultEngineOptions`
- `prefer?: RsaEngineName`
### `resetEngineSelectionCounterForTesting()`
Test-only helper.
## Implementation Notes
- The selection rule is: if `prefer` is set, use it (subtle requested
but missing → throw); otherwise prefer subtle, fall back to noble.
The counter records the actual choice made, not the request.
- Detecting subtle availability is a single `globalThis.crypto.subtle`
read. Cached lookups would be incorrect — runtimes can polyfill
subtle mid-process (e.g. test setup adding a Web Crypto polyfill).
- The counter cardinality is bounded to two label values
(`noble`/`subtle`) so dashboards aggregate cleanly.
- This selector is the recommended default entry point for engine
consumers; calling `nobleEngine` / `subtleEngine` directly is
appropriate only when the caller has committed to a specific engine
for the lifetime of the operation.