CKKS Part4: CKKS的乘法和重線性化

PamShao發表於2022-02-06

本文翻譯於CKKS EXPLAINED, PART 4: MULTIPLICATION AND RELINEARIZATION,主要介紹CKKS方案中的密文乘法和重線性化技術

介紹

在上一篇 CKKS Part3: CKKS的加密和解密 ,我們看到了如何基於RLWE問題建立同態加密方案,實現同態加法和密文明文乘法。

雖然執行密文-明文乘法很容易,但正如我們將看到的,密文-密文要複雜得多。事實上,我們需要處理很多事情才能正確地完成它,比如找到正確的操作,這樣一旦解密,我們就可以得到兩個密文的乘積,以及管理密文的大小。

因此,本文將介紹密文乘法和重新線性化的概念,以減少生成的密文的大小。

基本概念

為了瞭解我們將如何在CKKS中執行密文-密文乘法,讓我們回顧一下我們在前一篇文章中看到的內容。

首先,記住我們研究的是多項式空間\(R_{q}=\Zeta _{q}\left[ X \right]/\left( X^{N}+1 \right)\)。我們將s作為我們的私鑰,然後我們可以安全地輸出一個公鑰p=(b,a)=(−a. s+e,a),其中a均勻取樣\(R_{q}\)、 e是一個小的隨機多項式。

然後我們有\(\mbox{E}ncrypt\left( u,s \right)=c=\left( c_{0},c_{1} \right)=\left( u,0 \right)+p=\left( b+u,a \right)\in R_{q}^{2}\)是明文\(u \in \Zeta _{q}\left[ X \right]/\left( X^{N}+1 \right)\)使用公鑰p的加密操作。要使用私鑰s解密密文c,我們執行以下操作:$$Decrypt\left( c,s \right)=c_{0}+c_{1}.s=u+e$$

然後我們發現定義一個在密文上的加法運算\(?_{???}(c,c′)\)很容易,所以一旦我們解密\(?_{???}\) 我們將大致得到兩個基本明文的加法。

