c2pa-text-binding
v0.2.0
Published
C2PA soft binding and content fingerprinting for text assets (watermark + fingerprint family)
Maintainers
Readme
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 | Algorithm (list id) | Kind |
|---|---|---|
| simhash | com.writerslogic.text-fingerprint.1 (41) | surface fingerprint |
| stego | com.writerslogic.zwc-watermark.2 (42) | zero-width watermark |
| structure | com.writerslogic.text-structure.1 (43) | structural fingerprint |
| minhash | com.writerslogic.text-minhash.1 (44) | excerpt/quotation fingerprint |
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
[dependencies]
c2pa-text-binding = "0.1"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 c2pa_text_binding::{simhash::Fingerprint, soft_binding, sign_cose, SOFT_BINDING_LABEL};
let text = "…the document being bound…";
let secret_key = [7u8; 32]; // caller-supplied Ed25519 secret
let assertion = soft_binding::from_fingerprint(&Fingerprint::compute(text));
let cbor = assertion.to_cbor()?; // store under SOFT_BINDING_LABEL
let signed = sign_cose(&cbor, &secret_key)?; // detached-key COSE_Sign1
# Ok::<(), c2pa_text_binding::Error>(())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 c2pa_text_binding::{simhash::Fingerprint, soft_binding::{self, SoftBinding}, verify, Confidence};
let text = "…the document being bound…";
let cbor = soft_binding::from_fingerprint(&Fingerprint::compute(text)).to_cbor()?;
let candidate = SoftBinding::from_cbor(&cbor)?;
let tier = verify(text, &candidate, /*watermark_verified=*/ false, /*crosscheck_ok=*/ true);
assert_eq!(tier, Confidence::Bound);
# Ok::<(), c2pa_text_binding::Error>(())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.
Related Crates
| Crate | Description | |---|---| | c2pa-structured-text | Structured text embedding via ASCII armour delimiters | | c2pa-text | Unstructured text embedding via Unicode Variation Selectors | | c2pa-rs | Official C2PA SDK |
License
Licensed under either of Apache License, Version 2.0 or MIT License at your option.
Built by WritersLogic
