# 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.