Implement KZG EF Tests (#4274)
This commit is contained in:
parent
9db6b39dc3
commit
a22e4bf636
4
Cargo.lock
generated
4
Cargo.lock
generated
@ -2004,6 +2004,8 @@ dependencies = [
|
|||||||
"compare_fields",
|
"compare_fields",
|
||||||
"compare_fields_derive",
|
"compare_fields_derive",
|
||||||
"derivative",
|
"derivative",
|
||||||
|
"eth2_network_config",
|
||||||
|
"eth2_serde_utils",
|
||||||
"eth2_ssz",
|
"eth2_ssz",
|
||||||
"eth2_ssz_derive",
|
"eth2_ssz_derive",
|
||||||
"ethereum-types 0.14.1",
|
"ethereum-types 0.14.1",
|
||||||
@ -2011,9 +2013,11 @@ dependencies = [
|
|||||||
"fork_choice",
|
"fork_choice",
|
||||||
"fs2",
|
"fs2",
|
||||||
"hex",
|
"hex",
|
||||||
|
"kzg",
|
||||||
"rayon",
|
"rayon",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
"serde_repr",
|
"serde_repr",
|
||||||
"serde_yaml",
|
"serde_yaml",
|
||||||
"snap",
|
"snap",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use kzg::{Error as KzgError, Kzg, BYTES_PER_BLOB};
|
use kzg::{Error as KzgError, Kzg, BYTES_PER_BLOB};
|
||||||
use types::{Blob, EthSpec, KzgCommitment, KzgProof};
|
use types::{Blob, EthSpec, Hash256, KzgCommitment, KzgProof};
|
||||||
|
|
||||||
/// Converts a blob ssz List object to an array to be used with the kzg
|
/// Converts a blob ssz List object to an array to be used with the kzg
|
||||||
/// crypto library.
|
/// crypto library.
|
||||||
@ -56,3 +56,25 @@ pub fn blob_to_kzg_commitment<T: EthSpec>(
|
|||||||
) -> Result<KzgCommitment, KzgError> {
|
) -> Result<KzgCommitment, KzgError> {
|
||||||
kzg.blob_to_kzg_commitment(ssz_blob_to_crypto_blob::<T>(blob))
|
kzg.blob_to_kzg_commitment(ssz_blob_to_crypto_blob::<T>(blob))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Compute the kzg proof for a given blob and an evaluation point z.
|
||||||
|
pub fn compute_kzg_proof<T: EthSpec>(
|
||||||
|
kzg: &Kzg,
|
||||||
|
blob: Blob<T>,
|
||||||
|
z: Hash256,
|
||||||
|
) -> Result<(KzgProof, Hash256), KzgError> {
|
||||||
|
let z = z.0.into();
|
||||||
|
kzg.compute_kzg_proof(ssz_blob_to_crypto_blob::<T>(blob), z)
|
||||||
|
.map(|(proof, z)| (proof, Hash256::from_slice(&z.to_vec())))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Verify a `kzg_proof` for a `kzg_commitment` that evaluating a polynomial at `z` results in `y`
|
||||||
|
pub fn verify_kzg_proof<T: EthSpec>(
|
||||||
|
kzg: &Kzg,
|
||||||
|
kzg_commitment: KzgCommitment,
|
||||||
|
kzg_proof: KzgProof,
|
||||||
|
z: Hash256,
|
||||||
|
y: Hash256,
|
||||||
|
) -> Result<bool, KzgError> {
|
||||||
|
kzg.verify_kzg_proof(kzg_commitment, z.0.into(), y.0.into(), kzg_proof)
|
||||||
|
}
|
||||||
|
@ -3,11 +3,11 @@ 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,
|
||||||
};
|
};
|
||||||
|
use c_kzg::{Bytes32, Bytes48};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@ -116,4 +116,29 @@ impl Kzg {
|
|||||||
.map_err(Error::InvalidBlob)
|
.map_err(Error::InvalidBlob)
|
||||||
.map(|com| KzgCommitment(com.to_bytes().into_inner()))
|
.map(|com| KzgCommitment(com.to_bytes().into_inner()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Computes the kzg proof for a given `blob` and an evaluation point `z`
|
||||||
|
pub fn compute_kzg_proof(&self, blob: Blob, z: Bytes32) -> Result<(KzgProof, Bytes32), Error> {
|
||||||
|
c_kzg::KzgProof::compute_kzg_proof(blob, z, &self.trusted_setup)
|
||||||
|
.map_err(Error::KzgProofComputationFailed)
|
||||||
|
.map(|(proof, y)| (KzgProof(proof.to_bytes().into_inner()), y))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Verifies a `kzg_proof` for a `kzg_commitment` that evaluating a polynomial at `z` results in `y`
|
||||||
|
pub fn verify_kzg_proof(
|
||||||
|
&self,
|
||||||
|
kzg_commitment: KzgCommitment,
|
||||||
|
z: Bytes32,
|
||||||
|
y: Bytes32,
|
||||||
|
kzg_proof: KzgProof,
|
||||||
|
) -> Result<bool, Error> {
|
||||||
|
c_kzg::KzgProof::verify_kzg_proof(
|
||||||
|
kzg_commitment.into(),
|
||||||
|
z,
|
||||||
|
y,
|
||||||
|
kzg_proof.into(),
|
||||||
|
&self.trusted_setup,
|
||||||
|
)
|
||||||
|
.map_err(Error::InvalidKzgProof)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,11 +17,15 @@ compare_fields_derive = { path = "../../common/compare_fields_derive" }
|
|||||||
derivative = "2.1.1"
|
derivative = "2.1.1"
|
||||||
ethereum-types = "0.14.1"
|
ethereum-types = "0.14.1"
|
||||||
hex = "0.4.2"
|
hex = "0.4.2"
|
||||||
|
kzg = { path = "../../crypto/kzg" }
|
||||||
rayon = "1.4.1"
|
rayon = "1.4.1"
|
||||||
serde = "1.0.116"
|
serde = "1.0.116"
|
||||||
serde_derive = "1.0.116"
|
serde_derive = "1.0.116"
|
||||||
|
serde_json = "1.0.58"
|
||||||
serde_repr = "0.1.6"
|
serde_repr = "0.1.6"
|
||||||
serde_yaml = "0.8.13"
|
serde_yaml = "0.8.13"
|
||||||
|
eth2_network_config = { path = "../../common/eth2_network_config" }
|
||||||
|
eth2_serde_utils = { path = "../../consensus/serde_utils" }
|
||||||
eth2_ssz = "0.4.1"
|
eth2_ssz = "0.4.1"
|
||||||
eth2_ssz_derive = "0.3.1"
|
eth2_ssz_derive = "0.3.1"
|
||||||
tree_hash = "0.4.1"
|
tree_hash = "0.4.1"
|
||||||
|
@ -18,6 +18,12 @@ mod fork;
|
|||||||
mod fork_choice;
|
mod fork_choice;
|
||||||
mod genesis_initialization;
|
mod genesis_initialization;
|
||||||
mod genesis_validity;
|
mod genesis_validity;
|
||||||
|
mod kzg_blob_to_kzg_commitment;
|
||||||
|
mod kzg_compute_blob_kzg_proof;
|
||||||
|
mod kzg_compute_kzg_proof;
|
||||||
|
mod kzg_verify_blob_kzg_proof;
|
||||||
|
mod kzg_verify_blob_kzg_proof_batch;
|
||||||
|
mod kzg_verify_kzg_proof;
|
||||||
mod merkle_proof_validity;
|
mod merkle_proof_validity;
|
||||||
mod operations;
|
mod operations;
|
||||||
mod rewards;
|
mod rewards;
|
||||||
@ -42,6 +48,12 @@ pub use epoch_processing::*;
|
|||||||
pub use fork::ForkTest;
|
pub use fork::ForkTest;
|
||||||
pub use genesis_initialization::*;
|
pub use genesis_initialization::*;
|
||||||
pub use genesis_validity::*;
|
pub use genesis_validity::*;
|
||||||
|
pub use kzg_blob_to_kzg_commitment::*;
|
||||||
|
pub use kzg_compute_blob_kzg_proof::*;
|
||||||
|
pub use kzg_compute_kzg_proof::*;
|
||||||
|
pub use kzg_verify_blob_kzg_proof::*;
|
||||||
|
pub use kzg_verify_blob_kzg_proof_batch::*;
|
||||||
|
pub use kzg_verify_kzg_proof::*;
|
||||||
pub use merkle_proof_validity::*;
|
pub use merkle_proof_validity::*;
|
||||||
pub use operations::*;
|
pub use operations::*;
|
||||||
pub use rewards::RewardsTest;
|
pub use rewards::RewardsTest;
|
||||||
|
@ -0,0 +1,46 @@
|
|||||||
|
use super::*;
|
||||||
|
use crate::case_result::compare_result;
|
||||||
|
use beacon_chain::kzg_utils::blob_to_kzg_commitment;
|
||||||
|
use kzg::KzgCommitment;
|
||||||
|
use serde_derive::Deserialize;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct KZGBlobToKZGCommitmentInput {
|
||||||
|
pub blob: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
#[serde(bound = "E: EthSpec")]
|
||||||
|
pub struct KZGBlobToKZGCommitment<E: EthSpec> {
|
||||||
|
pub input: KZGBlobToKZGCommitmentInput,
|
||||||
|
pub output: Option<String>,
|
||||||
|
#[serde(skip)]
|
||||||
|
_phantom: PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> LoadCase for KZGBlobToKZGCommitment<E> {
|
||||||
|
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
|
||||||
|
decode::yaml_decode_file(path.join("data.yaml").as_path())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> Case for KZGBlobToKZGCommitment<E> {
|
||||||
|
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
|
||||||
|
fork_name == ForkName::Deneb
|
||||||
|
}
|
||||||
|
|
||||||
|
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
|
||||||
|
let kzg = get_kzg()?;
|
||||||
|
|
||||||
|
let commitment = parse_blob::<E>(&self.input.blob).and_then(|blob| {
|
||||||
|
blob_to_kzg_commitment::<E>(&kzg, blob).map_err(|e| {
|
||||||
|
Error::InternalError(format!("Failed to compute kzg commitment: {:?}", e))
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
let expected = self.output.as_ref().and_then(|s| parse_commitment(s).ok());
|
||||||
|
|
||||||
|
compare_result::<KzgCommitment, _>(&commitment, &expected)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
use super::*;
|
||||||
|
use crate::case_result::compare_result;
|
||||||
|
use beacon_chain::kzg_utils::compute_blob_kzg_proof;
|
||||||
|
use kzg::KzgProof;
|
||||||
|
use serde_derive::Deserialize;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct KZGComputeBlobKZGProofInput {
|
||||||
|
pub blob: String,
|
||||||
|
pub commitment: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
#[serde(bound = "E: EthSpec")]
|
||||||
|
pub struct KZGComputeBlobKZGProof<E: EthSpec> {
|
||||||
|
pub input: KZGComputeBlobKZGProofInput,
|
||||||
|
pub output: Option<String>,
|
||||||
|
#[serde(skip)]
|
||||||
|
_phantom: PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> LoadCase for KZGComputeBlobKZGProof<E> {
|
||||||
|
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
|
||||||
|
decode::yaml_decode_file(path.join("data.yaml").as_path())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> Case for KZGComputeBlobKZGProof<E> {
|
||||||
|
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
|
||||||
|
fork_name == ForkName::Deneb
|
||||||
|
}
|
||||||
|
|
||||||
|
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
|
||||||
|
let parse_input = |input: &KZGComputeBlobKZGProofInput| -> Result<_, Error> {
|
||||||
|
let blob = parse_blob::<E>(&input.blob)?;
|
||||||
|
let commitment = parse_commitment(&input.commitment)?;
|
||||||
|
Ok((blob, commitment))
|
||||||
|
};
|
||||||
|
|
||||||
|
let kzg = get_kzg()?;
|
||||||
|
let proof = parse_input(&self.input).and_then(|(blob, commitment)| {
|
||||||
|
compute_blob_kzg_proof::<E>(&kzg, &blob, commitment)
|
||||||
|
.map_err(|e| Error::InternalError(format!("Failed to compute kzg proof: {:?}", e)))
|
||||||
|
});
|
||||||
|
|
||||||
|
let expected = self.output.as_ref().and_then(|s| parse_proof(s).ok());
|
||||||
|
|
||||||
|
compare_result::<KzgProof, _>(&proof, &expected)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
use super::*;
|
||||||
|
use crate::case_result::compare_result;
|
||||||
|
use beacon_chain::kzg_utils::compute_kzg_proof;
|
||||||
|
use kzg::KzgProof;
|
||||||
|
use serde_derive::Deserialize;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use types::Hash256;
|
||||||
|
|
||||||
|
pub fn parse_point(point: &str) -> Result<Hash256, Error> {
|
||||||
|
Hash256::from_str(&point[2..])
|
||||||
|
.map_err(|e| Error::FailedToParseTest(format!("Failed to parse point: {:?}", e)))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct KZGComputeKZGProofInput {
|
||||||
|
pub blob: String,
|
||||||
|
pub z: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
#[serde(bound = "E: EthSpec")]
|
||||||
|
pub struct KZGComputeKZGProof<E: EthSpec> {
|
||||||
|
pub input: KZGComputeKZGProofInput,
|
||||||
|
pub output: Option<(String, Hash256)>,
|
||||||
|
#[serde(skip)]
|
||||||
|
_phantom: PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> LoadCase for KZGComputeKZGProof<E> {
|
||||||
|
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
|
||||||
|
decode::yaml_decode_file(path.join("data.yaml").as_path())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> Case for KZGComputeKZGProof<E> {
|
||||||
|
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
|
||||||
|
fork_name == ForkName::Deneb
|
||||||
|
}
|
||||||
|
|
||||||
|
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
|
||||||
|
let parse_input = |input: &KZGComputeKZGProofInput| -> Result<_, Error> {
|
||||||
|
let blob = parse_blob::<E>(&input.blob)?;
|
||||||
|
let z = parse_point(&input.z)?;
|
||||||
|
Ok((blob, z))
|
||||||
|
};
|
||||||
|
|
||||||
|
let kzg = get_kzg()?;
|
||||||
|
let proof = parse_input(&self.input).and_then(|(blob, z)| {
|
||||||
|
compute_kzg_proof::<E>(&kzg, blob, z)
|
||||||
|
.map_err(|e| Error::InternalError(format!("Failed to compute kzg proof: {:?}", e)))
|
||||||
|
});
|
||||||
|
|
||||||
|
let expected = self
|
||||||
|
.output
|
||||||
|
.as_ref()
|
||||||
|
.and_then(|(s, z)| parse_proof(s).ok().map(|proof| (proof, *z)));
|
||||||
|
|
||||||
|
compare_result::<(KzgProof, Hash256), _>(&proof, &expected)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,92 @@
|
|||||||
|
use super::*;
|
||||||
|
use crate::case_result::compare_result;
|
||||||
|
use beacon_chain::kzg_utils::validate_blob;
|
||||||
|
use eth2_network_config::TRUSTED_SETUP;
|
||||||
|
use kzg::{Kzg, KzgCommitment, KzgProof, TrustedSetup};
|
||||||
|
use serde_derive::Deserialize;
|
||||||
|
use std::convert::TryInto;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use types::Blob;
|
||||||
|
|
||||||
|
pub fn get_kzg() -> Result<Kzg, Error> {
|
||||||
|
let trusted_setup: TrustedSetup = serde_json::from_reader(TRUSTED_SETUP)
|
||||||
|
.map_err(|e| Error::InternalError(format!("Failed to initialize kzg: {:?}", e)))?;
|
||||||
|
Kzg::new_from_trusted_setup(trusted_setup)
|
||||||
|
.map_err(|e| Error::InternalError(format!("Failed to initialize kzg: {:?}", e)))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_proof(proof: &str) -> Result<KzgProof, Error> {
|
||||||
|
hex::decode(&proof[2..])
|
||||||
|
.map_err(|e| Error::FailedToParseTest(format!("Failed to parse proof: {:?}", e)))
|
||||||
|
.and_then(|bytes| {
|
||||||
|
bytes
|
||||||
|
.try_into()
|
||||||
|
.map_err(|e| Error::FailedToParseTest(format!("Failed to parse proof: {:?}", e)))
|
||||||
|
})
|
||||||
|
.map(KzgProof)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_commitment(commitment: &str) -> Result<KzgCommitment, Error> {
|
||||||
|
hex::decode(&commitment[2..])
|
||||||
|
.map_err(|e| Error::FailedToParseTest(format!("Failed to parse commitment: {:?}", e)))
|
||||||
|
.and_then(|bytes| {
|
||||||
|
bytes.try_into().map_err(|e| {
|
||||||
|
Error::FailedToParseTest(format!("Failed to parse commitment: {:?}", e))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.map(KzgCommitment)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn parse_blob<E: EthSpec>(blob: &str) -> Result<Blob<E>, Error> {
|
||||||
|
hex::decode(&blob[2..])
|
||||||
|
.map_err(|e| Error::FailedToParseTest(format!("Failed to parse blob: {:?}", e)))
|
||||||
|
.and_then(|bytes| {
|
||||||
|
Blob::<E>::new(bytes)
|
||||||
|
.map_err(|e| Error::FailedToParseTest(format!("Failed to parse blob: {:?}", e)))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct KZGVerifyBlobKZGProofInput {
|
||||||
|
pub blob: String,
|
||||||
|
pub commitment: String,
|
||||||
|
pub proof: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
#[serde(bound = "E: EthSpec")]
|
||||||
|
pub struct KZGVerifyBlobKZGProof<E: EthSpec> {
|
||||||
|
pub input: KZGVerifyBlobKZGProofInput,
|
||||||
|
pub output: Option<bool>,
|
||||||
|
#[serde(skip)]
|
||||||
|
_phantom: PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> LoadCase for KZGVerifyBlobKZGProof<E> {
|
||||||
|
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
|
||||||
|
decode::yaml_decode_file(path.join("data.yaml").as_path())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> Case for KZGVerifyBlobKZGProof<E> {
|
||||||
|
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
|
||||||
|
fork_name == ForkName::Deneb
|
||||||
|
}
|
||||||
|
|
||||||
|
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
|
||||||
|
let parse_input = |input: &KZGVerifyBlobKZGProofInput| -> Result<(Blob<E>, KzgCommitment, KzgProof), Error> {
|
||||||
|
let blob = parse_blob::<E>(&input.blob)?;
|
||||||
|
let commitment = parse_commitment(&input.commitment)?;
|
||||||
|
let proof = parse_proof(&input.proof)?;
|
||||||
|
Ok((blob, commitment, proof))
|
||||||
|
};
|
||||||
|
|
||||||
|
let kzg = get_kzg()?;
|
||||||
|
let result = parse_input(&self.input).and_then(|(blob, commitment, proof)| {
|
||||||
|
validate_blob::<E>(&kzg, blob, commitment, proof)
|
||||||
|
.map_err(|e| Error::InternalError(format!("Failed to validate blob: {:?}", e)))
|
||||||
|
});
|
||||||
|
|
||||||
|
compare_result::<bool, _>(&result, &self.output)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
use super::*;
|
||||||
|
use crate::case_result::compare_result;
|
||||||
|
use beacon_chain::kzg_utils::validate_blobs;
|
||||||
|
use serde_derive::Deserialize;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct KZGVerifyBlobKZGProofBatchInput {
|
||||||
|
pub blobs: Vec<String>,
|
||||||
|
pub commitments: Vec<String>,
|
||||||
|
pub proofs: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
#[serde(bound = "E: EthSpec")]
|
||||||
|
pub struct KZGVerifyBlobKZGProofBatch<E: EthSpec> {
|
||||||
|
pub input: KZGVerifyBlobKZGProofBatchInput,
|
||||||
|
pub output: Option<bool>,
|
||||||
|
#[serde(skip)]
|
||||||
|
_phantom: PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> LoadCase for KZGVerifyBlobKZGProofBatch<E> {
|
||||||
|
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
|
||||||
|
decode::yaml_decode_file(path.join("data.yaml").as_path())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> Case for KZGVerifyBlobKZGProofBatch<E> {
|
||||||
|
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
|
||||||
|
fork_name == ForkName::Deneb
|
||||||
|
}
|
||||||
|
|
||||||
|
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
|
||||||
|
let parse_input = |input: &KZGVerifyBlobKZGProofBatchInput| -> Result<_, Error> {
|
||||||
|
let blobs = input
|
||||||
|
.blobs
|
||||||
|
.iter()
|
||||||
|
.map(|s| parse_blob::<E>(s))
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
let commitments = input
|
||||||
|
.commitments
|
||||||
|
.iter()
|
||||||
|
.map(|s| parse_commitment(s))
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
let proofs = input
|
||||||
|
.proofs
|
||||||
|
.iter()
|
||||||
|
.map(|s| parse_proof(s))
|
||||||
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
Ok((commitments, blobs, proofs))
|
||||||
|
};
|
||||||
|
|
||||||
|
let kzg = get_kzg()?;
|
||||||
|
let result = parse_input(&self.input).and_then(|(commitments, blobs, proofs)| {
|
||||||
|
validate_blobs::<E>(&kzg, &commitments, &blobs, &proofs)
|
||||||
|
.map_err(|e| Error::InternalError(format!("Failed to validate blobs: {:?}", e)))
|
||||||
|
});
|
||||||
|
|
||||||
|
compare_result::<bool, _>(&result, &self.output)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
use super::*;
|
||||||
|
use crate::case_result::compare_result;
|
||||||
|
use beacon_chain::kzg_utils::verify_kzg_proof;
|
||||||
|
use serde_derive::Deserialize;
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct KZGVerifyKZGProofInput {
|
||||||
|
pub commitment: String,
|
||||||
|
pub z: String,
|
||||||
|
pub y: String,
|
||||||
|
pub proof: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
#[serde(bound = "E: EthSpec")]
|
||||||
|
pub struct KZGVerifyKZGProof<E: EthSpec> {
|
||||||
|
pub input: KZGVerifyKZGProofInput,
|
||||||
|
pub output: Option<bool>,
|
||||||
|
#[serde(skip)]
|
||||||
|
_phantom: PhantomData<E>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> LoadCase for KZGVerifyKZGProof<E> {
|
||||||
|
fn load_from_dir(path: &Path, _fork_name: ForkName) -> Result<Self, Error> {
|
||||||
|
decode::yaml_decode_file(path.join("data.yaml").as_path())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<E: EthSpec> Case for KZGVerifyKZGProof<E> {
|
||||||
|
fn is_enabled_for_fork(fork_name: ForkName) -> bool {
|
||||||
|
fork_name == ForkName::Deneb
|
||||||
|
}
|
||||||
|
|
||||||
|
fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> {
|
||||||
|
let parse_input = |input: &KZGVerifyKZGProofInput| -> Result<_, Error> {
|
||||||
|
let commitment = parse_commitment(&input.commitment)?;
|
||||||
|
let z = parse_point(&input.z)?;
|
||||||
|
let y = parse_point(&input.y)?;
|
||||||
|
let proof = parse_proof(&input.proof)?;
|
||||||
|
Ok((commitment, z, y, proof))
|
||||||
|
};
|
||||||
|
|
||||||
|
let kzg = get_kzg()?;
|
||||||
|
let result = parse_input(&self.input).and_then(|(commitment, z, y, proof)| {
|
||||||
|
verify_kzg_proof::<E>(&kzg, commitment, proof, z, y)
|
||||||
|
.map_err(|e| Error::InternalError(format!("Failed to validate proof: {:?}", e)))
|
||||||
|
});
|
||||||
|
|
||||||
|
compare_result::<bool, _>(&result, &self.output)
|
||||||
|
}
|
||||||
|
}
|
@ -637,6 +637,126 @@ impl<E: EthSpec + TypeName> Handler for GenesisInitializationHandler<E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Derivative)]
|
||||||
|
#[derivative(Default(bound = ""))]
|
||||||
|
pub struct KZGBlobToKZGCommitmentHandler<E>(PhantomData<E>);
|
||||||
|
|
||||||
|
impl<E: EthSpec> Handler for KZGBlobToKZGCommitmentHandler<E> {
|
||||||
|
type Case = cases::KZGBlobToKZGCommitment<E>;
|
||||||
|
|
||||||
|
fn config_name() -> &'static str {
|
||||||
|
"general"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn runner_name() -> &'static str {
|
||||||
|
"kzg"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handler_name(&self) -> String {
|
||||||
|
"blob_to_kzg_commitment".into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Derivative)]
|
||||||
|
#[derivative(Default(bound = ""))]
|
||||||
|
pub struct KZGComputeBlobKZGProofHandler<E>(PhantomData<E>);
|
||||||
|
|
||||||
|
impl<E: EthSpec> Handler for KZGComputeBlobKZGProofHandler<E> {
|
||||||
|
type Case = cases::KZGComputeBlobKZGProof<E>;
|
||||||
|
|
||||||
|
fn config_name() -> &'static str {
|
||||||
|
"general"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn runner_name() -> &'static str {
|
||||||
|
"kzg"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handler_name(&self) -> String {
|
||||||
|
"compute_blob_kzg_proof".into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Derivative)]
|
||||||
|
#[derivative(Default(bound = ""))]
|
||||||
|
pub struct KZGComputeKZGProofHandler<E>(PhantomData<E>);
|
||||||
|
|
||||||
|
impl<E: EthSpec> Handler for KZGComputeKZGProofHandler<E> {
|
||||||
|
type Case = cases::KZGComputeKZGProof<E>;
|
||||||
|
|
||||||
|
fn config_name() -> &'static str {
|
||||||
|
"general"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn runner_name() -> &'static str {
|
||||||
|
"kzg"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handler_name(&self) -> String {
|
||||||
|
"compute_kzg_proof".into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Derivative)]
|
||||||
|
#[derivative(Default(bound = ""))]
|
||||||
|
pub struct KZGVerifyBlobKZGProofHandler<E>(PhantomData<E>);
|
||||||
|
|
||||||
|
impl<E: EthSpec> Handler for KZGVerifyBlobKZGProofHandler<E> {
|
||||||
|
type Case = cases::KZGVerifyBlobKZGProof<E>;
|
||||||
|
|
||||||
|
fn config_name() -> &'static str {
|
||||||
|
"general"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn runner_name() -> &'static str {
|
||||||
|
"kzg"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handler_name(&self) -> String {
|
||||||
|
"verify_blob_kzg_proof".into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Derivative)]
|
||||||
|
#[derivative(Default(bound = ""))]
|
||||||
|
pub struct KZGVerifyBlobKZGProofBatchHandler<E>(PhantomData<E>);
|
||||||
|
|
||||||
|
impl<E: EthSpec> Handler for KZGVerifyBlobKZGProofBatchHandler<E> {
|
||||||
|
type Case = cases::KZGVerifyBlobKZGProofBatch<E>;
|
||||||
|
|
||||||
|
fn config_name() -> &'static str {
|
||||||
|
"general"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn runner_name() -> &'static str {
|
||||||
|
"kzg"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handler_name(&self) -> String {
|
||||||
|
"verify_blob_kzg_proof_batch".into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Derivative)]
|
||||||
|
#[derivative(Default(bound = ""))]
|
||||||
|
pub struct KZGVerifyKZGProofHandler<E>(PhantomData<E>);
|
||||||
|
|
||||||
|
impl<E: EthSpec> Handler for KZGVerifyKZGProofHandler<E> {
|
||||||
|
type Case = cases::KZGVerifyKZGProof<E>;
|
||||||
|
|
||||||
|
fn config_name() -> &'static str {
|
||||||
|
"general"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn runner_name() -> &'static str {
|
||||||
|
"kzg"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handler_name(&self) -> String {
|
||||||
|
"verify_kzg_proof".into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Derivative)]
|
#[derive(Derivative)]
|
||||||
#[derivative(Default(bound = ""))]
|
#[derivative(Default(bound = ""))]
|
||||||
pub struct MerkleProofValidityHandler<E>(PhantomData<E>);
|
pub struct MerkleProofValidityHandler<E>(PhantomData<E>);
|
||||||
|
@ -563,6 +563,36 @@ fn genesis_validity() {
|
|||||||
// Note: there are no genesis validity tests for mainnet
|
// Note: there are no genesis validity tests for mainnet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn kzg_blob_to_kzg_commitment() {
|
||||||
|
KZGBlobToKZGCommitmentHandler::<MainnetEthSpec>::default().run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn kzg_compute_blob_kzg_proof() {
|
||||||
|
KZGComputeBlobKZGProofHandler::<MainnetEthSpec>::default().run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn kzg_compute_kzg_proof() {
|
||||||
|
KZGComputeKZGProofHandler::<MainnetEthSpec>::default().run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn kzg_verify_blob_kzg_proof() {
|
||||||
|
KZGVerifyBlobKZGProofHandler::<MainnetEthSpec>::default().run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn kzg_verify_blob_kzg_proof_batch() {
|
||||||
|
KZGVerifyBlobKZGProofBatchHandler::<MainnetEthSpec>::default().run();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn kzg_verify_kzg_proof() {
|
||||||
|
KZGVerifyKZGProofHandler::<MainnetEthSpec>::default().run();
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn merkle_proof_validity() {
|
fn merkle_proof_validity() {
|
||||||
MerkleProofValidityHandler::<MainnetEthSpec>::default().run();
|
MerkleProofValidityHandler::<MainnetEthSpec>::default().run();
|
||||||
|
Loading…
Reference in New Issue
Block a user