GregShen
GregShen

Blockchain Developer 走偏的統計仔 趁著服役期間寫寫文章

輕鬆了解 zk-SNARK — 第一篇

零知識證明簡介與ZCash如何運作
zkSNARKs

前段時間受到烏俄戰爭影響,不少隱私幣例如 ZCash, Monero都漲了一波,可能有人會有疑問,虛擬貨幣不是本身就已經有匿名性了嗎?為什麼還會需要隱私幣?

原因是…

匿名的只是你本人,錢包地址還是可以被追蹤到

如果今天我是一個大戶,我可能會面臨到:

  1. 鏈上資料監控
    在區塊鏈上,雖然顯示的只是我的錢包地址,看似讓我匿名了,但別人可以透過監控鏈上狀態來確認我做了什麼交易,甚至提前狙擊我。
    換句話說,我收了多少錢、做了什麼交易都是透明的,差別在身份從我的真名變成錢包地址而已。
  2. 提現問題
    要將虛擬貨幣兌現,可能會轉到中心化交易所或是跟別人面交,中心化交易所通常都要KYC;而面交就會直接暴露這個錢包地址背後的臉長什麼樣,身份暴露的風險極高。

有沒有什麼辦法可以讓我不被追蹤?

零知識證明(Zero Knowledge Proof)可以!至於它具體是什麼,正文會再說明。

我們常常聽到的隱私幣、混幣器也是因為有這些匿名需求而被開發出來的,今天這篇文章會講解其中的 zk-SNARK 的技術以及 ZCash的運作原理,以後有機會再介紹混幣器!

先聲明一下,V神曾說過看不懂 zk-SNARK 也不要懷疑自己的智商,因為它非常難,在這邊提醒各位水深請注意安全!

零知識證明

如上述所說,雖然區塊鏈包含匿名性這個特點,但它並不算真正的隱匿,好在世界上的聰明人真的很多,零知識證明可以用來解決這項問題。

其實零知識證明的出現在1985年,更早於區塊鏈,只是區塊鏈讓零知識證明發揚光大了。

首先我們來看看零知識證明想做到的事:

不透露一件事情的任何訊息為前提,證明這件事是正確的。

這整件事聽起來很弔詭,你怎麼可能不告訴我任何資訊,就向我證明某件事是對的?我完全不問就傻傻相信了,到時候被誆怎麼辦?

最常被舉出的例子 — 阿里巴巴的零知識山洞


圖取字Chainlink官方網站

在上圖中,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,讓我們拆解一下

  1. Zero Knowledger: 零知識。
    證明過程中不透露相關情報
  2. Succinct: 簡潔的。
    驗證過程不會將繁瑣的數據傳輸且驗證算法是簡單的
  3. Non-interactive: 無交互的。
    上例中的prover與verifier需經過多次互動才能得出結果,zk-SNARK 將改善此缺點。
  4. Argument of Knowledge: 知識證明。
    這是整個證明的主體,是我們最後想得出的內容,做了種種計算就是為了得出這個結果。

簡單來說 zk-SNARK 這技術就是簡潔的、無交互的、你知道我是對的就好了的技術。

圖取自網路

ZCash介紹

在講解 ZCash前讓我們複習一下 Bitcoin 是如何運作的,因為兩者間的概念差不多。

比特幣的UTXO(Unspent Transaction Output)


UTXO就是進進出出
  1. 一個比特幣交易接受數個輸入(Transaction Input, TI),同時產生數個輸出(Transaction Output, TO)。
  2. TI, TO是相對特定交易而言的。
    因為一個交易的TO可能是另一個交易的TI,換句話說就是一個將收到的錢再花出去的過程。
    在還沒花出去前,這些錢是Unspent的狀態,尚未成為下一筆交易的TI的TO稱為UTXO(Unspent Transaction Output),此為比特幣交易的基本單位。
  3. 交易付款方需證明自己有權使用此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的節點會包含兩個集合,每個集合都包含:

  1. Note Commitment (簽發通知)
    交易的輸出,表示一張新的 note被發出,一張有效的 commitment即為一張note的存在證明,此 commitment為 hash(note),因此可以確保他人不知道所有者、金額。
  2. 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。

過程如下:

  1. Alice隨機選擇一個序列號 (r) 並定義一個新的 Note4。
  2. 她將 Note4 發送給 Bob。
  3. Alice 通過將 Nullifier發送到所有節點來使 Note1無效。
  4. Alice 將新 Note4的 hash發送給所有節點
  5. 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
CC BY-NC-ND 2.0 版权声明

喜欢我的文章吗?
别忘了给点支持与赞赏,让我知道创作的路上有你陪伴。

加载中…
加载中…

发布评论