2022-11-15 18:46:52 +00:00
|
|
|
mod kzg_commitment;
|
|
|
|
mod kzg_proof;
|
|
|
|
|
2022-11-21 19:51:10 +00:00
|
|
|
pub use crate::{kzg_commitment::KzgCommitment, kzg_proof::KzgProof};
|
2022-11-28 14:53:15 +00:00
|
|
|
pub use c_kzg::bytes_to_g1;
|
2022-12-14 15:55:42 +00:00
|
|
|
pub use c_kzg::{
|
|
|
|
Error as CKzgError, KZGSettings, BYTES_PER_BLOB, BYTES_PER_FIELD_ELEMENT,
|
|
|
|
FIELD_ELEMENTS_PER_BLOB,
|
|
|
|
};
|
2022-11-15 18:46:52 +00:00
|
|
|
use std::path::PathBuf;
|
|
|
|
|
2022-11-21 19:51:10 +00:00
|
|
|
/// The consensus type `Blob` is generic over EthSpec, so it cannot be imported
|
|
|
|
/// in this crate without creating a cyclic dependency between the kzg and consensus/types crates.
|
|
|
|
/// So need to use a Vec here unless we think of a smarter way of doing this
|
|
|
|
type Blob = [u8; BYTES_PER_BLOB];
|
2022-11-15 18:46:52 +00:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum Error {
|
|
|
|
InvalidTrustedSetup(CKzgError),
|
2022-11-21 19:51:10 +00:00
|
|
|
InvalidKzgCommitment(CKzgError),
|
|
|
|
InvalidKzgProof(CKzgError),
|
|
|
|
KzgVerificationFailed(CKzgError),
|
|
|
|
InvalidLength(String),
|
|
|
|
KzgProofComputationFailed(CKzgError),
|
2022-11-29 10:34:16 +00:00
|
|
|
InvalidBlob(String),
|
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.
|
2022-11-15 18:46:52 +00:00
|
|
|
pub struct Kzg {
|
2022-11-21 19:51:10 +00:00
|
|
|
trusted_setup: KZGSettings,
|
2022-11-15 18:46:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Kzg {
|
|
|
|
pub fn new_from_file(file_path: PathBuf) -> Result<Self, Error> {
|
|
|
|
Ok(Self {
|
2022-12-14 15:55:42 +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
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-11-21 19:51:10 +00:00
|
|
|
pub fn compute_aggregate_kzg_proof(&self, blobs: &[Blob]) -> Result<KzgProof, Error> {
|
|
|
|
c_kzg::KZGProof::compute_aggregate_kzg_proof(blobs, &self.trusted_setup)
|
|
|
|
.map_err(Error::KzgProofComputationFailed)
|
|
|
|
.map(|proof| KzgProof(proof.to_bytes()))
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn verify_aggregate_kzg_proof(
|
|
|
|
&self,
|
|
|
|
blobs: &[Blob],
|
|
|
|
expected_kzg_commitments: &[KzgCommitment],
|
|
|
|
kzg_aggregated_proof: KzgProof,
|
|
|
|
) -> Result<bool, Error> {
|
|
|
|
if blobs.len() != expected_kzg_commitments.len() {
|
|
|
|
return Err(Error::InvalidLength(
|
|
|
|
"blobs and expected_kzg_commitments should be of same size".to_string(),
|
|
|
|
));
|
|
|
|
}
|
|
|
|
let commitments = expected_kzg_commitments
|
|
|
|
.into_iter()
|
|
|
|
.map(|comm| {
|
|
|
|
c_kzg::KZGCommitment::from_bytes(&comm.0).map_err(Error::InvalidKzgCommitment)
|
|
|
|
})
|
|
|
|
.collect::<Result<Vec<c_kzg::KZGCommitment>, Error>>()?;
|
|
|
|
let proof =
|
|
|
|
c_kzg::KZGProof::from_bytes(&kzg_aggregated_proof.0).map_err(Error::InvalidKzgProof)?;
|
|
|
|
proof
|
|
|
|
.verify_aggregate_kzg_proof(blobs, &commitments, &self.trusted_setup)
|
|
|
|
.map_err(Error::InvalidKzgProof)
|
|
|
|
}
|
2022-11-15 18:46:52 +00:00
|
|
|
|
2022-11-21 19:51:10 +00:00
|
|
|
pub fn blob_to_kzg_commitment(&self, blob: Blob) -> KzgCommitment {
|
|
|
|
KzgCommitment(
|
|
|
|
c_kzg::KZGCommitment::blob_to_kzg_commitment(blob, &self.trusted_setup).to_bytes(),
|
|
|
|
)
|
|
|
|
}
|
2022-11-15 18:46:52 +00:00
|
|
|
}
|