alloy_eips/eip4844/
trusted_setup_points.rs

1use alloc::boxed::Box;
2use alloy_primitives::hex;
3use core::fmt;
4use derive_more::{AsMut, AsRef, Deref, DerefMut};
5
6pub use c_kzg::{BYTES_PER_COMMITMENT as BYTES_PER_G1_POINT, FIELD_ELEMENTS_PER_BLOB};
7
8/// Bytes per G2 point.
9pub const BYTES_PER_G2_POINT: usize = 96;
10
11/// Number of G1 Points.
12pub const NUM_G1_POINTS: usize = 4096;
13
14/// Number of G2 Points.
15pub const NUM_G2_POINTS: usize = 65;
16
17/// A newtype over list of G1 point from kzg trusted setup.
18#[derive(Clone, Debug, PartialEq, Eq, AsRef, AsMut, Deref, DerefMut)]
19#[repr(transparent)]
20pub struct G1Points(pub [[u8; BYTES_PER_G1_POINT]; NUM_G1_POINTS]);
21
22impl Default for G1Points {
23    fn default() -> Self {
24        Self([[0; BYTES_PER_G1_POINT]; NUM_G1_POINTS])
25    }
26}
27
28/// A newtype over list of G2 point from kzg trusted setup.
29#[derive(Clone, Debug, PartialEq, Eq, AsRef, AsMut, Deref, DerefMut)]
30#[repr(transparent)]
31pub struct G2Points(pub [[u8; BYTES_PER_G2_POINT]; NUM_G2_POINTS]);
32
33impl Default for G2Points {
34    fn default() -> Self {
35        Self([[0; BYTES_PER_G2_POINT]; NUM_G2_POINTS])
36    }
37}
38
39/// Parses the contents of a KZG trusted setup file into a list of G1 and G2 points.
40///
41/// These can then be used to create a KZG settings object with
42/// [`KzgSettings::load_trusted_setup`](c_kzg::KzgSettings::load_trusted_setup).
43pub fn parse_kzg_trusted_setup(
44    trusted_setup: &str,
45) -> Result<(Box<G1Points>, Box<G2Points>), KzgErrors> {
46    let mut lines = trusted_setup.lines();
47
48    // load number of points
49    let n_g1 = lines
50        .next()
51        .ok_or(KzgErrors::FileFormatError)?
52        .parse::<usize>()
53        .map_err(|_| KzgErrors::ParseError)?;
54    let n_g2 = lines
55        .next()
56        .ok_or(KzgErrors::FileFormatError)?
57        .parse::<usize>()
58        .map_err(|_| KzgErrors::ParseError)?;
59
60    if n_g1 != NUM_G1_POINTS {
61        return Err(KzgErrors::MismatchedNumberOfPoints);
62    }
63
64    if n_g2 != NUM_G2_POINTS {
65        return Err(KzgErrors::MismatchedNumberOfPoints);
66    }
67
68    // load g1 points
69    let mut g1_points = Box::<G1Points>::default();
70    for bytes in &mut g1_points.0 {
71        let line = lines.next().ok_or(KzgErrors::FileFormatError)?;
72        hex::decode_to_slice(line, bytes).map_err(|_| KzgErrors::ParseError)?;
73    }
74
75    // load g2 points
76    let mut g2_points = Box::<G2Points>::default();
77    for bytes in &mut g2_points.0 {
78        let line = lines.next().ok_or(KzgErrors::FileFormatError)?;
79        hex::decode_to_slice(line, bytes).map_err(|_| KzgErrors::ParseError)?;
80    }
81
82    if lines.next().is_some() {
83        return Err(KzgErrors::FileFormatError);
84    }
85
86    Ok((g1_points, g2_points))
87}
88
89/// KZG custom Error types
90#[derive(Clone, Copy, Debug)]
91pub enum KzgErrors {
92    /// Failed to get current directory.
93    FailedCurrentDirectory,
94    /// The specified path does not exist.
95    PathNotExists,
96    /// Problems related to I/O.
97    IOError,
98    /// Not a valid file.
99    NotValidFile,
100    /// File is not properly formatted.
101    FileFormatError,
102    /// Not able to parse to usize.
103    ParseError,
104    /// Number of points does not match what is expected.
105    MismatchedNumberOfPoints,
106}
107
108impl fmt::Display for KzgErrors {
109    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110        let s = match self {
111            Self::FailedCurrentDirectory => "failed to get current directory",
112            Self::PathNotExists => "the specified path does not exist",
113            Self::IOError => "IO error",
114            Self::NotValidFile => "not a valid file",
115            Self::FileFormatError => "file is not properly formatted",
116            Self::ParseError => "could not parse as usize",
117            Self::MismatchedNumberOfPoints => "number of points does not match what is expected",
118        };
119        f.write_str(s)
120    }
121}
122
123impl core::error::Error for KzgErrors {}