先來看一張圖:
顯而易見,圖中有無數企鵝。不過,其中藏著一只與企鵝相似的海鸚(如下圖)。
現在的情況是,我知道這個海鸚藏的地方,但是我不想告訴你具體的位置。問題在于:我要怎么做才能在不泄露具體位置的情況下,向你證明我的確知道海鸚的位置呢?一個簡單辦法是,我拿一塊塑料板,上面留個孔,把整張圖放到板子后面,并且讓海鸚對準那個孔。
只要你通過洞往里邊看,你就可以看到海鸚。
回顧一下這個過程,你可以發現:雖然我沒有指出海鸚的具體位置,也沒有給出任何明示或暗示信息,但你能肯定圖中確實有一只海鸚,而且你也相信我知道這個位置。
這就是“零知識證明(zero-knowledge proof)”。
奇怪的定義
零知識證明指的是證明者能夠在不向驗證者提供任何有用信息的情況下,使驗證者相信某個論斷是正確的。其實質是一種涉及兩方或更多方的協議,即兩方或更多方完成一項任務所需采取的一系列步驟。簡言之,零知識證明系統要完成的任務是“證明某一個事實并且不泄露知識”。
官方定義比較拗口,可以再舉個通俗易懂的經典例子加以說明。
假設:現在你的手里有紅綠兩個小球,面對一個有紅綠色盲的朋友,你不能告訴他你兩個球分別是什么顏色,但是你要讓他相信那的確是兩個不同顏色的球。這種情況下,你要怎么做?
方案:先將兩個球分別放在他的兩只手中,并記住最初左右手中球的顏色;讓他將手放背后,隨機決定是否在背后交換手中的球,然后將手中的球展示給你并讓你判斷他是否在背后交換了手中的球。
從結果來說,你通過對比他手中球的顏色就可以直接判斷出他是否在背后換了球。你的朋友知道換球的次數,可以證明你的判斷正確與否。同時為了排除偶然性,可以進行反復多次試驗,只要你的判斷每次都是正確的,基本就可以說明這兩個球的確是不同色的。
在證明的整個過程中,你(證明者)并沒有向他(驗證者)透露任何有關球的顏色的具體信息,他也無法自行判斷球的顏色,因此在這個過程中并沒有傳遞任何關于被證明消息的有用的信息,同時他也確實相信了“兩個球是不同色”的論斷。
零知識證明的研究最早始于1985年,由MIT教授 Shafi Goldwasser,Silvio Micali 和密碼學大師Charles Rackoff在《The Knowledge Complexity of Interactive Proof-Systems》論文中提出。這篇文章提出了“零知識證明”這一概念,并逐步成為了現代密碼學理論的根基之一。
一個正常工作的零知識證明系統必須包含三個屬性:
- 完備性(completeness):在證明者與驗證者都是誠實的情況下,證明過程符合規則并且正確,那么這個證明一定是成功的,證明者最終會說服驗證者。
- 可靠性(Soundness):只有證明者能夠做出證明,且證明者只能說服驗證者該陳述是否屬實,證明者沒有辦法通過欺詐的手段讓驗證者相信他。
- 零知識性(Zero-knowledgeness):證明過程執行完之后,驗證者只獲得了“證明者擁有這個知識”這條信息,而沒有獲得關于這個知識本身的信息。
應用:從象牙塔走到區塊鏈
最初關于零知識證明的研究基本只在學術界進行,研究人員把主要精力都放在塊加密、流加密和公鑰體系的密碼學研究上。但隨著互聯網尤其移動互聯網的發展,大量涉及隱私性的信息在聯網設備上存儲、交換和計算,不可避免地造成大量的隱私信息泄露和互聯網詐騙事件盛行。
在隱私安全備受關注的今天,零知識證明有了更大的“用武之地”。比如:
保護隱私數據:購買保險的時候,只想證明自己沒有家族病史,而不想暴露病例的所有信息。不管是哪種信息,都可以把不想暴露的部分換成一個很像隨機數字的零知識證明,在證明數據真實可信的同時也保護了其他隱私。
身份認證:在使用網站時,用戶可以向網站證明他擁有私鑰,或者知道某個只有自己才知道的答案,網站不用知道密鑰,但可以通過零知識證明確認用戶身份,通過去中心化存儲,服務器可以向用戶證明數據被妥善保存下來且不被泄露。
計算壓縮與區塊鏈擴容:在傳統的區塊架構中,同樣的計算被重復多次,比如簽名校驗,交易的合法性校驗,智能合約執行等一些其他的地方,因為有了計算的證明,同一個計算就不需要多次重復了,計算過程可以被零知識技術證明壓縮。
4個主流的零知識證明開發庫推薦
理論上,凡是今天存儲的數據必然都會在未來泄露,泄露的早晚只是一個時間的問題。技術上能做的只是在這個數據泄露上增加一個難度,讓其泄露時缺乏即時性和完整性,降低其利用價值。針對這一方面,設計良好的零知識協議實際是一個比較有前景的方案。推薦4 個主流的零知識證明開發庫,希望對讀者有所幫助。
libsnark:SCIPR Lab開發的zkSNARK方案實現,開發語言為C++,應用于zcash等多個項目。
snarkjs:zkSARNK方案的javascript實現庫。利用snarkjs你可以進行可信設置、生成證據并驗證證據。
bellman:用于開發zk-SNARK電路的Rust庫,它提供電路接口、基礎結構以及一些基本電路實現,例如布爾和數值抽象。
pysnark:用Python開發的zk-snark方案實現,支持Pinocchio協議,支持生成用于以太坊的智能合約用于驗證零知識證據。
參考資料: