bfc

Binary File Container — an append-only, single-file container format with a C17 library and CLI. POSIX metadata, fast random access, optional ZSTD and ChaCha20-Poly1305, CRC32C everywhere.

Ccontainer format · zstd · chacha20-poly1305 · crc32cbfc & filesystemssource on github

Why

Pack a directory tree into one file that keeps permissions, timestamps and symlinks, opens instantly, gives random access to any single file, and can be compressed, encrypted and verified — without unpacking. Simplicity, performance and POSIX metadata first.

How

  • Layout. [header 4 KiB][objects…][index][footer 56 B], little-endian throughout. A reader opens a container by reading the last 56 bytes: the footer points at the index.
  • Append-only writes. Each object is a header (type, compression, encryption, mode, mtime in ns, sizes, CRC32C), the path, padding and 16-byte-aligned content. Object headers are back-patched with final sizes and CRCs; the index and footer are written last, so an interrupted write never corrupts what came before.
  • Index. Sorted by path, for O(log n) lookup and prefix listing.
  • CRC32C uses SSE4.2 on x86-64 and the ARMv8 CRC instructions on ARM64, with a portable fallback.
  • Compression. ZSTD levels 1–22 (default 3). The writer samples content to decide whether compression is worth it; files under 64 bytes are stored as is.
  • Encryption. libsodium ChaCha20-Poly1305 per file with its own nonce, keyed by Argon2id from a password or by a 32-byte key file. Compress first, then encrypt.
  • OCI. An optional module stores and extracts OCI manifests, configs and layers.
  • Hardening. Paths are normalized (no absolute paths, no ..), extraction uses O_NOFOLLOW, and the parser has fuzz targets.

File names and metadata are not encrypted — the structure of a container stays visible.

bfc create -c zstd -e secret -l 6 archive.bfc /data/
bfc verify --deep archive.bfc
bfc_create("archive.bfc", 4096, 0, &writer);
bfc_set_compression(writer, BFC_COMP_ZSTD, 3);
bfc_add_file(writer, "document.txt", file, 0644, time_ns, &crc);
bfc_finish(writer);
$ git clone https://github.com/zombocoder/bfc
← all projects