openvm_native_recursion/halo2/
utils.rs1use std::{
2 collections::HashMap,
3 env::var,
4 io::BufReader,
5 path::{Path, PathBuf},
6 sync::{Arc, Mutex},
7};
8
9use lazy_static::lazy_static;
10use once_cell::sync::Lazy;
11use rand::{prelude::StdRng, SeedableRng};
12use snark_verifier_sdk::{
13 halo2::{PoseidonTranscript, POSEIDON_SPEC},
14 snark_verifier::{
15 halo2_base::{
16 halo2_proofs::{
17 halo2curves::bn256::{Bn256, G1Affine},
18 poly::{
19 commitment::{CommitmentScheme, Params},
20 kzg::commitment::{KZGCommitmentScheme, ParamsKZG},
21 },
22 },
23 utils::fs::read_params as read_params_impl,
24 },
25 pcs::kzg::KzgDecidingKey,
26 verifier::{plonk::PlonkProof, SnarkVerifier},
27 },
28 NativeLoader, PlonkVerifier, Snark, SHPLONK,
29};
30
31use crate::halo2::Halo2Params;
32static TESTING_KZG_PARAMS_23: Lazy<Halo2Params> = Lazy::new(|| gen_kzg_params(23));
33
34pub(crate) fn gen_kzg_params(k: u32) -> Halo2Params {
35 let mut rng = StdRng::seed_from_u64(42);
36 ParamsKZG::setup(k, &mut rng)
37}
38
39lazy_static! {
40 static ref SVK: G1Affine =
41 serde_json::from_str("\"0100000000000000000000000000000000000000000000000000000000000000\"")
42 .unwrap();
43
44 pub static ref DK: KzgDecidingKey<Bn256> = serde_json::from_str(r#"
48 {
49 "_marker": null,
50 "g2": "edf692d95cbdde46ddda5ef7d422436779445c5e66006a42761e1f12efde0018c212f3aeb785e49712e7a9353349aaf1255dfb31b7bf60723a480d9293938e19",
51 "s_g2": "0016e2a0605f771222637bae45148c8faebb4598ee98f30f20f790a0c3c8e02a7bf78bf67c4aac19dcc690b9ca0abef445d9a576c92ad6041e6ef1413ca92a17",
52 "svk": {
53 "g": "0100000000000000000000000000000000000000000000000000000000000000"
54 }
55 }
56 "#).unwrap();
57 static ref FAKE_KZG_PARAMS: Halo2Params = KZGCommitmentScheme::new_params(1);
59}
60
61pub static KZG_PARAMS_FOR_SVK: Lazy<Halo2Params> = Lazy::new(|| {
62 if std::env::var("RANDOM_SRS").is_ok() {
63 read_params(1).as_ref().clone()
64 } else {
65 build_kzg_params_for_svk(*SVK)
66 }
67});
68
69fn build_kzg_params_for_svk(g: G1Affine) -> Halo2Params {
70 FAKE_KZG_PARAMS.from_parts(
71 1,
72 vec![g],
73 Some(vec![g]),
74 Default::default(),
75 Default::default(),
76 )
77}
78
79#[allow(dead_code)]
80pub(crate) fn verify_snark(dk: &KzgDecidingKey<Bn256>, snark: &Snark) {
81 let mut transcript =
82 PoseidonTranscript::<NativeLoader, &[u8]>::from_spec(snark.proof(), POSEIDON_SPEC.clone());
83 let proof: PlonkProof<_, _, SHPLONK> =
84 PlonkVerifier::read_proof(dk, &snark.protocol, &snark.instances, &mut transcript)
85 .expect("Failed to read PlonkProof");
86 PlonkVerifier::verify(dk, &snark.protocol, &snark.instances, &proof)
87 .expect("PlonkVerifier failed");
88}
89
90pub trait Halo2ParamsReader {
91 fn read_params(&self, k: usize) -> Arc<Halo2Params>;
92}
93
94#[derive(Clone)]
95pub struct CacheHalo2ParamsReader {
96 params_dir: PathBuf,
97 cached_params: Arc<Mutex<HashMap<usize, Arc<Halo2Params>>>>,
98}
99
100impl Halo2ParamsReader for CacheHalo2ParamsReader {
101 fn read_params(&self, k: usize) -> Arc<Halo2Params> {
102 self.cached_params
103 .lock()
104 .unwrap()
105 .entry(k)
106 .or_insert_with(|| Arc::new(self.read_params_from_folder(k)))
107 .clone()
108 }
109}
110impl CacheHalo2ParamsReader {
111 pub fn new(params_dir: impl AsRef<Path>) -> Self {
112 Self {
113 params_dir: params_dir.as_ref().to_path_buf(),
114 cached_params: Default::default(),
115 }
116 }
117 pub fn new_with_default_params_dir() -> Self {
118 let default_params_dir = PathBuf::from(var("HOME").unwrap())
119 .join(".openvm")
120 .join("params");
121 CacheHalo2ParamsReader::new(default_params_dir)
122 }
123 fn read_params_from_folder(&self, k: usize) -> Halo2Params {
124 let file_path = self.params_dir.as_path().join(format!("kzg_bn254_{k}.srs"));
125 ParamsKZG::<Bn256>::read(&mut BufReader::new(
126 std::fs::File::open(&file_path)
127 .unwrap_or_else(|e| panic!("Params file {:?} does not exist: {e:?}", file_path)),
128 ))
129 .unwrap()
130 }
131}
132
133fn read_params(k: u32) -> Arc<Halo2Params> {
136 if std::env::var("RANDOM_SRS").is_ok() {
137 let mut ret = TESTING_KZG_PARAMS_23.clone();
138 ret.downsize(k);
139 Arc::new(ret)
140 } else {
141 Arc::new(read_params_impl(k))
142 }
143}