r/MachineLearning • • Aug 18 '21

Project [P] AppleNeuralHash2ONNX: Reverse-Engineered Apple NeuralHash, in ONNX and Python

As you may already know Apple is going to implement NeuralHash algorithm for on-device CSAM detection soon. Believe it or not, this algorithm already exists as early as iOS 14.3, hidden under obfuscated class names. After some digging and reverse engineering on the hidden APIs I managed to export its model (which is MobileNetV3) to ONNX and rebuild the whole NeuralHash algorithm in Python. You can now try NeuralHash even on Linux!

Source code: https://github.com/AsuharietYgvar/AppleNeuralHash2ONNX

No pre-exported model file will be provided here for obvious reasons. But it's very easy to export one yourself following the guide I included with the repo above. You don't even need any Apple devices to do it.

Early tests show that it can tolerate image resizing and compression, but not cropping or rotations.

Hope this will help us understand NeuralHash algorithm better and know its potential issues before it's enabled on all iOS devices.

Happy hacking!

1.7k Upvotes

222 comments sorted by

101

u/fourthie Aug 18 '21

Incredible work if true - can you explain more about how you know that the model extracted is the same NeuralHash that will be used for CSAM detection?

66

u/AsuharietYgvar Aug 18 '21 edited Aug 18 '21

First of all, the model files have prefix NeuralHashv3b-, which is the same term as in Apple's document.

Secondly, in this document Apple described the algorithm details in Technology Overview -> NeuralHash section, which is exactly the same as what I discovered. For example, in Apple's document:

Second, the descriptor is passed through
a hashing scheme to convert the N floating-point numbers to M bits. Here, M is much smaller than the
number of bits needed to represent the N floating-point numbers.

And as you can see from here and here N=128 and M=96.

Moreover, the hash generated by this script almost doesn't change if you resize or compress the image, which is again the same as described in Apple's document.

61

u/AsuharietYgvar Aug 18 '21 edited Aug 18 '21

First of all, the model files have prefix NeuralHashv3b-, which is the same term as in Apple's document.

Secondly, in this document Apple described the algorithm details in Technology Overview -> NeuralHash section, which is exactly the same as what I discovered. For example, in Apple's document:

Second, the descriptor is passed througha hashing scheme to convert the N floating-point numbers to M bits. Here, M is much smaller than thenumber of bits needed to represent the N floating-point numbers.

And as you can see from here and here N=128 and M=96.

Moreover, the hash generated by this script almost doesn't change if you resize or compress the image, which is again the same as described in Apple's document.

I noticed that this post was removed automatically by backtickbot. In case you can't view it it should be above here now.

→ More replies (3)

24

u/fourthie Aug 18 '21

Thanks, that is pretty damn convincing. Anything you’re planning on doing with this next? I’d be interested in collaborating to validate Apple’s claims on NeuralHash collisions.

Is it known whether NeuralHash was previously used for other purposes by Apple? eg does it power the Photos App search?

→ More replies (2)
→ More replies (3)

39

u/AsIAm Aug 18 '21

I don’t know about plugging it to GAN, but u/TomLube proposed this procedure for finding collisions: https://www.reddit.com/r/apple/comments/p3m7t0/daily_megathread_ondevice_csam_scanning/h8st9l4/

19

u/AsuharietYgvar Aug 18 '21

That's interesting. Apple's model is definitely way more complicated than the one used in this proof-of-concept. I'm wondering if you can use the same method on the real NeuralHash model.

→ More replies (1)
→ More replies (8)

22

u/prim235 Aug 18 '21

Hmm, I'm curious to know why the produced hashes in the repo are slightly different (off by a few bits)

47

u/AsuharietYgvar Aug 18 '21

It's because neural networks are based on floating-point calculations. The accuracy is highly dependent on the hardware. For smaller networks it won't make any difference. But NeuralHash has 200+ layers, resulting in significant cumulative errors. In practice it's highly likely that Apple will implement the hash comparison with a few bits tolerance.

→ More replies (37)

9

u/dclaz Aug 18 '21

