Files
reverse-SynthID/README.md
T
2026-03-06 21:20:00 +05:30

388 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<p align="center">
<img src="assets/synthid_watermark.png" alt="SynthID Watermark Analysis" width="100%">
</p>
<h1 align="center">🔍 Reverse-Engineering SynthID</h1>
<p align="center">
<b>Discovering, detecting, and surgically removing Google's AI watermark through spectral analysis</b>
</p>
<p align="center">
<img src="https://img.shields.io/badge/Python-3.10+-blue?style=flat-square&logo=python" alt="Python">
<img src="https://img.shields.io/badge/License-Research-green?style=flat-square" alt="License">
<img src="https://img.shields.io/badge/Detection_Rate-90%25-success?style=flat-square" alt="Detection">
<img src="https://img.shields.io/badge/Bypass_V3-PSNR_40dB+-blueviolet?style=flat-square" alt="Bypass V3">
</p>
---
## 🎯 Overview
This project reverse-engineers **Google's SynthID** watermarking system - the invisible watermark embedded into every image generated by Google Gemini. Using only signal processing and spectral analysis (no access to the proprietary encoder/decoder), we:
1. **Discovered** the watermark's exact frequency-domain structure
2. **Built a detector** that identifies SynthID watermarks with 90% accuracy
3. **Developed a spectral bypass** (V3) that surgically removes watermark components while preserving image quality at **40+ dB PSNR**
### What Makes This Different
Unlike brute-force approaches (JPEG compression, noise injection), our V3 bypass uses a **SpectralCodebook** - a fingerprint of the watermark's exact frequency signature - extracted from reference images. This allows surgical, frequency-bin-level removal rather than blind signal destruction.
---
## 🔬 Key Findings
### The Watermark is a Fixed Spectral Pattern
By generating pure black and white images through Google Gemini, we isolated the watermark signal from content. The results are striking:
<p align="center">
<img src="assets/synthid_black.jpg" alt="Watermark on black background" width="45%">
<img src="assets/synthid_white.jpg" alt="Watermark on white background" width="45%">
</p>
<p align="center">
<i>Left: SynthID watermark extracted from a pure-black Gemini image (enhanced 100×). Right: Same watermark on a white background. The diagonal stripe pattern and carrier frequencies are clearly visible.</i>
</p>
### Carrier Frequency Discovery
The watermark embeds energy at specific carrier frequencies with **>99.9% phase coherence** across all images:
| Carrier Frequency (fy, fx) | Phase Coherence | Magnitude | Phase (rad) |
|:--------------------------:|:---------------:|:---------:|:-----------:|
| **(±14, ±14)** | 99.96% | 16,807 | ±1.44 |
| **(±126, ±14)** | 99.96% | 8,046 | ±2.37 |
| **(±98, ∓14)** | 99.94% | 6,283 | ±0.61 |
| **(±128, ±128)** | 99.25% | 6,908 | ±2.29 |
| **(±210, ∓14)** | 99.96% | 6,032 | ±1.13 |
| **(±238, ±14)** | 99.90% | 4,190 | ±1.61 |
> **Key insight:** Most carriers cluster along the `y = ±14` line in frequency space, suggesting a structured frequency selection algorithm. The diagonal stripe pattern visible in the enhanced images corresponds to these carrier frequencies.
### Phase Consistency - A Fixed Model-Level Key
The watermark's phase template is **identical across all images** from the same Gemini model:
- **Green channel phase std**: < 0.007 radians across 50 reference images
- **Cross-image correlation**: 21.8% mean pairwise noise correlation
- **Noise structure ratio**: 1.32 ± 0.02 (byproduct of the neural encoder)
This means SynthID does not embed per-image messages - it uses a **fixed spectral fingerprint** that can be profiled and subtracted.
### Frequency Spectrum Analysis
<p align="center">
<img src="artifacts/visualizations/synthid_watermark_spectrum.png" alt="FFT Magnitude Spectrum" width="35%">
<img src="artifacts/visualizations/synthid_watermark_carriers.png" alt="Carrier Frequencies" width="35%">
</p>
<p align="center">
<i>Left: FFT magnitude spectrum showing bright carrier frequency peaks. Right: Reconstructed carrier pattern showing the diagonal structure.</i>
</p>
<p align="center">
<img src="artifacts/visualizations/deep_analysis/frequency_analysis.png" alt="Frequency Analysis" width="80%">
</p>
<p align="center">
<i>Detailed frequency analysis: Average magnitude spectrum (left) and phase coherence map (right). The carrier positions are marked with crosshairs.</i>
</p>
---
## 🏗️ Architecture
### Three Generations of Bypass
| Version | Approach | PSNR | Detection Impact | Status |
|:-------:|:---------|:----:|:----------------:|:------:|
| **V1** | JPEG compression (Q50) | 37 dB | ~11% phase drop | ✅ Baseline |
| **V2** | Multi-stage transforms (noise, color, frequency) | 27-37 dB | ~0% confidence drop | ✅ Quality trade-off |
| **V3** | Spectral codebook subtraction | **33-43 dB** | **1-7% confidence drop** | ✅ Best quality |
### V3 Pipeline (Spectral Bypass)
```
Input Image → FFT per channel → Estimate Watermark → Subtract → IFFT → Clip → Output
SpectralCodebook
(25 black + 25 white refs)
```
1. **SpectralCodebook** profiles the watermark from reference images (pure black/white Gemini outputs)
2. **Selective notch filter** targets only high-magnitude (P97+), high-consistency (≥95%) frequency bins
3. **Safe magnitude cap** limits subtraction to 30% of image energy per bin - preserving content
4. **Content-adaptive scaling** adjusts subtraction based on image luminance
---
## 📊 Results
### V3 Bypass Quality (PSNR in dB - higher is better)
| Image | Gentle | Moderate | Aggressive | Maximum |
|:-----:|:------:|:--------:|:----------:|:-------:|
| 121407 | **42.9** | 41.4 | 40.0 | 39.3 |
| 110802 | 33.4 | 33.3 | 33.1 | 33.0 |
| 131614 | **38.4** | 38.0 | 37.5 | 37.2 |
| 119198 | **38.4** | 37.7 | 37.0 | 36.6 |
| 12085 | **42.5** | 41.6 | 40.7 | 40.3 |
> All images maintain **>33 dB PSNR** - visually indistinguishable from the original.
### Watermark Detection Confidence
| Image | Before | After (Aggressive) | Drop |
|:-----:|:------:|:------------------:|:----:|
| 121407 | 0.394 | 0.387 | 1.7% |
| 131614 | 0.437 | 0.422 | 3.4% |
| 12085 | 0.394 | 0.366 | **7.2%** |
| 119198 | 0.389 | 0.386 | 0.9% |
### Sample Output
<p align="center">
<img src="assets/sample_watermarked.png" alt="Original watermarked image" width="45%">
<img src="assets/sample_cleaned.png" alt="V3 bypass output" width="45%">
</p>
<p align="center">
<i>Left: Original SynthID-watermarked Gemini image. Right: After V3 spectral bypass - visually identical, watermark energy reduced.</i>
</p>
---
## 🚀 Quick Start
### Installation
```bash
git clone https://github.com/aloshdenny/reverse-SynthID.git
cd reverse-SynthID
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -r requirements.txt
```
### 1. Build Detection Codebook
```bash
python src/extraction/robust_extractor.py extract /path/to/watermarked/images \
--output artifacts/codebook/robust_codebook.pkl
```
### 2. Detect Watermark
```bash
python src/extraction/robust_extractor.py detect image.png \
--codebook artifacts/codebook/robust_codebook.pkl
```
```
Detection Results:
Watermarked: True
Confidence: 0.95
Phase Match: 0.6683
```
### 3. Build Spectral Codebook (V3)
```python
from synthid_bypass import SpectralCodebook
codebook = SpectralCodebook()
codebook.extract_from_references(
black_dir='assets/black/', # Pure-black Gemini images
white_dir='assets/white/' # Pure-white Gemini images
)
codebook.save('artifacts/spectral_codebook.npz')
```
### 4. Run V3 Bypass
```python
from synthid_bypass import SynthIDBypass, SpectralCodebook
codebook = SpectralCodebook()
codebook.load('artifacts/spectral_codebook.npz')
bypass = SynthIDBypass()
result = bypass.bypass_v3(image_rgb, codebook, strength='aggressive')
print(f"PSNR: {result.psnr:.1f} dB") # ~40 dB
```
**Strength levels:** `gentle` (minimal change, ~43 dB) → `moderate``aggressive``maximum` (strongest removal, ~33 dB)
---
## 📁 Project Structure
```
reverse-SynthID/
├── src/
│ ├── extraction/
│ │ ├── synthid_bypass.py # V1/V2/V3 bypass implementations + SpectralCodebook
│ │ ├── robust_extractor.py # Multi-scale watermark detection (90% accuracy)
│ │ ├── watermark_remover.py # Frequency-domain watermark removal
│ │ ├── benchmark_extraction.py # Performance benchmarking suite
│ │ └── synthid_codebook_extractor.py # Original codebook extractor (legacy)
│ └── analysis/
│ ├── deep_synthid_analysis.py # FFT/phase analysis scripts
│ └── synthid_codebook_finder.py # Carrier frequency discovery
├── assets/
│ ├── synthid_black.jpg # Watermark on black (enhanced)
│ ├── synthid_white.jpg # Watermark on white (enhanced)
│ ├── black/ # Reference black images from Gemini
│ └── white/ # Reference white images from Gemini
├── artifacts/
│ ├── codebook/ # Detection codebooks (.pkl)
│ ├── spectral_codebook.npz # V3 spectral fingerprint (119 MB)
│ ├── v3_output/ # V3 bypass output samples
│ └── visualizations/ # FFT, phase, carrier visualizations
├── watermark_investigation/ # Early-stage Nano-150k analysis (archived)
├── SYNTHID_CODEBOOK_ANALYSIS.md # Detailed codebook reverse-engineering report
├── synthid.pdf # SynthID paper reference
└── requirements.txt
```
---
## 🔬 Technical Deep Dive
### How SynthID Works (Reverse-Engineered)
```
┌──────────────────────────────────────────────────────────────┐
│ SynthID Encoder (in Gemini) │
├──────────────────────────────────────────────────────────────┤
│ 1. Generate carrier frequencies: {(14,14), (126,14), ...} │
│ 2. Assign fixed phase values to each carrier │
│ 3. Neural encoder adds learned noise pattern to image │
│ 4. Watermark is imperceptible - spread across spectrum │
├──────────────────────────────────────────────────────────────┤
│ SynthID Decoder (in Google) │
├──────────────────────────────────────────────────────────────┤
│ 1. Extract noise residual (wavelet denoising) │
│ 2. FFT → check phase at known carrier frequencies │
│ 3. If phases match expected values → Watermarked │
└──────────────────────────────────────────────────────────────┘
```
### SpectralCodebook Extraction
The codebook captures the watermark's full frequency fingerprint:
- **50 reference images** (25 pure black + 25 pure white, all from Gemini)
- Extracts **magnitude envelope** and **phase template** per channel
- Computes **phase consistency score** per frequency bin
- Content-adaptive profiles for dark vs. light image regions
### Selective Notch Filter
The V3 bypass doesn't subtract blindly - it targets only bins where:
1. **Magnitude** exceeds the 97th percentile (strong watermark energy)
2. **Phase consistency** ≥ 0.95 across reference images (confirmed watermark, not noise)
3. **Subtraction** is capped at 30% of the image's energy at each bin
This surgical precision is why V3 achieves 40+ dB PSNR while still reducing watermark energy.
### Noise Correlation Signature
| Metric | Value | Significance |
|:-------|:-----:|:-------------|
| Mean pairwise noise correlation | **0.218** | Identical watermark in all images |
| Noise structure ratio | **1.32** | Neural encoder byproduct |
| Phase coherence (top carriers) | **>99.9%** | Fixed model-level key |
| Green channel phase std | **<0.007 rad** | Strongest consistency channel |
### Bit Plane Analysis
| Bit Plane | Consistency | Role |
|:---------:|:-----------:|:-----|
| Bit 0 (LSB) | 0.049 | Watermark signal |
| Bit 1 | 0.074 | Watermark signal |
| Bit 2 | 0.125 | Partially watermarked |
| Bit 3 | 0.513 | Mixed |
| Bits 4-7 | 0.6351.000 | Image structure |
---
## 🛠️ Core Modules
### `robust_extractor.py` - Detection
Multi-scale, multi-denoiser watermark detector achieving 90% detection rate.
```python
from robust_extractor import RobustSynthIDExtractor
extractor = RobustSynthIDExtractor()
extractor.load_codebook('artifacts/codebook/robust_codebook.pkl')
result = extractor.detect_array(image)
print(f"Watermarked: {result.is_watermarked}")
print(f"Confidence: {result.confidence:.4f}")
print(f"Phase Match: {result.phase_match:.4f}")
```
**Features:**
- Multi-scale analysis (256, 512, 1024px)
- Wavelet + bilateral + NLM denoising fusion
- ICA-based watermark/content separation
- Ensemble carrier detection across scales
### `synthid_bypass.py` - Bypass (V1/V2/V3)
Three generations of watermark bypass:
```python
from synthid_bypass import SynthIDBypass, SpectralCodebook
bypass = SynthIDBypass()
# V1: Simple JPEG compression
result = bypass.bypass_simple(image, jpeg_quality=50)
# V2: Multi-stage transform pipeline
result = bypass.bypass_v2(image, strength='moderate')
# V3: Spectral codebook subtraction (best)
codebook = SpectralCodebook()
codebook.load('artifacts/spectral_codebook.npz')
result = bypass.bypass_v3(image, codebook, strength='aggressive')
```
### `watermark_remover.py` - Removal
Quality-preserving frequency-domain removal:
```python
from watermark_remover import WatermarkRemover
remover = WatermarkRemover(extractor)
result = remover.remove(image, mode='balanced')
```
---
## 📚 References
- [SynthID: Identifying AI-generated images](https://deepmind.google/technologies/synthid/)
- [SynthID Paper (arXiv:2510.09263)](https://arxiv.org/abs/2510.09263)
---
## ⚠️ Disclaimer
This project is for **research and educational purposes only**. SynthID is proprietary technology owned by Google DeepMind. These tools are intended for:
- 🎓 Academic research on watermarking robustness
- 🔒 Security analysis of AI-generated content identification
- 📡 Understanding spread-spectrum encoding methods
**Do not use these tools to misrepresent AI-generated content as human-created.**