輕鬆了解 zk-SNARK — 第一篇
前段時間受到烏俄戰爭影響,不少隱私幣例如 ZCash, Monero都漲了一波,可能有人會有疑問,虛擬貨幣不是本身就已經有匿名性了嗎?為什麼還會需要隱私幣?
原因是…
匿名的只是你本人,錢包地址還是可以被追蹤到
如果今天我是一個大戶,我可能會面臨到:
- 鏈上資料監控
在區塊鏈上,雖然顯示的只是我的錢包地址,看似讓我匿名了,但別人可以透過監控鏈上狀態來確認我做了什麼交易,甚至提前狙擊我。
換句話說,我收了多少錢、做了什麼交易都是透明的,差別在身份從我的真名變成錢包地址而已。 - 提現問題
要將虛擬貨幣兌現,可能會轉到中心化交易所或是跟別人面交,中心化交易所通常都要KYC;而面交就會直接暴露這個錢包地址背後的臉長什麼樣,身份暴露的風險極高。
有沒有什麼辦法可以讓我不被追蹤?
零知識證明(Zero Knowledge Proof)可以!至於它具體是什麼,正文會再說明。
我們常常聽到的隱私幣、混幣器也是因為有這些匿名需求而被開發出來的,今天這篇文章會講解其中的 zk-SNARK 的技術以及 ZCash的運作原理,以後有機會再介紹混幣器!
先聲明一下,V神曾說過看不懂 zk-SNARK 也不要懷疑自己的智商,因為它非常難,在這邊提醒各位水深請注意安全!
零知識證明
如上述所說,雖然區塊鏈包含匿名性這個特點,但它並不算真正的隱匿,好在世界上的聰明人真的很多,零知識證明可以用來解決這項問題。
其實零知識證明的出現在1985年,更早於區塊鏈,只是區塊鏈讓零知識證明發揚光大了。
首先我們來看看零知識證明想做到的事:
不透露一件事情的任何訊息為前提,證明這件事是正確的。
這整件事聽起來很弔詭,你怎麼可能不告訴我任何資訊,就向我證明某件事是對的?我完全不問就傻傻相信了,到時候被誆怎麼辦?
最常被舉出的例子 — 阿里巴巴的零知識山洞
在上圖中,Alice是 prover、Bob是 verifier,Alice要在不告訴 Bob門鎖密碼的前提下,向 Bob證明自己知道門鎖密碼。
證明過程是這樣的:
- Alice不可以直接跟 Bob説密碼是多少
- Alice先從 A或是 B進去洞穴中
- Bob不可以看 Alice從哪進洞穴,因此不知道Alice從 A還是 B進去,但他可以要求 Alice從 A或 B出來,出來的時候可以看。
如何確定 Alice知道密碼?
- 如果 Alice不知道門鎖密碼,那她通過一次測試的機率只有50%
- 連續通過十次的機率將不足千分之一
- 如果次數拉到一百次呢?
- 其實還是有可能在不知道門鎖密碼的情況下通過,但機率非常非常小
零知識證明如何應用在區塊鏈上的
在虛擬貨幣傳輸中,prover在不告訴 verifier付款人、收款人、金額的前提下,向 verifier證明這筆交易是沒問題的。
也就是說,你不必知道我的錢從哪來、要轉給誰、要轉多少,反正我可以證明我真的擁有消費這筆錢的能力。
現在我們來聊聊 zk-SNARK吧!
zk-SNARK 跟零知識證明的關聯是什麼?
zk-SNARK 全名是 Zero Knowledge Succinct Non-interactive Argument of Knowledge,讓我們拆解一下
- Zero Knowledger: 零知識。
證明過程中不透露相關情報 - Succinct: 簡潔的。
驗證過程不會將繁瑣的數據傳輸且驗證算法是簡單的 - Non-interactive: 無交互的。
上例中的prover與verifier需經過多次互動才能得出結果,zk-SNARK 將改善此缺點。 - Argument of Knowledge: 知識證明。
這是整個證明的主體,是我們最後想得出的內容,做了種種計算就是為了得出這個結果。
簡單來說 zk-SNARK 這技術就是簡潔的、無交互的、你知道我是對的就好了的技術。
ZCash介紹
在講解 ZCash前讓我們複習一下 Bitcoin 是如何運作的,因為兩者間的概念差不多。
比特幣的UTXO(Unspent Transaction Output)
- 一個比特幣交易接受數個輸入(Transaction Input, TI),同時產生數個輸出(Transaction Output, TO)。
- TI, TO是相對特定交易而言的。
因為一個交易的TO可能是另一個交易的TI,換句話說就是一個將收到的錢再花出去的過程。
在還沒花出去前,這些錢是Unspent的狀態,尚未成為下一筆交易的TI的TO稱為UTXO(Unspent Transaction Output),此為比特幣交易的基本單位。 - 交易付款方需證明自己有權使用此UTXO。
如何證明?要提供私鑰進行驗證,因為每個TO都會指定收款人的公鑰來保證只有收款人可以繼續消費此TO。若不太了解公鑰、私鑰的觀念應該算是走錯棚了,可以先去補一下非對稱式加密(Asymmetric Encryption)。
ZCash運作原理
ZCash的交易模型基本上與比特幣相同,但是其中的 UTXO被 note所代替,note為 ZCash的基本交易單位。一個交易的輸入和輸出都是數個 note,我們後面將以 note=(PK, v, r)來表示 note,PK為公鑰(Public Key)、v是金額(Value)、r是序列號(Random Serial Number)。
ZCash的節點會包含兩個集合,每個集合都包含:
- Note Commitment (簽發通知)
交易的輸出,表示一張新的 note被發出,一張有效的 commitment即為一張note的存在證明,此 commitment為 hash(note),因此可以確保他人不知道所有者、金額。 - Nullifier Commitment (廢止通知)
交易的輸入,表示要將一張 note花掉了,一個 nullifier對應唯一的commitment,為了要知道是哪個 commitment,nullifier為 hash(r)。現在大家應該知道為什麼需要序列號了吧!
透過 commitment與 nullifier,交易的雙方從路人皆知變成雙方的心照不宣。
ZCash實例
此為 Zcash網站上的一個例子,從比較 high level的角度講解他們的屏蔽交易 (Shielding Transaction)。
首先,Alice 想向 Bob發送 ZEC(ZCash所發的代幣), Alice可以控制 PK1(她的公鑰)而 Bob可以控制 PK2(他的公鑰)。與比特幣相比,Zcash的一個不同之處在於 Alice生成一個零知識證明來證明她有權使用 Note1。
過程如下:
- Alice隨機選擇一個序列號 (r) 並定義一個新的 Note4。
- 她將 Note4 發送給 Bob。
- Alice 通過將 Nullifier發送到所有節點來使 Note1無效。
- Alice 將新 Note4的 hash發送給所有節點
- Alice 發布一個證明(proof-string)告訴節點,Note1的 Hash存在於 Hash集合中,sk1是 PK1的私鑰,而 hash(r) 是 Note1的 Nullifier。
為了發送 ZEC,通過組合交易的輸入和輸出的描述來創建交易。
交易的輸入如下,消費掉前一筆 note:
- cv: 提交輸入的值。cv為 commit value
- anchor: commitment tree 的 merkle tree root。此處先不解釋
- note — rk(步驟 1–2)。
- nullifier — 銷毀(步驟 3),此步驟防止雙重消費。
- zkproof — 證明(步驟 5)。
- sendAuthSig — 授權支出。
交易的輸出如下,創建一個新的 note。
- cv-value 提交輸出的值。
- anchor — 輸出前一個塊的 Sapling tree狀態。Sapling tree的概念有興趣可以去查查,有點像區塊鏈。
- cm — 提交。cm為 note commitment縮寫。
- outCiphertext — 允許公私鑰都有的持有者打開 note。
- zkproof — — 證明。
這就是ZCash的交易流程啦,原本想把 zk-SNARK的流程也寫進去,但這篇已經太長了,留到下一篇吧。
追蹤以獲得更新通知,歡迎隨時聯繫我
Email: gregshen0925@gmail
Telegram: @gregshen0925