2022-11-15 18:46:52 +00:00
|
|
|
mod kzg_commitment;
|
|
|
|
mod kzg_proof;
|
2023-01-09 07:04:16 +00:00
|
|
|
mod trusted_setup;
|
2022-11-15 18:46:52 +00:00
|
|
|
|
2023-01-09 07:04:16 +00:00
|
|
|
pub use crate::{kzg_commitment::KzgCommitment, kzg_proof::KzgProof, trusted_setup::TrustedSetup};
|
2023-03-14 06:43:15 +00:00
|
|
|
use c_kzg::Bytes48;
|
2022-12-14 15:55:42 +00:00
|
|
|
pub use c_kzg::{
|
2023-04-11 00:05:01 +00:00
|
|
|
Blob, Error as CKzgError, KzgSettings, BYTES_PER_BLOB, BYTES_PER_FIELD_ELEMENT,
|
2022-12-14 15:55:42 +00:00
|
|
|
FIELD_ELEMENTS_PER_BLOB,
|
|
|
|
};
|
2022-11-15 18:46:52 +00:00
|
|
|
use std::path::PathBuf;
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum Error {
|
|
|
|
InvalidTrustedSetup(CKzgError),
|
2022-11-21 19:51:10 +00:00
|
|
|
InvalidKzgProof(CKzgError),
|
2023-03-14 06:43:15 +00:00
|
|
|
InvalidBytes(CKzgError),
|
2022-11-21 19:51:10 +00:00
|
|
|
KzgProofComputationFailed(CKzgError),
|
2023-03-14 06:43:15 +00:00
|
|
|
InvalidBlob(CKzgError),
|
2022-11-15 18:46:52 +00:00
|
|
|
}
|
|
|
|
|
2022-11-21 20:28:21 +00:00
|
|
|
/// A wrapper over a kzg library that holds the trusted setup parameters.
|
2023-04-27 18:18:21 +00:00
|
|
|
#[derive(Debug)]
|
2022-11-15 18:46:52 +00:00
|
|
|
pub struct Kzg {
|
2023-04-11 00:05:01 +00:00
|
|
|
trusted_setup: KzgSettings,
|
2022-11-15 18:46:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Kzg {
|
2023-01-09 07:04:16 +00:00
|
|
|
/// Load the kzg trusted setup parameters from a vec of G1 and G2 points.
|
|
|
|
///
|
|
|
|
/// The number of G1 points should be equal to FIELD_ELEMENTS_PER_BLOB
|
|
|
|
/// Note: this number changes based on the preset values.
|
|
|
|
/// The number of G2 points should be equal to 65.
|
|
|
|
pub fn new_from_trusted_setup(trusted_setup: TrustedSetup) -> Result<Self, Error> {
|
|
|
|
Ok(Self {
|
2023-04-11 00:05:01 +00:00
|
|
|
trusted_setup: KzgSettings::load_trusted_setup(
|
2023-01-09 07:04:16 +00:00
|
|
|
trusted_setup.g1_points(),
|
|
|
|
trusted_setup.g2_points(),
|
|
|
|
)
|
|
|
|
.map_err(Error::InvalidTrustedSetup)?,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Loads a trusted setup given the path to the file containing the trusted setup values.
|
|
|
|
/// The format is specified in `c_kzg::KzgSettings::load_trusted_setup_file`.
|
|
|
|
///
|
|
|
|
/// Note: This function will likely be deprecated. Use `Kzg::new_from_trusted_setup` instead.
|
|
|
|
#[deprecated]
|
2022-11-15 18:46:52 +00:00
|
|
|
pub fn new_from_file(file_path: PathBuf) -> Result<Self, Error> {
|
|
|
|
Ok(Self {
|
2023-04-11 00:05:01 +00:00
|
|
|
trusted_setup: KzgSettings::load_trusted_setup_file(file_path)
|
2022-11-21 19:51:10 +00:00
|
|
|
.map_err(Error::InvalidTrustedSetup)?,
|
2022-11-15 18:46:52 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-03-14 06:43:15 +00:00
|
|
|
/// Compute the kzg proof given a blob and its kzg commitment.
|
|
|
|
pub fn compute_blob_kzg_proof(
|
|
|
|
&self,
|
|
|
|
blob: Blob,
|
|
|
|
kzg_commitment: KzgCommitment,
|
|
|
|
) -> Result<KzgProof, Error> {
|
2023-04-11 00:05:01 +00:00
|
|
|
c_kzg::KzgProof::compute_blob_kzg_proof(blob, kzg_commitment.into(), &self.trusted_setup)
|
2022-11-21 19:51:10 +00:00
|
|
|
.map_err(Error::KzgProofComputationFailed)
|
2023-03-14 06:43:15 +00:00
|
|
|
.map(|proof| KzgProof(proof.to_bytes().into_inner()))
|
2022-11-21 19:51:10 +00:00
|
|
|
}
|
|
|
|
|
2023-03-14 06:43:15 +00:00
|
|
|
/// Verify a kzg proof given the blob, kzg commitment and kzg proof.
|
|
|
|
pub fn verify_blob_kzg_proof(
|
|
|
|
&self,
|
|
|
|
blob: Blob,
|
|
|
|
kzg_commitment: KzgCommitment,
|
|
|
|
kzg_proof: KzgProof,
|
|
|
|
) -> Result<bool, Error> {
|
2023-04-11 00:05:01 +00:00
|
|
|
c_kzg::KzgProof::verify_blob_kzg_proof(
|
2023-03-14 06:43:15 +00:00
|
|
|
blob,
|
|
|
|
kzg_commitment.into(),
|
|
|
|
kzg_proof.into(),
|
|
|
|
&self.trusted_setup,
|
|
|
|
)
|
|
|
|
.map_err(Error::InvalidKzgProof)
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Verify a batch of blob commitment proof triplets.
|
|
|
|
///
|
|
|
|
/// Note: This method is slightly faster than calling `Self::verify_blob_kzg_proof` in a loop sequentially.
|
|
|
|
/// TODO(pawan): test performance against a parallelized rayon impl.
|
|
|
|
pub fn verify_blob_kzg_proof_batch(
|
2022-11-21 19:51:10 +00:00
|
|
|
&self,
|
|
|
|
blobs: &[Blob],
|
2023-03-14 06:43:15 +00:00
|
|
|
kzg_commitments: &[KzgCommitment],
|
|
|
|
kzg_proofs: &[KzgProof],
|
2022-11-21 19:51:10 +00:00
|
|
|
) -> Result<bool, Error> {
|
2023-03-14 06:43:15 +00:00
|
|
|
let commitments_bytes = kzg_commitments
|
|
|
|
.iter()
|
|
|
|
.map(|comm| Bytes48::from_bytes(&comm.0))
|
|
|
|
.collect::<Result<Vec<Bytes48>, _>>()
|
|
|
|
.map_err(Error::InvalidBytes)?;
|
|
|
|
|
|
|
|
let proofs_bytes = kzg_proofs
|
2023-01-26 19:18:59 +00:00
|
|
|
.iter()
|
2023-03-14 06:43:15 +00:00
|
|
|
.map(|proof| Bytes48::from_bytes(&proof.0))
|
|
|
|
.collect::<Result<Vec<Bytes48>, _>>()
|
|
|
|
.map_err(Error::InvalidBytes)?;
|
2023-04-11 00:05:01 +00:00
|
|
|
c_kzg::KzgProof::verify_blob_kzg_proof_batch(
|
2023-03-14 06:43:15 +00:00
|
|
|
blobs,
|
|
|
|
&commitments_bytes,
|
|
|
|
&proofs_bytes,
|
|
|
|
&self.trusted_setup,
|
|
|
|
)
|
|
|
|
.map_err(Error::InvalidKzgProof)
|
2022-11-21 19:51:10 +00:00
|
|
|
}
|
2022-11-15 18:46:52 +00:00
|
|
|
|
2023-01-09 07:04:16 +00:00
|
|
|
/// Converts a blob to a kzg commitment.
|
2023-03-14 06:43:15 +00:00
|
|
|
pub fn blob_to_kzg_commitment(&self, blob: Blob) -> Result<KzgCommitment, Error> {
|
2023-04-11 00:05:01 +00:00
|
|
|
c_kzg::KzgCommitment::blob_to_kzg_commitment(blob, &self.trusted_setup)
|
2023-03-14 06:43:15 +00:00
|
|
|
.map_err(Error::InvalidBlob)
|
|
|
|
.map(|com| KzgCommitment(com.to_bytes().into_inner()))
|
2022-11-21 19:51:10 +00:00
|
|
|
}
|
2022-11-15 18:46:52 +00:00
|
|
|
}
|