原文來源:二級標題
概述
概述
原文來源:
二級標題
在研究區塊鏈系統的工作原理時,我們需要了解各種各樣密碼學知識,比如secp 256 k 1 ,它是一種曲線和非對稱簽名算法,在比特幣和以太坊系統中用於簽名和驗證賬號。比如sha 256 ,它是一種哈希算法,用於把變長信息壓縮成定長編碼。比如base 58 ,它可以把信息編碼轉換成可打印字符表示的字符串。比如ECDH,它是一種Diffie - Hellman 密鑰交換算法,用於在P2P 節點間安全交換通訊密鑰。
二級標題
ZKP 最早在1985 年就已經被提出,然而長期以來一直沒有找到大規模應用的場景,所以技術的發展也十分緩慢。一直到2009 年比特幣誕生後,人們發現它非常適合用於解決區塊鏈中的隱私和擴展性問題,至此大量的資本和人才投入到了這項技術的開發和工程應用中。 ZKP 有很多實現,例如:Groth 16、PlonK、STARK 等,至今還沒出現真正的行業標準,本文將為大家盤點各種ZKP 實現的技術特點,希望能給大家的學習研究和工程開髮帶來幫助。
二級標題
二級標題
二級標題
二級標題
二級標題
二級標題
二級標題
一級標題
Mina 是另一個例子,在很多高速區塊鏈系統中,交易的數據十分龐大,系統需要保留所有的區塊以備共識協議的驗證,所以系統對硬件的要求極高,永久保存意味著區塊鏈節點將需要不斷增大磁盤空間和數據索引能力。這時候可以藉助ZKP,將驗證數據壓縮,Mina 通過遞歸零知識證明,將賬本壓縮到11 KB,但依舊可以驗證區塊的正確性。
二級標題
一級標題
一級標題
證明系統是ZKP 的底層算法實現,可分為交互式和非交互式兩種:
二級標題
二級標題
1. 交互式證明系統
Bulletproofs
交互證明系統由兩方參與,分別稱為證明者(Prover,簡記為P)和驗證者(Verifier,簡記為V),其中P 知道某一秘密(如公鑰密碼體制的秘密鑰或一個二次剩餘x 的平方根),P 希望使V 相信自己的確掌握這一秘密。交互證明由若干輪組成,在每一輪,P 和V 可能需根據從對方收到的消息和自己計算的某個結果向對方發送消息。比較典型的方式是在每輪V 都向P 發出一個詢問,P 向V 做出一個應答。所有輪執行完後, V 根據P 是否在每一輪對自己發出的詢問都能正確應答,決定是否接受P 的證明。
2. 非交互式證明系統
SNARKs (Succinct Non-interactive ARguments of Knowledge)
在上述交互式證明系統中,P 和V 不進行交互,證明由P 產生後直接給V,V 對證明直接進行驗證,這種證明系統稱為非交互式證明系統(NIZK)。
我們在區塊鏈中使用的證明系統一般都是NIZK,區塊鏈中的節點就是驗證者V ,終端用戶或者二層網絡(Layer 2 )就是證明者P。
SNORKs (Succinct Non-interactive Oecumenical (Universal) aRguments of Knowledge)
文末參考鏈接[ 1 ] 描述了近十年來公開發表的NIZK 方案及特點。
在實際工程應用中我們主要關注的是性能和通用性,因此我們對一些常見證明系統進行更細緻的分類對比,見文末參考鏈接[ 2 ]:
STARKs (Succinct (Scalable) Transparent ARguments of Knowledge)
特點:簡潔證明大小,無需可信設置,但證明生成和驗證耗時相比較長。
代表項目:Bulletproofs, Halo, Halo 2 。
代表項目:Groth 16 。
代表項目:Sonic, PlonK, Marlin, Plonky 2 。
二級標題
一級標題
3. 性能對比
圖片描述
(見文末參考鏈接[ 3 ])
一級標題
電路是ZKP 系統的業務邏輯實現,開發ZKP 應用需要進行電路編程,為什麼ZKP 邏輯代碼被稱為“電路”?主要有以下幾個原因:
二級標題
libsnark
ZKP 證明的代碼會被轉換成一系列簡單約束條件的表達式R 1 CS,然後使用拉格朗日插值法,轉換為一個巨大的多項式QAP,最終以門電路的形式被約束。
與硬件電路類似,所有分支的代碼將被一起執行。
我們不需要從頭去用密碼學實現ZKP 應用,有很多開發庫已經實現了這些底層證明系統,我們只需要關注業務邏輯的實現。當然每一種庫都有不同的抽象程度,有的需要去學習描述電路的表達式,有的只需要按流程定義好代碼就可以輕鬆實現。
gnark
二級標題
二級標題
1. 常用開發庫
bellman
用C++ 語言實現了通用證明系統、基礎電路庫和應用示例。
證明系統:BBFR 15、BCCT 12、BCCT 13、BCGT V1 3、BCIOP 13、BCT V1 4 a、BCT V1 4 b、CT V1 5、DFGK 14、Groth 16、GM 17、GGPR 13、PGHR 13 。
鏈接:https://github.com/scipr-lab/libsnark。
snarkjs
用Go 語言實現的證明系統,提供高級API 來設計電路。
證明系統:Groth 16、PlonK。
鏈接:https://github.com/consensys/gnark。
ethsnarks
Rust 實現的證明系統,它提供電路接口、 基礎結構以及一些基本電路實現,例如布爾和數值抽象。
證明系統:Groth 16 。
鏈接:https://github.com/zkcrypto/bellman。
bulletproofs
Javascript 和WASM 實現的證明系統,可用於可信設置、生成證明並驗證證明。 snarkjs 使用iden 3 自己的circom 編譯器對DSL 定義的電路進行編譯。
證明系統:Groth 16、PlonK。
鏈接:https://github.com/iden 3/snarkjs。
halo 2
使用Python 實現,可以在用戶瀏覽器生成證明,使用以太坊智能合約做為驗證者。目前項目開發不活躍,相同的場景下使用Circom 可能是更好的選擇。
證明系統:Groth 16 。
證明系統:bulletproofs。
二級標題
鏈接:https://github.com/dalek-cryptography/bulletproofs。
一個基於Rust 的實現的證明系統,由ZCash 團隊維護。 Halo 2 特定於PLONKish,可以非常直接地控制電路在算術運算中的表示方式,非常適合編寫高度優化的電路。
鏈接:https://github.com/zcash/halo 2 。
二級標題
二級標題
以gnark 為例,一個典型的工作流程如下圖:
3 )對R 1 CS 進行可信設置,得到Proving key 和Verify key。
二級標題
Cairo
5 )驗證者使用Verify key 驗證Proof。
一級標題
電路編程專用語言
Zokrates
二級標題
二級標題
1. 基於以太坊平台
Circom
Cairo 是一種用於編寫可證明程序的編程語言,其中一方可以向另一方證明某個計算已正確執行。 Cairo 和類似的證明系統可用於為區塊鏈提供可擴展性。 StarkNet 將Cairo 編程語言用於其基礎設施和編寫StarkNet 合約。
證明系統:STARK。
鏈接:https://www.cairo-lang.org/docs/。
Noir
ZoKrates 採用DSL 描述電路,提供了一些常用的電路庫,它可以幫助你在DApp 中使用可驗證的計算,從用高級語言規範您的程序到生成計算證明,再到在Solidity 中驗證這些證明。
證明系統:GM 17、Groth 16、Marlin。
鏈接:https://zokrates.github.io/。
zkEVM
Circom 語言採用DSL 描述電路,可以配合snarkjs 在用戶瀏覽器生成證明,使用以太坊智能合約做為驗證者。
Aztec 基於Rust 的隱私編程語言,採用DSL 描述電路,允許安全、無縫地構建隱私保護零知識電路。
二級標題
zkApp (Mina)
證明系統:PlonK。
鏈接:https://noir-lang.org/index.html。
目前有zkSync、Polygon、Scroll、Starkware 等團隊正致力於zkEVM 的實現,已取得重大進展。
LEO (Aleo)
二級標題
二級標題
證明系統:PlonK。
一級標題
鏈接:https://docs.minaprotocol.com/zkapps。
Leo 是一種函數式靜態類型編程語言,專為編寫私有應用程序而構建。它專為開發人員設計,可以直觀地在Aleo 區塊鏈上構建,為私有的、去中心化的生態系統提供基礎。
鏈接:https://leo-lang.org/。
一級標題
一級標題
ZKP 常見安全問題
在過去幾年,慢霧安全團隊已為多個知名ZKP 產品進行了電路及應用安全審計,包括ZKSwap、Zkdex、Zksafe 等,發現了多個中高危漏洞,對基於Circom、libsnark 等流行框架開發的應用有較為深入的理解。慢霧安全團隊在ZKP 應用審計中發現常見的安全問題有:
信任參數風險
為了使用zk-SNARKs,需要一組公共參數,稱為公共參考字符串(CRS)。但是這些參數的創建也會產生一些私有參數,如果某一方獲得這些私有參數,他們就可以偽造證明。
另外,生成CRS 的流程需要經過審計,確保不會有隨機數後門,或者私有參數不會被蓄意保留。使用zk-SNORKs 時也需要確保結構化參考字符串(SRS)是可信的。
可信配置階段的安全隱患問題可以使用安全多方計算(MPC)來解決,MPC 的特點是只要任何一個參與者能誠實參與,那麼通過這套多方計算系統最終得到的計算結果就是可信的。
靜態代碼安全
這部分主要是由於編碼不規範造成的安全問題,例如:參數未校驗、返回值未處理、數值溢出、邊界未檢查等,如果編寫電路的語言是C/C++,那麼還會存在內存溢出風險。
供應鏈攻擊風險
供應鏈的風險主要來自使用了存在漏洞的代碼庫,例如:舊版本的倉庫。通常ZKP 應用還需要配合客戶端或者Web 前端使用,而這部分也很容易遭受多種方式黑客攻擊。
邏輯錯誤
邏輯錯誤是電路實現中最容易出現的錯誤,需要結合需求文檔檢查電路的設計是否符合需求。
雙花攻擊
錯誤的設計可能導致雙花攻擊,例如:某些ZKP 庫存在延展性風險,攻擊者可利用已知的Proof 生成不同Proof,如果設計不當會導致雙花攻擊。
證明偽造
有效的證明是ZKP 首要解決的問題,確保滿足完備性和可靠性,即“假的真不了,真的假不了”,所以如果一個電路可以創建假證明,通常是由於底層庫出現漏洞,通常我們會建議項目方使用公開的經過審計的ZKP 庫,並使用穩定的發行版。
側信道攻擊
如果電路設計不當,不同的隱私信息可能存在不同的計算特徵,攻擊者可能通過公開的輸入或者證明猜解出私有輸入數據。
電路約束失效
智能合約風險
智能合約風險
智能合約風險
一級標題
總結
總結
一級標題
參考鏈接:
[ 1 ]. https://en.wikipedia.org/wiki/Zero-knowledge_proof
[ 2 ]. https://github.com/matter-labs/awesome-zero-knowledge-proofs
[ 3 ].https://docs.google.com/presentation/d/1gfB6WZMvM9mmDKofFibIgsyYShdf0RV_Y8TLz3k1Ls0/edit