網絡上講解零知識證明的文章就不多,這些文章要不太淺顯,要不太深入,很少有能給入門者整體框架上的認識。
比如,阿里巴巴零知識證明就是一個非常好的通俗理解零知識證明的例子:
阿里巴巴被強盜抓住,爲了保命,他需要向強盜證明自己擁有打開石門的密碼,同時又不能把密碼告訴強盜。他想出一個解決辦法,先讓強盜離開自己一箭之地,距離足夠遠讓強盜無法聽到口令,足夠近讓阿里巴巴無法在強盜的弓箭下逃生。阿里巴巴就在這個距離下向強盜展示了石門的打開和關閉。
這個整個過程就是零知識證明,證明者能夠在不向驗證者提供任何有用信息(石門的口令)的情況下,使驗證者相信某個論斷(阿里巴巴知道打開石門的方法)是正確的。
技術人除了通俗的理解零知識證明外,還需要對零知識的理論和推導過程深入理解運用。以太坊的一篇blog,比較適合想深入理解零知識證明的小夥伴。
https://blog.ethereum.org/2016/12/05/zksnarks-in-a-nutshell/
這篇文章也是這篇blog的翻譯和我自己的理解。通過這篇文章,能快速建立零知識證明的邏輯框架。雖然這篇文章有些推導公式,但是相對簡單,小夥伴可以耐心閱讀。
先給出零知識證明的邏輯框架:
0 - 零知識證明的基本概念
零知識證明,zkSNARK,zero-knowledge Succint Non-interactive ARguments of Knowledge的簡稱:
- Succinct:證明的數據量比較小
- Non-interactive:沒有或者只有很少交互。
- ARguments:驗證者只對計算能力有限的證明者有效。擁有足夠計算能力的證明者可以僞造證明。這也叫“計算可靠性"(相對的還有”完美可靠性")。
- of Knowledge:對於證明者來說在不知道證據(Witness,比如一個哈希函數的輸入或者一個確定 Merkle-tree 節點的路徑)的情況下,構造出一組參數和證明是不可能的。
零知識證明大體由四部分組成:
- 多項式問題的轉化 - 需要證明的問題轉化爲多項式問題 t(x)h(x) = w(x)v(x),證明者提交證明讓驗證者確認多項式成立。
- 隨機挑選驗證 - 隨機選擇驗證的數值s,驗證t(s)h(s) = w(s)v(s)。相對於驗證多項式相等t(x)h(x) = w(x)v(x),隨機挑選驗證,簡單,驗證數據少。隨機挑選驗證,安全性肯定不及多項式等式驗證,但如果確實足夠隨機,安全性還是相當高的。
- 同態隱藏 - 同態隱藏指的是函數的一種特性。輸入的計算和輸出的計算保持“同態”。以加法同態爲例,滿足如下的三個條件的函數E(x),稱爲加法同態:1. 給定 E(x),很難推導出x. 2. 不同的輸入,對應不同輸出 3. E(x+y) 可以由 E(x),E(y)計算出來。乘法同態類似。
- 零知識 - 證明者和驗證者之間除了“問題證明與否”知識外,不知道其他任何知識(不知道隨機挑選值,不知道挑選值的多項式計算結果等等)。
在瞭解零知識的基礎概念上,慢慢推導整個零知識證明過程,先從NP問題說起。
1- NP問題以及約化
解決一個問題需要花費時間。如果解決問題需要的時間與問題的規模之間是多項式關係,則可以稱該問題具有多項式複雜度。一般問題可分成兩類:P問題和NP問題。P問題指的是在多項式時間內可解的問題。 NP問題(Non-Deterministic Polynomial Problem,非確定性多項式問題),指不能在多項式內可解,但是可以在多項式時間內驗證的問題。
很顯然,P問題也是NP問題,但是是否NP問題是P問題,NP=P?,目前爲止還沒有人能證明。一般認爲,NP問題不等於P問題,也就是說,NP問題不存在多項式解法。
約化(Reduction),可以理解成問題的轉化。對任意一個程序A的輸入,都能按某種法則變換成程序B的輸入,使兩程序的輸出相同,那麼,可以說,問題A可約化爲問題B。
NPC問題,是一個NP問題,並且,其他所有的NP問題都能歸約到它。簡單的說,NP問題之間可以相互歸約,一個NP問題求解,其他NP問題一樣能求解。
舉例說明,NP問題以及NP問題的歸約。
布爾公式滿足性問題(SAT問題,boolean formula satisfiability) 就是一個NP問題。布爾公式定義如下:
-
假設變量x1, x2, x3, … 是布爾公式
-
假設f是布爾公式,¬f也是布爾公式(取反)
-
假設f和g是布爾公式,f∧g和f∨g也是布爾公式(與和或)
一個布爾公式可滿足,指輸入是0/1的情況下,存在輸出爲真。SAT問題指,找出所有可滿足的布爾公式。SAT問題看上去,除了枚舉一個個可能的布爾公式外,沒有更好的辦法,也就是多項式時間內不可解。如果知道一個可滿足的布爾公式,驗證非常方便(輸入是0/1的情況下,看看輸出是否爲真)。SAT問題是NP問題。
再看看另外一個NP問題:PolyZero問題。PolyZero問題指某個多項式滿足:多項式輸入是0或1的情況下,多項式輸出爲0。
PolyZero(f):=1
f滿足輸入是0/1的情況下,多項式輸出爲0。
一個布爾表達式f可以通過如下的歸約函數r,轉化爲多項式:
- r(xi):=(1−xi)
- r(¬f):=(1−r(f))
- r(f∧g):=(1−(1−r(f))(1−r(g)))
- r(f∨g):=r(f)r(g)
也就是說,一個SAT問題,通過歸約函數r,可以歸約爲一個PolyZero問題:f是可滿足的,當且僅當r(f)輸出爲0。
SAT(f)=PolyZero(r(f))
總結一下,NP問題是在多項式時間內無解,但是可以多項式時間驗證的問題。NP問題可以相互歸約。
2 - QSP問題
需要證明的問題,肯定是NP問題,如果是P問題,不存在問題解的”尋找“,也就不存在證明。簡單的說,zkSNARK問題處理的都是NP問題。既然NP問題相互可以歸約,首先需要確定一個NP問題,其他NP問題都可以歸約到這個NP問題,再進行證明。也就是,證明了一個NP問題,就可以證明所有NP問題。
QSP問題是個NP問題,也特別適合zkSNARK。爲啥特別適合,目前還不需要深究。有相關的論文論證:https://eprint.iacr.org/2012/215.pdf。
QSP問題是這樣一個NP問題:給定一系列的多項式,以及給定一個目標多項式,找出多項式的組合能整除目標多項式。輸入爲n位的QSP問題定義如下:
- 給定多個多項式:v0,...,vm,w0,...,wm
- 目標多項式:t
- 映射函數:f:{(i,j)∣1≤i≤n,j∈0,1}→{1,...m}
給定一個證據(Witness)u,滿足如下條件,即可驗證u是QSP問題的解:
-
ak,bk=1 如果k=f(i,u[i])
-
ak,bk=0 如果k=f(i,1−u[i])
-
vawb能整除 t,其中va=v0+a1v1+...+amvm,wb=w0+b1w1+...+bmwm
對一個證據u,對每一位進行兩次映射計算(u[i]以及1−u[i]),確定多項式之間的係數。因爲針對證據u的每一位,計算兩次,確定多項式之間的係數,如果2n<m,多項式的選擇還是有很大的靈活性。
如果證明者知道QSP問題的解,需要提供證據(也就是u)。驗證者在獲知證據u的情況下,按照上述的規則恢復出多項式的係數,驗證vavb是否能整除t:th=vawb。爲了方便驗證者驗證,證明者可以同時提供h。在多項式維度比較大的情況下,多項式的乘法還是比較複雜的。
有個簡單的想法,與其驗證者驗證整個多項式是否相等,不如隨機挑選數值進行驗證。假設驗證者隨機挑選驗證數值s,驗證者只需要驗證t(s)h(s)=va(s)wb(s)。
以上是基礎知識,下面開始介紹zkSNARK的證明過程。在繼續深入一個QSP問題證明細節之前,先看看一個多項式問題的證明過程。
3 - 多項式問題的證明過程
假設一個多項式f(x)=a0+a1x+a2x2+...+ad−1xd−1+adxd。證明一個多項式,即給定一個輸入x,提供f(x)的證明。
3.1 有線羣論基礎(橢圓曲線)
定一個有限羣,生成元是g,階爲n,則該羣包括如下的元素:g0,g1,g2,...,gn−1。通過有限羣加密的方式很簡單:E(x):=gx。也就是說,得知gx的情況下,不能反推出x。
3.2 選定隨機數
驗證者隨機選擇一個有限羣中的元素,比如s。提供如下的計算結果(s的不同階的加密結果):
E(s0),E(s1),...,E(sd)
在生成這些計算結果後,s就不需要了,可以忘記。
3.3 E(f(s))計算
舉個例子,f(x)=4+2x+4x2,E(f(s))=E(s0)4E(s1)2E(s2)4。顯然,E(f(s)) 可以不知道s 的情況下,通過驗證者提供的數據計算出來。
3.4 α對
注意的是,驗證者是不知道待證明的多項式參數的,即使證明者提供了E(f(s)),驗證者也無法驗證。 α對的方法可以讓驗證者確認證明者是通過多項式計算出結果。 在3.2的基礎上,驗證者還隨機選擇另外一個元素α,並提供額外的計算結果:
E(αs0),E(αs1),...,E(αsd)
證明者需要提供E(f(s))和E(αf(s))。
E(f(s))=E(s0)4E(s1)2E(s2)4
E(αf(s))=E(αs0)4E(αs1)2E(αs2)4
3.5 配對函數
配對函數e,滿足如下定義:
e(gx,gy)=e(g,g)xy
驗證者驗證α對的方式很簡單,檢驗如下的等式是否成立:
e(E(f(s)),gα)=e(E(αf(s)),g)
假設A=e(E(f(s)),B=E(αf(s))推導過程如下:
e(A,gα)=e(E(f(s)),gα)=e(gf(s),gα)=e(g,g)αf(s)
e(B,g)=e(E(αf(s)),g)=e(gαf(s),g)=e(g,g)αf(s)
到此爲止,驗證者提供α對的情況下,證明者可以證明通過某個多項式計算出某個結果,驗證者不知道具體的多項式的參數。
3.6 δ 偏移
更進一步,證明者採用δ 偏移,甚至不想讓驗證者知道E(f(s))。採用δ 偏移,證明者不再提供A和B,而是隨機一個δ參數,提供A′和B′。
A′=E(δ+f(s))=gδ+f(s)=gδgf(s)=E(δ)E(f(s))=E(δ)A
B′=E(α(δ+f(s)))=E(αδ+αf(s))=gαδ+αf(s)=E(α)δE(αf(s))=E(α)δB
很顯然,驗證者從A′無法推導出E(f(s)),但驗證者一樣能驗證α對的配對函數是否成立:
e(A′,gα)=e(E(δ+f(s)),gα)=e(gδ+f(s),gα)=e(g,g)α(δ+f(s))
e(B,g)=e(E(α(δ+f(s)),g)=e(gα(δ+f(s)),g)=e(g,g)α(δ+f(s))
多項式的整個證明過程如下圖所示:
4 - QSP問題的skSNARK證明
skSNARK證明過程分爲兩部分:a) setup階段 b)證明階段。QSP問題就是給定一系列的多項式v0,...,vm,w0,...,wm以及目標多項式t,證明存在一個證據u。這些多項式中的最高階爲d。
4.1 setup和CRS
CRS - Common Reference String,也就是預先setup的公開信息。在選定s和α的情況下,發佈如下信息:
-
s和α的計算結果
E(s0),E(s1),...,E(sd)
E(αs0),E(αs1),...,E(αsd)
-
多項式的α對的計算結果
E(t(s)),E(αt(s))
E(v0(s)),...E(vm(s)),E(αv0(s)),...,E(αvm(s))
E(w0(s)),...E(wm(s)),E(αw0(s)),...,E(αwm(s))
-
多項式的βv,βw,γ 參數的計算結果
E(γ),E(βvγ),E(βwγ)
E(βvv1(s)),...,E(βvvm(s))
E(βww1(s)),...,E(βwwm(s))
E(βvt(s)),E(βwt(s))
4.2 證明者提供證據
在QSP的映射函數中,如果2n<m,1,...,m中有些數字沒有映射到。這些沒有映射到的數字組成Ifree,並定義(k爲未映射到的數字):
vfree(x)=k∑akvk(x)
證明者需提供的證據如下
-
Vfree:=E(vfree(s)), W:=E(w(s)), H:=E(h(s)),
-
Vfree′:=E(αvfree(s)),W′:=E(αw(s)),H′:=E(αh(s)),
-
Y:=E(βvvfree(s)+βww(s))
Vfree/Vfree′,W/W′,H/H′是α對,用以驗證vfree,w,h是否是多項式形式。t是已知,公開的,毋需驗證。Y用來確保vfree(s)和w(s)的計算採用一致的參數。
4.3 驗證者驗證
在QSP的映射函數中,如果2n<m,1,...,m中所有映射到的數字作爲組成係數組成的二項式定義爲(和vfree互補):
vin(x)=k∑akvk(x)
驗證者需要驗證如下的等式是否成立:
-
e(Vfree′,g)=e(Vfree,gα),e(W′,E(1))=e(W,E(α)),e(H′,E(1))=e(H,E(α))
-
e(E(γ),Y)=e(E(βvγ),Vfree)e(E(βwγ),W)
-
e(E(v0(s))E(vin(s))Vfree,E(w0(s))W)=e(H,E(t(s)))
第一個(系列)等式驗證Vfree/Vfree′,W/W′,H/H′是否是α對。
第二個等式驗證Vfree和W的計算採用一致的參數。因爲vfree和w都是二項式,它們的和也同樣是一個多項式,所以採用γ 參數進行確認。證明過程如下:
e(E(γ),Y)=e(E(γ),E(βvvfree(s)+βww(s)))=e(g,g)γ(βvvfree(s)+βww(s))
e(E(βvγ),Vfree)e(E(βwγ),W)=e(E(βvγ),E(vfree(s)))e(E(βwγ),E(w(s)))=e(g,g)(βvγ)vfree(s)e(g,g)(βwγ)w(s)=e(g,g)γ(βvvfree(s)+βww(s))
第三個等式驗證v(s)w(s)=h(s)t(s),其中v0(s)+vin(s)+vfree(s)=v(s)。
簡單的說,邏輯是確認v,w,h是多項式,並且v,w採用同樣的參數,滿足v(s)w(s)=h(s)t(s)。
到目前爲止,整個QSP的zkSNARK的證明過程邏輯已見雛形:
圖2
4.4 δ 偏移
爲了進一步“隱藏” Vfree和W,額外需要採用兩個偏移: δfree和δw。 vfree(s)/w(s)/h(s)進行如下的變形,驗證者用同樣的邏輯驗證。
vfree(s)→vfree(s)+δfreet(s)
w(s)→w(s)+δwt(s)
h(s)→h(s)+δfree(w0(s)+w(s))+δw(v0(s)+vin(s)+vfree(s))+(δfreeδw)t(s)
至此,zkSNARK的推導邏輯就基本完整。使用zkSNARK證明,由如下的幾步組成:
1/ 問題轉化: 一個需要證明的NP問題轉化爲選定的NP問題(比如QSP問題)
2/ 設置參數(setup):設置參數的過程也是挑選隨機數的過程,並提供CRS
3/ 證明者獲取證據u,通過CRS計算證據(proof)
4/ 驗證者驗證證據以及響應的proof
總結:零知識證明由四部分組成:多項式問題的轉化,隨機挑選驗證,同態隱藏以及零知識。需要零知識證明的問題先轉化爲特定的NP問題,挑選隨機數,設置參數,公佈CRS。證明者,在求得證據的情況下,通過CRS計算出證據。驗證者再無需其他知識的情況下可以進行驗證。