156 lines
8.1 KiB
Markdown
156 lines
8.1 KiB
Markdown
# @suaveplan/bitpacker-crypto - Bit-packer-aware crypto primitives — SignedBitSchema, EncryptedBitSchema, EnvelopeSchema, HashChainSchema, MultiSignedBitSchema, SchemaFingerprint, HashAlgorithmRegistry. Authority/AeadOps/DomainTag types live in @suaveplan/types; the canonical implementations are in @suaveplan/crypto and dependency-injected by the caller.
|
|
|
|
## Summary
|
|
|
|
Bit-packer-aware crypto primitives. The shared interfaces (`Authority`,
|
|
`DomainTag`, `AuthorityVerifier`, `AeadOps`) live in `@suaveplan/types`;
|
|
the canonical implementations come from `@suaveplan/crypto` and are
|
|
**dependency-injected** by the caller. This package has zero runtime
|
|
dependency on `@suaveplan/crypto`, so consumers in any layer (including
|
|
`@suaveplan/crypto` itself, e.g. `crypto::ChainBundle`) can adopt these
|
|
primitives without inducing a circular package dependency.
|
|
|
|
<!-- begin:auto-docs -->
|
|
## Documentation tree
|
|
|
|
- [encrypted](./src/encrypted/encrypted-bitschema.md) — Niche AEAD-encrypted envelope around a bit-packed body. Wire format: `[version u8][algTag u8][nonceLen u8][nonce][ciphe…
|
|
- [encrypted-bitschema](./src/encrypted/encrypted-bitschema.md) — Niche AEAD-encrypted envelope around a bit-packed body. Wire format: `[version u8][algTag u8][nonceLen u8][nonce][ciphe…
|
|
- [envelope](./src/envelope/envelope-schema.md) — A typed, version-aware envelope schema for bit-packed payloads. Wraps a caller-supplied `BodyCodec` with a `[magic][for…
|
|
- [envelope-schema](./src/envelope/envelope-schema.md) — A typed, version-aware envelope schema for bit-packed payloads. Wraps a caller-supplied `BodyCodec` with a `[magic][for…
|
|
- [fingerprint](./src/fingerprint/schema-fingerprint.md) — Content-hash a `BitPackerSchema` so two parties can agree they're using byte-identical schemas before they exchange pay…
|
|
- [schema-fingerprint](./src/fingerprint/schema-fingerprint.md) — Content-hash a `BitPackerSchema` so two parties can agree they're using byte-identical schemas before they exchange pay…
|
|
- [hash-registry](./src/hash-registry/hash-registry.md) — A pluggable registry of named hash algorithms used by every hashing-aware primitive in `@suaveplan/bitpacker-crypto` (n…
|
|
- [hash-registry](./src/hash-registry/hash-registry.md) — A pluggable registry of named hash algorithms used by every hashing-aware primitive in `@suaveplan/bitpacker-crypto` (n…
|
|
- [hashchain](./src/hashchain/hashchain-schema.md) — Append-only signed hash chain. Each entry carries a sequence number, the hash of the previous entry, an opaque payload,…
|
|
- [hashchain-schema](./src/hashchain/hashchain-schema.md) — Append-only signed hash chain. Each entry carries a sequence number, the hash of the previous entry, an opaque payload,…
|
|
- [multisigned](./src/multisigned/multisigned-bitschema.md) — Bit-packed payload co-signed by N independent authorities. Wire format is `[bit-packed body][sig_1][sig_2]…[sig_N]`. Pi…
|
|
- [multisigned-bitschema](./src/multisigned/multisigned-bitschema.md) — Bit-packed payload co-signed by N independent authorities. Wire format is `[bit-packed body][sig_1][sig_2]…[sig_N]`. Pi…
|
|
- [signed](./src/signed/signed-bitschema.md) — Bit-packed payload signed by an `Authority` under a fixed `DomainTag`. Wire format is `[bit-packed body][signature]`. V…
|
|
- [signed-bitschema](./src/signed/signed-bitschema.md) — Bit-packed payload signed by an `Authority` under a fixed `DomainTag`. Wire format is `[bit-packed body][signature]`. V…
|
|
- [crc32](./src/crc32.md) — Fast non-cryptographic checksums for bit-packed payloads. `crc32` implements the IEEE-802.3 / zlib polynomial (`0xedb88…
|
|
- [index](./src/index.md) — **Path:** `bitpacker-crypto/src/index.ts` **Export:** See source for details.
|
|
- [xxhash32](./src/xxhash32.md) — **Path:** `src/xxhash32.ts` **Export:** `calculateXxhash32`, `verifyXxhash32`, `packXxhash32`, `unpackXxhash32`, `appen…
|
|
<!-- end:auto-docs -->
|
|
|
|
## Install
|
|
|
|
```bash
|
|
bun add @suaveplan/bitpacker-crypto
|
|
```
|
|
|
|
## Public surface
|
|
|
|
| Primitive | Use it for |
|
|
|---|---|
|
|
| `EnvelopeSchema` | `[magic][formatVersion][body]` framing — version-aware wire formats |
|
|
| `SignedBitSchema` | Authority-signed payloads under a `DomainTag` |
|
|
| `MultiSignedBitSchema` | N-of-N co-signed payloads with `firstBadSignerIndex` reporting |
|
|
| `HashChainSchema` | Append-only signed hash chain (audit logs, mesh state) |
|
|
| `EncryptedBitSchema` | **Niche** AEAD-only envelope for **small** encrypted payloads |
|
|
| `SchemaFingerprint` | Canonical-hash a `BitPackerSchema` for handshakes |
|
|
| `HashAlgorithmRegistry` | Pluggable hash registry — sha256/xxhash32/crc32 default; register blake3 |
|
|
| `crc32` / `xxhash32` / `adler32` | Existing checksum surface, unchanged |
|
|
|
|
## Intended scope
|
|
|
|
`EncryptedBitSchema` is for **small** encrypted payloads only — token
|
|
bodies, key-wrap envelopes, sub-MTU control records. **Do NOT use it as a
|
|
chunked-file encoder.** For chunked-file encryption with a streaming
|
|
verifier and locked v0x0001 codec, reach for `@suaveplan/packer` instead.
|
|
|
|
## Crypto provider needs?
|
|
|
|
This package ships **bit-packer-aware** crypto primitives. For raw AEAD,
|
|
signing, key derivation, or authenticated encryption (without a bit-packer
|
|
schema), reach for the crypto family directly:
|
|
|
|
- [`@suaveplan/crypto`](../../crypto/crypto) — multi-algorithm façade (AEAD, sign,
|
|
agree, sealed-box, auth-box).
|
|
- [`@suaveplan/crypto-sodium`](../../crypto/crypto-sodium) — libsodium engine.
|
|
- [`@suaveplan/crypto-browser`](../../crypto/crypto-browser) — WebCrypto engine.
|
|
- [`@suaveplan/crypto-vault`](../../crypto/crypto-vault) — BIP39 + Argon2id HD vault.
|
|
- [`@suaveplan/packer`](../../data/packer) — chunked AEAD with manifest.
|
|
|
|
Upstream's `bitpacker/src/crypto/` provider abstraction is **not ported**;
|
|
see [SUPERSEDED.md](./SUPERSEDED.md) for the per-symbol replacement table.
|
|
|
|
## Quick examples
|
|
|
|
### Envelope a bit-packed body
|
|
|
|
```ts
|
|
import { defineEnvelopeSchema } from "@suaveplan/bitpacker-crypto";
|
|
import { defineBitSchema } from "@suaveplan/bitpacker";
|
|
|
|
const headerSchema = defineBitSchema<{ foo: number }>([
|
|
{ name: "foo", type: "uint", bits: 32 },
|
|
]);
|
|
const env = defineEnvelopeSchema({
|
|
magic: new Uint8Array([0x53, 0x56, 0x43, 0x42]),
|
|
formatVersion: 1,
|
|
bodyCodec: {
|
|
pack: (b) => headerSchema.pack(b),
|
|
unpack: (bytes) => headerSchema.unpack(bytes),
|
|
},
|
|
});
|
|
const bytes = env.pack({ foo: 7 });
|
|
```
|
|
|
|
### Wiring the canonical crypto bindings
|
|
|
|
Every primitive that needs a verifier or AEAD bundle accepts it via
|
|
options. Pass the canonical wiring once in your application bootstrap:
|
|
|
|
```ts
|
|
import { aeadEncrypt, aeadDecrypt } from "@suaveplan/crypto";
|
|
import { verifyAuthoritySignature } from "@suaveplan/crypto/authority";
|
|
import type { AeadOps, AuthorityVerifier } from "@suaveplan/types";
|
|
|
|
export const verifier: AuthorityVerifier = verifyAuthoritySignature;
|
|
export const aead: AeadOps = { encrypt: aeadEncrypt, decrypt: aeadDecrypt };
|
|
|
|
// Then everywhere you build a primitive:
|
|
defineSignedBitSchema(codec, { domain, verifier });
|
|
defineMultiSignedBitSchema(codec, { domain, verifier, signerCount });
|
|
defineHashChainSchema({ domain, verifier, payloadCodec });
|
|
defineEncryptedBitSchema(codec, { key, aead });
|
|
```
|
|
|
|
### Sign + encrypt a token
|
|
|
|
```ts
|
|
import {
|
|
defineEncryptedBitSchema,
|
|
defineSignedBitSchema,
|
|
} from "@suaveplan/bitpacker-crypto";
|
|
import { DOMAIN_BITPACKER_SIGNED_V1 } from "@suaveplan/crypto/domain-tags";
|
|
|
|
const inner = defineEncryptedBitSchema(tokenCodec, { key: aeadKey });
|
|
const innerCodec = {
|
|
pack: (t) => inner.pack(t),
|
|
unpack: (bytes) => inner.unpack(bytes),
|
|
};
|
|
// (Signing receives Promise.unwrap() on the body — for the canary chain
|
|
// pattern, prefer `defineSignedBitSchema(envCodec, ...)` directly.)
|
|
```
|
|
|
|
### Schema-fingerprint handshake
|
|
|
|
```ts
|
|
import { schemaFingerprint, assertSchemaFingerprint } from "@suaveplan/bitpacker-crypto";
|
|
|
|
const local = { foo: 255, bar: 65535 };
|
|
const fp = await schemaFingerprint(local);
|
|
// On the peer:
|
|
await assertSchemaFingerprint(remoteSchema, fp);
|
|
```
|
|
|
|
## Algorithms (existing checksum surface, unchanged)
|
|
|
|
| Algorithm | Speed | Use Case |
|
|
|-----------|-------|----------|
|
|
| CRC32 | Medium | General integrity checking |
|
|
| Adler32 | Fast | Quick checksums (used in zlib) |
|
|
| XXHash32 | Very fast | High-throughput hashing |
|
|
|