zk-img: Fighting Deepfakes with Zero-Knowledge Proofs
Over the past few years, the use of deepfakes for malicious purposes has exploded. Deepfakes have been used to steal funds from unsuspecting investors and even to convince soldiers to surrender. The rise of deepfakes has partially been driven by the rise of generative artificial intelligence (AI) methods, like Stable Diffusion. As these AI methods become more powerful, an important question emerges: how can we trust the validity of the images we see?
Example of a deepfake.
There have been some steps towards verifying that an image was taken by a real camera. Attested cameras can prove that an image was taken by a particular sensor by using digital signatures. However, the majority of photos released on the internet are edited to remove sensitive information and to improve legibility of the images. These edits are not attested by the camera and must be verified some other way. Recent work has proposed verifying these image edits using zero-knowledge proofs, in particular ZK-SNARKs (zero-knowledge succinct non-interactive argument of knowledge). ZK-SNARKs can prove that the edits on the image were legitimate.
Unfortunately, this work on ZK-SNARKs for images has several drawbacks. First, they require revealing the original or intermediate images.12 This breaks the privacy of the original image and can potentially leak sensitive information! Second, they are impractical, operating on images smaller than 128x128.12 Third, they require custom cryptographic arguments13 or trusted third parties.3
To address these issues, we have built zk-img, which allows image edits to be verified with no assumptions on trust while keeping the original/intermediate images private. zk-img is also efficient; it is the first library that can privately and securely verify arbitrary transformations on HD images.
In this blog post, we’ll briefly describe the internals and illustrate the usage of zk-img. For further details, please read our paper.
Using zk-img
Before we describe zk-img, we’ll first describe why zk-img is needed.
Hiding the original image
In most cases, the original image must be hidden. The original image may contain sensitive or embarrassing information, which should be edited. For example, the piglet below is carrying sensitive information in its mouth:
How can we keep the card hidden? (image from here.)
How can we keep the original image hidden while simultaneously allowing an image consumer to verify that the transformations were done honestly?
zk-img accomplishes this by computing the hash of the original image and the transformations themselves inside the ZK-SNARK. It only reveals the original image’s hash and the output image. Since ZK-SNARKs allow a verifier to be convinced the computation was done correctly, the image consumer can verify that the hash was computed correctly as well as transformations. We illustrate the process below:
Here, H1 and H2 are the hashes of the original image and intermediate image (after cropping and resizing). Since only the hash of the intermediate image is released, privacy is preserved.
Hiding the original and output image
In some cases, both the original and output image must be hidden. For example, the image producer might want to attest that they took an image before some point in time and release the hashes before releasing the output image. A biometric identification system may wish to hide the original and edited image, but still be able to prove that the images came from an attested source.
zk-img accomplishes this by computing the hashes of the original and transformed images. It only reveals the hashes, and not the images.
How zk-img works
Now that we’ve described how to use zk-img in a variety of scenarios, we’ll describe how zk-img works internally.
From an application developer perspective, zk-img takes as input an image from an attested camera, a sequence of image transformations, and whether or not the final image should be revealed. Given these inputs, zk-img produces a ZK-SNARK of the transformation.
We’ve built zk-img leveraging the recent developments in proving systems, which have dramatically improved in efficiency and usability. In particular, we built zk-img using the halo2 library. Internally, zk-img has a standardized interface for image transformations so they can be composed. This interface allows the addition of image transformations beyond what is currently implemented in zk-img.
The standardized interface for zk-img is critical as it allows a registry of valid transformations that users can trust. We have currently implemented the following transformations:
Developers can add other implementations to zk-img’s registry!
In order to implement these transformations efficiently, we leverage features from the Plonkish arithmetization, which halo2 is based on. See our paper for details.
Benchmarks
We benchmarked zk-img for image transformations on HD images, which is over 50x the size of previous work in this space. We first benchmarked zk-img on input-privacy preserving transformations:
Although the proof times are high, the verification times are as low as 4.59 ms! The verification costs are low enough to perform them on device.
The costs increase when keeping the output image hidden as well:
However, the verification times still remain small, taking at most 9.32 ms.
In our paper, we show that zk-img is orders of magnitude faster than prior work, up to 112x faster for proving and 94x faster for verifying.
Conclusion
The world is becoming increasingly connected and information is spreading faster than ever. Just this year, images from the front line in the Ukraine conflict spread rapidly over social media. Mixed in with real information, there were malicious images.
Imagine if every image on the internet was attested. Social media platforms could indicate which images were attested and which ones were not. Furthermore, anyone could see and verify on their own computer if an image came from a real camera!
As a first step towards this vision, we’ve built zk-img. zk-img can securely and privately attest to image transformations while keeping the original image hidden. By optimizing these transformations, zk-img can be orders of magnitude faster than prior work. For more details, see our paper and look out for our code release soon!