kimchi_msm/
precomputed_srs.rs1use crate::{Fp, BN254, DOMAIN_SIZE};
4use ark_ec::pairing::Pairing;
5use ark_ff::UniformRand;
6use ark_serialize::Write;
7use kimchi::circuits::domains::EvaluationDomains;
8use poly_commitment::{kzg::PairingSRS, precomputed_srs::TestSRS, SRS as _};
9use rand::{rngs::StdRng, SeedableRng};
10use serde::{Deserialize, Serialize};
11use std::{fs::File, io::BufReader, path::PathBuf};
12use zeroize::Zeroize;
13
14#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
16pub struct TestPairingSRS<Pair: Pairing> {
17 pub full_srs: TestSRS<Pair::G1Affine>,
18 pub verifier_srs: TestSRS<Pair::G2Affine>,
19}
20
21impl<Pair: Pairing> From<PairingSRS<Pair>> for TestPairingSRS<Pair> {
22 fn from(value: PairingSRS<Pair>) -> Self {
23 TestPairingSRS {
24 full_srs: From::from(value.full_srs),
25 verifier_srs: From::from(value.verifier_srs),
26 }
27 }
28}
29
30impl<Pair: Pairing> From<TestPairingSRS<Pair>> for PairingSRS<Pair> {
31 fn from(value: TestPairingSRS<Pair>) -> Self {
32 PairingSRS {
33 full_srs: From::from(value.full_srs),
34 verifier_srs: From::from(value.verifier_srs),
35 }
36 }
37}
38
39pub fn get_bn254_srs(domain: EvaluationDomains<Fp>) -> PairingSRS<BN254> {
41 let srs = if domain.d1.size as usize == DOMAIN_SIZE {
42 read_bn254_srs_from_disk(get_bn254_srs_path())
43 } else {
44 PairingSRS::create(domain.d1.size as usize)
45 };
46 srs.full_srs.get_lagrange_basis(domain.d1); srs
48}
49
50pub fn get_bn254_srs_path() -> PathBuf {
52 let base_path = env!("CARGO_MANIFEST_DIR");
53 if base_path.is_empty() {
54 println!("WARNING: BN254 precomputation: CARGO_MANIFEST_DIR is absent, can't determine working directory. It is sometimes absent in release mode.");
55 }
56 PathBuf::from(base_path).join("../srs/test_bn254.srs")
57}
58
59fn read_bn254_srs_from_disk(srs_path: PathBuf) -> PairingSRS<BN254> {
62 let file =
63 File::open(srs_path.clone()).unwrap_or_else(|_| panic!("missing SRS file: {srs_path:?}"));
64 let reader = BufReader::new(file);
65 let srs: TestPairingSRS<BN254> = rmp_serde::from_read(reader).unwrap();
66 From::from(srs)
67}
68
69fn create_and_store_srs_with_path(
72 force_overwrite: bool,
73 domain_size: usize,
74 srs_path: PathBuf,
75) -> PairingSRS<BN254> {
76 let mut rng = &mut StdRng::from_seed([42u8; 32]);
78 let mut trapdoor = Fp::rand(&mut rng);
79 let srs = PairingSRS::create_trusted_setup_with_toxic_waste(trapdoor, domain_size);
80 trapdoor.zeroize();
81
82 for sub_domain_size in 1..=domain_size {
83 let domain = EvaluationDomains::<Fp>::create(sub_domain_size).unwrap();
84 srs.full_srs.get_lagrange_basis(domain.d1);
85 }
86
87 if force_overwrite || std::env::var("SRS_OVERWRITE").is_ok() {
89 std::fs::create_dir_all(srs_path.parent().unwrap()).unwrap();
91 let mut file = std::fs::OpenOptions::new()
93 .create(true)
94 .truncate(true)
95 .write(true)
96 .open(srs_path.clone())
97 .expect("failed to open SRS file");
98
99 let test_srs: TestPairingSRS<BN254> = From::from(srs.clone());
100 let srs_bytes = rmp_serde::to_vec(&test_srs).unwrap();
101 file.write_all(&srs_bytes).expect("failed to write file");
102 file.flush().expect("failed to flush file");
103 }
104
105 let srs_on_disk = read_bn254_srs_from_disk(srs_path);
107
108 assert_eq!(srs, srs_on_disk);
110
111 srs
112}
113
114pub fn create_and_store_srs(force_overwrite: bool, domain_size: usize) -> PairingSRS<BN254> {
116 let srs_path = get_bn254_srs_path();
117 create_and_store_srs_with_path(force_overwrite, domain_size, srs_path)
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 pub fn heavy_test_create_or_check_srs() {
128 let domain_size = DOMAIN_SIZE;
129 create_and_store_srs_with_path(false, domain_size, get_bn254_srs_path());
130 }
131
132 #[test]
133 pub fn check_bn256_srs_serialization() {
135 let domain_size = 1 << 8;
136 let test_srs_path = PathBuf::from("/tmp/test_bn254.srs");
137 create_and_store_srs_with_path(true, domain_size, test_srs_path);
138 }
139
140 #[test]
141 pub fn check_get_bn254_srs() {
144 let domain_size = DOMAIN_SIZE;
145 let domain = EvaluationDomains::<Fp>::create(domain_size).unwrap();
146 get_bn254_srs(domain);
147 }
148}