Ordinary image fallback
Without the BBP payload, the file remains a valid image containing its safe base.
Open image format · BBP v1
An ordinary viewer displays the safe base. A BBP viewer reveals each protected region when it has the required private keys.
Without the BBP payload, the file remains a valid image containing its safe base.
Each region is encrypted independently, so the same file can reveal different regions to different viewers.
BBP stores a JUMBF payload in a supported image carrier. It does not require a special file extension.
Reference implementation
Protect regions, open the resulting file, and reveal each region with its matching key.
Encoder and viewer
Draw protected regions, assign recipients, then compare the safe base with the regions your loaded keys can open.
Drag across the image to add a protected region.
Image source
Fallback image
Choose how protected regions appear in the ordinary image. BBP does not prescribe this treatment.
For example, the smiley overlay intentionally leaves source pixels visible.
Public keys encrypt assigned regions. A matching private key also lets this preview decrypt them.
Each region is encrypted for its selected recipient. Overlaps become intersection entities automatically.
The format
BBP adds encrypted region entities to an ordinary image carrier. Viewers without BBP support display the safe base.
Payload = {
v: uint,
entities: [ Entity, ... ]
}
Entity = {
kind: "region" | "intersection",
body: bytes, // AEAD ciphertext
wraps: [ Wrap, ... ] // opaque recipients
}
// A compliant viewer paints every entity
// it can open over the safe base.Encoders create the safe base first, seal each original crop independently, shuffle the encrypted entities, encode deterministic CBOR, then bind the same JUMBF superbox to the chosen carrier.
Viewers always paint the safe base first. They trial-open region wraps, paint every authenticated region, then paint an intersection only when every participating key share is available. BBP v1 supports intersections between two or more regions.
No BBP box means an ordinary image. Malformed metadata and unsupported versions are errors, while a wrap that does not open is an expected recipient mismatch. Inaccessible regions remain safely pixelated.
Implementations must bound carrier sizes, CBOR nesting, entity counts, crop sizes, and trial-decryption work before processing untrusted files.
Non-compliant viewers render the base and ignore the ancillary payload. Losing the BBP payload loses reveal capability; it never exposes a hidden original.
The base still reveals the scene and mosaic geometry. A downloaded file is a frozen grant, and BBP does not survive recompression or metadata stripping.
The complete draft defines carrier framing, deterministic CBOR, body coordinates, envelope byte layouts, rendering order, error handling, and producer/viewer conformance requirements.
The wire format is explicit enough for independent implementations, but BBP v1 is not frozen. Recipient anonymity and robustness still need independent cryptographic review, followed by frozen carrier and end-to-end fixtures.
Carrier adapters
The JUMBF payload is unchanged across carriers. Only the binding that places it in the image differs.
Ancillary RIFF JUMB chunk. The default for the browser demo and a strong photo carrier.
Read · write · web exportBBP JUMBF payload in JPEG APP11 segments, with fragmentation for larger metadata.
Read · write · web exportPrivate ancillary bBPj chunk with a valid PNG CRC.
Read · write · web exportTop-level ISO BMFF uuid box. The carrier implementation exists in @brightblur/bbp.
Read · write · web readReference implementation
The reference implementation includes a format package, a viewer web component, this browser demo, and a native macOS viewer.
@brightblur/bbpCBOR payloads, X-Wing recipient wraps, detection, and carrier embedding/extraction for WebP, JPEG, PNG, and HEIF.
<bbp-viewer>A framework-neutral custom element. Give it a URL or File, then use instance keys or one shared keyring for the page.
apps/bbp-previewThe page above is the runnable reference: local redaction, key assignment, export, and reveal with no server dependency.
A fully native macOS preview app reads ordinary and BBP image files, exposes the metadata inspector, and uses the same Rust crypto core.
URLs work declaratively when the response is same-origin or CORS-enabled. Browser files and byte buffers use the src property.
<bbp-viewer
id="viewer"
src="/photo.bbp.jpg">
</bbp-viewer>
input.onchange = () => {
const file = input.files?.[0];
viewer.src = file ?? null;
};Shared keys update every current viewer and become the default for viewers connected later. An explicit instance value remains an override.
import {
setBbpViewerPrivateKeys
} from '@brightblur/bbp-viewer';
setBbpViewerPrivateKeys([
privateKey
]);
viewer.privateKeys = [overrideKey];
viewer.useSharedPrivateKeys();import { bbpEncode } from '@brightblur/bbp';
import '@brightblur/bbp-viewer';
const bytes = await bbpEncode({
base: redactedImageBytes,
regions: [{
bbox,
epoch: 0,
pixels: crop,
recipientPublicKey
}],
intersections: []
});
viewer.src = bytes;
viewer.privateKeys = [privateKey];To add a carrier, preserve the same payload and implement the four boundary operations below. Then add the carrier to detection and the public dispatch. Keep the binding ancillary so ordinary decoders still render the safe base.
type CarrierAdapter = {
detect(bytes): boolean;
embed(base, jumbf): Uint8Array;
extract(file): Uint8Array | null;
strip(file): Uint8Array;
};packages/bbp/src/container.ts contains the carrier dispatch and the WebP, JPEG, PNG, and HEIF bindings. packages/bbp/src/encoder.ts assembles the CBOR payload; packages/bbp-viewer/src/index.ts performs local trial-decryption and composition.
The format document is the normative starting point. The current implementation is a reference for the draft, not a claim that the draft has completed its independent security audit or final test-vector freeze.