CRUMB a card from devarno-cloud

Blake3 Fingerprint API

stratt intermediate 4 min read

ELI5

A fingerprint is a 64-character receipt for a unit. To check authenticity, you re-run the canonical pipeline on the bytes you received and compare receipts. A 16-character preview (the SPUH) rides at the front so routers don’t need the whole digest to dispatch.

Technical Deep Dive

Verify Path

sequenceDiagram
participant R as Receiver
participant FP as @stratt/fingerprint
participant B3 as blake3-wasm
R->>FP: fingerprintYaml(rawYaml)
FP->>FP: canonicalise (NFC, sort, encode)
FP->>B3: hash(bytes)
B3-->>FP: 32-byte digest
FP-->>R: { full, prefix, algorithm }
R->>R: compare full vs claimed fingerprint
alt match
R-->>R: VerifyStatus.OK
else mismatch
R-->>R: VerifyStatus.TAMPERED
end

Type Surface

type Fingerprint = { full: string; prefix: bigint; algorithm: string }
type VerifyResult = { status: VerifyStatus; expected?: string; actual?: string }
  • full: blake3:{64 lowercase hex}
  • prefix: first 64 bits of the digest as bigint — this is the SPUH (Stratt Prompt Unit Header) value
  • algorithm: "blake3" for spec v1; reserved for future migration

SPUH

The SPUH is not a separate hash — it is the leading 16 hex characters (8 bytes / 64 bits) of the same Blake3 digest, exposed as prefix. Wire formats include the SPUH so routers can index by prefix without re-hashing the full payload. Collisions within the 64-bit space are tolerated; final verification always uses full.

Spec Version Pin

SPEC_VERSION = "1" (packages/fingerprint/src/types.ts). Decision 0002 pins the blake3-wasm build to keep the digest reproducible across Node, Bun, and browser hosts.

Key Terms

  • SPUH → 64-bit prefix of the Blake3 digest, used as a routing key.
  • TamperedVerifyStatus raised when a recomputed fingerprint disagrees with the claimed one.
  • blake3: prefix → mandatory algorithm tag in the full field; verifiers reject untagged digests.

Q&A

Q: Why expose prefix as a bigint rather than a hex string? A: Routers compare prefixes numerically (range queries, modulo bucketing). A bigint skips parsing on every lookup.

Q: What happens if the algorithm tag is absent? A: verify rejects the input — it never falls back to assuming Blake3.

Examples

blake3:9af1c2…ef03 — the leading 9af1c2ef0… slice (16 hex chars) becomes prefix = 0x9af1c2ef0…n, used as the SPUH on outbound envelopes.

neighbors on the map