mirror of
https://github.com/wiltodelta/remove-ai-watermarks.git
synced 2026-08-31 17:50:35 +02:00
Keep Model 1 as a research AI-versus-camera result outside the library. Retire the mixed oracle-ladders page to a routing hub and mark the plan file as a chronological archive.
124 lines
6.1 KiB
Markdown
124 lines
6.1 KiB
Markdown
# SynthID local detector research
|
|
|
|
> Research archive for the hunt for a local, keyless SynthID pixel detector.
|
|
> Not a statement of current product capability. Shipped behavior:
|
|
> [supported signals](supported-signals.md) and
|
|
> [known limitations](known-limitations.md).
|
|
>
|
|
> Sister pages: [classifier models](synthid-classifiers.md),
|
|
> [SynthID mark removal](synthid-removal-research.md),
|
|
> [mechanism reference](synthid.md). Dated measurements live in the
|
|
> [chronological plan](synthid-detector-removal-plan.md).
|
|
|
|
## Result
|
|
|
|
The local OpenAI SynthID detector hunt closed 2026-08-20. Google has no
|
|
public payload decoder. Nothing in this project reproduces one.
|
|
|
|
The mark behaves like a keyed spread-spectrum residual: a content-adaptive
|
|
`x' = x + g(x)` with a paired decoder (DeepMind patent family, optional
|
|
secret in intermediate layers, encoder/decoder ensembles that do not
|
|
recognize each other). Without that pair, the residual sits under the
|
|
scene. Keyless energy, TrustMark transfer, L1 distillation, a flat-field
|
|
stamp, and a 16-32 band student all failed to read the official oracle
|
|
contrast on photographs.
|
|
|
|
What the product uses for the *watermark* is signed provenance and
|
|
`verify-openai-synthid`. The experimental pixel route in `identify` is
|
|
`pipeline_lattice`, a generation-pipeline ID, not SynthID. Lineage rates
|
|
for that route are in [classifier models](synthid-classifiers.md).
|
|
|
|
## Closed detector routes
|
|
|
|
| Route | Close | Why |
|
|
| --- | --- | --- |
|
|
| Keyless energy in 16-32 px | 2026-08-20 | L1 AUC 0.53; official decoder reads phase structure, not energy |
|
|
| TrustMark / open-encoder transfer | 2026-08-20 | E3 leave-one-encoder-out at chance on TrustMark (0.505 ridge, 0.510 conv) |
|
|
| L1 distillation of oracle bits | 2026-08-20 | Geometry-only AUC 0.78-0.83 beats pixel 124-d (0.64). ChatGPT export and `opened` C2PA predict `not_detected`. Inside 1254x1254, permutation p=0.45 |
|
|
| Flat 16-32 matched filter | 2026-08-21 | Leave-one-out residual correlation 0.645 on gray flats; 0.007-0.025 on COCO photo residuals. L1 AUC 0.70 was a size confound (size-matched 0.59 / 0.44) |
|
|
| `gpt-image-1` as encoder-off pair | 2026-08-21 | Does not stamp. `gpt-image-2` does |
|
|
| CNN on raw L1 bits | 2026-08-21 | Do not train. Labels are export geometry and presentation, not the mark |
|
|
| Origin-locked lattice as SynthID | 2026-08-16 | Two-pixel crop kills it; published SynthID keeps 99.97% TPR under aggressive crop. See classifiers for the honest `google_lineage_renderer` name |
|
|
|
|
Open: Google (no oracle); `chatgpt-image-latest` once the organization is
|
|
verified. A size-specific whitened 16-32 template on photographs is not
|
|
justified until amplitude is measured without the flat-arm G.
|
|
|
|
## Oracle and seeds
|
|
|
|
Official `POST /v1/content_provenance_checks`, metadata stripped, pixels
|
|
preserved. Raw files stay gitignored under
|
|
`.local-eval/synthid/prc-oklab-attack-2026-08-15/`.
|
|
|
|
| Seed | Path | Size |
|
|
| --- | --- | --- |
|
|
| s1 | `originals/2026-05-31/31e55ea8a4de42029659654a80814630_src.png` | 1024x1536 |
|
|
| s2 | `originals/2026-05-31/37ae95821a3447c78f94e56bdebf0c88_src.png` | 1024x1536 |
|
|
| s3 | `originals/2026-07-10/d76f35fee69e4531865e88b786fa52e5_src.png` | 1086x1448 |
|
|
|
|
All three `detected` before attacks.
|
|
|
|
## Source-matched pairs (2026-08-21)
|
|
|
|
`gpt-image-2` (ChatGPT Images 2.0) can mint encoder-on/off pairs.
|
|
`chatgpt-image-latest` is 403 until the org is verified.
|
|
|
|
| Input | C2PA | Oracle | Aligned PSNR |
|
|
| --- | --- | --- | ---: |
|
|
| Camera JPEG 960x1280 | none | not_detected | - |
|
|
| ChatGPT UI + frame 1086x1448 | watermarked.unbound | detected | 16.6 dB (redraw) |
|
|
| `gpt-image-1` edit, high fidelity, red dot | created, converted only | not_detected | 30.9 dB |
|
|
| `gpt-image-2` edit, red dot 1024x1536 | watermarked.unbound | detected | 28.2 dB |
|
|
|
|
The `gpt-image-2` photo residual is broadband (std 9.1), not a 16-32 stamp.
|
|
COCO `gpt-image-2` edits: 11/12 `watermarked.unbound`, one safety block.
|
|
|
|
Solid gray/white through `gpt-image-2` "reproduce exactly" is
|
|
`watermarked.unbound`. Gray 128 at 1024x1536: PSNR 41.9 dB vs the flat,
|
|
source `not_detected`, output `detected`. Other gray levels 32-220: PSNR
|
|
38-49 dB. Eight gray 1024x1536 residuals, leave-one-out correlation after
|
|
highpass: 0.645 (shuffle 0). That shared stamp does not transfer to COCO
|
|
photo residuals (0.007-0.025).
|
|
|
|
## Presentation gate versus residual
|
|
|
|
An official `not_detected` is not one event. Collage, photo-pad, two-panel
|
|
self-concat, and 8x8 scramble can be a *presentation gate* (this upload is
|
|
not a single photograph). Blur sigma 7 and in-band 16-32 destruction sit on
|
|
the single-photo manifold and are residual damage; those belong in
|
|
[mark removal](synthid-removal-research.md).
|
|
|
|
Do not train a surrogate on mixed collage misses if the goal is a mark
|
|
student.
|
|
|
|
Identity (s1, 2026-08-19): JPEG q80/q20, crop 2 px, crop 8 px, keep 0.75
|
|
and 0.50, rot90, rotate 5, flip, grayscale all stay `detected`.
|
|
|
|
Token / layout (s1): each quadrant at 512x768 `detected`; `hstack` and
|
|
`vstack` of marked\|marked `not_detected`; 4x4 tile scramble `detected`;
|
|
8x8 `not_detected`. Two copies of a detecting image still miss. Tomography
|
|
3x3: all nine cells `not_detected` (a 1/9 window is below support).
|
|
|
|
Preprocess E1 (s1): stretch 2x `detected`; centre-crop of marked\|marked
|
|
hstack back to native `detected`; 0.20x pixels on a native-size white
|
|
canvas `not_detected` (the same 0.20x file uploaded alone was `detected`).
|
|
|
|
## L1 is not a mark task
|
|
|
|
Control-only 283 rows: 203 detected, 80 not_detected. Forward-temporal
|
|
nested ridge on 124 pixel features: AUC 0.649 / 0.641. Geometry-only:
|
|
0.781 / 0.826. All 21 `claim_generator=ChatGPT` controls are
|
|
`not_detected`. C2PA `opened`: 24/24 `not_detected`. Inside 1254x1254,
|
|
mean-feature permutation p=0.45.
|
|
|
|
OpenAI-supervised ridge on 16-32 band-passed `image_features`:
|
|
forward-temporal AUC 0.53 vs L1 `not_detected`, 0.95 vs COCO, 0.97 vs COCO
|
|
after a 2 px crop. The student learns OpenAI-versus-photo and still does
|
|
not see the oracle mark contrast.
|
|
|
|
## Product remainder for the watermark
|
|
|
|
Signed provenance (`identify`) and `verify-openai-synthid` (remote, explicit
|
|
upload). A local `indeterminate` from `detect-synthid` is not a clean
|
|
SynthID negative.
|