rtvm_primitives/kzg/
trusted_setup_points.rs1use core::fmt;
2use derive_more::{AsMut, AsRef, Deref, DerefMut};
3use std::boxed::Box;
4
5pub use c_kzg::{BYTES_PER_G1_POINT, BYTES_PER_G2_POINT};
6
7pub const NUM_G1_POINTS: usize = 4096;
9
10pub const NUM_G2_POINTS: usize = 65;
12
13#[derive(Debug, Clone, PartialEq, AsRef, AsMut, Deref, DerefMut)]
15#[repr(transparent)]
16pub struct G1Points(pub [[u8; BYTES_PER_G1_POINT]; NUM_G1_POINTS]);
17
18impl Default for G1Points {
19 fn default() -> Self {
20 Self([[0; BYTES_PER_G1_POINT]; NUM_G1_POINTS])
21 }
22}
23
24#[derive(Debug, Clone, Eq, PartialEq, AsRef, AsMut, Deref, DerefMut)]
26#[repr(transparent)]
27pub struct G2Points(pub [[u8; BYTES_PER_G2_POINT]; NUM_G2_POINTS]);
28
29impl Default for G2Points {
30 fn default() -> Self {
31 Self([[0; BYTES_PER_G2_POINT]; NUM_G2_POINTS])
32 }
33}
34
35pub const G1_POINTS: &G1Points = {
37 const BYTES: &[u8] = include_bytes!("./g1_points.bin");
38 assert!(BYTES.len() == core::mem::size_of::<G1Points>());
39 unsafe { &*BYTES.as_ptr().cast::<G1Points>() }
40};
41
42pub const G2_POINTS: &G2Points = {
44 const BYTES: &[u8] = include_bytes!("./g2_points.bin");
45 assert!(BYTES.len() == core::mem::size_of::<G2Points>());
46 unsafe { &*BYTES.as_ptr().cast::<G2Points>() }
47};
48
49pub fn parse_kzg_trusted_setup(
54 trusted_setup: &str,
55) -> Result<(Box<G1Points>, Box<G2Points>), KzgErrors> {
56 let mut lines = trusted_setup.lines();
57
58 let n_g1 = lines
60 .next()
61 .ok_or(KzgErrors::FileFormatError)?
62 .parse::<usize>()
63 .map_err(|_| KzgErrors::ParseError)?;
64 let n_g2 = lines
65 .next()
66 .ok_or(KzgErrors::FileFormatError)?
67 .parse::<usize>()
68 .map_err(|_| KzgErrors::ParseError)?;
69
70 if n_g1 != NUM_G1_POINTS {
71 return Err(KzgErrors::MismatchedNumberOfPoints);
72 }
73
74 if n_g2 != NUM_G2_POINTS {
75 return Err(KzgErrors::MismatchedNumberOfPoints);
76 }
77
78 let mut g1_points = Box::<G1Points>::default();
80 for bytes in &mut g1_points.0 {
81 let line = lines.next().ok_or(KzgErrors::FileFormatError)?;
82 crate::hex::decode_to_slice(line, bytes).map_err(|_| KzgErrors::ParseError)?;
83 }
84
85 let mut g2_points = Box::<G2Points>::default();
87 for bytes in &mut g2_points.0 {
88 let line = lines.next().ok_or(KzgErrors::FileFormatError)?;
89 crate::hex::decode_to_slice(line, bytes).map_err(|_| KzgErrors::ParseError)?;
90 }
91
92 if lines.next().is_some() {
93 return Err(KzgErrors::FileFormatError);
94 }
95
96 Ok((g1_points, g2_points))
97}
98
99#[derive(Debug)]
100pub enum KzgErrors {
101 FailedCurrentDirectory,
103 PathNotExists,
105 IOError,
107 NotValidFile,
109 FileFormatError,
111 ParseError,
113 MismatchedNumberOfPoints,
115}
116
117impl fmt::Display for KzgErrors {
118 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119 let s = match self {
120 Self::FailedCurrentDirectory => "failed to get current directory",
121 Self::PathNotExists => "the specified path does not exist",
122 Self::IOError => "IO error",
123 Self::NotValidFile => "not a valid file",
124 Self::FileFormatError => "file is not properly formatted",
125 Self::ParseError => "could not parse as usize",
126 Self::MismatchedNumberOfPoints => "number of points does not match what is expected",
127 };
128 f.write_str(s)
129 }
130}
131
132#[cfg(feature = "std")]
133impl std::error::Error for KzgErrors {}