Remove c-kzg (#8930)

#7330


  Removes `c-kzg` from our `kzg` crate and rely fully on the `rust_eth_kzg` crate.

This removes the old `Blob` type entirely and instead handles `rust_eth_kzg::KzgBlobRef`s directly which allows us to avoid some extra stack allocations . Similarly, we make `Bytes32` and `Bytes48` type aliases rather than structs as this fits better with the new `rust_eth_kzg` API.


Co-Authored-By: Mac L <mjladson@pm.me>
This commit is contained in:
Mac L
2026-03-11 07:43:26 +02:00
committed by GitHub
parent 2bb79f43aa
commit 815040dc3c
14 changed files with 129 additions and 188 deletions

View File

@@ -1,6 +1,5 @@
use kzg::{
Blob as KzgBlob, Bytes48, Cell as KzgCell, CellRef as KzgCellRef, CellsAndKzgProofs,
Error as KzgError, Kzg, KzgBlobRef,
Cell as KzgCell, CellRef as KzgCellRef, CellsAndKzgProofs, Error as KzgError, Kzg, KzgBlobRef,
};
use rayon::prelude::*;
use ssz_types::{FixedVector, VariableList};
@@ -15,18 +14,18 @@ use types::{
SignedBeaconBlock, SignedBeaconBlockHeader, SignedBlindedBeaconBlock, Slot,
};
/// Converts a blob ssz List object to an array to be used with the kzg
/// crypto library.
fn ssz_blob_to_crypto_blob<E: EthSpec>(blob: &Blob<E>) -> Result<KzgBlob, KzgError> {
KzgBlob::from_bytes(blob.as_ref()).map_err(Into::into)
/// Converts a blob ssz FixedVector to a reference to a fixed-size array
/// to be used with `rust_eth_kzg`.
fn ssz_blob_to_kzg_blob_ref<E: EthSpec>(blob: &Blob<E>) -> Result<KzgBlobRef<'_>, KzgError> {
blob.as_ref().try_into().map_err(|e| {
KzgError::InconsistentArrayLength(format!(
"blob should have a guaranteed size due to FixedVector: {e:?}"
))
})
}
fn ssz_blob_to_crypto_blob_boxed<E: EthSpec>(blob: &Blob<E>) -> Result<Box<KzgBlob>, KzgError> {
ssz_blob_to_crypto_blob::<E>(blob).map(Box::new)
}
/// Converts a cell ssz List object to an array to be used with the kzg
/// crypto library.
/// Converts a cell ssz FixedVector to a reference to a fixed-size array
/// to be used with `rust_eth_kzg`.
fn ssz_cell_to_crypto_cell<E: EthSpec>(cell: &Cell<E>) -> Result<KzgCellRef<'_>, KzgError> {
let cell_bytes: &[u8] = cell.as_ref();
cell_bytes
@@ -42,8 +41,8 @@ pub fn validate_blob<E: EthSpec>(
kzg_proof: KzgProof,
) -> Result<(), KzgError> {
let _timer = crate::metrics::start_timer(&crate::metrics::KZG_VERIFICATION_SINGLE_TIMES);
let kzg_blob = ssz_blob_to_crypto_blob_boxed::<E>(blob)?;
kzg.verify_blob_kzg_proof(&kzg_blob, kzg_commitment, kzg_proof)
let kzg_blob = ssz_blob_to_kzg_blob_ref::<E>(blob)?;
kzg.verify_blob_kzg_proof(kzg_blob, kzg_commitment, kzg_proof)
}
/// Validate a batch of `DataColumnSidecar`.
@@ -72,7 +71,7 @@ where
}
for &proof in data_column.kzg_proofs() {
proofs.push(Bytes48::from(proof));
proofs.push(proof.0);
}
// In Gloas, commitments come from the block's ExecutionPayloadBid, not the sidecar.
@@ -90,7 +89,7 @@ where
};
for &commitment in kzg_commitments.iter() {
commitments.push(Bytes48::from(commitment));
commitments.push(commitment.0);
}
let expected_len = column_indices.len();
@@ -120,7 +119,7 @@ pub fn validate_blobs<E: EthSpec>(
let _timer = crate::metrics::start_timer(&crate::metrics::KZG_VERIFICATION_BATCH_TIMES);
let blobs = blobs
.into_iter()
.map(|blob| ssz_blob_to_crypto_blob::<E>(blob))
.map(|blob| ssz_blob_to_kzg_blob_ref::<E>(blob))
.collect::<Result<Vec<_>, KzgError>>()?;
kzg.verify_blob_kzg_proof_batch(&blobs, expected_kzg_commitments, kzg_proofs)
@@ -132,8 +131,8 @@ pub fn compute_blob_kzg_proof<E: EthSpec>(
blob: &Blob<E>,
kzg_commitment: KzgCommitment,
) -> Result<KzgProof, KzgError> {
let kzg_blob = ssz_blob_to_crypto_blob_boxed::<E>(blob)?;
kzg.compute_blob_kzg_proof(&kzg_blob, kzg_commitment)
let kzg_blob = ssz_blob_to_kzg_blob_ref::<E>(blob)?;
kzg.compute_blob_kzg_proof(kzg_blob, kzg_commitment)
}
/// Compute the kzg commitment for a given blob.
@@ -141,8 +140,8 @@ pub fn blob_to_kzg_commitment<E: EthSpec>(
kzg: &Kzg,
blob: &Blob<E>,
) -> Result<KzgCommitment, KzgError> {
let kzg_blob = ssz_blob_to_crypto_blob_boxed::<E>(blob)?;
kzg.blob_to_kzg_commitment(&kzg_blob)
let kzg_blob = ssz_blob_to_kzg_blob_ref::<E>(blob)?;
kzg.blob_to_kzg_commitment(kzg_blob)
}
/// Compute the kzg proof for a given blob and an evaluation point z.
@@ -151,10 +150,9 @@ pub fn compute_kzg_proof<E: EthSpec>(
blob: &Blob<E>,
z: Hash256,
) -> Result<(KzgProof, Hash256), KzgError> {
let z = z.0.into();
let kzg_blob = ssz_blob_to_crypto_blob_boxed::<E>(blob)?;
kzg.compute_kzg_proof(&kzg_blob, &z)
.map(|(proof, z)| (proof, Hash256::from_slice(&z.to_vec())))
let kzg_blob = ssz_blob_to_kzg_blob_ref::<E>(blob)?;
kzg.compute_kzg_proof(kzg_blob, &z.0)
.map(|(proof, z)| (proof, Hash256::from_slice(&z)))
}
/// Verify a `kzg_proof` for a `kzg_commitment` that evaluating a polynomial at `z` results in `y`
@@ -165,7 +163,7 @@ pub fn verify_kzg_proof<E: EthSpec>(
z: Hash256,
y: Hash256,
) -> Result<bool, KzgError> {
kzg.verify_kzg_proof(kzg_commitment, &z.0.into(), &y.0.into(), kzg_proof)
kzg.verify_kzg_proof(kzg_commitment, &z.0, &y.0, kzg_proof)
}
/// Build data column sidecars from a signed beacon block and its blobs.

View File

@@ -989,7 +989,7 @@ pub fn generate_pow_block(
#[cfg(test)]
mod test {
use super::*;
use kzg::{Bytes48, CellRef, KzgBlobRef, trusted_setup::get_trusted_setup};
use kzg::{CellRef, KzgBlobRef, trusted_setup::get_trusted_setup};
use types::{MainnetEthSpec, MinimalEthSpec};
#[test]
@@ -1015,10 +1015,11 @@ mod test {
fn validate_blob_bundle_v1<E: EthSpec>() -> Result<(), String> {
let kzg = load_kzg()?;
let (kzg_commitment, kzg_proof, blob) = load_test_blobs_bundle_v1::<E>()?;
let kzg_blob = kzg::Blob::from_bytes(blob.as_ref())
.map(Box::new)
.map_err(|e| format!("Error converting blob to kzg blob: {e:?}"))?;
kzg.verify_blob_kzg_proof(&kzg_blob, kzg_commitment, kzg_proof)
let kzg_blob: KzgBlobRef = blob
.as_ref()
.try_into()
.map_err(|e| format!("Error converting blob to kzg blob ref: {e:?}"))?;
kzg.verify_blob_kzg_proof(kzg_blob, kzg_commitment, kzg_proof)
.map_err(|e| format!("Invalid blobs bundle: {e:?}"))
}
@@ -1028,8 +1029,8 @@ mod test {
load_test_blobs_bundle_v2::<E>().map(|(commitment, proofs, blob)| {
let kzg_blob: KzgBlobRef = blob.as_ref().try_into().unwrap();
(
vec![Bytes48::from(commitment); proofs.len()],
proofs.into_iter().map(|p| p.into()).collect::<Vec<_>>(),
vec![commitment.0; proofs.len()],
proofs.into_iter().map(|p| p.0).collect::<Vec<_>>(),
kzg.compute_cells(kzg_blob).unwrap(),
)
})?;