Zerocash: 數字貨幣領域的暗科技

自從Zcash(一種新興的匿名數字貨幣)由2016年11月正式上線以來,我一直在關注它的進展。起初的動機很單純,只是覺得這項黑科技特別高大上,特別神秘:僅僅通過發送一些信息到公網,就可以實現兩個匿名用戶之間完全隱私的轉賬: 不僅付款人和收款人的身份保密,甚至連交易金額都完全保密!這種完全匿名究竟是怎麼實現的?

Zcash其實可以看作是比特幣的加強隱私版: 我們已經知道比特幣可以實現點對點之間的快速低費用轉賬,而不需要通過銀行或第三方機構(如支付寶,微信等等)。它在比特幣的基礎上, 實現了兩項創新:轉賬金額保密 以及 完全匿名交易。可以這麼說: Zcash是密碼學領域的兩項黑科技 -- 區塊鏈(blockchain)技術和簡短零知識證明(zk-SNARK)的一次聯姻。

Zcash的實現有兩種方式:可以完全開闢一個新區塊鏈,也可以依附在比特幣的區塊鏈上。下面介紹的是第二種實現方式。依附在比特幣上有一個好處: 允許用戶在ZEC (Zcash的貨幣單位) 和比特幣之間自由轉換。

Zcash的兩種交易: Mint (鑄幣)和 Pour (轉賬)。

鑄幣交易(Mint )

先來看鑄幣的功能:假設我有v單位的比特幣,如何轉換成ZEC呢?

我們先來回憶一個標準的比特幣交易內容:

A: 我要轉賬 y 比特幣給B, z 比特幣給C, 我的 x = y +z 比特幣來源於早前的 block K 交易 T。

這裡假設的情形是: 作為一個用戶A, 我需要向兩個用戶B,C轉賬。

最重要的步驟是, 我需要通過一個身份驗證, 來證明我確實擁有block K 交易 T 的比特幣的所有權。比特幣里是這樣實現所有權驗證的: 假設在上個月 block K的交易T中, 用戶D轉給了我 x 比特幣。為了保證只有我可以動用這筆金額,D會在交易內容中加入一個數字簽名驗證函數,確保只有我可以通過這個驗證。

然後我需要提供 B,C 的地址。當然這裡提到的地址不是B,C的家庭住址,而是他們的公鑰。 同時,我還需要確定轉賬金額。 在最後一步, 我要對整個交易內容進行數字簽名。現在交易(在我的電腦上是一個字元串)已經生成成功,可以發送到比特幣公網上去了!回憶結束~~~~

Zcash上的鑄幣交易可以採取如下的形式: 我們假設用戶A需要把面值為v的比特幣轉化成ZEC。A會首先隨機生成三個字元串 r, s, 
ho,然後使用一個commitment scheme來計算兩個字元串 cm 和 sn,細節如下圖。

(圖片來自Zerocash: Decentralized Anonymous Payments from Bitcoin)

所以ZEC幣是完全數字化的,一枚幣只不過是一個向量 (a_{pk}, v, r, s, 
ho, cm, sn)。其中 v 是這枚ZEC的面值,而cm, sn是用於記錄ZEC幣的生成和消費歷史的,在下面我們還會再次回到這兩個重要的數值。

然後 A 在比特幣的公網上公開如下的交易內容:

A: 我需要用v比特幣來鑄造金額為v的ZEC, 我的commitment是cm, 我的v比特幣來源於比特幣賬本上的第K個block的第T個交易。

注意:這裡A僅僅公開了自己的cm和v, 而ZEC的其他信息只有A自己才知道。

Pour交易

Okay! 現在我們已經成功地鑄造了一枚ZEC。然而新的問題也隨之而來:怎麼花掉它呢!?!?這就要轉到Pour交易了。Pour是Zcash的核心創新, 可以說他是Zcash和比特幣的本質區別。Pour的基本功能是:摧毀一個ZEC, 創造兩個新ZEC, 滿足金額守恆條件

兩個新ZEC的面值之和 = 輸入的ZEC的面值。

這兩個新ZEC幣可以被匿名收款人接收,而且(!)在交易中的所有數額都對公網保密。

那麼Pour是如何實現的呢? 我們用一個實際生活中的情況來舉例說明。還記得在Mint中我得到了一個面值為 v的ZEC嗎?假設我到SF市參加密碼學會議,在一個當地的支持ZEC的咖啡館買了一杯咖啡:假設咖啡的價格為y ZEC, 那麼我需要在交易中付給咖啡店 y , 並且付給自己 v - y (找回的錢)。從我原有的ZEC開始:

{f c} = (a_{pk}, v, r, s, 
ho, cm, sn)

首先我需要向咖啡店小哥問到他們的地址b_{pk},然後我用和鑄幣相似的手段,生成兩個新幣

{f c_1} = (b_{pk}, y , 
ho_1, r_1,s_1, cm_1)

(這個幣將會轉給咖啡店)

{f c_2} = (a_{pk}, v- y, 
ho_2, r_2, s_2, cm_2)

(這個幣找給自己)。

雖然這兩個新幣和{f c}看起來十分相似,但它們之間有著本質區別的~~

這個區別在於對幣{f c_1}{f c_2}, 序列號sn不見了! 我們實際上來到了理解Pour交易的第一個關鍵點:先回憶一下這個「序列號」是怎麼計算出來的:

sn = PRF(a_{sk}, 
ho)

(這裡PRF是一個給定的偽隨機函數)。現在我們就能看出來,要計算這個序列號,需要兩項

信息:第一項是ZEC生成的時候選取的隨機數 
ho , 第二項是收款人的地址密鑰。由於Zcash的設計,在使用任何一枚幣的時候是需要出示序列號的。 所以除了收款人本人以外,任何人都無法出示正確的序列號,也就無法使用!

那麼細心的各位肯定要問了:收款人雖然有密鑰a_{sk} , 但是 
ho 在付款人手中啊,這樣豈不是誰都花不了這筆錢?確實是這樣。所以付款人還要把 
ho 用一種可靠的途徑發給收款人。這個發送的方式就多種多樣了:可以在用加密的電子郵件傳送,或者可以面對面傳遞小紙條,...

然後我將如下交易信息發送到公網上: TX_{pour} = (sn, cm_1, cm_2, pi). 這裡注意:我需要向所有人出示自己的序列號sn(證明我確實是幣{f c}的所有人), 以及生成兩個新幣的Commitments。那麼最後的這個pi是什麼呢?它是一個確保我在整個交易過程中的計算誠實可靠的 --- 零知識證明。 關於這個零知識證明是什麼?它又怎麼樣確保我沒有在交易中作弊(比如確保我有足夠多的錢來完成這筆交易, i.e., v geq y) ? 請期待下回分解~

(題圖來自 Zcash blog )


推薦閱讀:

移動充值卡的密碼是怎麼編碼的,理論上我亂輸能否猜中?
破解一個加密 zip 文件要多久?
求教知乎大神破解密碼?
CSDN 密碼泄漏事件會對 CSDN 和國內互聯網造成怎樣的後果?
向男神表白「你願意跟我在一起嗎?」收到了回復:Y65RFBJI87這是什麼意思?A、同意  B、拒絕

TAG:密码 | 比特币Bitcoin | 区块链Blockchain |