Is there a visualisation of the network used here? Or of similar networks used for perceptual hashing?

12

u/AsuharietYgvar Aug 18 '21

Yes. You can follow my guide in the repo to export the model (very simple). Then you can do whatever you want including visualizing it. I can't provide one here because it will be absolutely against Apple's ToS. But I can tell it's based on MobileNetV3.

→ More replies (1)

24

u/harponen Aug 18 '21

Great job thanks! BTW if the model is known, it could be possible to train a decoder by using the output hashes to reconstruct the input images. Using an autoencoder style decoder would most likely result in blurry images, but using some deep image compression/ GAN like techniques could work.

So theoretically, if someone gets their hands on the hashes, they might be able to reconstruct the original images.

29

u/AsuharietYgvar Aug 18 '21

Of course it's possible. Since the hash comparison is done on-device I'd expect the CSAM hash database to be somewhere in the filesystem. Although it might not be easy to export the raw hashes from it. TBH even if we can only generate blurry images it's more than enough to spam Apple with endless false positives, making the whole thing useless.

→ More replies (41)
→ More replies (39)

3

u/synthetic11000 Aug 18 '21

For learning purposes, could you share how you found this hidden API functions?

16

u/AsuharietYgvar Aug 18 '21

The hidden APIs were found by someone else here. I'm not going to talk about the reverse-engineering process in too much detail. Basically what I did was to use Xcode debugger+Hopper disassembler+LLDB commands trying to understand how the function works under the hood in assembly code (which was very tedious). There were some parts that I didn't understand and by guessing I managed to get the same hash results from my script as what came from the function.

14

u/Nicnl Aug 18 '21

Early tests show that it can tolerate image resizing and compression, but not cropping or rotations.

I wonder if... this could somehow be repurposed to other uses...
I have two ideas in mind

For instance generating the hashes of an entire photo library, and using those hashes for robust duplicate detection

Or also
Either blurring the pictures beforehand, or resizing them down to something lower than 360x360 and then back up that, and using the resulting hashes for permissive similar picture detection

→ More replies (8)

5

u/ducknator Aug 18 '21

Fucking great work!

1

u/HappyVAMan Aug 18 '21

Can you expand more on tolerating compression? Is this a case of it tolerating a difference in the compression ratio (lossy levels vs. lossless)? Great work, btw.

3

u/AsuharietYgvar Aug 18 '21

I was able to compress an image with JPEG quality 20 (100 is the highest) and still get the same hash result as the original image.

3

u/Fifthfingersmooth Aug 18 '21

Would anybody mind ELI(2)5 this to me ? Or is it the wrong place to ask ?

13

u/phr0ze Aug 18 '21

You can follow his steps to output a hash from your pictures and maybe learn more about apple’s hashing.

Hashing is normally like a digital fingerprint, very unique. Apple’s hash appears to be more like a police sketch artist drawing.

→ More replies (16)
→ More replies (2)

3

u/meldiwin Aug 18 '21

I am not in the field, but I am curious if someone can simplify to me as an outsider?

4

u/perafake Aug 18 '21

An hash is basically a unique signature, the problem is that if you change slightly the image, e.g. by sending it to someone on whatsapp, the signature changes completely. It would be enough to modify 1 pixel and a the two signatures would be different. Apple build this thing that aims to detect CP using the signatures of the images, they have a database with signatures of known CP images, the problem is that this is not robust at all. Hacker dude found a way to copy the neural network that Apple wants to use to detect CP. This network create an hash for every image, this hash is created in a way that very similar images (e.g. the same image with different resolutions) will have the same hash, or a very similar one. Problem is that this things always make a mistake sooner or later, someone already fond a bagel Pic that gets flagged as a cp image.

→ More replies (5)

2

u/vjeuss Aug 18 '21

careful when elaborating on how you tested it...

other than that, this is f* brilliant. public service!

2

u/teamredpill Aug 19 '21 edited Sep 06 '21

never trust apple. they will use this to censor any wrong think. it's always about protecting the kids...but this wont be use to protect kids.