Obfuscation (Part II): Diamond iO
Special thanks to Sora Suegami and Janmajaya Mall for feedback and review.
特别感谢 Sora Suegami 和 Janmajaya Mall 的反馈和审查。
In the last part of this series, we went through the full tech tree of the most mainstream and conservative line of cryptographic obfuscation (iO) protocols.
在本系列的最后一部分中,我们了解了最主流和最保守的加密混淆 (iO) 协议系列的完整技术树。
These protocols allow you to "encrypt" programs in such a way that anyone can run the "encrypted" program on plaintext inputs and get plaintext outputs, without being able to see the internal logic of the program.
这些协议允许您以任何人都可以在明文输入上运行“加密”程序并获得明文输出的方式“加密”程序,而无需看到程序的内部逻辑。
This can be used for all kinds of use cases, particularly situations where the program contains some secret key internally, and obfuscating accomplishes the goal of giving someone a package that lets them do some things with the secret key in some circumstances , but not anything else.
这可以用于各种用例,特别是程序内部包含一些秘密密钥的情况,并且混淆实现了为某人提供一个包的目标,该包允许他们在某些情况下使用秘密密钥做一些事情,但不能做其他任何事情。
The biggest downside of these protocols so far has been their literally galactic runtime - if you actually try to figure out how long it would take to run one of them, you would get an answer longer than the lifetime of the universe.
到目前为止,这些协议的最大缺点是它们的实际运行时间——如果你真的试图计算出运行其中一个协议需要多长时间,你会得到比宇宙寿命还要长的答案。
As a result, despite recent breakthroughs in feasibility, obfuscation protocols have so far been theoretical curiosities.
因此,尽管最近在可行性方面取得了突破,但混淆协议迄今为止仍只是理论上的好奇心。
This post will describe in detail a different style of obfuscation: diamond iO ( paper , presentation ).
这篇文章将详细描述一种不同风格的混淆:diamond iO(论文,演示文稿)。
This approach relies on much "braver" and more untested cryptographic assumptions, but it achieves having merely "planetary", rather than galactic runtime - still infeasible today, but perhaps only a few further optimizations away from becoming a reality at least for a few use cases.
这种方法依赖于更“勇敢”和更未经测试的加密假设,但它仅实现了“行星”运行时间,而不是银河运行时间——今天仍然不可行,但至少在一些用例中,可能只需要进行一些进一步的优化就可以成为现实。
At a high level, diamond iO is built by modifying the BGG+14 attribute-based encryption (ABE) scheme, explained in the previous post .
在较高层面上,diamond iO 是通过修改 BGG+14 基于属性的加密 (ABE) 方案构建的,如上一篇文章所述。
I highly recommend re-reading that section before continuing.
我强烈建议您在继续之前重新阅读该部分。
It's also not this Abe.
也不是这个安倍。
Bonus points if you know which Abe this one is - harder than the four in the last post!
如果你知道这是哪个 Abe,那就加分了 - 比上一篇文章中的四个更难!
Like, the more traditional iO protocols, diamond iO runs the computation in FHE inside of ABE, and then gives the evaluator a way to decrypt the result only if it's actually the outcome of running the computation correctly.
与更传统的 iO 协议一样,diamond iO 在 ABE 内部的 FHE 中运行计算,然后仅当结果实际上是正确运行计算的结果时,才为评估者提供解密结果的方法。
But the way that diamond iO uses this machinery is different.
但 Diamond iO 使用这台机器的方式却有所不同。
First, it uses a completely different mechanism to do conditional FHE decryption.
首先,它使用完全不同的机制来进行条件 FHE 解密。
Second, it uses a completely different mechanism to generate the encodings for the input.
其次,它使用完全不同的机制来生成输入的编码。
These two modifications are connected to each other, and are the real reason why diamond iO manages to be much more efficient - it's "just as computationally intensive as" functional encryption, instead of being a much more complicated tower on top of FE.
这两个修改是相互关联的,也是 Diamond iO 能够变得更加高效的真正原因 - 它“与功能加密一样计算密集”,而不是在 FE 之上建造一个更加复杂的塔。
As a reminder, BGG+14 works by maintaining encodings of the form
提醒一下,BGG+14 的工作原理是维护以下形式的编码
(alternatively, you can add \(G * m\) instead of subtracting; both give equally valid and efficient schemes)
(或者,您可以添加 \(G * m\) 而不是减去;两者都给出同样有效且高效的方案)
Given two \(B\) matrices representing two "input wires" to an operation - either addition, multiplication or negation - you can generate a \(B\) matrix representing the output wire.
给定两个表示两个“输入线”的 B 矩阵(加法、乘法或求反),您可以生成表示输出线的 B 矩阵。
Given valid encodings for two inputs to an operation, you can get an encoding for the output - \(1 - m\) , \(m_a + m_b\) or \(m_a * m_b\) - that is based on the \(B\) matrix representing the output wire.
给定操作的两个输入的有效编码,您可以获得输出的编码 - \(1 - m\) 、 \(m_a + m_b\) 或 \(m_a * m_b\) - 基于表示输出线的 \(B\) 矩阵。
Importantly, this is not fully-homomorphic encryption: to multiply, you need to know either \(m_a\) or \(m_b\) in the clear.
重要的是,这不是完全同态加密:要相乘,您需要清楚地知道 \(m_a\) 或 \(m_b\)。
In BGG+14, there is a step at the end, which allows decoding a pre-selected output, only if the value in the computation on some "output" wire equals 0.
在 BGG+14 中,最后有一个步骤,仅当某些“输出”线上的计算值等于 0 时,才允许解码预选的输出。
Here, we do not do that.
在这里,我们不这样做。
Instead, what we will do is just extract the data that we need from the encoding.
相反,我们要做的只是从编码中提取我们需要的数据。
But in both cases, the decryption method depends on the encoding being based on a specific matrix \(B_{final}\) representing the output wire - this is how we enforce that decryption can happen if you did the computation correctly, but not in any other context.
但在这两种情况下,解密方法都取决于基于表示输出线的特定矩阵 \(B_{final}\) 的编码 - 这就是我们强制执行解密的方式,如果您正确地进行了计算,但在任何其他上下文中则不然。
The first two ideas came from prior work, particularly HLL23 and AKY24 .
前两个想法来自之前的工作,特别是 HLL23 和 AKY24 。
The third piece, the mechanism for constructing the ABE encodings of the inputs, originally came from GGH15 ; the new contribution in diamond iO is to use it not to evaluate the whole program (which turned out insecure) but to generate BGG+ encodings for the inputs.
第三部分,构建输入的 ABE 编码的机制,最初来自 GGH15 ; Diamond iO 的新贡献是不使用它来评估整个程序(结果证明是不安全的),而是为输入生成 BGG+ 编码。
Assume for now that the evaluator somehow gets as input four types of BGG+ encodings of:
现在假设评估器以某种方式获取四种类型的 BGG+ 编码作为输入:
The evaluator first runs the BGG+ computation using the encodings of \(E[z]\) and \(x\) .
评估器首先使用 \(E[z]\) 和 \(x\) 的编码运行 BGG+ 计算。
Remember, the computation is not \(f(x, z)\) directly, rather, it's \(FHE.eval(f, x, E[z])\) .
请记住,计算不是直接 \(f(x, z)\) ,而是 \(FHE.eval(f, x, E[z])\) 。
From the BGG+ perspective, \(x\) and \(E[z]\) are both cleartext bits.
从 BGG+ 的角度来看,\(x\) 和 \(E[z]\) 都是明文位。
From the FHE perspective, \(z\) is a hidden input, of which only the encrypted form is known to the evaluator.
从 FHE 的角度来看,\(z\) 是一个隐藏输入,评估者只知道其加密形式。
At the end of doing the BGG+ computation, the evaluator has BGG+ encodings of bits of the FHE ciphertext representing \(f(x, z)\) .
在执行 BGG+ 计算结束时,评估器具有表示 \(f(x, z)\) 的 FHE 密文位的 BGG+ 编码。
BGG+ is not fully homomorphic encryption; in general, computing on BGG+ encodings requires having the underlying cleartext.
BGG+不是完全同态加密;一般来说,BGG+编码的计算需要有底层的明文。
But we can avoid this rule for additions , and for multiplications by known values .
但我们可以在加法和乘以已知值时避免这条规则。
This is because a BGG+ encoding of \(m_a * m_b\) is computed via:
这是因为 \(m_a * m_b\) 的 BGG+ 编码是通过以下方式计算的:
(If the encodings were adding \(G * m\) instead of subtracting, then it would be \(G^{-1}(-B_a)\) instead)
(如果编码是加 \(G * m\) 而不是减,那么它将是 \(G^{-1}(-B_a)\) )
We can allow \(m_a\) to be unknown (ie.
我们可以允许 \(m_a\) 未知(即
given to us via encodings only), as long as \(m_b\) is known.
仅通过编码提供给我们),只要 \(m_b\) 已知。
This is an important fact for us.
这对我们来说是一个重要的事实。
To see why, remember the structure of GSW decryption (also described in the previous post in this series ):
要了解原因,请记住 GSW 解密的结构(也在本系列的上一篇文章中进行了描述):
Because the evaluator knows all the bits of the actual execution trace, including the final FHE ciphertext (which we'll call \(Y\) ), we can give the evaluator the FHE decryption key, \(t\) , only as BGG+ encodings.
因为评估器知道实际执行跟踪的所有位,包括最终的 FHE 密文(我们称之为 \(Y\) ),所以我们可以向评估器提供 FHE 解密密钥 \(t\) ,仅作为 BGG+ 编码。
We want to compute \(t * Y\) .
我们想要计算 \(t * Y\) 。
We have only BGG+ encodings of \(t\) , and we have both the BGG+ encodings and the raw bits of \(Y\) .
我们只有 \(t\) 的 BGG+ 编码,并且我们同时拥有 BGG+ 编码和 \(Y\) 的原始位。
So in principle we can do it.
所以原则上我们是可以做到的。
But there's a problem: \(Y\) is given to us as a series of bits.
但有一个问题:\(Y\) 是作为一系列位提供给我们的。
That is, we don't get a vector of the form \([2, 6, 11...]\) .
也就是说,我们没有得到 \([2, 6, 11...]\) 形式的向量。
We get a vector of the form \([0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1...]\) , where each bucket of bits (in this example, 4 bits) is a binary-encoding of a number, by convention least-significant-bits first.
我们得到一个形式为 \([0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1...]\) 的向量,其中每个位桶(在本例中为 4 位)都是数字的二进制编码,按照惯例,最低有效位在前。
So we have to somehow re-scale the bits, so that in every cell where we BGG+ multiply some cell \(t_j * Y_{\{i,j,b\}}\) , where \(Y_{\{i,j,b\}}\) is the order \(2^b\) bit of the cell \(Y_{\{i,j\}}\) , the encoding that comes out is scaled by \(2^b\) .
因此,我们必须以某种方式重新缩放位,以便在 BGG+ 乘以某个单元 \(t_j * Y_{\{i,j,b\}}\) 的每个单元中,其中 \(Y_{\{i,j,b\}}\) 是单元 \(Y_{\{i,j\}}\) 的顺序 \(2^b\) 位,产生的编码按 \(2^b\) 缩放。
For convenience, let's group together encodings of bits that are of the same order and that will eventually be inside the same value in the answer: that is, the whole column \(t_j * Y_{\{i,j,b\}}\) for some specific \(i\) and \(b\) across all \(j\) .
为了方便起见,让我们将具有相同顺序且最终位于答案中相同值内的位编码分组在一起:即,对于所有 \(j\) 中的某些特定 \(i\) 和 \(b\) ,整个列 \(t_j * Y_{\{i,j,b\}}\) 。
\(\sum_j s * (B_{\{out,i,j,b\}} - t_j * Y_{\{i,j,b\}} * G) + e_{\{out,i,j,b\}}\)
\(\sum_j s * (B_{\{out,i,j,b\}} - t_j * Y_{\{i,j,b\}} * G) + e_{\{out,i,j,b\}}\)
\(= s * (B_{\{out,i,b\}} - (tY)_{\{i,b\}} * G) + e_{\{out,i,b\}}\)
\(= s * (B_{\{out,i,b\}} - (tY)_{\{i,b\}} * G) + e_{\{out,i,b\}}\)
Now we get to the puzzle: how do we combine together bits of different orders?
现在我们遇到了难题:如何将不同顺序的位组合在一起?
\(\sum_{b=0}^{log(q)-1} (s * (B_{\{out,i,b\}} - (tY)_{\{i,b\}} * G) + e_{\{out,i,b\}}) * 2^b\)
\(\sum_{b=0}^{log(q)-1} (s * (B_{\{out,i,b\}} - (tY)_{\{i,b\}} * G) + e_{\{out,i,b\}}) * 2^b\)
The problem with this is that it multiplies up the errors of the high-order digits too much: the error of the highest-order term would get multiplied by \(2^{log(q)-1} = \frac{q}{2}\) so it would flood the whole range.
这样做的问题是,它会将高阶数字的误差放大太多:最高阶项的误差将乘以 \(2^{log(q)-1} = \frac{q}{2}\),因此它会淹没整个范围。
\(\sum_{b=0}^{log(q)-1} (s * (B_{\{out,i,b\}} - (tY)_{\{i,b\}} * G) + e_{\{out,i,b\}}) * G^{-1}(2^bG)\)
\(\sum_{b=0}^{log(q)-1} (s * (B_{\{out,i,b\}} - (tY)_{\{i,b\}} * G) + e_{\{out,i,b\}}) * G^{-1}(2^bG)\)
\(G^{-1}(2^bG)\) is doing all the work here.
\(G^{-1}(2^bG)\) 正在这里完成所有工作。
Basically, this is a bucket-wise left shift operator - it takes each \(log(q)\) -bit bucket \(tY\) , and shifts them all to the left.
基本上,这是一个桶式左移运算符 - 它采用每个 \(log(q)\) 位桶 \(tY\) ,并将它们全部向左移动。
Remember, BGG+ encodings are of the form \(s * (B - G * m) + e\) .
请记住,BGG+ 编码的形式为 \(s * (B - G * m) + e\) 。
And remember that \(G\) has this form:
请记住 \(G\) 具有以下形式:
This means that BGG+ encodings encode \(m\) simultaneously at every scale .
这意味着 BGG+ 编码在每个尺度上同时编码 \(m\) 。
And what we're doing here is we're moving higher-scale encodings of higher-order bits into the first column of each bucket.
我们在这里所做的是将高阶位的更大规模编码移动到每个存储桶的第一列中。
And because we're just doing additions and shifts, not multiplications, we avoid the error blowing up by more than the small amount that is introduced by the additions.
而且因为我们只是进行加法和移位,而不是乘法,所以我们可以避免误差放大超过加法引入的少量误差。
To see why \(G^{-1}(2^bG)\) has this shift effect, let's also look at \(G^{-1}\) .
要了解为什么 \(G^{-1}(2^bG)\) 具有这种移位效果,我们还可以看看 \(G^{-1}\) 。
On its own, \(G^{-1}\) is the right-inverse of \(G\) , the bit decomposition operator (not a matrix).
就其本身而言, \(G^{-1}\) 是位分解运算符(不是矩阵) \(G\) 的右逆。
But if we multiply \(G\) by \(2\) before sticking it into \(G^{-1}\) , each binary decomposition is shifted up by one place, and so we get the desired shift:
但是,如果我们将 \(G\) 乘以 \(2\),然后将其粘贴到 \(G^{-1}\) 中,则每个二进制分解都会向上移动一位,因此我们得到了所需的移位:
This is just a notational trick that allows the "left-shift every bucket" mechanism to be easily encoded into vector-and-matrix algebra.
这只是一个符号技巧,允许将“每个桶左移”机制轻松编码为向量和矩阵代数。
See also that the \(G^{-1}(2^bG)\) matrix is also clearly very low-norm (only ones and zeroes); this is another way to know that this step does not unreasonably blow up error.
另请参见 \(G^{-1}(2^bG)\) 矩阵显然也是非常低范数的(只有 1 和 0);这是了解此步骤不会无理放大错误的另一种方式。
The final outcome of this step is that you get a BGG+ encoding of \(tY\) :
这一步的最终结果是你得到 \(tY\) 的 BGG+ 编码:
Note that these are no longer "normal" encodings, both because the \((tY)_i\) 's are full-range values modulo q, and because the evaluator does not know the cleartext values.
请注意,这些不再是“正常”编码,因为 \((tY)_i\) 是以 q 为模的全范围值,并且因为评估器不知道明文值。
The evaluator cannot do any further BGG+ multiplication on them.
评估者无法对它们进行任何进一步的 BGG+ 乘法。
But that's okay, because they do not have to; the only step the evaluator has left is to remove the "wrapping with \(s\) " so that we can get to our final goal, extracting \((tY)_i + e\) .
但这没关系,因为他们不必这样做;评估者剩下的唯一步骤是删除“用 \(s\) 包裹”,以便我们可以达到最终目标,提取 \((tY)_i + e\) 。
To extract \((tY)_i + e\) , we are going to diverge from BGG+ ABE fully.
为了提取 \((tY)_i + e\) ,我们将完全偏离 BGG+ ABE 。
In ABE, we know that, in those cases where decryption is supposed to be possible, the answer \(C(tag)\) equals 0.
在 ABE 中,我们知道,在那些应该可以解密的情况下,答案 \(C(tag)\) 等于 0。
\(G * C(tag)\) disappears, and that's exactly why we can extract the message.
\(G * C(tag)\) 消失了,这正是我们可以提取消息的原因。
\(G * C(tag)\) plays the role of a blinding factor .
\(G * C(tag)\) 起着致盲因素的作用。
Here, the use case is different: \((tY)_i\) is the entire thing that we want to extract.
这里,用例有所不同:\((tY)_i\) 是我们想要提取的整个内容。
Now, let's extract a single column from this expression - the lowest-order column in the last bucket.
现在,让我们从此表达式中提取单个列 - 最后一个存储桶中的最低顺序列。
The choice of lowest-order column diverges from "traditional GSW decryption", where we extract the highest-order column, but remember: because of our bucket-wise shifting trick, by this point the lowest-order column contains information that was grabbed from the highest-order columns representing the values that we care most about (the message).
最低阶列的选择与“传统 GSW 解密”不同,在“传统 GSW 解密”中,我们提取最高阶列,但请记住:由于我们的桶式移位技巧,此时最低阶列包含从代表我们最关心的值(消息)的最高阶列中获取的信息。
We constrain \(s\) so that its last value (which we'll denote \(s_{last}\) ) equals -1.
我们限制 \(s\) 使其最后一个值(我们将其表示为 \(s_{last}\) )等于 -1。
Also, notice that the column of \(G\) we chose, \(g\) , is just a bunch of zeroes followed by a 1.
另外,请注意,我们选择的 \(G\) 列 \(g\) 只是一堆零,后面跟着一个 1。
Hence, we get a nicely simplified expression:
因此,我们得到一个非常简化的表达式:
Now, our task is to compute \(s * b_i\) so we can remove it.
现在,我们的任务是计算 \(s * b_i\),以便我们可以删除它。
Let us pull in one fact from a later section: the evaluator has "access" to \(s\) in the form of an encoded sample \(ct = (m \otimes s) P_L + e_L\) , where \(m\) is the full input to the obfuscated computation and \(\otimes\) is the "tensor product".
让我们从后面的部分中引入一个事实:评估器可以以编码样本的形式“访问”\(s\) \(ct = (m \otimes s) P_L + e_L\) ,其中 \(m\) 是模糊计算的完整输入,而 \(\otimes\) 是“张量积”。
That is, \(m \otimes s\) is a vector of length \(len(m) * len(s)\) that contains \(s\) multiplied by the first value in \(m\) , then right after that \(s\) multiplied by the second value in \(m\) , and so on.
也就是说,\(m \otimes s\) 是长度为 \(len(m) * len(s)\) 的向量,其中包含 \(s\) 乘以 \(m\) 中的第一个值,然后紧接着 \(s\) 乘以 \(m\) 中的第二个值,依此类推。
Conveniently, the first value in \(m\) is fixed to be 1.
为方便起见,\(m\) 中的第一个值固定为 1。
Now, we use the trapdoor machinery, described in the ABE section of the previous post , to make a low-norm preimage \(K_G\) that satisfies:
现在,我们使用上一篇文章的 ABE 部分中描述的陷门机制来制作满足以下条件的低范数原像 \(K_G\):
Here, \(M\) is a matrix that contains all of the \(b_i\) 's - that is, the extracted columns from each \(B_{\{final,i\}}\) matrix - and then is padded with extra zeroes to make the dimensions match up.
这里,\(M\) 是一个包含所有 \(b_i\) 的矩阵 - 即从每个 \(B_{\{final,i\}}\) 矩阵中提取的列 - 然后用额外的零填充以使维度匹配。
Now, notice that only the first \(len(s)\) rows of \(M\) are nonzero, and the first \(len(s)\) values in \(m \otimes s\) are just \(s\) .
现在,请注意,只有 \(M\) 的前 \(len(s)\) 行非零,并且 \(m \otimes s\) 中的前 \(len(s)\) 值只是 \(s\) 。
So the above reduces to:
所以上面的内容简化为:
Which is a concatenation of all of the \(s * b_i + e_{\{i,g\}}\) that we need.
这是我们需要的所有 \(s * b_i + e_{\{i,g\}}\) 的串联。
Now, we can subtract that, and get the \((tY)_i + e_i\) values we need, which are our FHE decryption result.
现在,我们可以减去它,得到我们需要的 \((tY)_i + e_i\) 值,这就是我们的 FHE 解密结果。
And then finally, the evaluator rounds, to get the final value of \(f(x, z)\) .
最后,评估器进行舍入,以获得 \(f(x, z)\) 的最终值。
Here we can once again see where the security comes from: the \(K_G\) "trapdoor" allows the evaluator to extract this only for those specific \(b_i\) , and the \(b_i\) come from \(B_{\{final,i\}}\) , which are bound to the exact shape of the circuit.
在这里,我们可以再次看到安全性的来源:\(K_G\)“活板门”允许评估器仅针对那些特定的\(b_i\)提取安全性,而\(b_i\)来自\(B_{\{final,i\}}\),它们与电路的确切形状绑定。
If the evaluator computes \(s * b'_i + e{\{i,g\}}\) for some different \(b'_i\) , then they would be left with a \(s * (b_i - b'_i)\) term blinding the \((tY)_i + e_i\) , and would not be able to extract the answer.
如果评估者为某些不同的 \(b'_i\) 计算 \(s * b'_i + e{\{i,g\}}\) ,那么他们将留下一个 \(s * (b_i - b'_i)\) 项,使 \((tY)_i + e_i\) 失明,并且无法提取答案。
It turns out the security of the scheme we described above is only provable under one condition: that the outputs \((tY)_i + e_i\) are uniformly random - in fact, jointly pseudorandom across all \(2^L\) inputs.
事实证明,我们上面描述的方案的安全性只能在一种条件下得到证明:输出 \((tY)_i + e_i\) 是均匀随机的 - 事实上,所有 \(2^L\) 输入都是联合伪随机的。
"Jointly pseudorandom" here basically means that if you were given unlimited access to the full exponentially-sized table (though still only polynomial computation time), you would not be able to distinguish it from random data.
这里的“联合伪随机”基本上意味着,如果您可以无限制地访问完整的指数大小的表(尽管仍然只有多项式计算时间),您将无法将其与随机数据区分开来。
This actually makes our work challenging.
这实际上使我们的工作充满挑战。
In a "normal" GSW decryption, the last entry of \(t * Y\) equals \(\frac{q}{2} * m + e\) .
在“正常”GSW 解密中,\(t * Y\) 的最后一项等于 \(\frac{q}{2} * m + e\) 。
This would give us two problems:
这会给我们带来两个问题:
First, we modify the function that we evaluate in FHE.
首先,我们修改在 FHE 中评估的函数。
We make \(z\) contain two secrets \((z_1, z_2)\) : the secret input to the function, and a random PRF key.
我们使 \(z\) 包含两个秘密 \((z_1, z_2)\) :函数的秘密输入和一个随机 PRF 密钥。
Then, we do \(FHE.eval(f', x, E[z])\) , where:
然后,我们执行 \(FHE.eval(f', x, E[z])\) ,其中:
\(f'(x, z) = \frac{q}{2} * f(x, z_1) - (\frac{q}{4} - e_{max}) + H_1(x, z_2)\)
\(f'(x, z) = \frac{q}{2} * f(x, z_1) - (\frac{q}{4} - e_{max}) + H_1(x, z_2)\)
Here, \(H_1\) is a hash function that returns values in \([0 ...
这里,\(H_1\) 是一个哈希函数,返回 \([0 ...
\frac{q}{2}-2e_{max})\) , where \(e_{max}\) is a bound on the largest possible error that our whole procedure could introduce.
\frac{q}{2}-2e_{max})\) ,其中 \(e_{max}\) 是我们整个过程可能引入的最大可能误差的界限。
Formally, \(H_1\) must be a PRF ("pseudorandom function").
形式上,\(H_1\) 必须是 PRF(“伪随机函数”)。
For correctness, it's okay to just think of it as a hash.
为了正确性,可以将其视为散列。
However, in practice, computing this hash is where almost all of the evaluation time lies, and so making diamond iO practical will almost certainly involve heavily optimizing \(H_1\) to target its specific needs, and not using generic algorithms like SHA256.
然而,在实践中,计算这个哈希几乎是所有评估时间的所在,因此,使 Diamond iO 实用化几乎肯定需要大量优化 \(H_1\) 以满足其特定需求,而不是使用 SHA256 等通用算法。
In "normal" GSW, the \(\frac{q}{2}\) factor is implicit - of course you multiply the message by \(\frac{q}{2}\) because otherwise it might get smudged by the error.
在“正常”GSW 中,\(\frac{q}{2}\) 因子是隐式的 - 当然,您将消息乘以 \(\frac{q}{2}\),否则它可能会被错误弄脏。
Here, we multiply the \(f(x, z_1)\) part by \(\frac{q}{2}\) but not the \(H_1(x, z_2)\) part, and we're okay with a few lower-order digits of that getting mangled by the error - the \(H_1(x, z_2)\) is not data we care about recovering, rather it's meant to be "maximum-range" pseudorandom noise that is there to smudge out the FHE and ABE-related noise.
在这里,我们将 \(f(x, z_1)\) 部分乘以 \(\frac{q}{2}\),而不是 \(H_1(x, z_2)\) 部分,并且我们可以接受其中的一些低位数字被错误破坏 - \(H_1(x, z_2)\) 不是我们关心恢复的数据,而是意味着“最大范围”伪随机噪声。消除 FHE 和 ABE 相关噪声。
The goal of the \(\frac{q}{4} - e_{max}\) offset is to "center" the output of \(H_1\) (ie.
\(\frac{q}{4} - e_{max}\) 偏移的目标是将 \(H_1\) 的输出“居中”(即
make its range \([-(\frac{q}{4} - e_{max}), \frac{q}{4} - e_{max}]\) ), so that you can round to the nearest \(\frac{q}{2}\) and then divide to get back \(f(x, z)\) .
使其范围 \([-(\frac{q}{4} - e_{max}), \frac{q}{4} - e_{max}]\) ) ),以便您可以四舍五入到最接近的 \(\frac{q}{2}\) 然后除以得到 \(f(x, z)\) 。
Second, we modify the function again , by xoring a hash into \(f\) itself:
其次,我们再次修改该函数,将哈希值异或到 \(f\) 本身:
\(f'(x, z) = \frac{q}{2} * xor(f(x, z_1), H_2(x)) - (\frac{q}{4} - e_{max}) + H_1(x, z_2)\)
\(f'(x, z) = \frac{q}{2} * xor(f(x, z_1), H_2(x)) - (\frac{q}{4} - e_{max}) + H_1(x, z_2)\)
From \(H_2\) , we want a random oracle property.
从 \(H_2\) 中,我们想要一个随机的预言属性。
But \(H_2\) is not a bottleneck for efficiency, so using generic algorithms like SHA256 is great here.
但 \(H_2\) 并不是效率的瓶颈,因此使用 SHA256 等通用算法在这里非常有用。
To get the final output in the clear, we xor \(H_2(x)\) back out after we get the final \(f'(x, z)\) output from the diamond iO.
为了获得清晰的最终输出,在从钻石 iO 获得最终的 \(f'(x, z)\) 输出后,我们将 \(H_2(x)\) 进行异或运算。
The result of this trickery is that \((tY)_i\) is now fully pseudorandom:
这种欺骗的结果是 \((tY)_i\) 现在完全是伪随机的:
This technique is sometimes called "PROM bootstrap", and it is a generic transformation that converts "obfuscation for pseudorandom functionalities" into a more general form of obfuscation that works for any \(f\) .
这种技术有时被称为“PROM bootstrap”,它是一种通用转换,将“伪随机功能的混淆”转换为适用于任何 \(f\) 的更通用的混淆形式。
Looking at a hash simultaneously as a random oracle and an implementable circuit is also sometimes considered a "sketchy" cryptographic assumption, though it is used widely today, eg.
同时将哈希视为随机预言和可实现的电路有时也被认为是“粗略”的密码学假设,尽管它今天被广泛使用,例如。
in recursive STARKs.
在递归 STARK 中。
Finally, if we want to do "traditional" iO, which hides the function, instead of fixing a public function \(f\) and hiding a private input \(z\) , then we do the trick we already did many times in the more conservative forms of obfuscation: make \(f\) be a "universal circuit" \(VM\) whose private input is a program \(P\) , and that satisfies \(VM(x, P) = P(x)\) .
最后,如果我们想做“传统的”iO,隐藏函数,而不是固定公共函数 \(f\) 并隐藏私有输入 \(z\) ,那么我们就采用我们已经在更保守的混淆形式中多次做过的技巧:使 \(f\) 成为一个“通用电路”\(VM\),其私有输入是程序 \(P\) ,并且满足 \(VM(x, P) = P(x)\) 。
So far, we have just magically assumed that the evaluator gets BGG+ encodings \(s * (B_i - G * m_i) + e_i\) .
到目前为止,我们只是神奇地假设评估器获得 BGG+ 编码 \(s * (B_i - G * m_i) + e_i\) 。
But unfortunately things are not that simple.
但不幸的是事情并没有那么简单。
The obfuscator could construct \(len(m) + L\) such encodings, for \(m_i \in \{0,1\}\) , with the same \(s\) (they would only have to provide both the \(0\) option and the \(1\) option for the \(x\) portion of \(m\) ).
混淆器可以使用相同的 \(s\) 为 \(m_i \in \{0,1\}\) 构造 \(len(m) + L\) 这样的编码(它们只需为 \(m\) 的 \(x\) 部分提供 \(0\) 选项和 \(1\) 选项)。
But this is not secure: if you get two encodings with the same \(B_i\) and the same \(s\) but different \(m_i\) (if we're dealing with binary bits, that means \(0\) and \(1\) ), then you can just subtract them and get \(s * G + (e_1 - e_2)\) , leaking \(s\) in the clear.
但这并不安全:如果你得到两个具有相同 \(B_i\) 和相同 \(s\) 但不同 \(m_i\) 的编码(如果我们处理二进制位,这意味着 \(0\) 和 \(1\) ),那么你只需将它们相减并得到 \(s * G + (e_1 - e_2)\) ,就可以清楚地泄漏 \(s\) 。
So we have to somehow give the evaluator a gadget that lets them produce encodings for any \(m\) , but with a different \(s\) for each \(m\) .
因此,我们必须以某种方式为评估者提供一个小工具,让他们为任何 \(m\) 生成编码,但为每个 \(m\) 生成不同的 \(s\) 。
Even one bit of change in \(m\) should completely change the \(s\) .
即使\(m\) 中的一点变化也应该完全改变\(s\) 。
This is where the core of diamond iO's machinery comes in.
这就是 Diamond iO 机械的核心发挥作用的地方。
The trick is as follows.
技巧如下。
First, remember the structure of \(m\) : \([1, E[z], x, t]\) .
首先,记住 \(m\) 的结构:\([1, E[z], x, t]\) 。
The only thing that changes between different evaluations is \(x\) .
不同评估之间唯一变化的是 \(x\) 。
We will start off with a "base" message, \(m_0 = [1, E[z], 000...000, t]\) , and a "base" secret \(s_0\) .
我们将从“基本”消息 \(m_0 = [1, E[z], 000...000, t]\) 和“基本”秘密 \(s_0\) 开始。
For the i'th bit, we will define matrices \(M_{\{i,0\}}\) and \(M_{\{i,1\}}\) which are the identity matrix, but with the 1 in the slot corresponding to the i'th bit of \(x\) either deleted or moved to the first row.
对于第 i 位,我们将定义矩阵 \(M_{\{i,0\}}\) 和 \(M_{\{i,1\}}\),它们是单位矩阵,但与 \(x\) 第 i 位对应的槽中的 1 要么被删除,要么移到第一行。
That is, \(M_{\{i,b_i\}}\) represents the idea "keep \(m\) as is, except change the i'th bit in \(x\) to \(b_i\) ".
也就是说,\(M_{\{i,b_i\}}\) 表示“保持 \(m\) 不变,除了将 \(x\) 中的第 i 位更改为 \(b_i\)”。
We also define low-norm matrices \(S_{\{i,0\}}\) and \(S_{\{i,1\}}\) , whose goal is to transform the secret.
我们还定义了低范数矩阵 \(S_{\{i,0\}}\) 和 \(S_{\{i,1\}}\) ,其目标是转换秘密。
Hence, any final vector \(m_L\) can be expressed as \(m_0 * M_{\{1,b_1\}} * M_{\{2,b_2\}} * ...
因此,任何最终向量 \(m_L\) 都可以表示为 \(m_0 * M_{\{1,b_1\}} * M_{\{2,b_2\}} * ...
* M_{\{L,b_L\}}\) .
* M_{\{L,b_L\}}\) 。
And the corresponding \(s_0 * S_{{1,b_1}} * S_{{2,b_2}} * ...
以及相应的 \(s_0 * S_{{1,b_1}} * S_{{2,b_2}} * ...
* S_{{L,b_L}}\) gives us a unique secret \(s_L\) .
* S_{{L,b_L}}\) 给我们一个独特的秘密 \(s_L\) 。
Our goal will be to "fuse" these transformations together, so that for each specific \(m_L\) you generate, you get BGG+ encodings constructed with a unique corresponding secret \(s_L\) .
我们的目标是将这些转换“融合”在一起,以便对于您生成的每个特定的 \(m_L\) ,您将获得使用唯一的对应秘密 \(s_L\) 构建的 BGG+ 编码。
We will "fuse" these vectors and matrices by tensoring them together, and then wrapping them in encodings so that they cannot be unpacked.
我们将通过将这些向量和矩阵张量在一起来“融合”它们,然后将它们包装在编码中,以便它们无法被解包。
A mini example - we'll start with tensoring the vectors \(m\) and \(s\) :
一个小例子 - 我们将从张量向量 \(m\) 和 \(s\) 开始:
The leftmost value in \(m\) is constrained to equal \(1\) , and the rightmost value in \(s\) is constrained to equal \(-1\) .
\(m\) 中最左边的值被限制为等于 \(1\) ,而 \(s\) 中最右边的值被限制为等于 \(-1\) 。
And now this is what tensoring matrices looks like (all un-written entries are zeroes):
现在这就是张量矩阵的样子(所有未写入的条目都是零):
See how \(M\) is in the shape we described above, and \(S\) is constrained so that it doesn't touch the last column, keeping the last value of \(s\) at -1.
看看 \(M\) 是如何成为我们上面描述的形状的,并且 \(S\) 受到约束,使其不接触最后一列,从而将 \(s\) 的最后一个值保持为 -1。
A key property of tensoring is that if \(m_1 = m_0 * M_{\{1, b_1\}}\) and \(s_1 = s_0 * S_{\{1, b_1\}}\) , then \((m_1 \otimes s_1) = (m_0 \otimes s_0) * (M_{\{1, b_1\}} \otimes S_{\{1, b_1\}})\) .
张量的一个关键属性是,如果 \(m_1 = m_0 * M_{\{1, b_1\}}\) 和 \(s_1 = s_0 * S_{\{1, b_1\}}\) ,则 \((m_1 \otimes s_1) = (m_0 \otimes s_0) * (M_{\{1, b_1\}} \otimes S_{\{1, b_1\}})\) 。
For convenience, we'll define \(Q_{\{i,b\}}\) as equaling \((M_{\{i, b\}} \otimes S_{\{i, b\}})\)
为了方便起见,我们将 \(Q_{\{i,b\}}\) 定义为等于 \((M_{\{i, b\}} \otimes S_{\{i, b\}})\)
So far, the evaluator's formula is: start with \(q_0 = m_0 \otimes s_0\) , multiply by each \(Q_{\{i, b_i\}} =M_{\{i, b_i\}} \otimes S_{\{i, b_i\}}\) in sequence, and then get \(q_L = m_L \otimes s_L\) at the end.
到目前为止,评估器的公式是:从 \(q_0 = m_0 \otimes s_0\) 开始,依次乘以每个 \(Q_{\{i, b_i\}} =M_{\{i, b_i\}} \otimes S_{\{i, b_i\}}\),最后得到 \(q_L = m_L \otimes s_L\)。
We have already gotten somewhere: we now have a way to generate some kind of encoding of each possible \(m_L\) that the evaluator might need, such that it's bound to a unique \(s_L\) .
我们已经取得了一些进展:我们现在有一种方法可以为评估者可能需要的每个可能的 \(m_L\) 生成某种编码,以便它绑定到唯一的 \(s_L\) 。
The problem: so far, this encoding exposes \(m_L\) (including the \(t\) bits which the evaluator is not meant to know) and \(s_L\) completely in the clear.
问题是:到目前为止,这种编码完全公开了 \(m_L\) (包括评估者不应该知道的 \(t\) 位)和 \(s_L\) 。
The next step will be multiplying in matrices in the right places to "blind" these encodings at each step.
下一步将在正确的位置乘以矩阵,以在每一步“隐藏”这些编码。
The obfuscator will give the evaluator an encoding \(p_0 =q_0 * P_0 + e_0\)
混淆器会给评估器一个编码 \(p_0 =q_0 * P_0 + e_0\)
The obfuscator will then generate low-norm matrices \(K_{\{i,b\}}\) , which satisfy \(P_{i-1} * K_{\{i,b\}} = Q_{\{i,b\}} * P_i + E_{\{i,b\}}\) .
然后混淆器将生成低范数矩阵 \(K_{\{i,b\}}\) ,满足 \(P_{i-1} * K_{\{i,b\}} = Q_{\{i,b\}} * P_i + E_{\{i,b\}}\) 。
This is allowed, again, because of the trapdoor mechanism.
由于活板门机制,这是允许的。
The evaluator can then walk down the exponentially-sized tree of possible encodings.
然后,评估器可以沿着指数大小的可能编码树走下去。
Here's what this tree looks like graphically.
这就是这棵树的图形外观。
Notice that even though the tree is of size \(2^L\) , the number of actually-distinct "edge matrices" that generate this whole tree is only \(2L+1\) , including the final \(K_f\) that we'll get to later).
请注意,即使树的大小为 \(2^L\) ,生成整个树的实际不同的“边缘矩阵”的数量也仅为 \(2L+1\) ,包括我们稍后将介绍的最终 \(K_f\) 。
\(= q_0 * Q_{\{1,b_1\}} * P_1 + e_0 * K_{\{1,b_1\}} + q_0 * E_{\{1,b_1\}}\)
\(= q_0 * Q_{\{1,b_1\}} * P_1 + e_0 * K_{\{1,b_1\}} + q_0 * E_{\{1,b_1\}}\)
\(= q_0 * Q_{\{1,b_1\}} * P_1 * K_{\{2,b_2\}} + e_1 * K_{\{2,b_2\}}\)
\(= q_0 * Q_{\{1,b_1\}} * P_1 * K_{\{2,b_2\}} + e_1 * K_{\{2,b_2\}}\)
\(= q_0 * Q_{\{1,b_1\}} * Q_{\{2,b_2\}} * P_2 + e_1 * K_{\{2,b_2\}} + q_0 * Q_{\{1,b_1\}} * E_{\{2,b_2\}}\)
\(= q_0 * Q_{\{1,b_1\}} * Q_{\{2,b_2\}} * P_2 + e_1 * K_{\{2,b_2\}} + q_0 * Q_{\{1,b_1\}} * E_{\{2,b_2\}}\)
And so on all the way up until \(p_L = q_0 * Q_{\{1,b_1\}} * ...
依此类推,直到 \(p_L = q_0 * Q_{\{1,b_1\}} * ...
* Q_{\{L,b_L\}} * P_L + e_L\) , where \(q_0 * Q_{{1,b_1}} * ...
* Q_{\{L,b_L\}} * P_L + e_L\) ,其中 \(q_0 * Q_{{1,b_1}} * ...
* Q_{{L,b_L}} = q_L\) .
* Q_{{L,b_L}} = q_L\) 。
Notice \(e_{i-1} * K_{\{i,b_i\}}\) and \(q_{i-1} * E_{{i,b_i}}\) both collapse into \(e_i\) .
注意 \(e_{i-1} * K_{\{i,b_i\}}\) 和 \(q_{i-1} * E_{{i,b_i}}\) 都折叠成 \(e_i\) 。
This means that \(K_{\{i,b\}}\) , \(Q_{\{i,b\}}\) and \(q\) (and hence \(m\) , \(s\) , \(M_{\{i,b\}}\) , \(S_{\{i,b\}}\) ) all have to be low-norm (and they are).
这意味着 \(K_{\{i,b\}}\) 、 \(Q_{\{i,b\}}\) 和 \(q\) (因此 \(m\) 、 \(s\) 、 \(M_{\{i,b\}}\) 、 \(S_{\{i,b\}}\) )都必须是低范数(而且它们确实是)。
Now, we have an actually-blinded encoding of \(q_L = m_L \otimes s_L\) .
现在,我们有了 \(q_L = m_L \otimes s_L\) 的实际盲编码。
But it's not quite the right format.
但这不是完全正确的格式。
We have:
我们有:
To cross this bridge, we add another trapdoor \(K_f\) .
为了穿过这座桥,我们添加另一个活板门 \(K_f\) 。
It needs to satisfy:
它需要满足:
Here we just introduced a few pieces of new notation, so let's go through them:
这里我们只是介绍了一些新的符号,所以让我们来看看它们:
Also notice that here (like the \(K_G\) case, unlike the \(K_{\{i,b\}}\) case), there is no error on the right side; that is fine, because the error in the final ciphertexts will come from elsewhere, and the value on the right is a public expression, so there is no security risk to not masking it.
另请注意,这里(与 \(K_G\) 情况相同,与 \(K_{\{i,b\}}\) 情况不同),右侧没有错误;没关系,因为最终密文中的错误将来自其他地方,而右侧的值是公开表达,因此不屏蔽它不存在安全风险。
Now, let's see what happens if we multiply \((m_L \otimes s_L) * P_L + e_L\) by \(K_f\) :
现在,让我们看看如果将 \((m_L \otimes s_L) * P_L + e_L\) 乘以 \(K_f\) 会发生什么:
\(= (m_L \otimes s_L) * u_1 \otimes B_{full} - (m_L \otimes s_L) * (I \otimes G) + e_f\)
\(= (m_L \otimes s_L) * u_1 \otimes B_{full} - (m_L \otimes s_L) * (I \otimes G) + e_f\)
\(= s_L * B_{full} - (m_L \otimes s_L) * (I \otimes G) + e_f\)
\(= s_L * B_{full} - (m_L \otimes s_L) * (I \otimes G) + e_f\)
The last two lines are the most nonobvious.
最后两行是最不明显的。
What's going on is: because \(m_L\) (like all message vectors) starts with 1, the first bucket of \(m_L \otimes s_L\) is just \(s_L\) .
发生的事情是:因为 \(m_L\) (像所有消息向量一样)以 1 开头,所以 \(m_L \otimes s_L\) 的第一个桶只是 \(s_L\) 。
And on the other hand, below the first bucket of rows, \(u_1 \otimes B_{full}\) just equals zero.
另一方面,在第一个行桶下方,\(u_1 \otimes B_{full}\) 恰好等于零。
Hence, \((m_L \otimes s_L) * (u_1 \otimes B_{full})\) just reduces to \(s_L * B_{full}\) .
因此, \((m_L \otimes s_L) * (u_1 \otimes B_{full})\) 只是减少到 \(s_L * B_{full}\) 。
And then the \(I \otimes G\) plays its role as many copies of \(G\) that all get multiplied by many copies of \(s\) , one for each message value in \(m_L\) .
然后 \(I \otimes G\) 发挥其作用,因为 \(G\) 的许多副本都乘以 \(s\) 的许多副本,其中一个对应于 \(m_L\) 中的每个消息值。
(In the paper, they split up \(B_{full}\) into \(B_{att}\) (excluding \(t\) in the inputs) and \(B_t\) , and run the above procedure on those two pieces separately.
(在论文中,他们将 \(B_{full}\) 分成 \(B_{att}\) (不包括输入中的 \(t\) )和 \(B_t\) ,并分别在这两部分上运行上述过程。
This is mathematically equivalent to what was described here.
这在数学上等同于此处描述的内容。
The conceptual reason to separate is that they are different kinds of data - the raw values of \([1, E[z], x]\) are given to the evaluator, but the raw values in \(t\) are not)
分离的概念原因是它们是不同类型的数据 - \([1, E[z], x]\) 的原始值被提供给评估器,但 \(t\) 中的原始值不是)
And the output is literally just the concatenation of all the \(s_L * (B_i - G * m_L[i]) + e_{\{f,i\}}\) BGG+ encodings that we need.
输出实际上只是我们需要的所有 \(s_L * (B_i - G * m_L[i]) + e_{\{f,i\}}\) BGG+ 编码的串联。
The most "controversial" part of this protocol is the mechanism for generating the BGG+ encodings for the input.
该协议最“有争议”的部分是为输入生成 BGG+ 编码的机制。
This relies on two fairly new cryptographic assumptions, called all-product LWE and evasive LWE .
这依赖于两个相当新的密码学假设,称为全产品 LWE 和规避 LWE 。
Evasive LWE was introduced in Wee22 ; all-product LWE is unique to diamond iO.
Evasive LWE 在 Wee22 中引入;全产品 LWE 是 Diamond iO 所独有的。
These LWE assumptions are at the same time plausible, avoiding many pitfalls that we have come to understand from a decade of attempts to create novel LWE assumptions that ended up broken by "zeroizing" attacks, but also novel and risky.
这些 LWE 假设同时是合理的,避免了我们在十年来尝试创建新颖的 LWE 假设时了解到的许多陷阱,这些假设最终被“零化”攻击打破,但也新颖且有风险。
Evasive LWE is non-falsifiable in Naor's sense : formally, it says "for every algorithm that can distinguish X there exists an algorithm that can distinguish Y..." so it's hard to tell if you even have a counterexample.
从 Naor 的意义上来说,Evasive LWE 是不可证伪的:形式上,它说“对于每一个可以区分 X 的算法,都存在一个可以区分 Y 的算法……”,所以很难判断是否有反例。
There are already known classes of situations in which evasive LWE is false; diamond iO deliberately chooses a type of evasive LWE assumption that avoids this.
已知在某些情况下,回避 LWE 是错误的; Diamond iO 故意选择了一种回避 LWE 假设来避免这种情况。
More security analysis is needed to verify that these assumptions are safe.
需要更多的安全分析来验证这些假设是否安全。
Constructing the BGG+ encodings is relatively "easy" (in part because you can actually use a fan-out greater than 2, eg.
构建 BGG+ 编码相对“容易”(部分原因是您实际上可以使用大于 2 的扇出,例如
a fan-out of 256 fills in 8 bits of \(x\) per multiplication).
256 的扇出在每次乘法中填充 8 位 \(x\))。
The hard part is the BGG+ evaluation, which has "ABE * FHE" overhead, where the FHE is itself GSW, which nobody uses in production because it's far less efficient than more mainstream algorithms like BFV.
困难的部分是 BGG+ 评估,它有“ABE * FHE”开销,其中 FHE 本身就是 GSW,没有人在生产中使用它,因为它的效率远低于 BFV 等更主流的算法。
GSW is needed because it has "nice" algebraic properties, including no need for relinearization or key-switching, and the ability to put plaintext into any size bits of the ciphertext.
需要 GSW 是因为它具有“良好”的代数特性,包括不需要重新线性化或密钥切换,以及将明文放入密文的任意大小位的能力。
On top of this, there are other sources of inefficiency and limitation:
除此之外,还有其他低效率和限制的来源:
The main concrete bottleneck is actually computation of \(H_1(x, z)\) inside of the ABE * FHE.
主要的具体瓶颈实际上是 ABE * FHE 内部的 \(H_1(x, z)\) 计算。
The main contributor to cost is depth (as depth increases the dimensions needed to handle the error).
成本的主要贡献者是深度(随着深度的增加,处理错误所需的尺寸也随之增加)。
If the computation itself is deep, there are ways to "refresh" noise for BGG+ encodings, but these methods themselves depend on having a feasible \(H_1\) .
如果计算本身很深,有一些方法可以“刷新”BGG+编码的噪声,但这些方法本身取决于是否有一个可行的 \(H_1\) 。
Hence, depth of \(H_1\) is the concrete bottleneck.
因此,\(H_1\) 的深度是具体的瓶颈。
Diamond iO currently uses a "tree" of Goldreich PRG executions to instantiate \(H_1\) .
Diamond iO 目前使用 Goldreich PRG 执行的“树”来实例化 \(H_1\) 。
This has multiplicative depth 3 per fan-out, and the number of fan-outs required is proportional to the input length.
每个扇出的乘法深度为 3,所需的扇出数量与输入长度成正比。
These reasons are why, in the chart showing different types of obfuscation at the start of this post, diamond iO lands in the "very aggressive" and "planetary" point of the chart.
这些原因就是为什么在本文开头显示不同类型混淆的图表中,diamond iO 落在图表的“非常激进”和“行星”点上。
If we want to improve concrete efficiency of diamond iO, a few possible paths come to mind:
如果我们想提高 Diamond iO 的具体效率,我们会想到以下几种可能的路径:
A key advantage of diamond iO is its friendliness to analysis, because of its simplicity.
Diamond iO 的一个关键优势是由于其简单性而易于分析。
There are no towers of "protocols inside protocols inside protocols" like in more conservative obfuscation variants - the only nesting is the FHE inside of ABE.
没有像更保守的混淆变体那样的“协议内协议内协议”的塔 - 唯一的嵌套是 ABE 内的 FHE。
It can be understood without reference to the entire tower of constructions invented over the past 20 years by cryptographers: you don't need sublinear randomized encodings, functional encryption, garbled circuits, split FHE or even full ABE (we're using the core machinery of BGG+, but the details are sufficiently different that the advantage to someone who already knows how it works is much lower).
无需参考密码学家在过去 20 年发明的整个结构塔即可理解它:您不需要亚线性随机编码、函数加密、乱码电路、分割 FHE 甚至完整的 ABE(我们使用的是 BGG+ 的核心机制,但细节有很大不同,对于已经知道其工作原理的人来说,优势要低得多)。
For these reasons, I hope that diamond iO can get much more attention and analysis on both security and optimization, and we can get to an obfuscation protocol that we can actually run.
出于这些原因,我希望Diamond iO能够在安全性和优化方面得到更多的关注和分析,并且我们能够得到一个可以实际运行的混淆协议。