Generate an image with Windows Paint on a Copilot+ PC, and the diffusion model's inference really does run on your local NPU — but reverse engineering by security researcher Xusheng Li shows the result is not a purely "local" artifact: buried deep in the pixels is a unique GUID issued by a Microsoft server at prompt-moderation time. Full analysis at the source (https://xusheng.dev/posts/reversing/mspaint_invisible_watermark/main/).
Local generation ≠ local completion
Paint and the Photos app both ship local AI models: four .onnxe files totaling roughly 370MB, with the generation backbone mager.onnxe alone at 302MB. These model files are obfuscated with a layer of XOR — one of the keys is the string Microsoft_2023 — and decode into standard ONNX models.
The catch: even on the local generation path, the user's prompt is still sent first to Microsoft's moderation service (endpoint path /v1/paint-cocreator/moderate-prompt). The server returns a revised prompt, a promptGenerationId, a watermarkId, and other fields. After the image is generated on-device, the watermarkId is written into the pixels — only the model inference is "local"; prompt moderation and identifier issuance both happen in the cloud.
How the watermark gets into the pixels
The watermark is applied by the WmkWriteWatermark function in Watermarker.dll. It strictly requires the payload to be exactly 16 bytes — precisely the length of a GUID. What actually gets embedded is an 18-byte message: the magic byte 0x4c, the 16-byte GUID, plus a one-byte checksum, expanded into 144 bits, with every bit required to be placed at least three times; images must be at least 192 pixels in both dimensions or the encoder returns an insufficient-capacity error.
The encoder performs content-adaptive, block-domain quantized modifications. Testing with a synthetic 512×512 image, the author found 193,376 of 262,144 pixels changed — invisible to the eye, yet roughly three-quarters of the picture altered. The failure semantics reveal the design intent: in Paint, a watermarking failure turns the entire generation into an error rather than returning an unmarked image; the Photos app is laxer, logging the failure and still returning the image.
Two layers of provenance, one GUID
When saving, Paint also calls an online signing service to attach C2PA Content Credentials. Parsing the PNG chunks of a real generated image, the author found an 18,979-byte caBX manifest in which the c2pa.soft-binding field names the algorithm com.microsoft.invismark.1, and its value is exactly the watermarkId returned by the moderation service. The pixel-level invisible watermark and the file-level signed manifest are two layers of the same provenance system.
Save formats for AI-generated results are restricted to PNG, JPEG, GIF, and .paint (BMP cannot embed a C2PA manifest); across successive generations, the previous promptGenerationId is echoed back with the next request, chaining multiple turns together.
So what
Microsoft's support page discloses content filtering and C2PA credentials, but not that the manifest carries a GUID bound to prompt moderation, let alone that it is written into the pixels. This does not conflict with Article 50 of the EU AI Act (effective August 2, 2026) — the regulation requires a detectable, machine-readable mark on AI content, but not a per-generation identifier that can be linked back to a moderation session. For users the lesson is direct: in system-level AI tools, the phrase "local generation" deserves renewed scrutiny. For the industry, watermarks are sliding from "was this content AI-generated" toward "who generated it, in which session" — the former is transparency, the latter is traceability, and blurring the two quietly dilutes the right to know.