poly_commitment/
precomputed_srs.rs1use crate::{ipa::SRS, CommitmentCurve, PolyComm};
15use ark_serialize::{CanonicalDeserialize, CanonicalSerialize};
16use mina_curves::named::NamedCurve;
17use serde::{Deserialize, Serialize};
18use serde_with::serde_as;
19use std::{collections::HashMap, fs::File, io::BufReader, path::PathBuf, sync::Arc};
20
21#[derive(Clone, Copy, PartialEq, Eq)]
24pub enum StoredSRSType {
25 Test,
26 Prod,
27}
28
29#[serde_as]
36#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
37#[serde(bound = "G: CanonicalDeserialize + CanonicalSerialize")]
38pub struct TestSRS<G> {
39 #[serde_as(as = "Vec<o1_utils::serialization::SerdeAsUnchecked>")]
42 pub g: Vec<G>,
43
44 #[serde_as(as = "o1_utils::serialization::SerdeAsUnchecked")]
46 pub h: G,
47
48 #[serde_as(as = "HashMap<_,Arc<Vec<PolyComm<o1_utils::serialization::SerdeAsUnchecked>>>>")]
50 pub lagrange_bases: HashMap<usize, Arc<Vec<PolyComm<G>>>>,
51}
52
53pub const SERIALIZED_SRS_SIZE: u32 = 16;
55
56fn get_srs_path<G: NamedCurve>(srs_type: StoredSRSType) -> PathBuf {
58 let test_prefix: String = (match srs_type {
59 StoredSRSType::Test => "test_",
60 StoredSRSType::Prod => "",
61 })
62 .to_owned();
63 let base_path = env!("CARGO_MANIFEST_DIR");
64 PathBuf::from(base_path)
65 .join("../srs")
66 .join(test_prefix + &format!("{}.srs", G::NAME))
67}
68
69#[must_use]
76pub fn get_srs_generic<G>(srs_type: StoredSRSType) -> SRS<G>
77where
78 G: NamedCurve + CommitmentCurve,
79{
80 let srs_path = get_srs_path::<G>(srs_type);
81 let file = File::open(srs_path.clone())
82 .unwrap_or_else(|_| panic!("missing SRS file: {}", srs_path.display()));
83 let reader = BufReader::new(file);
84 match srs_type {
85 StoredSRSType::Test => {
86 let test_srs: TestSRS<G> = rmp_serde::from_read(reader).unwrap();
87 From::from(test_srs)
88 }
89 StoredSRSType::Prod => rmp_serde::from_read(reader).unwrap(),
90 }
91}
92
93#[must_use]
99pub fn get_srs<G>() -> SRS<G>
100where
101 G: NamedCurve + CommitmentCurve,
102{
103 get_srs_generic(StoredSRSType::Prod)
104}
105
106#[must_use]
112pub fn get_srs_test<G>() -> SRS<G>
113where
114 G: NamedCurve + CommitmentCurve,
115{
116 get_srs_generic(StoredSRSType::Test)
117}
118
119#[cfg(test)]
120mod tests {
121 use super::*;
122
123 use crate::SRS as _;
124 use ark_ec::AffineRepr;
125 use ark_ff::PrimeField;
126 use ark_poly::{EvaluationDomain, Radix2EvaluationDomain};
127 use ark_serialize::Write;
128 use hex;
129 use mina_curves::pasta::{Pallas, Vesta};
130
131 fn test_regression_serialization_srs_with_generators<G: AffineRepr>(exp_output: &str) {
132 let h = G::generator();
133 let g = vec![h];
134 let srs = SRS::new(g, h);
135 let srs_bytes = rmp_serde::to_vec(&srs).unwrap();
136 let output = hex::encode(srs_bytes);
137 assert_eq!(output, exp_output);
138 }
139
140 #[test]
141 fn test_regression_serialization_srs_with_generators_vesta() {
142 let exp_output = "9291c421010000000000000000000000000000000000000000000000000000000000000000c421010000000000000000000000000000000000000000000000000000000000000000";
145 test_regression_serialization_srs_with_generators::<Vesta>(exp_output);
146 }
147
148 #[test]
149 fn test_regression_serialization_srs_with_generators_pallas() {
150 let exp_output = "9291c421010000000000000000000000000000000000000000000000000000000000000000c421010000000000000000000000000000000000000000000000000000000000000000";
153 test_regression_serialization_srs_with_generators::<Pallas>(exp_output);
154 }
155
156 fn create_or_check_srs<G>(log2_size: u32, srs_type: StoredSRSType)
157 where
158 G: NamedCurve + CommitmentCurve,
159 G::BaseField: PrimeField,
160 {
161 let domain_size = 1 << log2_size;
163 let srs = SRS::<G>::create(domain_size);
164
165 if srs_type == StoredSRSType::Test {
167 for sub_domain_size in 1..=domain_size {
169 let domain = Radix2EvaluationDomain::new(sub_domain_size).unwrap();
170 srs.get_lagrange_basis(domain);
171 }
172 }
173
174 let srs_path = get_srs_path::<G>(srs_type);
176 if std::env::var("SRS_OVERWRITE").is_ok() {
177 let mut file = std::fs::OpenOptions::new()
178 .create(true)
179 .truncate(true)
180 .write(true)
181 .open(srs_path)
182 .expect("failed to open SRS file");
183
184 let srs_bytes = match srs_type {
185 StoredSRSType::Test => {
186 let srs: TestSRS<G> = From::from(srs.clone());
187 rmp_serde::to_vec(&srs).unwrap()
188 }
189 StoredSRSType::Prod => rmp_serde::to_vec(&srs).unwrap(),
190 };
191
192 file.write_all(&srs_bytes).expect("failed to write file");
193 file.flush().expect("failed to flush file");
194 }
195
196 let srs_on_disk: SRS<G> = get_srs_generic::<G>(srs_type);
198
199 assert_eq!(srs, srs_on_disk);
201 }
202
203 #[test]
205 pub fn heavy_check_get_srs_prod_pallas() {
206 let _ = get_srs::<Pallas>();
207 }
208
209 #[test]
211 pub fn heavy_check_get_srs_prod_vesta() {
212 let _ = get_srs::<Vesta>();
213 }
214
215 #[test]
217 pub fn check_get_srs_test_pallas() {
218 let _ = get_srs_test::<Pallas>();
219 }
220
221 #[test]
223 pub fn check_get_srs_test_vesta() {
224 let _ = get_srs_test::<Vesta>();
225 }
226
227 #[test]
229 pub fn heavy_test_srs_serialization() {
230 create_or_check_srs::<Vesta>(SERIALIZED_SRS_SIZE, StoredSRSType::Prod);
231 create_or_check_srs::<Pallas>(SERIALIZED_SRS_SIZE, StoredSRSType::Prod);
232 create_or_check_srs::<Vesta>(SERIALIZED_SRS_SIZE, StoredSRSType::Test);
233 create_or_check_srs::<Pallas>(SERIALIZED_SRS_SIZE, StoredSRSType::Test);
234 }
235}