pub use c_kzg::{BYTES_PER_G1_POINT, BYTES_PER_G2_POINT};
use core::fmt::Display;
use derive_more::{AsMut, AsRef, Deref, DerefMut};
use std::boxed::Box;
pub const NUM_G1_POINTS: usize = 4096;
pub const NUM_G2_POINTS: usize = 65;
#[derive(Debug, Clone, PartialEq, AsRef, AsMut, Deref, DerefMut)]
#[repr(transparent)]
pub struct G1Points(pub [[u8; BYTES_PER_G1_POINT]; NUM_G1_POINTS]);
impl Default for G1Points {
fn default() -> Self {
Self([[0; BYTES_PER_G1_POINT]; NUM_G1_POINTS])
}
}
#[derive(Debug, Clone, Eq, PartialEq, AsRef, AsMut, Deref, DerefMut)]
#[repr(transparent)]
pub struct G2Points(pub [[u8; BYTES_PER_G2_POINT]; NUM_G2_POINTS]);
impl Default for G2Points {
fn default() -> Self {
Self([[0; BYTES_PER_G2_POINT]; NUM_G2_POINTS])
}
}
pub const G1_POINTS: &G1Points = {
const BYTES: &[u8] = include_bytes!("./g1_points.bin");
assert!(BYTES.len() == core::mem::size_of::<G1Points>());
unsafe { &*BYTES.as_ptr().cast::<G1Points>() }
};
pub const G2_POINTS: &G2Points = {
const BYTES: &[u8] = include_bytes!("./g2_points.bin");
assert!(BYTES.len() == core::mem::size_of::<G2Points>());
unsafe { &*BYTES.as_ptr().cast::<G2Points>() }
};
pub fn parse_kzg_trusted_setup(
trusted_setup: &str,
) -> Result<(Box<G1Points>, Box<G2Points>), KzgErrors> {
let mut lines = trusted_setup.lines();
let n_g1 = lines
.next()
.ok_or(KzgErrors::FileFormatError)?
.parse::<usize>()
.map_err(|_| KzgErrors::ParseError)?;
let n_g2 = lines
.next()
.ok_or(KzgErrors::FileFormatError)?
.parse::<usize>()
.map_err(|_| KzgErrors::ParseError)?;
if n_g1 != NUM_G1_POINTS {
return Err(KzgErrors::MismatchedNumberOfPoints);
}
if n_g2 != NUM_G2_POINTS {
return Err(KzgErrors::MismatchedNumberOfPoints);
}
let mut g1_points = Box::<G1Points>::default();
for bytes in &mut g1_points.0 {
let line = lines.next().ok_or(KzgErrors::FileFormatError)?;
crate::hex::decode_to_slice(line, bytes).map_err(|_| KzgErrors::ParseError)?;
}
let mut g2_points = Box::<G2Points>::default();
for bytes in &mut g2_points.0 {
let line = lines.next().ok_or(KzgErrors::FileFormatError)?;
crate::hex::decode_to_slice(line, bytes).map_err(|_| KzgErrors::ParseError)?;
}
if lines.next().is_some() {
return Err(KzgErrors::FileFormatError);
}
Ok((g1_points, g2_points))
}
#[derive(Debug)]
pub enum KzgErrors {
FailedCurrentDirectory,
PathNotExists,
IOError,
NotValidFile,
FileFormatError,
ParseError,
MismatchedNumberOfPoints,
}
impl Display for KzgErrors {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
KzgErrors::FailedCurrentDirectory => write!(f, "Failed to get current directory"),
KzgErrors::PathNotExists => write!(f, "The specified path does not exist"),
KzgErrors::IOError => write!(f, "Problems related to I/O"),
KzgErrors::NotValidFile => write!(f, "Not a valid file"),
KzgErrors::FileFormatError => write!(f, "File is not properly formatted"),
KzgErrors::ParseError => write!(f, "Not able to parse to usize"),
KzgErrors::MismatchedNumberOfPoints => {
write!(f, "Number of points does not match what is expected")
}
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for KzgErrors {}