Tôi đang cố xác minh zk-SNARK từ một hợp đồng solidity ngoại tuyến, trong Rust.
Đây là hợp đồng xác minh để kiểm tra bằng chứng trong bên vững chắc.
Và cái này là giao dịch mang bằng chứng và đầu vào công khai.
Bằng chứng là hợp lệ và tôi đã có thể sao chép xác thực ngoại tuyến bằng Solidity.
Tuy nhiên, trong Rust, tôi không có quyền truy cập vào trình biên dịch trước solidity để kiểm tra các cặp BN254. Vì vậy, tôi đang sử dụng triển khai này dựa trên thùng hòm/đường cong:
pub fn check_pairings(g1s: Vec<G1Affine>, g2s: Vec<G2Affine>) -> bool {
assert_eq!(g1s.len(), g2s.len());
hãy để mut res = Fp12::one();
cho (g1, g2) trong g1s.iter().zip(g2s.iter()) {
nếu g1.is_zero() || g2.is_zero() {
tiếp tục;
}
res = res * Bn254::pairing(*g1, *g2);
}
res.is_one()
}
Mã được dựa trên Triển khai Ethereum BN526 và xin lưu ý rằng:
Các đầu vào (vectơ của các điểm G1 và G2) tương đương với việc triển khai solidity. Vì vậy, tôi có thể chắc chắn rằng sự kết hợp của đầu vào, tải bằng chứng, v.v. là chính xác.
Về cơ bản, đó là thuật toán được mô tả trong bản gốc Groth16 paper, trang 18. Thành phần điểm A đã bị phủ định sao cho tất cả các số hạng ở cùng một vế của phương trình.
Đó là cùng một đường cong trong cả hai lần triển khai.
Tui bỏ lỡ điều gì vậy? Có một số bước thực tế bổ sung khi xác minh zk-SNARK không? Là một chuẩn hóa của các giá trị cần thiết?