diff --git a/Cargo.lock b/Cargo.lock index 979921faedd..ef60e0e22d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -863,21 +863,7 @@ dependencies = [ [[package]] name = "c-kzg" version = "0.1.0" -source = "git+https://github.com/ethereum//c-kzg-4844?rev=f5f6f863d475847876a2bd5ee252058d37c3a15d#f5f6f863d475847876a2bd5ee252058d37c3a15d" -dependencies = [ - "bindgen 0.66.1", - "blst", - "cc", - "glob", - "hex", - "libc", - "serde", -] - -[[package]] -name = "c-kzg" -version = "0.1.0" -source = "git+https://github.com/ethereum/c-kzg-4844?rev=f5f6f863d475847876a2bd5ee252058d37c3a15d#f5f6f863d475847876a2bd5ee252058d37c3a15d" +source = "git+https://github.com/pawanjay176/c-kzg-4844?rev=843d4c7ed087ad472f76933b158791b0a9184e52#843d4c7ed087ad472f76933b158791b0a9184e52" dependencies = [ "bindgen 0.66.1", "blst", @@ -2189,7 +2175,6 @@ dependencies = [ "discv5", "eth2_config", "ethereum_ssz", - "kzg", "logging", "pretty_reqwest_error", "reqwest", @@ -3820,8 +3805,7 @@ name = "kzg" version = "0.1.0" dependencies = [ "arbitrary", - "c-kzg 0.1.0 (git+https://github.com/ethereum//c-kzg-4844?rev=f5f6f863d475847876a2bd5ee252058d37c3a15d)", - "c-kzg 0.1.0 (git+https://github.com/ethereum/c-kzg-4844?rev=f5f6f863d475847876a2bd5ee252058d37c3a15d)", + "c-kzg", "derivative", "ethereum_hashing", "ethereum_serde_utils", @@ -3869,7 +3853,6 @@ dependencies = [ "ethereum_ssz", "genesis", "int_to_bytes", - "kzg", "lighthouse_network", "lighthouse_version", "log", diff --git a/beacon_node/beacon_chain/src/beacon_chain.rs b/beacon_node/beacon_chain/src/beacon_chain.rs index 918d0bd29b7..12c51041d3a 100644 --- a/beacon_node/beacon_chain/src/beacon_chain.rs +++ b/beacon_node/beacon_chain/src/beacon_chain.rs @@ -481,7 +481,7 @@ pub struct BeaconChain { /// they are collected and combined. pub data_availability_checker: Arc>, /// The KZG trusted setup used by this chain. - pub kzg: Option::Kzg>>>, + pub kzg: Option>, } type BeaconBlockAndState = ( diff --git a/beacon_node/beacon_chain/src/blob_verification.rs b/beacon_node/beacon_chain/src/blob_verification.rs index 1c8bc9be85b..880aa9a4296 100644 --- a/beacon_node/beacon_chain/src/blob_verification.rs +++ b/beacon_node/beacon_chain/src/blob_verification.rs @@ -499,7 +499,7 @@ impl KzgVerifiedBlob { /// Returns an error if the kzg verification check fails. pub fn verify_kzg_for_blob( blob: Arc>, - kzg: &Kzg, + kzg: &Kzg, ) -> Result, AvailabilityCheckError> { let _timer = crate::metrics::start_timer(&crate::metrics::KZG_VERIFICATION_SINGLE_TIMES); //TODO(sean) remove clone @@ -519,7 +519,7 @@ pub fn verify_kzg_for_blob( /// in a loop since this function kzg verifies a list of blobs more efficiently. pub fn verify_kzg_for_blob_list( blob_list: &BlobSidecarList, - kzg: &Kzg, + kzg: &Kzg, ) -> Result<(), AvailabilityCheckError> { let _timer = crate::metrics::start_timer(&crate::metrics::KZG_VERIFICATION_BATCH_TIMES); let (blobs, (commitments, proofs)): (Vec<_>, (Vec<_>, Vec<_>)) = blob_list diff --git a/beacon_node/beacon_chain/src/builder.rs b/beacon_node/beacon_chain/src/builder.rs index fd8a3f04606..9feb2a44e49 100644 --- a/beacon_node/beacon_chain/src/builder.rs +++ b/beacon_node/beacon_chain/src/builder.rs @@ -688,6 +688,9 @@ where let kzg = if let Some(trusted_setup) = self.trusted_setup { let kzg = Kzg::new_from_trusted_setup(trusted_setup) .map_err(|e| format!("Failed to load trusted setup: {:?}", e))?; + if TEthSpec::field_elements_per_blob() != kzg.field_elements_per_blob() { + return Err("Trusted setup is inconsistent with spec preset".to_string()); + } let kzg_arc = Arc::new(kzg); Some(kzg_arc) } else { diff --git a/beacon_node/beacon_chain/src/data_availability_checker.rs b/beacon_node/beacon_chain/src/data_availability_checker.rs index e1024da46c9..ca6f58ee408 100644 --- a/beacon_node/beacon_chain/src/data_availability_checker.rs +++ b/beacon_node/beacon_chain/src/data_availability_checker.rs @@ -50,8 +50,8 @@ pub struct DataAvailabilityChecker { processing_cache: RwLock>, availability_cache: Arc>, slot_clock: T::SlotClock, - kzg: Option::Kzg>>>, log: Logger, + kzg: Option>, spec: ChainSpec, } @@ -79,7 +79,7 @@ impl Debug for Availability { impl DataAvailabilityChecker { pub fn new( slot_clock: T::SlotClock, - kzg: Option::Kzg>>>, + kzg: Option>, store: BeaconStore, log: &Logger, spec: ChainSpec, diff --git a/beacon_node/beacon_chain/src/data_availability_checker/availability_view.rs b/beacon_node/beacon_chain/src/data_availability_checker/availability_view.rs index fea2ee101ee..125830b17b4 100644 --- a/beacon_node/beacon_chain/src/data_availability_checker/availability_view.rs +++ b/beacon_node/beacon_chain/src/data_availability_checker/availability_view.rs @@ -286,7 +286,7 @@ pub mod tests { pub fn pre_setup() -> Setup { let trusted_setup: TrustedSetup = - serde_json::from_reader(get_trusted_setup::<::Kzg>()).unwrap(); + serde_json::from_reader(get_trusted_setup::()).unwrap(); let kzg = Kzg::new_from_trusted_setup(trusted_setup).unwrap(); let mut rng = StdRng::seed_from_u64(0xDEADBEEF0BAD5EEDu64); diff --git a/beacon_node/beacon_chain/src/kzg_utils.rs b/beacon_node/beacon_chain/src/kzg_utils.rs index 144e2136758..b3c288cced0 100644 --- a/beacon_node/beacon_chain/src/kzg_utils.rs +++ b/beacon_node/beacon_chain/src/kzg_utils.rs @@ -1,75 +1,60 @@ -use kzg::{Error as KzgError, Kzg, KzgPreset}; +use kzg::{Error as KzgError, Kzg}; use types::{Blob, EthSpec, Hash256, 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( - blob: &Blob, -) -> Result<<::Kzg as KzgPreset>::Blob, KzgError> { - T::blob_from_bytes(blob.as_ref()) -} - /// Validate a single blob-commitment-proof triplet from a `BlobSidecar`. pub fn validate_blob( - kzg: &Kzg, + kzg: &Kzg, blob: Blob, kzg_commitment: KzgCommitment, kzg_proof: KzgProof, ) -> Result { - kzg.verify_blob_kzg_proof( - &ssz_blob_to_crypto_blob::(&blob)?, - kzg_commitment, - kzg_proof, - ) + kzg.verify_blob_kzg_proof(blob.as_ref(), kzg_commitment, kzg_proof) } /// Validate a batch of blob-commitment-proof triplets from multiple `BlobSidecars`. pub fn validate_blobs( - kzg: &Kzg, + kzg: &Kzg, expected_kzg_commitments: &[KzgCommitment], blobs: &[Blob], kzg_proofs: &[KzgProof], ) -> Result { - let blobs = blobs - .iter() - .map(|blob| ssz_blob_to_crypto_blob::(blob)) // Avoid this clone - .collect::, KzgError>>()?; + let blobs = blobs.iter().map(|blob| blob.as_ref()).collect::>(); kzg.verify_blob_kzg_proof_batch(&blobs, expected_kzg_commitments, kzg_proofs) } /// Compute the kzg proof given an ssz blob and its kzg commitment. pub fn compute_blob_kzg_proof( - kzg: &Kzg, + kzg: &Kzg, blob: &Blob, kzg_commitment: KzgCommitment, ) -> Result { // Avoid this blob clone - kzg.compute_blob_kzg_proof(&ssz_blob_to_crypto_blob::(blob)?, kzg_commitment) + kzg.compute_blob_kzg_proof(blob.as_ref(), kzg_commitment) } /// Compute the kzg commitment for a given blob. pub fn blob_to_kzg_commitment( - kzg: &Kzg, + kzg: &Kzg, blob: &Blob, ) -> Result { - kzg.blob_to_kzg_commitment(&ssz_blob_to_crypto_blob::(blob)?) + kzg.blob_to_kzg_commitment(blob.as_ref()) } /// Compute the kzg proof for a given blob and an evaluation point z. pub fn compute_kzg_proof( - kzg: &Kzg, + kzg: &Kzg, blob: &Blob, z: Hash256, ) -> Result<(KzgProof, Hash256), KzgError> { let z = z.0.into(); - kzg.compute_kzg_proof(&ssz_blob_to_crypto_blob::(blob)?, &z) + kzg.compute_kzg_proof(blob.as_ref(), &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( - kzg: &Kzg, + kzg: &Kzg, kzg_commitment: KzgCommitment, kzg_proof: KzgProof, z: Hash256, diff --git a/beacon_node/beacon_chain/src/test_utils.rs b/beacon_node/beacon_chain/src/test_utils.rs index a4abb90104e..81a5feb2dd2 100644 --- a/beacon_node/beacon_chain/src/test_utils.rs +++ b/beacon_node/beacon_chain/src/test_utils.rs @@ -492,7 +492,7 @@ where .expect("cannot build without validator keypairs"); let chain_config = self.chain_config.unwrap_or_default(); let trusted_setup: TrustedSetup = - serde_json::from_reader(eth2_network_config::get_trusted_setup::()) + serde_json::from_reader(eth2_network_config::get_trusted_setup::()) .map_err(|e| format!("Unable to read trusted setup file: {}", e)) .unwrap(); @@ -571,7 +571,7 @@ pub fn mock_execution_layer_from_parts( }); let trusted_setup: TrustedSetup = - serde_json::from_reader(eth2_network_config::get_trusted_setup::()) + serde_json::from_reader(eth2_network_config::get_trusted_setup::()) .map_err(|e| format!("Unable to read trusted setup file: {}", e)) .expect("should have trusted setup"); let kzg = Kzg::new_from_trusted_setup(trusted_setup).expect("should create kzg"); @@ -2526,7 +2526,7 @@ pub enum NumBlobs { pub fn generate_rand_block_and_blobs( fork_name: ForkName, num_blobs: NumBlobs, - kzg: &Kzg, + kzg: &Kzg, rng: &mut impl Rng, ) -> (SignedBeaconBlock>, Vec>) { let inner = map_fork_name!(fork_name, BeaconBlock, <_>::random_for_test(rng)); diff --git a/beacon_node/beacon_chain/tests/store_tests.rs b/beacon_node/beacon_chain/tests/store_tests.rs index 90b680ca8f3..09275573f6b 100644 --- a/beacon_node/beacon_chain/tests/store_tests.rs +++ b/beacon_node/beacon_chain/tests/store_tests.rs @@ -2154,10 +2154,9 @@ async fn weak_subjectivity_sync_test(slots: Vec, checkpoint_slot: Slot) { let store = get_store(&temp2); let spec = test_spec::(); let seconds_per_slot = spec.seconds_per_slot; - let trusted_setup: TrustedSetup = - serde_json::from_reader(get_trusted_setup::<::Kzg>()) - .map_err(|e| println!("Unable to read trusted setup file: {}", e)) - .unwrap(); + let trusted_setup: TrustedSetup = serde_json::from_reader(get_trusted_setup::()) + .map_err(|e| println!("Unable to read trusted setup file: {}", e)) + .unwrap(); let mock = mock_execution_layer_from_parts(&harness.spec, harness.runtime.task_executor.clone(), None); diff --git a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs index c191fb2a00e..6e1ac51a5ef 100644 --- a/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs +++ b/beacon_node/execution_layer/src/test_utils/execution_block_generator.rs @@ -131,7 +131,7 @@ pub struct ExecutionBlockGenerator { * deneb stuff */ pub blobs_bundles: HashMap>, - pub kzg: Option>>, + pub kzg: Option>, rng: Arc>, } @@ -148,7 +148,7 @@ impl ExecutionBlockGenerator { terminal_block_hash: ExecutionBlockHash, shanghai_time: Option, cancun_time: Option, - kzg: Option>, + kzg: Option, ) -> Self { let mut gen = Self { head_block: <_>::default(), @@ -645,7 +645,7 @@ impl ExecutionBlockGenerator { pub fn generate_random_blobs( n_blobs: usize, - kzg: &Kzg, + kzg: &Kzg, rng: &mut R, ) -> Result<(BlobsBundle, Transactions), String> { let mut bundle = BlobsBundle::::default(); diff --git a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs index f1bd89868c8..bd6ddabc2a5 100644 --- a/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs +++ b/beacon_node/execution_layer/src/test_utils/mock_execution_layer.rs @@ -46,7 +46,7 @@ impl MockExecutionLayer { builder_threshold: Option, jwt_key: Option, spec: ChainSpec, - kzg: Option>, + kzg: Option, ) -> Self { let handle = executor.handle().unwrap(); diff --git a/beacon_node/execution_layer/src/test_utils/mod.rs b/beacon_node/execution_layer/src/test_utils/mod.rs index f56a04b074c..f41219d9e80 100644 --- a/beacon_node/execution_layer/src/test_utils/mod.rs +++ b/beacon_node/execution_layer/src/test_utils/mod.rs @@ -107,7 +107,7 @@ impl MockServer { pub fn new_with_config( handle: &runtime::Handle, config: MockExecutionConfig, - kzg: Option>, + kzg: Option, ) -> Self { let MockExecutionConfig { jwt_key, @@ -188,7 +188,7 @@ impl MockServer { terminal_block_hash: ExecutionBlockHash, shanghai_time: Option, cancun_time: Option, - kzg: Option>, + kzg: Option, ) -> Self { Self::new_with_config( handle, diff --git a/beacon_node/src/config.rs b/beacon_node/src/config.rs index 39bc7f8a24c..7e59146a1b7 100644 --- a/beacon_node/src/config.rs +++ b/beacon_node/src/config.rs @@ -389,7 +389,8 @@ pub fn get_config( client_config.trusted_setup = context .eth2_network_config .as_ref() - .and_then(|config| config.kzg_trusted_setup.clone()); + .and_then(|config| config.kzg_trusted_setup.clone()) + .and_then(|trusted_setup_bytes| serde_json::from_slice(trusted_setup_bytes.as_ref()).ok()); // Override default trusted setup file if required // TODO: consider removing this when we get closer to launch diff --git a/common/eth2_network_config/Cargo.toml b/common/eth2_network_config/Cargo.toml index 8bc114487a3..3807c2e9930 100644 --- a/common/eth2_network_config/Cargo.toml +++ b/common/eth2_network_config/Cargo.toml @@ -18,7 +18,6 @@ tokio = { workspace = true } serde_yaml = { workspace = true } serde_json = { workspace = true } types = { workspace = true } -kzg = { workspace = true } ethereum_ssz = { workspace = true } eth2_config = { workspace = true } discv5 = { workspace = true } diff --git a/common/eth2_network_config/src/lib.rs b/common/eth2_network_config/src/lib.rs index 510f76ad5f5..a75ebb7d243 100644 --- a/common/eth2_network_config/src/lib.rs +++ b/common/eth2_network_config/src/lib.rs @@ -14,7 +14,6 @@ use bytes::Bytes; use discv5::enr::{CombinedKey, Enr}; use eth2_config::{instantiate_hardcoded_nets, HardcodedNet}; -use kzg::{KzgPreset, KzgPresetId, TrustedSetup}; use pretty_reqwest_error::PrettyReqwestError; use reqwest::{Client, Error}; use sensitive_url::SensitiveUrl; @@ -53,29 +52,28 @@ const TRUSTED_SETUP: &[u8] = include_bytes!("../built_in_network_configs/testing_trusted_setups.json"); const TRUSTED_SETUP_MINIMAL: &[u8] = - include_bytes!("../built_in_network_configs/minimal_testing_trusted_setups.json"); + include_bytes!("../built_in_network_configs/testing_trusted_setups.json"); -pub fn get_trusted_setup() -> &'static [u8] { - get_trusted_setup_from_id(P::spec_name()) +pub fn get_trusted_setup() -> &'static [u8] { + get_trusted_setup_from_id(E::spec_name()) } -pub fn get_trusted_setup_from_id(id: KzgPresetId) -> &'static [u8] { - match id { - KzgPresetId::Mainnet => TRUSTED_SETUP, - KzgPresetId::Minimal => TRUSTED_SETUP_MINIMAL, +pub fn get_trusted_setup_from_id(spec_id: EthSpecId) -> &'static [u8] { + match spec_id { + EthSpecId::Mainnet | EthSpecId::Gnosis => TRUSTED_SETUP, + EthSpecId::Minimal => TRUSTED_SETUP_MINIMAL, } } -fn get_trusted_setup_from_config(config: &Config) -> Result, String> { +fn get_trusted_setup_from_config(config: &Config) -> Result>, String> { config .deneb_fork_epoch .filter(|epoch| epoch.value != Epoch::max_value()) .map(|_| { - let id = KzgPresetId::from_str(&config.preset_base) - .map_err(|e| format!("Unable to parse preset_base as KZG preset: {:?}", e))?; - let trusted_setup_bytes = get_trusted_setup_from_id(id); - serde_json::from_reader(trusted_setup_bytes) - .map_err(|e| format!("Unable to read trusted setup file: {}", e)) + let id = config + .eth_spec_id() + .ok_or_else(|| "Unable to parse preset_base as KZG preset".to_string())?; + Ok(get_trusted_setup_from_id(id).to_vec()) }) .transpose() } @@ -121,7 +119,7 @@ pub struct Eth2NetworkConfig { pub genesis_state_source: GenesisStateSource, pub genesis_state_bytes: Option, pub config: Config, - pub kzg_trusted_setup: Option, + pub kzg_trusted_setup: Option>, } impl Eth2NetworkConfig { diff --git a/consensus/types/src/blob_sidecar.rs b/consensus/types/src/blob_sidecar.rs index a5fbc3206a1..14a9a0aef80 100644 --- a/consensus/types/src/blob_sidecar.rs +++ b/consensus/types/src/blob_sidecar.rs @@ -1,7 +1,7 @@ use crate::test_utils::TestRandom; use crate::{Blob, EthSpec, Hash256, SignedRoot, Slot}; use derivative::Derivative; -use kzg::{Kzg, KzgCommitment, KzgPreset, KzgProof, BYTES_PER_FIELD_ELEMENT}; +use kzg::{Kzg, KzgCommitment, KzgProof, BYTES_PER_FIELD_ELEMENT}; use rand::Rng; use serde::{Deserialize, Serialize}; use ssz::Encode; @@ -142,12 +142,12 @@ impl BlobSidecar { } } - pub fn random_valid(rng: &mut R, kzg: &Kzg) -> Result { - let mut blob_bytes = vec![0u8; T::Kzg::BYTES_PER_BLOB]; + pub fn random_valid(rng: &mut R, kzg: &Kzg) -> Result { + let mut blob_bytes = vec![0u8; kzg.bytes_per_blob()]; rng.fill_bytes(&mut blob_bytes); // Ensure that the blob is canonical by ensuring that // each field element contained in the blob is < BLS_MODULUS - for i in 0..T::Kzg::FIELD_ELEMENTS_PER_BLOB { + for i in 0..kzg.field_elements_per_blob() { let Some(byte) = blob_bytes.get_mut( i.checked_mul(BYTES_PER_FIELD_ELEMENT) .ok_or("overflow".to_string())?, @@ -159,14 +159,13 @@ impl BlobSidecar { let blob = Blob::::new(blob_bytes) .map_err(|e| format!("error constructing random blob: {:?}", e))?; - let kzg_blob = T::blob_from_bytes(&blob).unwrap(); let commitment = kzg - .blob_to_kzg_commitment(&kzg_blob) + .blob_to_kzg_commitment(blob.as_ref()) .map_err(|e| format!("error computing kzg commitment: {:?}", e))?; let proof = kzg - .compute_blob_kzg_proof(&kzg_blob, commitment) + .compute_blob_kzg_proof(blob.as_ref(), commitment) .map_err(|e| format!("error computing kzg proof: {:?}", e))?; Ok(Self { diff --git a/consensus/types/src/eth_spec.rs b/consensus/types/src/eth_spec.rs index 3ad6781941b..70982e8d56b 100644 --- a/consensus/types/src/eth_spec.rs +++ b/consensus/types/src/eth_spec.rs @@ -1,6 +1,5 @@ use crate::*; -use kzg::{BlobTrait, KzgPreset, MainnetKzgPreset, MinimalKzgPreset}; use safe_arith::SafeArith; use serde::{Deserialize, Serialize}; use ssz_types::typenum::{ @@ -52,8 +51,6 @@ impl fmt::Display for EthSpecId { pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq + Eq + for<'a> arbitrary::Arbitrary<'a> { - type Kzg: KzgPreset; - /* * Constants */ @@ -270,10 +267,6 @@ pub trait EthSpec: Self::FieldElementsPerBlob::to_usize() } - fn blob_from_bytes(bytes: &[u8]) -> Result<::Blob, kzg::Error> { - ::Blob::from_bytes(bytes) - } - /// Returns the `BYTES_PER_BLOB` constant for this specification. fn bytes_per_blob() -> usize { Self::BytesPerBlob::to_usize() @@ -293,8 +286,6 @@ macro_rules! params_from_eth_spec { pub struct MainnetEthSpec; impl EthSpec for MainnetEthSpec { - type Kzg = MainnetKzgPreset; - type JustificationBitsLength = U4; type SubnetBitfieldLength = U64; type MaxValidatorsPerCommittee = U2048; @@ -344,8 +335,6 @@ impl EthSpec for MainnetEthSpec { pub struct MinimalEthSpec; impl EthSpec for MinimalEthSpec { - type Kzg = MinimalKzgPreset; - type SlotsPerEpoch = U8; type EpochsPerEth1VotingPeriod = U4; type SlotsPerHistoricalRoot = U64; @@ -356,8 +345,8 @@ impl EthSpec for MinimalEthSpec { type MaxPendingAttestations = U1024; // 128 max attestations * 8 slots per epoch type SlotsPerEth1VotingPeriod = U32; // 4 epochs * 8 slots per epoch type MaxWithdrawalsPerPayload = U4; - type FieldElementsPerBlob = U4; - type BytesPerBlob = U128; + type FieldElementsPerBlob = U4096; + type BytesPerBlob = U131072; type MaxBlobCommitmentsPerBlock = U16; params_from_eth_spec!(MainnetEthSpec { @@ -398,8 +387,6 @@ impl EthSpec for MinimalEthSpec { pub struct GnosisEthSpec; impl EthSpec for GnosisEthSpec { - type Kzg = MainnetKzgPreset; - type JustificationBitsLength = U4; type SubnetBitfieldLength = U64; type MaxValidatorsPerCommittee = U2048; diff --git a/crypto/kzg/Cargo.toml b/crypto/kzg/Cargo.toml index b1e93379544..e3bdce6c69a 100644 --- a/crypto/kzg/Cargo.toml +++ b/crypto/kzg/Cargo.toml @@ -16,11 +16,5 @@ serde_derive = "1.0.116" ethereum_serde_utils = "0.5.0" hex = "0.4.2" ethereum_hashing = "1.0.0-beta.2" -c-kzg = { git = "https://github.com/ethereum/c-kzg-4844", rev = "f5f6f863d475847876a2bd5ee252058d37c3a15d" , features = ["mainnet-spec", "serde"]} -c_kzg_min = { package = "c-kzg", git = "https://github.com/ethereum//c-kzg-4844", rev = "f5f6f863d475847876a2bd5ee252058d37c3a15d", features = ["minimal-spec", "serde"], optional = true } +c-kzg = { git = "https://github.com/pawanjay176/c-kzg-4844", rev = "843d4c7ed087ad472f76933b158791b0a9184e52" } arbitrary = { version = "1.0", features = ["derive"] } - -[features] -# TODO(deneb): enabled by default for convenience, would need more cfg magic to disable -default = ["c_kzg_min"] -minimal-spec = ["c_kzg_min"] diff --git a/crypto/kzg/src/kzg_commitment.rs b/crypto/kzg/src/kzg_commitment.rs index e62e6fa49db..04ecce0b30f 100644 --- a/crypto/kzg/src/kzg_commitment.rs +++ b/crypto/kzg/src/kzg_commitment.rs @@ -34,12 +34,6 @@ impl From for c_kzg::Bytes48 { } } -impl From for c_kzg_min::Bytes48 { - fn from(value: KzgCommitment) -> Self { - value.0.into() - } -} - impl Display for KzgCommitment { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { write!(f, "{}", serde_utils::hex::encode(self.0)) diff --git a/crypto/kzg/src/kzg_proof.rs b/crypto/kzg/src/kzg_proof.rs index 06022ae4717..c9a138a31c3 100644 --- a/crypto/kzg/src/kzg_proof.rs +++ b/crypto/kzg/src/kzg_proof.rs @@ -17,12 +17,6 @@ impl From for c_kzg::Bytes48 { } } -impl From for c_kzg_min::Bytes48 { - fn from(value: KzgProof) -> Self { - value.0.into() - } -} - impl KzgProof { /// Creates a valid proof using `G1_POINT_AT_INFINITY`. pub fn empty() -> Self { diff --git a/crypto/kzg/src/lib.rs b/crypto/kzg/src/lib.rs index 410ae8a4951..0abae72a202 100644 --- a/crypto/kzg/src/lib.rs +++ b/crypto/kzg/src/lib.rs @@ -2,266 +2,37 @@ mod kzg_commitment; mod kzg_proof; mod trusted_setup; -use serde::{Deserialize, Serialize}; -use std::fmt::Debug; -use std::ops::Deref; -use std::str::FromStr; - pub use crate::{kzg_commitment::KzgCommitment, kzg_proof::KzgProof, trusted_setup::TrustedSetup}; -pub use c_kzg::{Bytes32, Bytes48, BYTES_PER_COMMITMENT, BYTES_PER_FIELD_ELEMENT, BYTES_PER_PROOF}; +pub use c_kzg::{ + Bytes32, Bytes48, KzgSettings, BYTES_PER_COMMITMENT, BYTES_PER_FIELD_ELEMENT, BYTES_PER_PROOF, +}; #[derive(Debug)] pub enum Error { - InvalidTrustedSetup(CryptoError), - InvalidKzgProof(CryptoError), - InvalidBytes(CryptoError), - KzgProofComputationFailed(CryptoError), - InvalidBlob(CryptoError), - InvalidBytesForBlob(CryptoError), -} - -#[derive(Debug)] -pub enum CryptoError { - CKzg(c_kzg::Error), - CKzgMin(c_kzg_min::Error), - /// Trusted setup is for the incorrect kzg preset. - InconsistentTrustedSetup, -} - -impl From for CryptoError { - fn from(e: c_kzg::Error) -> Self { - Self::CKzg(e) - } + CKzgError(c_kzg::Error), } -impl From for CryptoError { - fn from(e: c_kzg_min::Error) -> Self { - Self::CKzgMin(e) +impl From for Error { + fn from(value: c_kzg::Error) -> Self { + Self::CKzgError(value) } } -pub trait BlobTrait: Sized + Clone { - fn from_bytes(bytes: &[u8]) -> Result; -} - -pub enum KzgPresetId { - Mainnet, - Minimal, -} - -impl FromStr for KzgPresetId { - type Err = String; - - fn from_str(s: &str) -> Result { - match s { - "mainnet" => Ok(KzgPresetId::Mainnet), - "minimal" => Ok(KzgPresetId::Minimal), - _ => Err(format!("Unknown eth spec: {}", s)), - } - } +/// A wrapper over a kzg library that holds the trusted setup parameters. +#[derive(Debug)] +pub struct Kzg { + trusted_setup: KzgSettings, } -pub trait KzgPreset: - 'static + Default + Sync + Send + Clone + Debug + PartialEq + Eq + for<'a> arbitrary::Arbitrary<'a> -{ - type KzgSettings: Debug + Sync + Send; - type Blob: BlobTrait; - type Bytes32: From<[u8; 32]> + Deref; - type Bytes48: From + From; - type Error: Into; - - const BYTES_PER_BLOB: usize; - const FIELD_ELEMENTS_PER_BLOB: usize; - - fn spec_name() -> KzgPresetId; - - fn bytes32_in(bytes: Bytes32) -> Self::Bytes32 { - let bytes: [u8; 32] = *bytes; - Self::Bytes32::from(bytes) +impl Kzg { + pub fn field_elements_per_blob(&self) -> usize { + self.trusted_setup.field_elements_per_blob() } - fn bytes32_out(bytes: Self::Bytes32) -> Bytes32 { - let bytes: [u8; 32] = *bytes; - Bytes32::from(bytes) + pub fn bytes_per_blob(&self) -> usize { + self.trusted_setup.bytes_per_blob() } - fn load_trusted_setup(trusted_setup: TrustedSetup) -> Result; - - fn compute_blob_kzg_proof( - blob: &Self::Blob, - kzg_commitment: KzgCommitment, - trusted_setup: &Self::KzgSettings, - ) -> Result; - - fn verify_blob_kzg_proof( - blob: &Self::Blob, - kzg_commitment: KzgCommitment, - kzg_proof: KzgProof, - trusted_setup: &Self::KzgSettings, - ) -> Result; - - fn verify_blob_kzg_proof_batch( - blobs: &[Self::Blob], - commitments_bytes: &[Self::Bytes48], - proofs_bytes: &[Self::Bytes48], - trusted_setup: &Self::KzgSettings, - ) -> Result; - - fn blob_to_kzg_commitment( - blob: &Self::Blob, - trusted_setup: &Self::KzgSettings, - ) -> Result; - - fn compute_kzg_proof( - blob: &Self::Blob, - z: &Self::Bytes32, - trusted_setup: &Self::KzgSettings, - ) -> Result<(KzgProof, Self::Bytes32), CryptoError>; - - fn verify_kzg_proof( - kzg_commitment: KzgCommitment, - z: &Self::Bytes32, - y: &Self::Bytes32, - kzg_proof: KzgProof, - trusted_setup: &Self::KzgSettings, - ) -> Result; -} - -macro_rules! implement_kzg_preset { - ($preset_type:ident, $module_name:ident, $preset_id:ident) => { - impl KzgPreset for $preset_type { - type KzgSettings = $module_name::KzgSettings; - type Blob = $module_name::Blob; - type Bytes32 = $module_name::Bytes32; - type Bytes48 = $module_name::Bytes48; - type Error = $module_name::Error; - - const BYTES_PER_BLOB: usize = $module_name::BYTES_PER_BLOB; - const FIELD_ELEMENTS_PER_BLOB: usize = $module_name::FIELD_ELEMENTS_PER_BLOB; - - fn spec_name() -> KzgPresetId { - KzgPresetId::$preset_id - } - - fn load_trusted_setup( - trusted_setup: TrustedSetup, - ) -> Result { - if trusted_setup.g1_len() != Self::FIELD_ELEMENTS_PER_BLOB { - return Err(CryptoError::InconsistentTrustedSetup); - } - $module_name::KzgSettings::load_trusted_setup( - &trusted_setup.g1_points(), - &trusted_setup.g2_points(), - ) - .map_err(CryptoError::from) - } - - fn compute_blob_kzg_proof( - blob: &Self::Blob, - kzg_commitment: KzgCommitment, - trusted_setup: &Self::KzgSettings, - ) -> Result { - $module_name::KzgProof::compute_blob_kzg_proof( - blob, - &kzg_commitment.into(), - trusted_setup, - ) - .map(|proof| KzgProof(proof.to_bytes().into_inner())) - .map_err(CryptoError::from) - } - - fn verify_blob_kzg_proof( - blob: &Self::Blob, - kzg_commitment: KzgCommitment, - kzg_proof: KzgProof, - trusted_setup: &Self::KzgSettings, - ) -> Result { - $module_name::KzgProof::verify_blob_kzg_proof( - blob, - &kzg_commitment.into(), - &kzg_proof.into(), - trusted_setup, - ) - .map_err(CryptoError::from) - } - - fn verify_blob_kzg_proof_batch( - blobs: &[Self::Blob], - commitments_bytes: &[Self::Bytes48], - proofs_bytes: &[Self::Bytes48], - trusted_setup: &Self::KzgSettings, - ) -> Result { - $module_name::KzgProof::verify_blob_kzg_proof_batch( - blobs, - commitments_bytes, - proofs_bytes, - trusted_setup, - ) - .map_err(CryptoError::from) - } - - fn blob_to_kzg_commitment( - blob: &Self::Blob, - trusted_setup: &Self::KzgSettings, - ) -> Result { - $module_name::KzgCommitment::blob_to_kzg_commitment(blob, trusted_setup) - .map(|com| KzgCommitment(com.to_bytes().into_inner())) - .map_err(CryptoError::from) - } - - fn compute_kzg_proof( - blob: &Self::Blob, - z: &Self::Bytes32, - trusted_setup: &Self::KzgSettings, - ) -> Result<(KzgProof, Self::Bytes32), CryptoError> { - $module_name::KzgProof::compute_kzg_proof(blob, z, trusted_setup) - .map(|(proof, y)| (KzgProof(proof.to_bytes().into_inner()), y)) - .map_err(CryptoError::from) - } - - fn verify_kzg_proof( - kzg_commitment: KzgCommitment, - z: &Self::Bytes32, - y: &Self::Bytes32, - kzg_proof: KzgProof, - trusted_setup: &Self::KzgSettings, - ) -> Result { - $module_name::KzgProof::verify_kzg_proof( - &kzg_commitment.into(), - z, - y, - &kzg_proof.into(), - trusted_setup, - ) - .map_err(CryptoError::from) - } - } - - impl BlobTrait for $module_name::Blob { - fn from_bytes(bytes: &[u8]) -> Result { - Self::from_bytes(bytes) - .map_err(CryptoError::from) - .map_err(Error::InvalidBlob) - } - } - }; -} - -#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize, arbitrary::Arbitrary)] -pub struct MainnetKzgPreset; -#[derive(Clone, PartialEq, Eq, Debug, Default, Serialize, Deserialize, arbitrary::Arbitrary)] -pub struct MinimalKzgPreset; - -implement_kzg_preset!(MainnetKzgPreset, c_kzg, Mainnet); -implement_kzg_preset!(MinimalKzgPreset, c_kzg_min, Minimal); - -/// A wrapper over a kzg library that holds the trusted setup parameters. -#[derive(Debug)] -pub struct Kzg { - trusted_setup: P::KzgSettings, -} - -impl Kzg

{ /// 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 @@ -269,30 +40,36 @@ impl Kzg

{ /// The number of G2 points should be equal to 65. pub fn new_from_trusted_setup(trusted_setup: TrustedSetup) -> Result { Ok(Self { - trusted_setup: P::load_trusted_setup(trusted_setup) - .map_err(Error::InvalidTrustedSetup)?, + trusted_setup: KzgSettings::load_trusted_setup( + trusted_setup.g1_points().as_slice(), + trusted_setup.g2_points().as_slice(), + ) + .map_err(Error::CKzgError)?, }) } /// Compute the kzg proof given a blob and its kzg commitment. pub fn compute_blob_kzg_proof( &self, - blob: &P::Blob, + blob: &[u8], kzg_commitment: KzgCommitment, ) -> Result { - P::compute_blob_kzg_proof(blob, kzg_commitment, &self.trusted_setup) - .map_err(Error::KzgProofComputationFailed) + self.trusted_setup + .compute_blob_kzg_proof(blob, &kzg_commitment.into()) + .map_err(Error::CKzgError) + .map(|proof| KzgProof(proof.to_bytes().into_inner())) } /// Verify a kzg proof given the blob, kzg commitment and kzg proof. pub fn verify_blob_kzg_proof( &self, - blob: &P::Blob, + blob: &[u8], kzg_commitment: KzgCommitment, kzg_proof: KzgProof, ) -> Result { - P::verify_blob_kzg_proof(blob, kzg_commitment, kzg_proof, &self.trusted_setup) - .map_err(Error::InvalidKzgProof) + self.trusted_setup + .verify_blob_kzg_proof(blob, &kzg_commitment.into(), &kzg_proof.into()) + .map_err(Error::CKzgError) } /// Verify a batch of blob commitment proof triplets. @@ -301,43 +78,43 @@ impl Kzg

{ /// TODO(pawan): test performance against a parallelized rayon impl. pub fn verify_blob_kzg_proof_batch( &self, - blobs: &[P::Blob], + blobs: &[&[u8]], kzg_commitments: &[KzgCommitment], kzg_proofs: &[KzgProof], ) -> Result { let commitments_bytes = kzg_commitments .iter() - .map(|comm| P::Bytes48::from(*comm)) + .map(|comm| Bytes48::from(*comm)) .collect::>(); let proofs_bytes = kzg_proofs .iter() - .map(|proof| P::Bytes48::from(*proof)) + .map(|proof| Bytes48::from(*proof)) .collect::>(); - P::verify_blob_kzg_proof_batch( - blobs, - &commitments_bytes, - &proofs_bytes, - &self.trusted_setup, - ) - .map_err(Error::InvalidKzgProof) + self.trusted_setup + .verify_blob_kzg_proof_batch(blobs, &commitments_bytes, &proofs_bytes) + .map_err(Error::CKzgError) } /// Converts a blob to a kzg commitment. - pub fn blob_to_kzg_commitment(&self, blob: &P::Blob) -> Result { - P::blob_to_kzg_commitment(blob, &self.trusted_setup).map_err(Error::InvalidBlob) + pub fn blob_to_kzg_commitment(&self, blob: &[u8]) -> Result { + self.trusted_setup + .blob_to_kzg_commitment(blob) + .map_err(Error::CKzgError) + .map(|commitment| KzgCommitment(commitment.to_bytes().into_inner())) } /// Computes the kzg proof for a given `blob` and an evaluation point `z` pub fn compute_kzg_proof( &self, - blob: &P::Blob, + blob: &[u8], z: &Bytes32, ) -> Result<(KzgProof, Bytes32), Error> { - P::compute_kzg_proof(blob, &P::bytes32_in(*z), &self.trusted_setup) - .map_err(Error::KzgProofComputationFailed) - .map(|(proof, y)| (proof, P::bytes32_out(y))) + self.trusted_setup + .compute_kzg_proof(blob, z) + .map_err(Error::CKzgError) + .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` @@ -348,13 +125,8 @@ impl Kzg

{ y: &Bytes32, kzg_proof: KzgProof, ) -> Result { - P::verify_kzg_proof( - kzg_commitment, - &P::bytes32_in(*z), - &P::bytes32_in(*y), - kzg_proof, - &self.trusted_setup, - ) - .map_err(Error::InvalidKzgProof) + self.trusted_setup + .verify_kzg_proof(&kzg_commitment.into(), z, y, &kzg_proof.into()) + .map_err(Error::CKzgError) } } diff --git a/lcli/Cargo.toml b/lcli/Cargo.toml index 1ef215fa897..854f718c591 100644 --- a/lcli/Cargo.toml +++ b/lcli/Cargo.toml @@ -12,7 +12,6 @@ jemalloc = ["malloc_utils/jemalloc"] [dependencies] bls = { workspace = true } -kzg = { workspace = true } clap = { workspace = true } log = { workspace = true } serde = { workspace = true } diff --git a/lcli/src/new_testnet.rs b/lcli/src/new_testnet.rs index c9a0f9c09c2..e69d4ccd987 100644 --- a/lcli/src/new_testnet.rs +++ b/lcli/src/new_testnet.rs @@ -6,7 +6,6 @@ use eth2_wallet::bip39::Seed; use eth2_wallet::bip39::{Language, Mnemonic}; use eth2_wallet::{recover_validator_secret_from_mnemonic, KeyType}; use ethereum_hashing::hash; -use kzg::TrustedSetup; use ssz::Decode; use ssz::Encode; use state_processing::process_activations; @@ -199,10 +198,8 @@ pub fn run(testnet_dir_path: PathBuf, matches: &ArgMatches) -> Resul let kzg_trusted_setup = if let Some(epoch) = spec.deneb_fork_epoch { // Only load the trusted setup if the deneb fork epoch is set if epoch != Epoch::max_value() { - let trusted_setup: TrustedSetup = - serde_json::from_reader(get_trusted_setup::()) - .map_err(|e| format!("Unable to read trusted setup file: {}", e))?; - Some(trusted_setup) + let trusted_setup_bytes = get_trusted_setup::().to_vec(); + Some(trusted_setup_bytes) } else { None } diff --git a/lighthouse/tests/beacon_node.rs b/lighthouse/tests/beacon_node.rs index 95172980f65..7937b1d496e 100644 --- a/lighthouse/tests/beacon_node.rs +++ b/lighthouse/tests/beacon_node.rs @@ -835,7 +835,7 @@ fn run_jwt_optional_flags_test(jwt_flag: &str, jwt_id_flag: &str, jwt_version_fl let id = "bn-1"; let version = "Lighthouse-v2.1.3"; CommandLineTest::new() - .flag("execution-endpoint", Some(execution_endpoint.clone())) + .flag("execution-endpoint", Some(execution_endpoint)) .flag(jwt_flag, dir.path().join(jwt_file).as_os_str().to_str()) .flag(jwt_id_flag, Some(id)) .flag(jwt_version_flag, Some(version)) diff --git a/testing/ef_tests/src/cases/kzg_blob_to_kzg_commitment.rs b/testing/ef_tests/src/cases/kzg_blob_to_kzg_commitment.rs index 72a6052fead..8c4870dc21d 100644 --- a/testing/ef_tests/src/cases/kzg_blob_to_kzg_commitment.rs +++ b/testing/ef_tests/src/cases/kzg_blob_to_kzg_commitment.rs @@ -32,7 +32,7 @@ impl Case for KZGBlobToKZGCommitment { } fn result(&self, _case_index: usize, _fork_name: ForkName) -> Result<(), Error> { - let kzg = get_kzg::()?; + let kzg = get_kzg::()?; let commitment = parse_blob::(&self.input.blob).and_then(|blob| { blob_to_kzg_commitment::(&kzg, &blob).map_err(|e| { diff --git a/testing/ef_tests/src/cases/kzg_compute_blob_kzg_proof.rs b/testing/ef_tests/src/cases/kzg_compute_blob_kzg_proof.rs index 2cec8f1fb3d..723211828f9 100644 --- a/testing/ef_tests/src/cases/kzg_compute_blob_kzg_proof.rs +++ b/testing/ef_tests/src/cases/kzg_compute_blob_kzg_proof.rs @@ -39,7 +39,7 @@ impl Case for KZGComputeBlobKZGProof { Ok((blob, commitment)) }; - let kzg = get_kzg::()?; + let kzg = get_kzg::()?; let proof = parse_input(&self.input).and_then(|(blob, commitment)| { compute_blob_kzg_proof::(&kzg, &blob, commitment) .map_err(|e| Error::InternalError(format!("Failed to compute kzg proof: {:?}", e))) diff --git a/testing/ef_tests/src/cases/kzg_compute_kzg_proof.rs b/testing/ef_tests/src/cases/kzg_compute_kzg_proof.rs index 0085b8bd29f..abf3260db55 100644 --- a/testing/ef_tests/src/cases/kzg_compute_kzg_proof.rs +++ b/testing/ef_tests/src/cases/kzg_compute_kzg_proof.rs @@ -46,7 +46,7 @@ impl Case for KZGComputeKZGProof { Ok((blob, z)) }; - let kzg = get_kzg::()?; + let kzg = get_kzg::()?; let proof = parse_input(&self.input).and_then(|(blob, z)| { compute_kzg_proof::(&kzg, &blob, z) .map_err(|e| Error::InternalError(format!("Failed to compute kzg proof: {:?}", e))) diff --git a/testing/ef_tests/src/cases/kzg_verify_blob_kzg_proof.rs b/testing/ef_tests/src/cases/kzg_verify_blob_kzg_proof.rs index 2d18c9bdc0b..60e06b15c8e 100644 --- a/testing/ef_tests/src/cases/kzg_verify_blob_kzg_proof.rs +++ b/testing/ef_tests/src/cases/kzg_verify_blob_kzg_proof.rs @@ -2,14 +2,14 @@ use super::*; use crate::case_result::compare_result; use beacon_chain::kzg_utils::validate_blob; use eth2_network_config::get_trusted_setup; -use kzg::{Kzg, KzgCommitment, KzgPreset, KzgProof, TrustedSetup}; -use serde::Deserialize; +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, Error> { - let trusted_setup: TrustedSetup = serde_json::from_reader(get_trusted_setup::

()) +pub fn get_kzg() -> Result { + let trusted_setup: TrustedSetup = serde_json::from_reader(get_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))) @@ -89,7 +89,7 @@ impl Case for KZGVerifyBlobKZGProof { Ok((blob, commitment, proof)) }; - let kzg = get_kzg::()?; + let kzg = get_kzg::()?; let result = parse_input(&self.input).and_then(|(blob, commitment, proof)| { validate_blob::(&kzg, blob, commitment, proof) .map_err(|e| Error::InternalError(format!("Failed to validate blob: {:?}", e))) diff --git a/testing/ef_tests/src/cases/kzg_verify_blob_kzg_proof_batch.rs b/testing/ef_tests/src/cases/kzg_verify_blob_kzg_proof_batch.rs index cc941618a75..d4ddfbcb507 100644 --- a/testing/ef_tests/src/cases/kzg_verify_blob_kzg_proof_batch.rs +++ b/testing/ef_tests/src/cases/kzg_verify_blob_kzg_proof_batch.rs @@ -52,7 +52,7 @@ impl Case for KZGVerifyBlobKZGProofBatch { Ok((commitments, blobs, proofs)) }; - let kzg = get_kzg::()?; + let kzg = get_kzg::()?; let result = parse_input(&self.input).and_then(|(commitments, blobs, proofs)| { validate_blobs::(&kzg, &commitments, &blobs, &proofs) .map_err(|e| Error::InternalError(format!("Failed to validate blobs: {:?}", e))) diff --git a/testing/ef_tests/src/cases/kzg_verify_kzg_proof.rs b/testing/ef_tests/src/cases/kzg_verify_kzg_proof.rs index cdf0aeb8e38..a392787610a 100644 --- a/testing/ef_tests/src/cases/kzg_verify_kzg_proof.rs +++ b/testing/ef_tests/src/cases/kzg_verify_kzg_proof.rs @@ -42,7 +42,7 @@ impl Case for KZGVerifyKZGProof { Ok((commitment, z, y, proof)) }; - let kzg = get_kzg::()?; + let kzg = get_kzg::()?; let result = parse_input(&self.input).and_then(|(commitment, z, y, proof)| { verify_kzg_proof::(&kzg, commitment, proof, z, y) .map_err(|e| Error::InternalError(format!("Failed to validate proof: {:?}", e)))