用程序員聽得懂的方式介紹零知識證明

本來想寫《用人話解釋零知識證明》,但是發現做不到,因為至今我也沒能用人話解釋區塊鏈原理,零知識證明比區塊鏈原理更抽象,網上的資料90%以上是關於這個算法的推導,但是對於90%以上的程序員來說,我們並不關心哈希算法的原理,我們只關心哈希算法怎麼用。 (作為一個10年+老碼農,我也不懂哈希的原理,但我並不慚愧,會用就好)

首先,這是一個非常基礎的函數結構:

如果這個function是一個哈希算法,那麼,輸入任意文件,就可以得到對應的哈希值。假設有這樣的一個情況,某個哈希值我們大家都知道了,想要知道是哪個文件,這個文件在你手上,你很興奮的說,文件找到了,大夥說好啊你把文件拿出來,我們算一下哈希,看能不能對上。這時候你就犯愁了,這是個機密文件,哪能說提供就提供的,咋辦?

這就請來零知識證明,這個算法結構如下:

橙色部分就是zk-proof,分成證明和驗證兩個部分,其中證明部分也叫電路circuit,需要用電路描述語言編程(Rust\C++\Circom),最終編譯為電路邏輯(.wsam\.r1cs)。在這個例子裡,我們用circuit寫了個哈希算法,用來替代原來的function,circuit的特點是輸入是不需要公開的,輸出的是哈希值和proof,這個proof證明的就是:

有一個未知input,經過circuit的運算,生成了output

有一個未知input,經過circuit的運算,生成了output

有一個未知input,經過circuit的運算,生成了output

重要的事情說三遍!並且我還要畫出來:

這個proof就相當於對這個過程的認證蓋章,就這麼板上釘釘了,無爭議了,別問input是啥,問就是不知道,所以叫零知識。已知的是啥呢,電路邏輯(這部分理應開源),輸出的值,還有證明文件proof。

在這個例子中,電路邏輯相當於哈希函數,如果你算出的哈希值和公開的那個哈希值一樣,那就說明你輸入的文件就是大家要找的那個機密文件,而你並不需要提供這個文件,只需要提供證明文件proof就行。

驗證的時候,大家把哈希值和proof放進verify函數,返回true,那就證明了:

你用某個文件,經過circuit的哈希算法,生成了這個哈希值

那還能是哪個文件,那肯定是那個正確的文件啊,要不怎么生成這個哈希!

混幣

zk-proof顯而易見在隱私場景很有用。混幣的原理是用戶把幣存進保險箱,保險箱的密碼的哈希值帖在保險箱上,誰要是能提供這個密碼,誰就能把保險箱裡的幣全部拿走。跟上面這個找文件的原理是一樣的,用戶不用提供密碼,只要提供proof就行,合約校驗通過就讓你提幣。

還有一個問題,如果你能開某個保險箱,那就說明你就是放錢進去的人,誰放了多少錢到哪個保險箱,這在鏈上是可查的,所以你開哪個保險箱,你不能說。在合約裡用樹形結構來存放保險箱,且層數固定,一般為16層。從你要開的保險箱到樹根root,中間的15個節點確定了,就確定了你要開哪個保險箱,所以這15個節點(路徑),也在circuit的private input裡面。

最後合約校驗的時候,證明了保險箱的位置、保險箱密碼全部正確,但不知道是什麼密碼也不知道是哪個保險箱,可能用戶也不知道,但是用戶把proof保管好就行,誰拿這個proof都可以去提款。

擴容

zk-proof除了隱私場景的應用,這兩年還發現可以做區塊鏈擴容。區塊裡的每一個tx,都有用戶的簽名,用來證明這個(轉賬)操作不是偽造的,一個區塊的大小是有限的(固定的),所以要是能在區塊中塞入的tx越多,TPS也就越高。

如果把簽名砍掉,給tx瘦身,那就可以塞入更多的tx。問題是,砍掉了簽名,又如何證明這個操作是用戶簽名過的呢?用零知識證明,把用戶簽名的校驗邏輯寫進circuit電路,輸入是(包括簽名的)區塊數據,輸出是(不包含簽名的)區塊數據,並附上proof,一個proof這就能證明所有tx都是被用戶簽名過的,達到瘦身目的。
本文來源:https://bress.xyz/zh/post/nKtuByYTvPri75xHQoA7f8vNyJ6NQPvCL_YH8KVp31Q

作者:加戈

Total
0
Shares
Related Posts