神奇的零知識——深入淺出zkSNARKs(一)
zkSNARKs的成功性令人印象深刻,因為你可以在不執行,甚至不知道執行的具體內容是什麼的情況下確定某個計算的結果是否正確 -- 而你唯一知道的資訊就是它正確的完成了。不幸的是,zkSNARKs的大多數解釋在某些時候都只是表面的,而且他們往往會留下一些“神奇的”東西,這表明只有最聰明的人才能理解他們的工作方式和原因。現實情況是,zkSNARKs可以簡化為四種簡單的技術,這篇博文旨在解釋它們。任何能夠理解RSA密碼系統如何工作的人,也應該對當前使用的zkSNARKs有很好的理解。讓我們拭目以待!
作為一個非常簡短的總結,當前使用的zkSNARKs有4個主要成分(不用擔心,我們將在後面的章節中解釋所有術語):
A)編碼為多項式問題
將需要檢查的程式被編譯成多項式的二次方程:t(x)h(x)= w(x)v(x),其中當且僅當程式被正確計算時,等式成立。證明者想要說服驗證者這個等式成立。
B)簡單隨機抽樣
驗證者會選擇一個私密評估點 s 來將多項式乘法和驗證多項式函式相等的問題簡化成簡單乘法和驗證等式 t(s)h(s) = w(s)v(s) 的問題。
這極大地減少了證明大小和驗證時間。
C)同態編碼/加密
使用具有一些同態屬性的編碼/加密函式E(但不是完全同態的,這是不可行的)。這允許證明者在不知道s的情況下計算E(t(s)),E(h(s)),E(w(s)),E(v(s)),她只知道E(s)和一些其他有用的加密值。
D)零知識
證明者通過乘以一個數字來置換值E(t(s)),E(h(s)),E(w(s)),E(v(s)),以便驗證者再不知道實際的編碼值仍然可以檢查它們的正確性結構。
有一個粗糙的想法是這樣的,因為校驗 t(s)h(s) = w(s)v(s) 和校驗 t(s)h(s) k = w(s)v(s) k(對於一個不等於 0 的私密的隨機數 k 來說)幾乎是完全一樣的,而不同的地方在於如果你只接收到了 (t(s)h(s) k) 和 (w(s)v(s) k) 那麼從中獲取到 t(s)h(s) 或者 w(s)v(s) 的值就幾乎是不可能了。
這只是表面的部分,這樣你就可以理解zkSNARKs的本質,現在我們深入瞭解細節。
RSA和零知識證明
讓我們首先快速回想一下RSA如何工作,省略一些瑣碎的細節。請記住,我們經常使用一個數字對一些數字取模,而並不是所有的整數。這裡的等式“a +b≡c(mod n)”,等價於“(a + b)%n = c%n”。注意,“(mod n)”部分不適用於右側“c”,但實際上適用於“≡”和所有其他“≡”上面。這使得它很難閱讀,但我保證會謹慎使用它。現在回到RSA:
證明者提出以下數字:
p,q:兩個隨機的私密素數n := p qd:1 < d < n – 1 的隨機數e:d e ≡ 1 (mod (p-1)(q-1))
公鑰是 (e, n),私鑰是 d。素數 p 和 q 可以丟棄,但是不能暴露。
訊息m通過下面公式加密
E(m):= me %n
並且c = E(m)通過解密
D(c):= cd %n。
因為cd ≡(me %N)d ≡med (mod n),m的指數就是對(P-1)(Q-1)這組數取模,我們得到med ≡m(mod n)。此外,RSA的安全性依賴於這樣的假設:n不能輕易被因式分解,因此d不能從e計算(如果我們知道p和q,這將是容易的)。
RSA 的一個牛逼的特性是同態乘法。通常來講,如果你可以交換兩個操作的順序而不影響計算結果,那麼我們就說這兩個操作是同態的。在同態加密中,這就是你可以對加密資料進行計算的一個屬性。完全同態加密是存在的,但是現在還沒有應用到實際中,它能夠對任何基於加密資料的程式完成計算。在這裡對於 RSA 來說,我們只討論組乘法。更正式地:E(x)E(y)≡xe ye ≡(xy)e ≡E(xy)(mod n),文字描述就是:兩個加密訊息的的乘積等於兩個資訊乘機的加密。
這種同態性已經允許某種零知識的乘法證明:證明者知道一些祕密數字x和y並計算它們的乘積,但只發送加密版本a = E(x),b = E(y)和c = E(xy)到驗證者。驗證者現在檢查(ab)%n≡c%n 是否成立,此時驗證者只知道加密版的乘積以及乘積是否被正確的計算,但是她不知道兩個乘數和真正的乘積。如果你用加法來替代乘法,那就是一個主要操作為新增餘額的區塊鏈方向了。
互動驗證
我們已經對零知識這個概念有了一定的瞭解了,讓我們現在關注zkSNARKs的另一個主要特徵,即簡潔性。正如您稍後將看到的,簡潔性是zkSNARKs中更為顯著的部分,因為由於某種編碼允許有限形式的同態編碼,零知識部分將“免費”給出。
SNARKs 是 succinct non-interactive arguments of knowledge 的縮寫。一般都通用設定之所以叫做互動式協議,是因為這裡有一個證明者和一個驗證者,證明者想要通過交換資訊的方式讓驗證者相信一個表示式(比如 f(x) = y)。一般來說,沒有證明者可以讓驗證者相信一個錯誤的表示式(可靠性),而且對於證明者來說一定存在一個確定的策略讓驗證者相信任何真實的表示式(完整性)。SNARKs 各個部分的的意義如下:
簡潔:與實際計算的長度相比,訊息的大小很小
非互動式:沒有或者只有很少很少的互動。對於 zkSNARKs 來說就是在證明者向驗證者傳送一條資訊之後的過程。此外,SNARKs 還常常擁有叫做『公共驗證者』的屬性,它的意思是在沒有再次互動的情況下任何人都可以驗證,這對於區塊鏈來說是至關重要的。
引數:驗證者僅受到計算限制的證明者的保護。具有足夠計算能力的證明器可以建立關於錯誤語句的證明/引數(注意,如果具有足夠的計算能力,則可以破壞任何公鑰加密)。這也稱為“計算可靠性”,而不是“完美可靠性”。
知識:對於證明者來說在不知道一個叫做證據(witness)(比如一個雜湊函式的原象或者一個確定 Merkle-tree 節點的路徑)的情況下,構造出一組引數和證明是不可能的。
如果你添加了零知識的字首,那麼在互動中你就需要一個性質,即驗證者除了知道表示式的正確與否之外其他一無所知。尤其是驗證者不能知道 見證字串 稍後我們會詳細解釋這是什麼。
舉個例子,讓我們考慮下面的交易驗證計算:當且僅當 σ1 和σ2 是賬戶默克樹s(pre 和 post 狀態)的根雜湊,s 和 r 是傳送者和接收者賬戶, PS 和PR 是默克樹 的證明(當 v 從 s 的餘額中轉移到 r 的餘額的過程中,能夠證明在 中 s 的餘額至少是 v 並且他們的雜湊結果是 而不是 ),這些條件都成立時,f(σ1, σ2, s ,r,v,ps ,pr ,v) 成立。
如果所有輸入都已知,則驗證f的計算相對容易。正因為如此,我們可以將F轉換成一個zkSNARK,其中只有σ 1和σ 2是公開的和(s ,r,v,ps ,pr ,v)是witmess-string。零知識屬性現在會使得驗證者能夠檢查證明方是否知道一些見證,它可以將根雜湊從σ 1轉換至σ 2,而這樣的轉換又不影響正常的交易,但是驗證者卻不知道到底是誰傳送了多少錢給誰。
關於零知識的部分相對正式的定義(仍然缺乏一些細節)就是:存在一個模擬器,它可以生成一些設定欄位,但是卻不知道私密的 證人,它還可以和驗證者互動 -- 但是外部的觀察者卻不能分辨出哪個與驗證者進行的互動,哪個是與證明者進行的互動。
(未完待續)
來源:格密鏈