- Today
- Total
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- defi
- overthewire
- pwnable
- wargame
- compound
- 코인
- Ethereum
- lending
- solidity
- 반딧
- 해킹
- 블록체인
- blockchain
- 해시
- pow
- shellcode
- DreamHack
- Linux
- 비트코인
- PWN
- 이더리움
- bitcoin
- Leak
- security
- V2
- Crypto
- hacking
- 리눅스
- web3
- BANDiT
Nullorm
circom을 이용한 zkp 생성 및 검증하기 본문
Terminology
- signal
- input, output, intermediate로 정의할 수 있음
- main component에서만 public, private구분하면 됨
- constraint
- signal들의 관계를 나타낸 것
- constraint = set of gates 정도로 이해하고있긴 함
- A * B + C = 0의 형태로 나타내야 함(근데 컴파일 과정에서 이렇게 변환해준다는 말인듯)
- R1CS꼴로 나타내려면 이렇게 해야 함
- witness
- constraint를 만족하는 input signal의 set으로 이해하고 있음
Circom
circom을 통해 circuit을 컴파일하고, r1cs 형식으로 formatting하여 zkp를 생성 및 검증할 수 있다.
Prerequisite: circom, snarkjs 설치
0. circom을 통한 zkp 생성 순서
- upside.circom 작성
- upside.circom 컴파일 (by circom)
output files:upside_cpp / upside_js / upside.sym / upside.r1cs
- upside.circom에 대한 witness 생성(valid/invalid한 input에 대한 signal set을 binary로 생성)
output files:witness.wtns
- Groth16을 이용한 zkp 생성 (by snarkjs)
- trusted setup을 통한
- Powers of Tau: general한 초기 설정
- Phase2: circuit 특화 설정
- trusted setup을 통한
1. upside.circom 작성
각종 signal에 대한 constraint를 표현한 upside.circom
작성
pragma circom 2.0.0;
template Add() {
signal input a[3];
a[0] === a[1] + a[2];
}
component main = Add();
2. 컴파일 및 input값 generate
circom compiler를 통해 compile
circom upside.circom --wasm --c --sym --r1cs
- wasm: witness 생성 위한 wasm 디렉토리 생성 (
upside_js
) - c: cpp witness 생성 위한 cpp 디렉토리 생성 (
upside_cpp
) - sym: 디버깅용 symbolic 파일 생성 (
upside.sym
) - r1cs: constraint를 R1CS형식으로 변환한 파일 생성 (
upside.r1cs
)
verifier에 verify를 하기 위한 input값 생성(json으로)
echo '{"a": [3, 1, 2]}' >> input.json
3. witness 생성 (아래 두 방법 중 택1)
constraint를 만족하는 input값을 알고있다는 것을 증명하기 위한 signal set인 witness.wtns
를 생성. snarkjs
에서 zkp를 생성할 때 사용한다.
3-1. wasm
cd upside_js/
node generate_witness.js upside.wasm input.json witness.wtns # 실행
3-2. cpp(wasm보다 큰 circuit 처리속도 빠름)
cd upside_cpp
make # Makefile 통해 build
./upside input.json witness.wtns # 실행
4. zkp 생성 및 검증
circuit
과 witness.wtns
에 대한 증명, 검증을 하는 단계
Groth16 protocol
zk-SNARK의 가장 많이 사용하는 구현.
trusted setup, prove, verify 이렇게 세 단계로 나뉜다.
1. Trusted Setup
Power of Tau, Phase2 이렇게 두 단계로 나뉜다.
1-1. Power of Tau
groth16을 사용하기 위한 기초적인 환경 세팅 단계
1-1-1. Lagrange Interpolation, 다항식 연산 효율적 수행을 위한 기초 데이터 생성
snarkjs powersoftau new bn128 12 pot12_0000.ptau -v
- bn128: 사용된 곡선
- 12: circuit 크기 (2122^{12}212크기까지 처리 가능)
- pot12_0000.ptau
파일 생성
1-1-2. contribution: 보안 강화를 위해, 여러 사람 또는 system의 contrbution을 통해 data를 생성(각 참여자는 개인 entropy를 추가)
snarkjs powersoftau contribute pot12_0000.ptau pot12_0001.ptau --name="First contribution" -v
- —name
을 통해 entropy 추가 X, 이거 하면 입력하라고 뜸
- pot12_0001.ptau
파일로 내용 업데이트
1-1-3. Phase 2로 전환
snarkjs powersoftau prepare phase2 pot12_0001.ptau pot12_final.ptau -v
- pot12_final.ptau
생성됨
1-2. Phase2
제작한 circuit에 최적화된 data를 생성하는 단계. Powers of Tau에서 생성된 데이터를 바탕으로, 각 circuit의 constraint를 만족하기 위한 proving key, verification key
를 생성하는 단계. R1CS를 GQP로 변환하는 과정도 포함된다.
1-2-1. .zkey 파일 생성
snarkjs groth16 setup multiplier2.r1cs pot12_final.ptau upside_0000.zkey
- r1cs 파일을 이용해 data를 생성함
- proving key: Prover가 zkp생성할 때 필요한 key
- verification key: verifier가 zkp를 검증하는 데 필요한 key
- proving key, verification key
∈ upside.zkey
1-2-2. contribution
이 또한 여러 사람, 시스템이 기여할 수 있다.
snarkjs zkey contribute upside_0000.zkey upside_0001.zkey --name="Contribute" -v
1-2-3. 검증키 추출
snarkjs zkey export verificationkey upside_0001.zkey verification_key.json
- verifier가 verify과정에 사용할 수 있는 verification key
를 추출
2. 증명 생성
snarkjs groth16 prove upside_0001.zkey witness.wtns proof.json public.json
- zkey, witness.wtns 이용해 zkp, public input
생성
3. 증명 검증
3-1. local에서 검증
snarkjs groth16 verify verification_key.json public.json proof.json
- ok
라고 나오면 증명 된 것임
3-2. verifier.sol 만들기
snarkjs zkey export solidityverifier upside_0001.zkey verifier.sol
- verifier.sol
파일 생성됨 (solidity)
snarkjs generatecall
- witness.wtns
를 calldata형식으로 만들어주는 명령어
- verifyProof()
함수 호출해서 True 반환하면 성공
(그런데 .sol에서 public signal의 수가 0일 때 함수의 매개변수로 uint[0]을 넣도록 코드가 작성되는데, 이 경우 solc에서 error를 띄우기 때문에, 이를 해결할 방법을 찾아야할 것 같긴 하다.)
'Web3 > Web3 수학&암호학' 카테고리의 다른 글
[Bitcoin 수학] SHA-256 해시 알고리즘 / hash algorithm / 특징 및 구조 (1) | 2024.04.07 |
---|