Overview
A concrete family of text soft-binding algorithms compatible with the C2PA Soft Binding framework, each registered in the C2PA soft binding algorithm list. A soft binding derives a content-keyed value that survives reformatting, re-encoding, excerpting, and light editing, so a manifest is recoverable when the hard binding — a byte-exact hash — has been broken.
| Module | Registered alg identifier |
Kind |
|---|---|---|
simhash |
com.writerslogic.text-fingerprint.1 |
surface fingerprint |
stego |
com.writerslogic.zwc-watermark.2 |
zero-width watermark |
structure |
com.writerslogic.text-structure.1 |
structural fingerprint |
minhash |
com.writerslogic.text-minhash.1 |
excerpt/quotation fingerprint |
The alg string is what a c2pa.soft-binding assertion carries and what a
recovery service matches on; it is the identifier that matters.
This crate is the perceptual/watermark recovery layer. It is distinct from the Variation-Selector transport used elsewhere in WritersProof, which is a hard binding (a c2pa.hash.data over normalized text) and is not soft binding. Registration in the algorithm list is not C2PA conformance certification.
Quick Start
[]
= "0.2"
Emit and sign a c2pa.soft-binding assertion
soft_binding builds the normative CBOR assertion (it round-trips through the
c2pa-rs reader — see tests/c2pa_roundtrip.rs); manifest signs it as a
COSE_Sign1 / EdDSA envelope.
use ;
let text = "…the document being bound…";
let secret_key = ; // caller-supplied Ed25519 secret
let assertion = from_fingerprint;
let cbor = assertion.to_cbor?; // store under SOFT_BINDING_LABEL
let signed = sign_cose?; // detached-key COSE_Sign1
# Ok::
Recover and classify a candidate
The verify path recomputes the fingerprint from the current text, compares it to
the stored value at the algorithm's registered threshold, and returns a
confidence tier. BOUND requires a durable fingerprint match (41/44, measured
zero false matches) plus the anti-transfer cross-check; a structural (43) match
or a watermark hit alone caps at LIKELY. Tier thresholds are grounded in
ROBUSTNESS.md.
use ;
let text = "…the document being bound…";
let cbor = from_fingerprint.to_cbor?;
let candidate = from_cbor?;
let tier = verify;
assert_eq!;
# Ok::
Register with the Soft Binding Resolution API
These algorithms are registered in the C2PA soft binding algorithm list, so a c2pa.soft-binding assertion referencing them can drive decentralized manifest recovery.
Transport Survivability Research
The soft-binding layer above exists because hard bindings are fragile in text pipelines. TRANSPORT.md is a reproducible benchmark quantifying that fragility, comparing every invisible-text carrier — A.8 variation selectors (v1 and a proposed v2), the zero-width Reed-Solomon watermark, Unicode Tag smuggling, naive zero-width binary — against the fingerprint recovery layer, across deterministic probes and real transports (HTML sanitizers, Office, email, Markdown, pandoc, macOS RTF).
Key results, all reproducible with cargo run --release --example transport_survivability and harness/tier1.py:
- Carrier survival is not provenance survival. Email, Markdown, and
pandocround trips leave the invisible carrier intact but reflow the visible text, breaking the A.8 hard binding. Only the reflow-tolerant fingerprint survives. - A.8 needs a checksum, not just a length. Property testing shows the v1 length field is self-corruptible — a single dropped length byte yields a wrong payload. Only an integrity field (this crate's HMAC watermark, or a v2 checksum) fails safe.
- Error correction is decisive. The Reed-Solomon watermark tolerates ~30–40% code-point loss where every un-coded carrier fails by 20%.
- Sanitizers preserve invisible payloads. Ten of thirteen real pipelines — including
bleachandnh3— pass the payload through untouched; a security-relevant result.
Interoperability. This crate's A.8 codec is byte-identical to Encypher's c2pa-text reference library in both directions (tests/interop.rs, harness/interop.py), so the comparison is against the real deployed format, not a stand-in.
Runs are reproducible via a pinned venv (harness/requirements.txt) or the Dockerfile, which stamps tool and library versions with every result.
Related Crates
Part of a family of single-purpose crates, one per C2PA embedding method. Each is standalone and independently versioned.
| Crate | Description |
|---|---|
| c2pa-structured-text | Structured text: ASCII-armoured manifest in a comment or front matter |
| c2pa-unstructured-text | Unstructured text: invisible Unicode variation-selector run |
| c2pa-html | HTML: script and link elements in the document head |
| c2pa-http | HTTP: the c2pa-manifest Link header, with a Tower middleware |
| c2pa-vtt | WebVTT caption and subtitle embedding |
| c2pa-zip | ZIP-based documents: EPUB, DOCX, ODT, OXPS |
| c2pa-warc | WARC web archive embedding (ISO 28500) |
| c2pa-fonts | OpenType/TrueType (SFNT) font embedding |
| c2pa-ml | ML model containers: GGUF, SafeTensors, ONNX |
| c2pa | Official C2PA SDK |
Security
Found a vulnerability? Please report it privately — see SECURITY.md.
License
Licensed under either of Apache License, Version 2.0 or MIT License at your option.
Built by WritersLogic