From 343da7f87d986e2aa4dbe8df2d81061fac3bccda Mon Sep 17 00:00:00 2001 From: Victor Kuznetsov Date: Fri, 28 Aug 2026 20:00:18 -0700 Subject: [PATCH] Add a synthetic Ideogram C2PA attribution fixture A throwaway test CA with leaf subject CN=Ideogram, Inc signs a flat PNG carrying a trainedAlgorithmicMedia claim. The fixture exercises the issuer-to-platform attribution end to end through the real reader and pins the second dimension the project separates: attribution names Ideogram while signer trust stays untrusted. Recipe documented in the fixtures README; no keys, vendor bytes, or user uploads are committed. --- data/fixtures/README.md | 20 ++++++++++++++++++++ data/fixtures/provenance/ideogram-c2pa.png | Bin 0 -> 43836 bytes tests/test_identify.py | 12 ++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 data/fixtures/provenance/ideogram-c2pa.png diff --git a/data/fixtures/README.md b/data/fixtures/README.md index c71559f..47176b6 100644 --- a/data/fixtures/README.md +++ b/data/fixtures/README.md @@ -13,3 +13,23 @@ example from [`adobe/trustmark`](https://github.com/adobe/trustmark) at commit - SHA-256: `e58c5825ed7e5d9fb04710ea541b61bd55879cad65554c0d46260aa24b3d0755` - Expected signal: TrustMark Variant P, schema 1 - License: MIT, reproduced in `../licenses/adobe-trustmark-MIT.txt` + + +## Ideogram C2PA attribution + +`ideogram-c2pa.png` is a SYNTHETIC signed manifest, not a vendor download: a +64x64 flat PNG carrying a C2PA claim (`trainedAlgorithmicMedia`, +`claim_generator "Ideogram/3.0"`) signed by a throwaway test CA whose leaf +certificate subject is `O=Ideogram, Inc, CN=Ideogram, Inc`. It exercises the +issuer-to-platform ATTRIBUTION path end to end through the real reader; the +signer is deliberately untrusted (no trust anchors ship), which is also the +fixture's second assertion: attribution and signer trust are separate +dimensions. + +- Expected signal: C2PA, platform `Ideogram`, `ai_from_metadata` True +- Expected signer: `untrusted` (test CA; attribution must not imply trust) +- Recipe (no keys are committed): create a CA and an ES256 leaf with + `digitalSignature` key usage and subject `CN=Ideogram, Inc`, then + `c2pa.Builder.from_json(...).sign_file(png, out, Signer.from_info( + C2paSignerInfo(b"es256", leaf_pem + ca_pem, pkcs8_key, None)))`. +- No user upload and no Ideogram artifact contributes pixels or bytes. diff --git a/data/fixtures/provenance/ideogram-c2pa.png b/data/fixtures/provenance/ideogram-c2pa.png new file mode 100644 index 0000000000000000000000000000000000000000..d3d47d0f2c565dce084832884c02e2e8fa371278 GIT binary patch literal 43836 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 L#{`xSo2>g6K-8;& literal 0 HcmV?d00001 diff --git a/tests/test_identify.py b/tests/test_identify.py index 4b1d002..e1156b0 100644 --- a/tests/test_identify.py +++ b/tests/test_identify.py @@ -1489,6 +1489,18 @@ class TestVendorOf: assert _vendor_of("Eleven Labs Inc.") == "ElevenLabs" assert _vendor_of("Ideogram") == "Ideogram" + def test_ideogram_fixture_attributed_end_to_end(self): + # Committed synthetic manifest signed by a test CA with CN "Ideogram, Inc": + # attribution must name the platform while signer trust stays untrusted. + # Reachability against the fixture, not a synthesized status set. + fixture = Path(__file__).resolve().parents[1] / "data" / "fixtures" / "provenance" / "ideogram-c2pa.png" + if not fixture.exists(): # the sdist ships no data/ + pytest.skip("provenance fixture not present") + report = identify(fixture, check_visible=False, check_invisible=False) + assert report.ai_from_metadata is True + assert report.platform == "Ideogram" + assert any("Ideogram" in w for w in report.watermarks) + def test_ideogram_issuer_attributed(self): # Corpus evidence 2026-08-08: four uploads signed "Ideogram, Inc" read as # unknown-signer C2PA with no platform. The issuer token is the org prefix.