--- library_name: pytorch pipeline_tag: image-classification tags: - watermarking - diffusion - provenance - attribution - stable-diffusion --- # DiffSign public watermark decoder (256-bit) Public verification artifact for the anonymous **DiffSign** submission, *Public Authorization and the Adaptive Attack Surface of Diffusion-Watermark Attribution*. This repository contains **only the public decoder** `D_psi`. The secret encoder `E_phi` is server-private by design and is deliberately not published: DiffSign's threat model assumes an adversary holds the full public verification interface but cannot invoke the encoder. ## Artifact | | | |---|---| | File | `diffsign_public_decoder_256bit.pth` | | Size | 21,702,122 bytes | | SHA-256 | `1cf105cd89de5aba6beefe5e48af2082de78de296e912557ab2d7905c2ab975c` | | Tensors | 38 (5,422,300 parameters) | | Output | logits `[batch, 256, 2]` | | Raw LLRs | `logit(bit=1) - logit(bit=0)`, shape `[batch, 256]` | Top-level fields: `format_version`, `artifact`, `decoder_state_dict`, `decoder_config`, `preprocessing`, `llr_convention`. It contains no `encoder_state_dict` and no optimizer, scheduler, or training state. ## Preprocessing Pair the decoder with the public VAE from [`stable-diffusion-v1-5/stable-diffusion-v1-5`](https://huggingface.co/stable-diffusion-v1-5/stable-diffusion-v1-5): 1. Convert to RGB and resize to 512x512. 2. Normalize pixels to `[-1, 1]`. 3. Take the VAE posterior mode and multiply by the latent scaling factor. 4. Evaluate `D_psi` once. 5. Return `logit(bit=1) - logit(bit=0)` as `float32[256]` raw LLRs. Public verification is normative in `float32`. Half precision is permitted for throughput but is not the reference configuration: it shifts raw LLRs by up to `2e-2` and can flip a hard decision on a bit whose LLR is already near zero, so two verifiers on different hardware may disagree. ## Usage ```python from diffsign.physical import PublicWatermarkDecoder decoder = PublicWatermarkDecoder.from_pretrained( "diffsign_public_decoder_256bit.pth", device="cuda", ) raw_llrs = decoder.decode_raw_llrs(image) # float32[256] ``` The raw LLRs are divided by the fixed calibration temperature `0.7144` and decoded by a CRC-aided successive-cancellation list decoder (length-256 non-systematic polar code, list size 8) into a 112-bit payload, which resolves through an audited transparency log to a signed receipt. ## Scope Inference only. No training loop, dataset loader, attack implementation, third-party baseline, benchmark harness, or bulk generation script.