Skip to content

Commit

Permalink
Merge pull request #225 from EchoAlice/polynomial_commitments
Browse files Browse the repository at this point in the history
deneb: implement poly comm spec
  • Loading branch information
ralexstokes authored Oct 12, 2023
2 parents f0fe891 + b164746 commit 8432749
Show file tree
Hide file tree
Showing 16 changed files with 157 additions and 27 deletions.
1 change: 1 addition & 0 deletions ethereum-consensus/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ multihash = { version = "0.16", default-features = false, features = [
"sha2",
] }
multiaddr = "0.14.0"
c-kzg = "0.1.1"

serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0.81", optional = true }
Expand Down
3 changes: 1 addition & 2 deletions ethereum-consensus/src/deneb/beacon_block.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::{
altair::SyncAggregate,
capella::SignedBlsToExecutionChange,
deneb::ExecutionPayload,
kzg::KzgCommitment,
deneb::{polynomial_commitments::KzgCommitment, ExecutionPayload},
phase0::{
Attestation, AttesterSlashing, Deposit, Eth1Data, ProposerSlashing, SignedVoluntaryExit,
},
Expand Down
3 changes: 1 addition & 2 deletions ethereum-consensus/src/deneb/blinded_beacon_block.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
use crate::{
altair::SyncAggregate,
capella::SignedBlsToExecutionChange,
deneb::ExecutionPayloadHeader,
kzg::KzgCommitment,
deneb::{polynomial_commitments::KzgCommitment, ExecutionPayloadHeader},
phase0::{
Attestation, AttesterSlashing, Deposit, Eth1Data, ProposerSlashing, SignedVoluntaryExit,
},
Expand Down
2 changes: 1 addition & 1 deletion ethereum-consensus/src/deneb/blinded_blob_sidecar.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
kzg::{KzgCommitment, KzgProof},
deneb::polynomial_commitments::{KzgCommitment, KzgProof},
primitives::{BlobIndex, BlsSignature, Root, Slot, ValidatorIndex},
ssz::prelude::*,
};
Expand Down
2 changes: 1 addition & 1 deletion ethereum-consensus/src/deneb/blob_sidecar.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
kzg::{KzgCommitment, KzgProof},
deneb::polynomial_commitments::{KzgCommitment, KzgProof},
primitives::{BlobIndex, BlsSignature, Root, Slot, ValidatorIndex},
ssz::prelude::*,
};
Expand Down
3 changes: 1 addition & 2 deletions ethereum-consensus/src/deneb/execution_engine.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::{
deneb::execution_payload::ExecutionPayload,
kzg::VersionedHash,
deneb::{execution_payload::ExecutionPayload, polynomial_commitments::VersionedHash},
primitives::Root,
state_transition::{ExecutionEngineError, Result},
};
Expand Down
7 changes: 4 additions & 3 deletions ethereum-consensus/src/deneb/helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ use crate::{
},
crypto::hash,
deneb::{
beacon_state::BeaconState, get_block_root, get_block_root_at_slot, get_current_epoch,
get_validator_churn_limit, AttestationData, VERSIONED_HASH_VERSION_KZG,
beacon_state::BeaconState,
get_block_root, get_block_root_at_slot, get_current_epoch, get_validator_churn_limit,
polynomial_commitments::{KzgCommitment, VersionedHash},
AttestationData, VERSIONED_HASH_VERSION_KZG,
},
kzg::{KzgCommitment, VersionedHash},
state_transition::{
invalid_operation_error, Context, InvalidAttestation, InvalidOperation, Result,
},
Expand Down
1 change: 1 addition & 0 deletions ethereum-consensus/src/deneb/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ pub mod fork;
pub mod genesis;
pub mod helpers;
pub mod networking;
pub mod polynomial_commitments;
pub mod presets;
pub mod spec;

Expand Down
137 changes: 137 additions & 0 deletions ethereum-consensus/src/deneb/polynomial_commitments.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
use crate::{deneb::blob_sidecar::Blob, primitives::Bytes32, ssz::prelude::*};
pub use c_kzg::KzgSettings;
use thiserror::Error;

pub const BYTES_PER_FIELD_ELEMENT: usize = 32;
pub const BYTES_PER_COMMITMENT: usize = 48;
pub const BYTES_PER_PROOF: usize = 48;

pub type VersionedHash = Bytes32;
pub type FieldElement = Bytes32;
pub type KzgCommitment = ByteVector<BYTES_PER_COMMITMENT>;
pub type KzgProof = ByteVector<BYTES_PER_PROOF>;

