Tales from the Hacker House: Building an Attested Image Editor

Tales from the Hacker House: Building an Attested Image Editor

Saul and Pablo built an in-browser attested image editor with SP1 at Upgrade the Internet, a hacker house hosted by Succinct, Celestia, and Conduit at ETHDenver. In this post, we cover their motivation for building this project, the technical challenges they faced, and the details of their implementation. Image provenance is an exciting new category for ZK applications. Try out the image editor here.

The attested image editor allows you to upload an image and track changes with ZK proofs.

The Problem

Every day new digital content is created, but we don’t have a universal way to verify if it’s authentic and where it comes from. Especially with deepfakes, it’s difficult to determine if something is real or not. There is an existing solution to these problems, but it only partially solves the issues and it relies heavily on a chain of trust. The Coalition for Content Provenance and Authenticity (C2PA) Standard attempts to address these issues through digital certificates that track media changes in metadata, but faces the following challenges:

  • The metadata can be altered separately from the image itself, allowing someone to change claimed capture dates or locations.
  • Trust chains require each signer to verify all previous claims, meaning one malicious entity could break the entire chain of authenticity.
  • Certificates only verify signer identity, so a valid signature confirms who signed the image but doesn't prove the authenticity of the metadata.

The Solution

Instead of relying on C2PA trust assumptions, Saul and Pablo built an image editor that uses ZKPs that verify every image transformation. This creates a tamper-proof solution for tracking media provenance.

Using SP1, they compute the image’s transformations and generate proofs that anyone can verify. Their solution works by:

  • Binding transformations to images. When an image is edited, their solution computes a hash of both the original and transformed image, exposing these hashes as public outputs in the ZKP.
  • Trustless verification. The verification process requires no trust in any participant, anyone can verify the proof.
  • Immutable provenance chain. Each time a proof is verified on-chain, it establishes a link between the original image hash and the transformed image hash.

Note: this solution doesn’t verify if the starting image is real. Ideally, a camera in a Trusted Execution Environment (TEE) would provide a verifiable attestation. For this proof-of-concept, Saul and Pablo mocked an attestation using Ethereum signatures on the original image, verified during the ZKP generation.

Technical Implementation

The solution consists of five core components working together to create attested image transformations:

  • Image Processing Library: Saul developed a Rust library that handles transformations like crop, rotate, blur, text overlays, and other common actions. It supports region-based transformations, allowing, for example, blurring a face from an image. To achieve consistent results both in the UI and the SP1 program, the library is compiled into WASM for the browser and into RISC-V for the SP1 program.
  • SP1 Program: This is the core element of the solution that generates the ZKP. It processes the original image transformations, creates the hashes of both original and transformed images, and verifies the Ethereum signatures are valid.
  • Prover API: An Axum API that handles proof generation requests. It communicates with the Succinct Prover Network to generate ZKPs and returns the proof data and the transformed image, allowing developers to build any application on top.
  • Image Verifier Contract: A contract that verifies proofs of image transformations and maintains a data structure tracking the complete lineage of all images and signature information.
  • User Interface: The team built a Next.js application similar to other image editors with real-time editing using the image library they developed. The UI also includes a gallery page showing the complete lineage of images and their proofs.
The image lineage shows how the image is edited over time.

When a user edits an image in the application, the browser loads the WASM module compiled from our Rust library, allowing transformations to be rendered in real-time. Once editing is complete, both the original image and the list of transformations are sent to the Prover API. 

The API constructs an input object containing the image data, transformations, and any signature information, which is then processed by the SP1 program. The program applies each transformation in sequence, creates hashes for both original and transformed images, and verifies signatures, outputting the hashes that establish the relationship between the original and transformed images and the signature when it’s valid.

After the proof is generated, users can submit it to the Image Verifier contract for on-chain verification, creating an immutable record of the image's provenance. The gallery interface displays this lineage with verification status, allowing anyone to trace an image's complete history with certainty.

Image editor architecture

Experience at the Hacker House

We asked Saul about his experience: "I really enjoyed the ambience at the hacker house. It gave me the opportunity to reconnect with friends and meet other hackers. I felt fully supported when I needed some help troubleshooting minor errors and with their help, I was able to successfully complete and present the project."

Read more