Merge branch 'deneb-free-blobs' into get-validator-block-and-blobs
This commit is contained in:
commit
e4608d44ea
3
Cargo.lock
generated
3
Cargo.lock
generated
@ -892,10 +892,11 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "c-kzg"
|
name = "c-kzg"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/ethereum/c-kzg-4844?rev=69f6155d7524247be9d3f54ab3bfbe33a0345622#69f6155d7524247be9d3f54ab3bfbe33a0345622"
|
source = "git+https://github.com/ethereum/c-kzg-4844?rev=549739fcb3aaec6fe5651e1912f05c604b45621b#549739fcb3aaec6fe5651e1912f05c604b45621b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hex",
|
"hex",
|
||||||
"libc",
|
"libc",
|
||||||
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
use kzg::{Error as KzgError, Kzg, BYTES_PER_BLOB};
|
use kzg::{Error as KzgError, Kzg, BYTES_PER_BLOB};
|
||||||
use types::{Blob, BlobsSidecar, EthSpec, Hash256, KzgCommitment, KzgProof, Slot};
|
use types::{Blob, EthSpec, KzgCommitment, KzgProof};
|
||||||
|
|
||||||
|
/// Converts a blob ssz List object to an array to be used with the kzg
|
||||||
|
/// crypto library.
|
||||||
fn ssz_blob_to_crypto_blob<T: EthSpec>(blob: Blob<T>) -> kzg::Blob {
|
fn ssz_blob_to_crypto_blob<T: EthSpec>(blob: Blob<T>) -> kzg::Blob {
|
||||||
let blob_vec: Vec<u8> = blob.into();
|
let blob_vec: Vec<u8> = blob.into();
|
||||||
let mut arr = [0; BYTES_PER_BLOB];
|
let mut arr = [0; BYTES_PER_BLOB];
|
||||||
@ -8,47 +10,48 @@ fn ssz_blob_to_crypto_blob<T: EthSpec>(blob: Blob<T>) -> kzg::Blob {
|
|||||||
arr.into()
|
arr.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn validate_blobs_sidecar<T: EthSpec>(
|
/// Validate a single blob-commitment-proof triplet from a `BlobSidecar`.
|
||||||
|
pub fn validate_blob<T: EthSpec>(
|
||||||
kzg: &Kzg,
|
kzg: &Kzg,
|
||||||
slot: Slot,
|
blob: Blob<T>,
|
||||||
beacon_block_root: Hash256,
|
kzg_commitment: KzgCommitment,
|
||||||
expected_kzg_commitments: &[KzgCommitment],
|
kzg_proof: KzgProof,
|
||||||
blobs_sidecar: &BlobsSidecar<T>,
|
|
||||||
) -> Result<bool, KzgError> {
|
) -> Result<bool, KzgError> {
|
||||||
if slot != blobs_sidecar.beacon_block_slot
|
kzg.verify_blob_kzg_proof(
|
||||||
|| beacon_block_root != blobs_sidecar.beacon_block_root
|
ssz_blob_to_crypto_blob::<T>(blob),
|
||||||
|| blobs_sidecar.blobs.len() != expected_kzg_commitments.len()
|
kzg_commitment,
|
||||||
{
|
kzg_proof,
|
||||||
return Ok(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
let blobs = blobs_sidecar
|
|
||||||
.blobs
|
|
||||||
.clone() // TODO(pawan): avoid this clone
|
|
||||||
.into_iter()
|
|
||||||
.map(|blob| ssz_blob_to_crypto_blob::<T>(blob))
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
kzg.verify_aggregate_kzg_proof(
|
|
||||||
&blobs,
|
|
||||||
expected_kzg_commitments,
|
|
||||||
blobs_sidecar.kzg_aggregated_proof,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compute_aggregate_kzg_proof<T: EthSpec>(
|
/// Validate a batch of blob-commitment-proof triplets from multiple `BlobSidecars`.
|
||||||
|
pub fn validate_blobs<T: EthSpec>(
|
||||||
kzg: &Kzg,
|
kzg: &Kzg,
|
||||||
|
expected_kzg_commitments: &[KzgCommitment],
|
||||||
blobs: &[Blob<T>],
|
blobs: &[Blob<T>],
|
||||||
) -> Result<KzgProof, KzgError> {
|
kzg_proofs: &[KzgProof],
|
||||||
|
) -> Result<bool, KzgError> {
|
||||||
let blobs = blobs
|
let blobs = blobs
|
||||||
.iter()
|
.iter()
|
||||||
.map(|blob| ssz_blob_to_crypto_blob::<T>(blob.clone())) // TODO(pawan): avoid this clone
|
.map(|blob| ssz_blob_to_crypto_blob::<T>(blob.clone())) // Avoid this clone
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
kzg.compute_aggregate_kzg_proof(&blobs)
|
kzg.verify_blob_kzg_proof_batch(&blobs, expected_kzg_commitments, kzg_proofs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn blob_to_kzg_commitment<T: EthSpec>(kzg: &Kzg, blob: Blob<T>) -> KzgCommitment {
|
/// Compute the kzg proof given an ssz blob and its kzg commitment.
|
||||||
let blob = ssz_blob_to_crypto_blob::<T>(blob);
|
pub fn compute_blob_kzg_proof<T: EthSpec>(
|
||||||
kzg.blob_to_kzg_commitment(blob)
|
kzg: &Kzg,
|
||||||
|
blob: Blob<T>,
|
||||||
|
kzg_commitment: KzgCommitment,
|
||||||
|
) -> Result<KzgProof, KzgError> {
|
||||||
|
kzg.compute_blob_kzg_proof(ssz_blob_to_crypto_blob::<T>(blob), kzg_commitment)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compute the kzg commitment for a given blob.
|
||||||
|
pub fn blob_to_kzg_commitment<T: EthSpec>(
|
||||||
|
kzg: &Kzg,
|
||||||
|
blob: Blob<T>,
|
||||||
|
) -> Result<KzgCommitment, KzgError> {
|
||||||
|
kzg.blob_to_kzg_commitment(ssz_blob_to_crypto_blob::<T>(blob))
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ serde_derive = "1.0.116"
|
|||||||
eth2_serde_utils = "0.1.1"
|
eth2_serde_utils = "0.1.1"
|
||||||
hex = "0.4.2"
|
hex = "0.4.2"
|
||||||
eth2_hashing = "0.3.0"
|
eth2_hashing = "0.3.0"
|
||||||
c-kzg = {git = "https://github.com/ethereum/c-kzg-4844", rev = "69f6155d7524247be9d3f54ab3bfbe33a0345622" }
|
c-kzg = {git = "https://github.com/ethereum/c-kzg-4844", rev = "549739fcb3aaec6fe5651e1912f05c604b45621b" }
|
||||||
arbitrary = { version = "1.0", features = ["derive"], optional = true }
|
arbitrary = { version = "1.0", features = ["derive"], optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use c_kzg::{Bytes48, BYTES_PER_COMMITMENT};
|
||||||
use derivative::Derivative;
|
use derivative::Derivative;
|
||||||
use serde::de::{Deserialize, Deserializer};
|
use serde::de::{Deserialize, Deserializer};
|
||||||
use serde::ser::{Serialize, Serializer};
|
use serde::ser::{Serialize, Serializer};
|
||||||
@ -7,12 +8,16 @@ use std::fmt::{Debug, Display, Formatter};
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use tree_hash::{PackedEncoding, TreeHash};
|
use tree_hash::{PackedEncoding, TreeHash};
|
||||||
|
|
||||||
const KZG_COMMITMENT_BYTES_LEN: usize = 48;
|
|
||||||
|
|
||||||
#[derive(Derivative, Clone, Encode, Decode)]
|
#[derive(Derivative, Clone, Encode, Decode)]
|
||||||
#[derivative(PartialEq, Eq, Hash)]
|
#[derivative(PartialEq, Eq, Hash)]
|
||||||
#[ssz(struct_behaviour = "transparent")]
|
#[ssz(struct_behaviour = "transparent")]
|
||||||
pub struct KzgCommitment(pub [u8; KZG_COMMITMENT_BYTES_LEN]);
|
pub struct KzgCommitment(pub [u8; BYTES_PER_COMMITMENT]);
|
||||||
|
|
||||||
|
impl From<KzgCommitment> for Bytes48 {
|
||||||
|
fn from(value: KzgCommitment) -> Self {
|
||||||
|
value.0.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Display for KzgCommitment {
|
impl Display for KzgCommitment {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
|
||||||
@ -22,13 +27,13 @@ impl Display for KzgCommitment {
|
|||||||
|
|
||||||
impl Default for KzgCommitment {
|
impl Default for KzgCommitment {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
KzgCommitment([0; KZG_COMMITMENT_BYTES_LEN])
|
KzgCommitment([0; BYTES_PER_COMMITMENT])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TreeHash for KzgCommitment {
|
impl TreeHash for KzgCommitment {
|
||||||
fn tree_hash_type() -> tree_hash::TreeHashType {
|
fn tree_hash_type() -> tree_hash::TreeHashType {
|
||||||
<[u8; KZG_COMMITMENT_BYTES_LEN] as TreeHash>::tree_hash_type()
|
<[u8; BYTES_PER_COMMITMENT] as TreeHash>::tree_hash_type()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tree_hash_packed_encoding(&self) -> PackedEncoding {
|
fn tree_hash_packed_encoding(&self) -> PackedEncoding {
|
||||||
@ -36,7 +41,7 @@ impl TreeHash for KzgCommitment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn tree_hash_packing_factor() -> usize {
|
fn tree_hash_packing_factor() -> usize {
|
||||||
<[u8; KZG_COMMITMENT_BYTES_LEN] as TreeHash>::tree_hash_packing_factor()
|
<[u8; BYTES_PER_COMMITMENT] as TreeHash>::tree_hash_packing_factor()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tree_hash_root(&self) -> tree_hash::Hash256 {
|
fn tree_hash_root(&self) -> tree_hash::Hash256 {
|
||||||
@ -86,15 +91,15 @@ impl FromStr for KzgCommitment {
|
|||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
if let Some(stripped) = s.strip_prefix("0x") {
|
if let Some(stripped) = s.strip_prefix("0x") {
|
||||||
let bytes = hex::decode(stripped).map_err(|e| e.to_string())?;
|
let bytes = hex::decode(stripped).map_err(|e| e.to_string())?;
|
||||||
if bytes.len() == KZG_COMMITMENT_BYTES_LEN {
|
if bytes.len() == BYTES_PER_COMMITMENT {
|
||||||
let mut kzg_commitment_bytes = [0; KZG_COMMITMENT_BYTES_LEN];
|
let mut kzg_commitment_bytes = [0; BYTES_PER_COMMITMENT];
|
||||||
kzg_commitment_bytes[..].copy_from_slice(&bytes);
|
kzg_commitment_bytes[..].copy_from_slice(&bytes);
|
||||||
Ok(Self(kzg_commitment_bytes))
|
Ok(Self(kzg_commitment_bytes))
|
||||||
} else {
|
} else {
|
||||||
Err(format!(
|
Err(format!(
|
||||||
"InvalidByteLength: got {}, expected {}",
|
"InvalidByteLength: got {}, expected {}",
|
||||||
bytes.len(),
|
bytes.len(),
|
||||||
KZG_COMMITMENT_BYTES_LEN
|
BYTES_PER_COMMITMENT
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -112,7 +117,7 @@ impl Debug for KzgCommitment {
|
|||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
impl arbitrary::Arbitrary<'_> for KzgCommitment {
|
impl arbitrary::Arbitrary<'_> for KzgCommitment {
|
||||||
fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
|
fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
|
||||||
let mut bytes = [0u8; KZG_COMMITMENT_BYTES_LEN];
|
let mut bytes = [0u8; BYTES_PER_COMMITMENT];
|
||||||
u.fill_buffer(&mut bytes)?;
|
u.fill_buffer(&mut bytes)?;
|
||||||
Ok(KzgCommitment(bytes))
|
Ok(KzgCommitment(bytes))
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
use c_kzg::{Bytes48, BYTES_PER_PROOF};
|
||||||
use serde::de::{Deserialize, Deserializer};
|
use serde::de::{Deserialize, Deserializer};
|
||||||
use serde::ser::{Serialize, Serializer};
|
use serde::ser::{Serialize, Serializer};
|
||||||
use ssz_derive::{Decode, Encode};
|
use ssz_derive::{Decode, Encode};
|
||||||
@ -6,15 +7,19 @@ use std::fmt::Debug;
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use tree_hash::{PackedEncoding, TreeHash};
|
use tree_hash::{PackedEncoding, TreeHash};
|
||||||
|
|
||||||
const KZG_PROOF_BYTES_LEN: usize = 48;
|
|
||||||
|
|
||||||
#[derive(PartialEq, Hash, Clone, Copy, Encode, Decode)]
|
#[derive(PartialEq, Hash, Clone, Copy, Encode, Decode)]
|
||||||
#[ssz(struct_behaviour = "transparent")]
|
#[ssz(struct_behaviour = "transparent")]
|
||||||
pub struct KzgProof(pub [u8; KZG_PROOF_BYTES_LEN]);
|
pub struct KzgProof(pub [u8; BYTES_PER_PROOF]);
|
||||||
|
|
||||||
|
impl From<KzgProof> for Bytes48 {
|
||||||
|
fn from(value: KzgProof) -> Self {
|
||||||
|
value.0.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl KzgProof {
|
impl KzgProof {
|
||||||
pub fn empty() -> Self {
|
pub fn empty() -> Self {
|
||||||
let mut bytes = [0; KZG_PROOF_BYTES_LEN];
|
let mut bytes = [0; BYTES_PER_PROOF];
|
||||||
bytes[0] = 192;
|
bytes[0] = 192;
|
||||||
Self(bytes)
|
Self(bytes)
|
||||||
}
|
}
|
||||||
@ -28,25 +33,25 @@ impl fmt::Display for KzgProof {
|
|||||||
|
|
||||||
impl Default for KzgProof {
|
impl Default for KzgProof {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
KzgProof([0; KZG_PROOF_BYTES_LEN])
|
KzgProof([0; BYTES_PER_PROOF])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<[u8; KZG_PROOF_BYTES_LEN]> for KzgProof {
|
impl From<[u8; BYTES_PER_PROOF]> for KzgProof {
|
||||||
fn from(bytes: [u8; KZG_PROOF_BYTES_LEN]) -> Self {
|
fn from(bytes: [u8; BYTES_PER_PROOF]) -> Self {
|
||||||
Self(bytes)
|
Self(bytes)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<[u8; KZG_PROOF_BYTES_LEN]> for KzgProof {
|
impl Into<[u8; BYTES_PER_PROOF]> for KzgProof {
|
||||||
fn into(self) -> [u8; KZG_PROOF_BYTES_LEN] {
|
fn into(self) -> [u8; BYTES_PER_PROOF] {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TreeHash for KzgProof {
|
impl TreeHash for KzgProof {
|
||||||
fn tree_hash_type() -> tree_hash::TreeHashType {
|
fn tree_hash_type() -> tree_hash::TreeHashType {
|
||||||
<[u8; KZG_PROOF_BYTES_LEN]>::tree_hash_type()
|
<[u8; BYTES_PER_PROOF]>::tree_hash_type()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tree_hash_packed_encoding(&self) -> PackedEncoding {
|
fn tree_hash_packed_encoding(&self) -> PackedEncoding {
|
||||||
@ -54,7 +59,7 @@ impl TreeHash for KzgProof {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn tree_hash_packing_factor() -> usize {
|
fn tree_hash_packing_factor() -> usize {
|
||||||
<[u8; KZG_PROOF_BYTES_LEN]>::tree_hash_packing_factor()
|
<[u8; BYTES_PER_PROOF]>::tree_hash_packing_factor()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tree_hash_root(&self) -> tree_hash::Hash256 {
|
fn tree_hash_root(&self) -> tree_hash::Hash256 {
|
||||||
@ -104,15 +109,15 @@ impl FromStr for KzgProof {
|
|||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
if let Some(stripped) = s.strip_prefix("0x") {
|
if let Some(stripped) = s.strip_prefix("0x") {
|
||||||
let bytes = hex::decode(stripped).map_err(|e| e.to_string())?;
|
let bytes = hex::decode(stripped).map_err(|e| e.to_string())?;
|
||||||
if bytes.len() == KZG_PROOF_BYTES_LEN {
|
if bytes.len() == BYTES_PER_PROOF {
|
||||||
let mut kzg_proof_bytes = [0; KZG_PROOF_BYTES_LEN];
|
let mut kzg_proof_bytes = [0; BYTES_PER_PROOF];
|
||||||
kzg_proof_bytes[..].copy_from_slice(&bytes);
|
kzg_proof_bytes[..].copy_from_slice(&bytes);
|
||||||
Ok(Self(kzg_proof_bytes))
|
Ok(Self(kzg_proof_bytes))
|
||||||
} else {
|
} else {
|
||||||
Err(format!(
|
Err(format!(
|
||||||
"InvalidByteLength: got {}, expected {}",
|
"InvalidByteLength: got {}, expected {}",
|
||||||
bytes.len(),
|
bytes.len(),
|
||||||
KZG_PROOF_BYTES_LEN
|
BYTES_PER_PROOF
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -130,7 +135,7 @@ impl Debug for KzgProof {
|
|||||||
#[cfg(feature = "arbitrary")]
|
#[cfg(feature = "arbitrary")]
|
||||||
impl arbitrary::Arbitrary<'_> for KzgProof {
|
impl arbitrary::Arbitrary<'_> for KzgProof {
|
||||||
fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
|
fn arbitrary(u: &mut arbitrary::Unstructured<'_>) -> arbitrary::Result<Self> {
|
||||||
let mut bytes = [0u8; KZG_PROOF_BYTES_LEN];
|
let mut bytes = [0u8; BYTES_PER_PROOF];
|
||||||
u.fill_buffer(&mut bytes)?;
|
u.fill_buffer(&mut bytes)?;
|
||||||
Ok(KzgProof(bytes))
|
Ok(KzgProof(bytes))
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ mod kzg_proof;
|
|||||||
mod trusted_setup;
|
mod trusted_setup;
|
||||||
|
|
||||||
pub use crate::{kzg_commitment::KzgCommitment, kzg_proof::KzgProof, trusted_setup::TrustedSetup};
|
pub use crate::{kzg_commitment::KzgCommitment, kzg_proof::KzgProof, trusted_setup::TrustedSetup};
|
||||||
|
use c_kzg::Bytes48;
|
||||||
pub use c_kzg::{
|
pub use c_kzg::{
|
||||||
Blob, Error as CKzgError, KZGSettings, BYTES_PER_BLOB, BYTES_PER_FIELD_ELEMENT,
|
Blob, Error as CKzgError, KZGSettings, BYTES_PER_BLOB, BYTES_PER_FIELD_ELEMENT,
|
||||||
FIELD_ELEMENTS_PER_BLOB,
|
FIELD_ELEMENTS_PER_BLOB,
|
||||||
@ -13,9 +14,9 @@ use std::path::PathBuf;
|
|||||||
pub enum Error {
|
pub enum Error {
|
||||||
InvalidTrustedSetup(CKzgError),
|
InvalidTrustedSetup(CKzgError),
|
||||||
InvalidKzgProof(CKzgError),
|
InvalidKzgProof(CKzgError),
|
||||||
InvalidLength(String),
|
InvalidBytes(CKzgError),
|
||||||
KzgProofComputationFailed(CKzgError),
|
KzgProofComputationFailed(CKzgError),
|
||||||
InvalidBlob(String),
|
InvalidBlob(CKzgError),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A wrapper over a kzg library that holds the trusted setup parameters.
|
/// A wrapper over a kzg library that holds the trusted setup parameters.
|
||||||
@ -51,40 +52,67 @@ impl Kzg {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the aggregated kzg proof given an array of blobs.
|
/// Compute the kzg proof given a blob and its kzg commitment.
|
||||||
pub fn compute_aggregate_kzg_proof(&self, blobs: &[Blob]) -> Result<KzgProof, Error> {
|
pub fn compute_blob_kzg_proof(
|
||||||
c_kzg::KZGProof::compute_aggregate_kzg_proof(blobs, &self.trusted_setup)
|
&self,
|
||||||
|
blob: Blob,
|
||||||
|
kzg_commitment: KzgCommitment,
|
||||||
|
) -> Result<KzgProof, Error> {
|
||||||
|
c_kzg::KZGProof::compute_blob_kzg_proof(blob, kzg_commitment.into(), &self.trusted_setup)
|
||||||
.map_err(Error::KzgProofComputationFailed)
|
.map_err(Error::KzgProofComputationFailed)
|
||||||
.map(|proof| KzgProof(proof.to_bytes()))
|
.map(|proof| KzgProof(proof.to_bytes().into_inner()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Verify an aggregate kzg proof given the blobs that generated the proof, the kzg commitments
|
/// Verify a kzg proof given the blob, kzg commitment and kzg proof.
|
||||||
/// and the kzg proof.
|
pub fn verify_blob_kzg_proof(
|
||||||
pub fn verify_aggregate_kzg_proof(
|
&self,
|
||||||
|
blob: Blob,
|
||||||
|
kzg_commitment: KzgCommitment,
|
||||||
|
kzg_proof: KzgProof,
|
||||||
|
) -> Result<bool, Error> {
|
||||||
|
c_kzg::KZGProof::verify_blob_kzg_proof(
|
||||||
|
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(
|
||||||
&self,
|
&self,
|
||||||
blobs: &[Blob],
|
blobs: &[Blob],
|
||||||
expected_kzg_commitments: &[KzgCommitment],
|
kzg_commitments: &[KzgCommitment],
|
||||||
kzg_aggregated_proof: KzgProof,
|
kzg_proofs: &[KzgProof],
|
||||||
) -> Result<bool, Error> {
|
) -> Result<bool, Error> {
|
||||||
if blobs.len() != expected_kzg_commitments.len() {
|
let commitments_bytes = kzg_commitments
|
||||||
return Err(Error::InvalidLength(
|
|
||||||
"blobs and expected_kzg_commitments should be of same size".to_string(),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
let commitments = expected_kzg_commitments
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(|comm| comm.0.into())
|
.map(|comm| Bytes48::from_bytes(&comm.0))
|
||||||
.collect::<Vec<c_kzg::KZGCommitment>>();
|
.collect::<Result<Vec<Bytes48>, _>>()
|
||||||
let proof: c_kzg::KZGProof = kzg_aggregated_proof.0.into();
|
.map_err(Error::InvalidBytes)?;
|
||||||
proof
|
|
||||||
.verify_aggregate_kzg_proof(blobs, &commitments, &self.trusted_setup)
|
let proofs_bytes = kzg_proofs
|
||||||
.map_err(Error::InvalidKzgProof)
|
.iter()
|
||||||
|
.map(|proof| Bytes48::from_bytes(&proof.0))
|
||||||
|
.collect::<Result<Vec<Bytes48>, _>>()
|
||||||
|
.map_err(Error::InvalidBytes)?;
|
||||||
|
c_kzg::KZGProof::verify_blob_kzg_proof_batch(
|
||||||
|
blobs,
|
||||||
|
&commitments_bytes,
|
||||||
|
&proofs_bytes,
|
||||||
|
&self.trusted_setup,
|
||||||
|
)
|
||||||
|
.map_err(Error::InvalidKzgProof)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a blob to a kzg commitment.
|
/// Converts a blob to a kzg commitment.
|
||||||
pub fn blob_to_kzg_commitment(&self, blob: Blob) -> KzgCommitment {
|
pub fn blob_to_kzg_commitment(&self, blob: Blob) -> Result<KzgCommitment, Error> {
|
||||||
KzgCommitment(
|
c_kzg::KZGCommitment::blob_to_kzg_commitment(blob, &self.trusted_setup)
|
||||||
c_kzg::KZGCommitment::blob_to_kzg_commitment(blob, &self.trusted_setup).to_bytes(),
|
.map_err(Error::InvalidBlob)
|
||||||
)
|
.map(|com| KzgCommitment(com.to_bytes().into_inner()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user