npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

c2pa-text-binding

v0.3.0

Published

C2PA soft binding and content fingerprinting for text assets (watermark + fingerprint family)

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 | 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

[dependencies]
c2pa-text-binding = "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 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.

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 pandoc round 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 bleach and nh3 — 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