實現這一點的方法是定義\(?_{???}\) 具體如下:$$\mbox{C}{Add}\left( c,c' \right)=\left( c{0}+c_{0}',c_{1}+c_{1}' \right)=c+c'=c_{add}$$

事實上,如果我們對其應用解密操作,我們會得到:$$Decrypt\left( c_{add},s \right)=c_{0}+c_{0}'+\left( c_{1}+c_{1}' \right).s=c_{0}+c_{1}.s+c_{0}'+c_{1}'.s=Decrypt\left( c,s \right)+Decrypt\left( c',s \right)約等於u+u'$$

這裡我們看到,對密文做加法非常簡單,我們只需要將兩個密文相加,我們可以使用常規的解密操作來解密結果,以獲得兩個對應明文的相加。

我們將看到,在進行密文乘法時,乘法和解密操作都更加複雜。

密文-密文乘法

現在我們看到了這一點,我們看到我們的目標是找到操作\(?_{????},???????????\), 對於兩個密文c,c′我們有:\(DecryptMult\left( \mbox{C}_{Mult}\left( c,c' \right),s \right)=Decrypt\left( c,s \right).Decrypt\left( c',s \right)\),切記\(Decrypt\left( c,s \right)=c_{0}+c_{1}.s\),我們展開上面的式子得到:

\[Decrypt\left( c,s \right).Decrypt\left( c',s \right)=\left( c_{0}+c_{1}.s \right).\left( c_{0}'+c_{1}'.s \right)=c_{0}.c_{0}'+\left( c_{0}.c_{1}'+c_{0}'.c_{1} \right).s+c_{1}.c_{1}'.s^{2}=d_{0}+d_{1}.s+d_{2}.s^{2} \]

其中\(d_{0}=c_{0}.c_{0}',d_{1}=\left( c_{0}.c_{1}'+c_{0}'c_{1} \right),d_{2}=c_{1}.c_{1}'\)

有趣的如果我們仔細想想,計算\(Decrypt\left( c,s \right)=c_{0}+c_{1}.s\),可以看作是關於私鑰s的多項式求值,它是形式為\(c_0+c_1.S\)的一次多項式。S是多項式中的變數。

因此,如果我們看到兩個密文乘積上的解密運算,它可以被看作是多項式$d_0+d_1.S+d_2.S^2,關於S的二次多項式

因此,我們可以使用以下操作來進行密文乘法:

\[\mbox{C}_{Mult}\left( c,c' \right)=c_{mult}=\left( d_{0},d_{1,}d_{2} \right)=\left( c_{0}.c_{0}',c_{0}.c_{1}'+c_{0}'.c_{1},c_{1}.c_{1}' \right) \]

\[DecryptMult\left( c_{mult},s \right)=d_{0}+d_{1}.s+d_{2}.s^{2} \]

使用這樣的操作可能會有效,但有一個問題:密文的大小增加了!事實上,雖然密文通常只是幾個多項式,但這裡有3個多項式用於密文。通過使用與之前相同的推理,如果我們什麼都不做,要正確解密下一個乘積,我們需要5個多項式,然後是9個,依此類推。因此,密文的大小將呈指數增長,如果我們這樣定義密文-密文乘法,它在實踐中將不可用。

我們需要找到一種不增加每一步密文大小的乘法方法。這就是重線性化的用武之地!

重線性化

我們可以把密文之間的乘法定義為運算:\(\mbox{C}_{Mult}\left( c,c' \right)=\left( d_{0},d_{1},d_{2} \right)\),問題是,現在的輸出是一個維數為3的密文,如果我們在每次計算後繼續增加密文的大小,那麼在實踐中使用它將變得不可行。

讓我們想想,問題是什麼?問題是我們需要第三個項\(d_2\),用於多項式解密\(DecryptMult\left( c_{mult},s \right)=d_{0}+d_{1}.s+d_{2}.s^{2}\),但如果我們能找到只有一個1次多項式作為解密去計算\(d_2.s^2\)的方法呢?那麼在這種情況下,密文的大小將是恆定的,它們都將只是用到了兩個多項式!

這就是重新線性化的本質:找到一對多項式\(\left( d_{0}',d_{1}' \right)=\mbox{Re}lin\left( c_{m\mu lt} \right)\),例如:$$Decrypt\left( \left( d_{0}',d_{1}' \right),s \right)=d_{0}'+d_{1}'.s=d_{0}+d_{1}.s+d_{2}.s^{2}=Decrypt\left( c,s \right).Decrypt\left( c',s \right)$$
具體來說,重線性化允許有一對多項式(s的一次方),而不是三對多項式(s的二次方),這樣,解密時就只需要用到s,而不用s的平方,我們就可以得到兩個明文的乘法。

因此,如果我們在每次密文-密文乘法後執行重線性化,我們將始終有相同大小的密文,具有相同的解密電路!

現在你可能想知道我們到底需要如何定義????? 。這個想法很簡單,我們知道我們需要一對多項式,例如:\(d_{0}'+d_{1}'.s=d_{0}+d_{1}.s+d_{2}.s^{2}\),我們的想法是定義\(\left( d_{0}',d_{1}' \right)=\left( d_{0},d_{1} \right)+P\),其中P表示一對多項式,例如\(Decrypt\left( P,s \right)=d_{2}.s^{2}\)

這樣,當我們用$(d′_0,d′_1)計算解密電路時,我們得到:

\[Decrypt\left( \left( d_{0}',d_{1}' \right),s \right)=Decrypt\left( \left( d_{0},d_{1},s \right) \right)+Decrypt\left( P,s \right)=d_{0}+d_{1}.s+d_{2}.s^{2} \]

一種方法是提供一個計算金鑰,用於計算P。使得\(evk=\left( -a_{0}.s+e_{0}+s^{2},a_{0} \right)\),其中\(e_0\)是一個小的隨機多項式,\(a_0\)是一個在\(R_q\)上均勻取樣的多項式,然後我們計算\(Decrypt\left( evk,s \right)=e_{0}+s^{2} 約等於 s^{2}\),太好了!我們可以看到,我們可以公開計算金鑰,因為基於RLWE問題很難提取私鑰,可以用來求s的平方項。

所以為了解密出\(d_{2}.s^{2}\), P可能是\(P=d_{2}.evk=\left( d_{2.}.\left( -a_{0}+e_{0}+s^{2} \right),d_{2}.a_{0} \right)\),的確正如我們所看到的那樣\(Decrypt\left( P,s \right)=d_{2}.s^{2}+d_{2}.e_{0}\),這時我們可能會考慮\(d_{2}.s^{2}+d_{2}.e_{0}約等於d_{2}.s^{2}\)

不幸的是,我們不能這樣做,因為\(d_{2}.e_0\)項比我們通常得到的噪聲要大得多。如果你之前注意到了,我們允許對結果進行近似,因為誤差多項式很小,比如加入一個小多項,它不會對結果產生太大的影響。但問題是\(d_2\)很大,因為\(d_2=c_1.c_1'\),其中,每個\(c_1\)包括一個從\(R_q\)中取樣的多項式a,因此,它比我們通常處理的小誤差多項式要大得多。

那麼,我們在實踐中如何處理這個問題呢?訣竅是稍微修改計算金鑰,並將其定義為\(evk=\left( -a_{0}.s+e_{0}+p.s^{2},a_{0} \right)(mod p.q)\),其中p是一個大整數,\(a_0\)\(R_{q.p}\)中隨機取樣。這裡的想法是,我們將除以p,以去除與\(d_2\)相乘時產生的噪聲,即

\[\frac{Decrypt\left( evk,s \right)}{p}=\; \frac{e_{0}+p.s^{2}}{p}約等於s^{2} \]

,因此最後我們使得:$$P=\left\lfloor p^{-1}.d_{2}.evk \right\rfloor\left( \mbox{mod}\ q \right)$$,這意味著我們將除以p並將其四捨五入到最接近的整數,然後使用模q(而不是p.q)。

\[Decrypt\left( P,s \right)=p^{-1}.d_{2}.e_{0}+d_{2}.s^{2}約等於d_{2}.s^{2} \]

,因為\(p^{-1}.d_2.e_0\)很小,可以約去!
我們終於有了合適的方法了!因此,為了定義重線性化,我們需要一個計算金鑰(可以在沒有風險的情況下公開),我們將其定義為:\(\mbox{Re}lin\left( \left( d_{0},d_{1},d_{2},evk \right) \right)=\left( d_{0},d_{1} \right)+\left\lfloor p^{-1}.d_{2}.evk \right\rfloor\)。可以看到,重線性化後的密文由三維變二維。

因此,如果我們有兩個密文c,c′,並且我們想要將它們相乘(可能幾次),然後解密結果,那麼工作流程將是:
1、相乘:\(c_{m\mu lt}=\mbox{C}_{Mult}\left( c,c' \right)=\left( d_{0},d_{1},d_{2} \right)\)
2、重線性化:\(c_{\mbox{re}lin}=\mbox{Re}lin\left( \left( d_{0},d_{1},d_{2} \right),evk \right)\)
3、解密輸出:\(u_{m\mu lt}=Decrypt\left( c_{m\mu lt},s \right)約等於u.u'\)

我在這裡只給出了總體思路,但如果您有興趣瞭解細節,我建議您閱讀"Somewhat Practical Fully Homomorphic Encryption".一文中的解釋。

現在我們知道了如何將兩個密文相乘,並保持它們的大小不變。太好了!雖然你可能認為這一切都結束了,但我們會看到,要實現同態加密方案,還有最後一步要做:rescaling,重新縮放。在我們自己編寫程式碼之前,我們將在下一篇文章中看到什麼是重縮放,以及如何進行重縮放!

相關文章