first commit
This commit is contained in:
89
docs/foundation/bitpacker/bitpacker-crypto/src/crc32.md
Normal file
89
docs/foundation/bitpacker/bitpacker-crypto/src/crc32.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# CRC32 + Adler32 Checksums
|
||||
|
||||
## Purpose
|
||||
|
||||
Fast non-cryptographic checksums for bit-packed payloads. `crc32` implements the IEEE-802.3 / zlib polynomial (`0xedb88320`); `adler32` implements the RFC 1950 algorithm. Both are designed to detect accidental corruption (single-bit flips, wire-level errors, dropped bytes), not adversarial tampering — for cryptographic integrity, use the AEAD or signed-bitschema primitives in `@suaveplan/bitpacker-crypto`'s `encrypted/` and `signed/` modules.
|
||||
|
||||
The four wrappers (`appendCrc32`, `verifyAndStripCrc32`, `appendAdler32`, `verifyAndStripAdler32`) bookend a payload with a 4-byte big-endian checksum so framed bitpacker output can be transmitted over a noisy channel and integrity-checked at the receiving end. The wrappers throw on truncated input or checksum mismatch; the bare `crc32` / `adler32` functions return the raw 32-bit value for callers that want to integrate the check elsewhere.
|
||||
|
||||
## Features
|
||||
|
||||
- `crc32(data)` — IEEE-802.3 / zlib polynomial CRC32 with a precomputed 256-entry table
|
||||
- `adler32(data)` — RFC 1950 Adler32 with the standard `MOD_ADLER = 65521` prime
|
||||
- `appendCrc32` / `appendAdler32` — append 4-byte big-endian checksum
|
||||
- `verifyAndStripCrc32` / `verifyAndStripAdler32` — verify and strip 4-byte checksum, throwing on mismatch or short input
|
||||
- Pure JS, no dependencies, deterministic output, browser- and Node-safe
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```ts
|
||||
import { crc32, appendCrc32, verifyAndStripCrc32 } from "@suaveplan/bitpacker-crypto";
|
||||
|
||||
const payload = new Uint8Array([1, 2, 3, 4]);
|
||||
const checksum = crc32(payload); // 0xb63cfbcd
|
||||
const framed = appendCrc32(payload); // 8 bytes: payload + 4-byte CRC
|
||||
const restored = verifyAndStripCrc32(framed); // -> [1, 2, 3, 4]
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
```ts
|
||||
import {
|
||||
appendCrc32,
|
||||
verifyAndStripCrc32,
|
||||
appendAdler32,
|
||||
verifyAndStripAdler32,
|
||||
} from "@suaveplan/bitpacker-crypto";
|
||||
|
||||
// Frame a bit-packed payload, transmit, and validate on receive.
|
||||
function transmit(payload: Uint8Array): Uint8Array {
|
||||
return appendCrc32(payload);
|
||||
}
|
||||
|
||||
function receive(framed: Uint8Array): Uint8Array {
|
||||
try {
|
||||
return verifyAndStripCrc32(framed);
|
||||
} catch (err) {
|
||||
// Caller decides: retransmit, drop, or escalate to a higher-level
|
||||
// integrity check (signed-bitschema for adversarial channels).
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
// Adler32 is faster but weaker; pick it for short payloads on trusted channels.
|
||||
const cheap = appendAdler32(new Uint8Array([0xde, 0xad, 0xbe, 0xef]));
|
||||
const back = verifyAndStripAdler32(cheap);
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `crc32(data: Uint8Array): number`
|
||||
|
||||
Returns the 32-bit unsigned CRC32 value of `data` using the IEEE-802.3 / zlib polynomial (`0xedb88320`). Uses a precomputed 256-entry table for one-byte-per-iteration throughput.
|
||||
|
||||
### `adler32(data: Uint8Array): number`
|
||||
|
||||
Returns the 32-bit unsigned Adler32 value of `data` per RFC 1950 (`a` and `b` accumulators with `MOD_ADLER = 65521`).
|
||||
|
||||
### `appendCrc32(data: Uint8Array): Uint8Array`
|
||||
|
||||
Returns a new array containing `data` followed by 4 big-endian bytes of `crc32(data)`.
|
||||
|
||||
### `verifyAndStripCrc32(data: Uint8Array): Uint8Array`
|
||||
|
||||
Returns the leading `data.length - 4` bytes if the trailing 4 bytes match `crc32(payload)`. Throws `Error` with `"Data too short for CRC32 verification"` if `data.length < 4`, or `"CRC32 mismatch: expected X, got Y"` on mismatch.
|
||||
|
||||
### `appendAdler32(data: Uint8Array): Uint8Array`
|
||||
|
||||
Returns a new array containing `data` followed by 4 big-endian bytes of `adler32(data)`.
|
||||
|
||||
### `verifyAndStripAdler32(data: Uint8Array): Uint8Array`
|
||||
|
||||
Mirrors `verifyAndStripCrc32` for Adler32. Same error semantics.
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
- **CRC32 polynomial = `0xedb88320`.** This is the bit-reversed form of the standard IEEE-802.3 polynomial (`0x04c11db7`). The reversal is encoded in the table-precomputation loop (`c & 1 ? POLY ^ (c >>> 1) : c >>> 1`) so the streaming inner loop processes least-significant bits first, matching zlib / gzip / PNG.
|
||||
- **Big-endian checksum framing.** Both append wrappers write the 32-bit checksum as big-endian bytes, matching network byte order. The `verifyAndStrip` counterparts read with `getUint32(offset, false)` (false = big-endian).
|
||||
- **Not cryptographically secure.** A motivated attacker can construct collisions for both CRC32 and Adler32 in O(1). Use these for accidental-corruption detection only; use AEAD or signature primitives elsewhere in `@suaveplan/bitpacker-crypto` for adversarial integrity.
|
||||
- **No allocation in the hot path.** `crc32` / `adler32` only allocate via the precomputed `CRC32_TABLE`. `appendCrc32` / `appendAdler32` allocate one output buffer; `verifyAndStripCrc32` / `verifyAndStripAdler32` allocate via `slice` for the returned payload.
|
||||
Reference in New Issue
Block a user