---
# System prepended metadata

title: ZKP 實作 circom
tags: [ZKP]

---

###### tags: `ZKP`
# ZKP 實作 circom 

搜尋ZKP 實作
https://medium.com/taipei-ethereum-meetup/zkp-%E8%88%87%E6%99%BA%E8%83%BD%E5%90%88%E7%B4%84%E7%9A%84%E9%96%8B%E7%99%BC%E5%85%A5%E9%96%80-6b2e7ece0714

原理是 使用者須提供一個**答案**以及**證明**
透過鏈上合約進行驗證(ZKP產生的驗證合約) 若答案紀錄的相同就OK

直接在circuits套用SHA3就好
答案就是SHA3產生出的HASH

---

安裝一定要透過這個方法 
https://docs.circom.io/getting-started/installation/#installing-circom

透過網路上一些npm install下載的都無法使用 (可能跟windows有關)
下載出來circom --help都會跟官方不一樣 然後編譯出問題

原先以為是VS C++沒有 還重新去安裝 結果也不能用
最後照官方文件安裝就可以了

---
https://medium.com/taipei-ethereum-meetup/zkp-%E8%88%87%E6%99%BA%E8%83%BD%E5%90%88%E7%B4%84%E7%9A%84%E9%96%8B%E7%99%BC%E5%85%A5%E9%96%80-6b2e7ece0714

https://medium.com/swf-lab/circom-snarkjs-728e4314e057

https://docs.circom.io/getting-started/computing-the-witness/

circom是會先變成R1CS，然後再轉成一堆的多項式，然後再用CRS去sample一些點，當成proof
power of tau ceremony 就是用來產生 common reference string (CRS)

1.建構電路
->circom
設計好電路 產生circom

2.輸入資料
透過輸入input.json進generate_witness 產生 witness.wtns
(node generate_witness.js multiplier2.wasm input.json witness.wtns) 這邊很快

->snark
witness

3.產生pua

生成 pua要調到14(小一點 跑不動) 看錯誤需求提升大小
Powers of Tau應該只需要做一次 就可以留著 因為產生的過程沒用到witness

4.plonk setup 產生zkey 到此基礎架設結束
使用到電路 pua 產生zkey

5.導出verify zkey的verification_key.json 此處只是把vertify叫出來 原本就存於zkey 此舉能產生出**驗證**的密鑰
snarkjs zkey export verificationkey circuit_final.zkey verification_key.json
使用電路zkey

6.產生證明 透過zkey跟withness 
snarkjs plonk prove circuit_final.zkey witness.wtns proof.json public.json
7.驗證證明 透過vertifykey跟前一個步驟產生的proof public
snarkjs plonk verify verification_key.json public.json proof.json

可以把第五步步驟倒出Vertify改成
snarkjs zkey export solidityverifier circuit_final.zkey verifier.sol
這樣第六步驟產生
https://github.com/iden3/snarkjs

3~5步驟應該只要做一次  因為這邊主要是產生zkey
後續會驗證的也只用到這個zkey 所以zk應該是主架構
代表3~5是產生出一個可驗證的架構流程

輸入資料步驟2產生的witness 只有步驟6需要用 產生證明
步驟7是拿步驟6產生的資訊驗證 
也就是說6的witness不對 那步驟7就會錯

---
已有架構zkey 輸入資料的流程
2.用input資料產生witness
6.用witness產生證明proof.json(證明) public.json(答案)

snakrjs提供的一定會對 因為他只是將上述流程跑一遍
真正的驗證是固定我們已知publicSingal跟vkey
證明者要提供唯一的proof上傳(步驟2跟6 只需更改input即可)
const res = await snarkjs.plonk.verify(vKey, publicSignals, proof);

所以可以按照測試跑 只是輸入資料換成自己的
將結果的publicSingal跟ver.sol上傳至solidity合約

測試則上傳使用者資料的public跟signal去合約驗證

---

也許用單純的sha256就好
https://stackoverflow.com/questions/73068557/conflicting-versions-of-sha256-bit-calculation
轉成bits後輸入in
字串放進去要透過後端轉成16進位 
可以轉換成acsi



https://docs.circom.io/background/background/#summary
zk-SNARK 證明是一種特定類型的零知識證明，可以讓你證明你知道一組信號匹配電路的所有約束，而不洩露除公共輸入和輸出之外的任何信號

一樣可以用 但可以用零知識證明換掉摘要密碼那段

可以明確的告知他人 驗證是由個人資料和隨機數組成
所以當你沒有本人該知道的個人資料和隨機數 是不可能通過認證的

