Initial Commit
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
# RawHasher
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->
|
||||
|
||||
## Purpose
|
||||
|
||||
`RawHasher` is the trivial `ChainHasher` strategy: it returns the payload
|
||||
bytes verbatim, performing no transformation. It exists so that consumers
|
||||
whose payload is already a canonical digest (a manifest hash, a CBOR
|
||||
fingerprint, a CID) can plug a chain signer in without paying for a
|
||||
redundant SHA-256 pass.
|
||||
|
||||
Because `ChainedKeySigner` always invokes `hash(payload, parent)` before
|
||||
delegating to `crypto-curve.sign(...)`, choosing `RawHasher` means the
|
||||
signer signs exactly the payload it was handed — useful for tests, for
|
||||
audit chains over pre-digested manifests, and for cases where the
|
||||
application wants full control over the pre-image format.
|
||||
|
||||
## Features
|
||||
|
||||
- Zero allocation: returns the input `Uint8Array` reference unchanged.
|
||||
- Stateless: safe to share a single instance across many signers and
|
||||
threads. No instance fields, no mutable state.
|
||||
- Ignores the optional `parent` argument by design. Chains needing
|
||||
parent-binding should pick `MerkleHasher` (or a custom hasher).
|
||||
- Stable `name: "raw"` for diagnostics and audit logs.
|
||||
|
||||
## Usage: Basic
|
||||
|
||||
```ts
|
||||
import { RawHasher } from "@suaveplan/crypto-keys/hashers/raw/raw";
|
||||
|
||||
const hasher = new RawHasher();
|
||||
const payload = new Uint8Array([1, 2, 3]);
|
||||
const bytesToSign = hasher.hash(payload);
|
||||
// bytesToSign === payload (same reference)
|
||||
```
|
||||
|
||||
## Usage: Advanced
|
||||
|
||||
Swap `RawHasher` in to verify that an externally computed manifest
|
||||
digest round-trips through the signer unchanged — useful for cross-stack
|
||||
interoperability with consumers that have already computed their own
|
||||
canonical digest:
|
||||
|
||||
```ts
|
||||
import { RawHasher } from "@suaveplan/crypto-keys/hashers/raw/raw";
|
||||
import type { ParsedChainLevel } from "@suaveplan/crypto-keys/types/chain-level";
|
||||
|
||||
const hasher = new RawHasher();
|
||||
const manifestDigest = new Uint8Array(32); // already-canonical 32-byte digest
|
||||
const parent: ParsedChainLevel | undefined = undefined;
|
||||
const signedPreImage = hasher.hash(manifestDigest, parent);
|
||||
// signedPreImage is bit-identical to manifestDigest
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `class RawHasher implements ChainHasher`
|
||||
|
||||
- `readonly name: "raw"` — canonical short name surfaced in diagnostics.
|
||||
- `hash(payload: Uint8Array, parent?: ParsedChainLevel): Uint8Array`
|
||||
— returns `payload` unchanged. The `parent` argument is accepted to
|
||||
satisfy the `ChainHasher` interface and is deliberately ignored.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The implementation returns the input reference directly rather than
|
||||
copying. Callers that need ownership of the returned bytes must clone
|
||||
explicitly. Reference-return is deliberate: it makes `RawHasher` a true
|
||||
no-op and ensures the cost of pre-image hashing is exactly zero — which
|
||||
matters for high-throughput audit logs where the payload is already a
|
||||
fixed-width digest. The test suite asserts both reference equality and
|
||||
content equality so any future refactor that switches to a copy would be
|
||||
caught immediately.
|
||||
Reference in New Issue
Block a user