I always mentally substituted FHE with “the ability to encrypt a function such that no attacker can reverse engineer how that function was implemented,” i.e. “input go in, output go brr.” Crucially, in FHE this is true even if you yourself are the one executing the program and can observe everything the program is doing.
Or... in whatever I thought FHE was.
The iO circuit would need the FHE decryption key and the hidden output. If there were exactly one FHE ciphertext for any plaintext (which can't work, otherwise you could distinguish FHE values and break it), then you could simply implement this by supplying <target FHE ciphertext> XOR <obfuscated secret>.
Is there a scheme where iO could do this, or is it impossible because any obfuscation would necessarily require both the FHE decryption key and the obfuscated secret?
In simple terms, why is FHE different from iO? I’ve read your reply a few times, but I don’t understand the concrete distinction. What is the “best possible result” of input + 42 obfuscatabiliry?
Note that I am using + 42 as a trivial example; please mentally substitute with “for example, a bunch of matrix operations to compute a super secret formula result.”
Here's what iO means: given two different circuits C_0 and C_1 that both compute a function f, the obfuscations iO(C_0) and iO(C_1) are indistinguishable (to a polytime adversary). In the email example, you could have a circuit C that computes isSpam over encrypted emails, but with a decrypted result. That is, C(Enc(email)) = isSpam(email). But note that this leaks information to Google, and the security definition of iO does NOT guarantee that Google does not learn anything about your secret key (the obfuscation might not hide the secret key at all).
Definitionally, they're very, very different things and have very different security guarantees. The weird thing about iO is that the security definition doesn't immediately appear to actually secure much, so it doesn't seem very useful. However, it turns out that iO is an incredibly powerful primitive because it can be combined with other things like pseudorandom generators to build up a lot of other primitives. For example, you can combine secret-key encryption and iO to get public-key encryption in a very elegant way.
[1] https://juliacomputing.com/blog/2019/11/encrypted-machine-le...
- I encrypt data Encrypt(key, data) = ciphertext1
- you operate on encrypted data f(ciphertext1) = ciphertext2
- I decrypt the result to obtain Decrypt(key, ciphertext2) = f(data)
for iO it's more like: I give you the algorithm to encrypt your data: some_algorithm(data) = Encrypt(key, data)
but you can't figure out what "key" is, even though you have the code and it's not some remote service
Have I been using that term incorrectly? It’s possible. If so, what’s the canonical acronym for “encrypting a function”?
The term you are looking for is "obfuscation". Either black-box obfuscation (which was shown to be impossible) or the indistinguishability obfuscation, which is what the article talks about.
Obfuscation roughly means "encrypting a function." But here be dragons: since the adversary gets non-black-box access to the implementation of the function (a circuit), and can also learn as many (input, output = f(input)) pairs as they want, it becomes impossible to say that the adversary cannot learn anything else about f in the general case (intuitively, consider a higher-order function f: you could learn a lot about f by computing f(f)).
However, that book does look daunting. I am curious if the book hints at more potential problems than the abstract indicates.
I wish I had endless free time. It would be so, so fun to dive into this. Because you’re right — I got the sense that there were more potential problems than was previously appreciated. It would be fascinating to know exactly what problems there are, and whether they’re fundamental problems or “dodgeable.”
Reads article
Yup! Gosh, I can't wait for it to become remotely practical.
It's been a few years -- wow, almost a decade -- but I remember a paper that claimed to prove that "no fully homomorphic program can be written such that the secret key was guarded in all cases," i.e. it's theoretically possible to trick a FHE program into giving up its own key, unless your program is basically trivial.
It was one of those papers that you run across, then never see again, and wistfully wish you'd saved a reference to. Tantalizing idea, if true, but probably not true.
EDIT: I just went back to finish the article, and they linked to it: https://link.springer.com/chapter/10.1007/3-540-44647-8_1 Welp. Looks like it was a good paper!