#[derive(Debug, Error)]
pub enum Error {
#[error(transparent)]
CKzg(#[from] c_kzg::Error),
#[error("proof verification failed")]
InvalidProof,
}

pub struct ProofAndEvaluation {
pub proof: KzgProof,
pub evaluation: FieldElement,
}

pub fn blob_to_kzg_commitment<const BYTES_PER_BLOB: usize>(
blob: &Blob<BYTES_PER_BLOB>,
kzg_settings: &KzgSettings,
) -> Result<KzgCommitment, Error> {
let blob = c_kzg::Blob::from_bytes(blob.as_ref())?;

let commitment = c_kzg::KzgCommitment::blob_to_kzg_commitment(&blob, kzg_settings)?;
let inner = KzgCommitment::try_from(commitment.to_bytes().as_slice()).expect("correct size");
Ok(inner)
}

pub fn compute_kzg_proof<const BYTES_PER_BLOB: usize>(
blob: &Blob<BYTES_PER_BLOB>,
evaluation_point: &FieldElement,
kzg_settings: &KzgSettings,
) -> Result<ProofAndEvaluation, Error> {
let blob = c_kzg::Blob::from_bytes(blob.as_ref())?;
let evaluation_point = c_kzg::Bytes32::from_bytes(evaluation_point.as_ref())?;

let (proof, evaluation) =
c_kzg::KzgProof::compute_kzg_proof(&blob, &evaluation_point, kzg_settings)?;
let proof = KzgProof::try_from(proof.to_bytes().as_ref()).expect("correct size");
let evaluation = FieldElement::try_from(evaluation.as_slice()).expect("correct size");

let result = ProofAndEvaluation { proof, evaluation };
Ok(result)
}

pub fn compute_blob_kzg_proof<const BYTES_PER_BLOB: usize>(
blob: &Blob<BYTES_PER_BLOB>,
commitment: &KzgCommitment,
kzg_settings: &KzgSettings,
) -> Result<KzgProof, Error> {
let blob = c_kzg::Blob::from_bytes(blob.as_ref())?;
let commitment = c_kzg::Bytes48::from_bytes(commitment.as_ref()).expect("correct size");

let proof = c_kzg::KzgProof::compute_blob_kzg_proof(&blob, &commitment, kzg_settings)?;

Ok(KzgProof::try_from(proof.to_bytes().as_ref()).expect("input is correct size"))
}

pub fn verify_kzg_proof(
commitment: &KzgCommitment,
evaluation_point: &FieldElement,
result_point: &FieldElement,
proof: &KzgProof,
kzg_settings: &KzgSettings,
) -> Result<(), Error> {
let evaluation_point = c_kzg::Bytes32::from_bytes(evaluation_point.as_ref())?;
let result_point = c_kzg::Bytes32::from_bytes(result_point.as_ref())?;
let commitment = c_kzg::Bytes48::from_bytes(commitment.as_ref()).expect("correct size");
let proof = c_kzg::Bytes48::from_bytes(proof.as_ref()).expect("correct size");

let res = c_kzg::KzgProof::verify_kzg_proof(
&commitment,
&evaluation_point,
&result_point,
&proof,
kzg_settings,
)?;

res.then_some(()).ok_or(Error::InvalidProof)
}

pub fn verify_blob_kzg_proof<const BYTES_PER_BLOB: usize>(
blob: &Blob<BYTES_PER_BLOB>,
commitment: &KzgCommitment,
proof: &KzgProof,
kzg_settings: &KzgSettings,
) -> Result<(), Error> {
let blob = c_kzg::Blob::from_bytes(blob.as_ref())?;
let commitment = c_kzg::Bytes48::from_bytes(commitment.as_ref()).unwrap();
let proof = c_kzg::Bytes48::from_bytes(proof.as_ref()).unwrap();

let res = c_kzg::KzgProof::verify_blob_kzg_proof(&blob, &commitment, &proof, kzg_settings)?;

res.then_some(()).ok_or(Error::InvalidProof)
}

pub fn verify_blob_kzg_proof_batch<const BYTES_PER_BLOB: usize>(
blobs: &[Blob<BYTES_PER_BLOB>],
commitments: &[KzgCommitment],
proofs: &[KzgProof],
kzg_settings: &KzgSettings,
) -> Result<(), Error> {
let mut c_kzg_blobs = Vec::with_capacity(blobs.len());
let mut c_kzg_commitments = Vec::with_capacity(commitments.len());
let mut c_kzg_proofs = Vec::with_capacity(proofs.len());

for blob in blobs {
let blob = c_kzg::Blob::from_bytes(blob.as_ref())?;
c_kzg_blobs.push(blob);
}
for commitment in commitments {
let commitment = c_kzg::Bytes48::from_bytes(commitment.as_ref()).unwrap();
c_kzg_commitments.push(commitment);
}
for proof in proofs {
let proof = c_kzg::Bytes48::from_bytes(proof.as_ref()).unwrap();
c_kzg_proofs.push(proof);
}

let res = c_kzg::KzgProof::verify_blob_kzg_proof_batch(
&c_kzg_blobs,
&c_kzg_commitments,
&c_kzg_proofs,
kzg_settings,
)?;

res.then_some(()).ok_or(Error::InvalidProof)
}
3 changes: 2 additions & 1 deletion ethereum-consensus/src/deneb/presets/mainnet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ pub const FIELD_ELEMENTS_PER_BLOB: usize = 4096;
pub const MAX_BLOB_COMMITMENTS_PER_BLOCK: usize = 4096;
pub const MAX_BLOBS_PER_BLOCK: usize = 6;

pub const BYTES_PER_BLOB: usize = crate::kzg::BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB;
pub const BYTES_PER_BLOB: usize =
crate::deneb::polynomial_commitments::BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB;

pub const MAX_REQUEST_BLOB_SIDECARS: usize = MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK;

Expand Down
3 changes: 2 additions & 1 deletion ethereum-consensus/src/deneb/presets/minimal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ pub const FIELD_ELEMENTS_PER_BLOB: usize = 4;
pub const MAX_BLOB_COMMITMENTS_PER_BLOCK: usize = 16;
pub const MAX_BLOBS_PER_BLOCK: usize = 6;

pub const BYTES_PER_BLOB: usize = crate::kzg::BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB;
pub const BYTES_PER_BLOB: usize =
crate::deneb::polynomial_commitments::BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB;

pub const MAX_REQUEST_BLOB_SIDECARS: usize = MAX_REQUEST_BLOCKS_DENEB * MAX_BLOBS_PER_BLOCK;

Expand Down
9 changes: 0 additions & 9 deletions ethereum-consensus/src/kzg.rs

This file was deleted.

1 change: 0 additions & 1 deletion ethereum-consensus/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ pub mod crypto;
pub mod deneb;
pub mod domains;
mod fork;
pub mod kzg;
pub mod networking;
pub mod networks;
pub mod phase0;
Expand Down
3 changes: 3 additions & 0 deletions ethereum-consensus/src/state_transition/error.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
capella::Withdrawal,
crypto::Error as CryptoError,
deneb::polynomial_commitments::Error as PolynomialCommitmentError,
phase0::{AttestationData, BeaconBlockHeader, Checkpoint},
primitives::{BlsPublicKey, BlsSignature, Bytes32, Epoch, Hash32, Root, Slot, ValidatorIndex},
ssz::prelude::*,
Expand Down Expand Up @@ -55,6 +56,8 @@ pub enum Error {
UnknownPreset(String),
#[error(transparent)]
ExecutionEngine(#[from] ExecutionEngineError),
#[error(transparent)]
PolynomialCommitment(#[from] PolynomialCommitmentError),
}

#[derive(Debug, Error)]
Expand Down
3 changes: 1 addition & 2 deletions ethereum-consensus/src/types/beacon_block_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use crate::{
altair::{beacon_block as altair, SyncAggregate},
bellatrix::beacon_block as bellatrix,
capella::{beacon_block as capella, SignedBlsToExecutionChange},
deneb::beacon_block as deneb,
kzg::KzgCommitment,
deneb::{beacon_block as deneb, polynomial_commitments::KzgCommitment},
phase0::{
beacon_block as phase0, Attestation, AttesterSlashing, Deposit, Eth1Data, ProposerSlashing,
SignedVoluntaryExit,
Expand Down
3 changes: 1 addition & 2 deletions ethereum-consensus/src/types/blinded_beacon_block_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use crate::{
altair::SyncAggregate,
bellatrix::blinded_beacon_block as bellatrix,
capella::{blinded_beacon_block as capella, SignedBlsToExecutionChange},
deneb::blinded_beacon_block as deneb,
kzg::KzgCommitment,
deneb::{blinded_beacon_block as deneb, polynomial_commitments::KzgCommitment},
phase0::{
Attestation, AttesterSlashing, Deposit, Eth1Data, ProposerSlashing, SignedVoluntaryExit,
},
Expand Down

0 comments on commit 8432749

Please sign in to comment.