Add kzg crate functions
This commit is contained in:
parent
3288404ec1
commit
e8b5f311aa
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -711,7 +711,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "c-kzg"
|
name = "c-kzg"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://github.com/pawanjay176/c-kzg-4844?rev=f4b0c2a84e7a90fa2e0e4e04e5d777be146c6e94#f4b0c2a84e7a90fa2e0e4e04e5d777be146c6e94"
|
source = "git+https://github.com/pawanjay176/c-kzg-4844?rev=cb3745d26b728ee526dc41912e3e1bc6f17a5eeb#cb3745d26b728ee526dc41912e3e1bc6f17a5eeb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"hex",
|
"hex",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -111,11 +111,11 @@ pub fn validate_blob_for_gossip<T: BeaconChainTypes>(
|
|||||||
|
|
||||||
// Verify that blobs are properly formatted
|
// Verify that blobs are properly formatted
|
||||||
//TODO: add the check while constructing a Blob type from bytes instead of after
|
//TODO: add the check while constructing a Blob type from bytes instead of after
|
||||||
for (i, blob) in blob_sidecar.blobs.iter().enumerate() {
|
// for (i, blob) in blob_sidecar.blobs.iter().enumerate() {
|
||||||
if blob.iter().any(|b| *b >= *BLS_MODULUS) {
|
// if blob.iter().any(|b| *b >= *BLS_MODULUS) {
|
||||||
return Err(BlobError::BlobOutOfRange { blob_index: i });
|
// return Err(BlobError::BlobOutOfRange { blob_index: i });
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Verify that the KZG proof is a valid G1 point
|
// Verify that the KZG proof is a valid G1 point
|
||||||
if PublicKey::deserialize(&blob_sidecar.kzg_aggregate_proof.0).is_err() {
|
if PublicKey::deserialize(&blob_sidecar.kzg_aggregate_proof.0).is_err() {
|
||||||
|
@ -3,7 +3,7 @@ use crate::*;
|
|||||||
use safe_arith::SafeArith;
|
use safe_arith::SafeArith;
|
||||||
use serde_derive::{Deserialize, Serialize};
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use ssz_types::typenum::{
|
use ssz_types::typenum::{
|
||||||
bit::B0, UInt, Unsigned, U0, U1024, U1048576, U1073741824, U1099511627776, U128, U16,
|
bit::B0, UInt, Unsigned, U0, U1024, U1048576, U1073741824, U1099511627776, U128, U131072, U16,
|
||||||
U16777216, U2, U2048, U256, U32, U4, U4096, U512, U625, U64, U65536, U8, U8192,
|
U16777216, U2, U2048, U256, U32, U4, U4096, U512, U625, U64, U65536, U8, U8192,
|
||||||
};
|
};
|
||||||
use std::fmt::{self, Debug};
|
use std::fmt::{self, Debug};
|
||||||
@ -105,6 +105,7 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
|
|||||||
*/
|
*/
|
||||||
type MaxBlobsPerBlock: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
type MaxBlobsPerBlock: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||||
type FieldElementsPerBlob: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
type FieldElementsPerBlob: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||||
|
type BytesPerFieldElement: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||||
/*
|
/*
|
||||||
* Derived values (set these CAREFULLY)
|
* Derived values (set these CAREFULLY)
|
||||||
*/
|
*/
|
||||||
@ -123,6 +124,11 @@ pub trait EthSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq +
|
|||||||
/// Must be set to `SyncCommitteeSize / SyncCommitteeSubnetCount`.
|
/// Must be set to `SyncCommitteeSize / SyncCommitteeSubnetCount`.
|
||||||
type SyncSubcommitteeSize: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
type SyncSubcommitteeSize: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||||
|
|
||||||
|
/// The total length of a blob in bytes.
|
||||||
|
///
|
||||||
|
/// Must be set to `BytesPerFieldElement * FieldElementsPerBlob`.
|
||||||
|
type BytesPerBlob: Unsigned + Clone + Sync + Send + Debug + PartialEq;
|
||||||
|
|
||||||
fn default_spec() -> ChainSpec;
|
fn default_spec() -> ChainSpec;
|
||||||
|
|
||||||
fn spec_name() -> EthSpecId;
|
fn spec_name() -> EthSpecId;
|
||||||
@ -293,7 +299,9 @@ impl EthSpec for MainnetEthSpec {
|
|||||||
type MinGasLimit = U5000;
|
type MinGasLimit = U5000;
|
||||||
type MaxExtraDataBytes = U32;
|
type MaxExtraDataBytes = U32;
|
||||||
type MaxBlobsPerBlock = U16; // 2**4 = 16
|
type MaxBlobsPerBlock = U16; // 2**4 = 16
|
||||||
|
type BytesPerFieldElement = U32;
|
||||||
type FieldElementsPerBlob = U4096;
|
type FieldElementsPerBlob = U4096;
|
||||||
|
type BytesPerBlob = U131072;
|
||||||
type SyncSubcommitteeSize = U128; // 512 committee size / 4 sync committee subnet count
|
type SyncSubcommitteeSize = U128; // 512 committee size / 4 sync committee subnet count
|
||||||
type MaxPendingAttestations = U4096; // 128 max attestations * 32 slots per epoch
|
type MaxPendingAttestations = U4096; // 128 max attestations * 32 slots per epoch
|
||||||
type SlotsPerEth1VotingPeriod = U2048; // 64 epochs * 32 slots per epoch
|
type SlotsPerEth1VotingPeriod = U2048; // 64 epochs * 32 slots per epoch
|
||||||
@ -347,7 +355,9 @@ impl EthSpec for MinimalEthSpec {
|
|||||||
MaxExtraDataBytes,
|
MaxExtraDataBytes,
|
||||||
MaxBlsToExecutionChanges,
|
MaxBlsToExecutionChanges,
|
||||||
MaxBlobsPerBlock,
|
MaxBlobsPerBlock,
|
||||||
FieldElementsPerBlob
|
FieldElementsPerBlob,
|
||||||
|
BytesPerFieldElement,
|
||||||
|
BytesPerBlob
|
||||||
});
|
});
|
||||||
|
|
||||||
fn default_spec() -> ChainSpec {
|
fn default_spec() -> ChainSpec {
|
||||||
@ -396,6 +406,8 @@ impl EthSpec for GnosisEthSpec {
|
|||||||
type MaxWithdrawalsPerPayload = U16;
|
type MaxWithdrawalsPerPayload = U16;
|
||||||
type MaxBlobsPerBlock = U16; // 2**4 = 16
|
type MaxBlobsPerBlock = U16; // 2**4 = 16
|
||||||
type FieldElementsPerBlob = U4096;
|
type FieldElementsPerBlob = U4096;
|
||||||
|
type BytesPerFieldElement = U32;
|
||||||
|
type BytesPerBlob = U131072;
|
||||||
|
|
||||||
fn default_spec() -> ChainSpec {
|
fn default_spec() -> ChainSpec {
|
||||||
ChainSpec::gnosis()
|
ChainSpec::gnosis()
|
||||||
|
@ -198,7 +198,7 @@ pub type Uint256 = ethereum_types::U256;
|
|||||||
pub type Address = H160;
|
pub type Address = H160;
|
||||||
pub type ForkVersion = [u8; 4];
|
pub type ForkVersion = [u8; 4];
|
||||||
pub type BLSFieldElement = Uint256;
|
pub type BLSFieldElement = Uint256;
|
||||||
pub type Blob<T> = FixedVector<BLSFieldElement, <T as EthSpec>::FieldElementsPerBlob>;
|
pub type Blob<T> = FixedVector<u8, <T as EthSpec>::BytesPerBlob>;
|
||||||
pub type VersionedHash = Hash256;
|
pub type VersionedHash = Hash256;
|
||||||
|
|
||||||
pub use bls::{
|
pub use bls::{
|
||||||
|
@ -19,4 +19,4 @@ eth2_serde_utils = "0.1.1"
|
|||||||
hex = "0.4.2"
|
hex = "0.4.2"
|
||||||
eth2_hashing = "0.3.0"
|
eth2_hashing = "0.3.0"
|
||||||
ethereum-types = "0.12.1"
|
ethereum-types = "0.12.1"
|
||||||
c-kzg = {git = "https://github.com/pawanjay176/c-kzg-4844", rev = "f4b0c2a84e7a90fa2e0e4e04e5d777be146c6e94" }
|
c-kzg = {git = "https://github.com/pawanjay176/c-kzg-4844", rev = "cb3745d26b728ee526dc41912e3e1bc6f17a5eeb" }
|
||||||
|
@ -1,30 +1,83 @@
|
|||||||
mod kzg_commitment;
|
mod kzg_commitment;
|
||||||
mod kzg_proof;
|
mod kzg_proof;
|
||||||
|
|
||||||
|
pub use crate::{kzg_commitment::KzgCommitment, kzg_proof::KzgProof};
|
||||||
|
use c_kzg::{Error as CKzgError, KZGSettings, BYTES_PER_FIELD_ELEMENT, FIELD_ELEMENTS_PER_BLOB};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use c_kzg::{Error as CKzgError, KZGSettings};
|
const BYTES_PER_BLOB: usize = FIELD_ELEMENTS_PER_BLOB * BYTES_PER_FIELD_ELEMENT;
|
||||||
|
|
||||||
pub use crate::{kzg_commitment::KzgCommitment, kzg_proof::KzgProof};
|
/// The consensus type `Blob` is generic over EthSpec, so it cannot be imported
|
||||||
|
/// in this crate without creating a cyclic dependency between the kzg and consensus/types crates.
|
||||||
|
/// So need to use a Vec here unless we think of a smarter way of doing this
|
||||||
|
type Blob = [u8; BYTES_PER_BLOB];
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
InvalidTrustedSetup(CKzgError),
|
InvalidTrustedSetup(CKzgError),
|
||||||
|
InvalidKzgCommitment(CKzgError),
|
||||||
|
InvalidKzgProof(CKzgError),
|
||||||
|
KzgVerificationFailed(CKzgError),
|
||||||
|
EmptyBlobs,
|
||||||
|
EmptyKzgCommitments,
|
||||||
|
InvalidLength(String),
|
||||||
|
KzgProofComputationFailed(CKzgError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Kzg {
|
pub struct Kzg {
|
||||||
_trusted_setup: KZGSettings,
|
trusted_setup: KZGSettings,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Kzg {
|
impl Kzg {
|
||||||
pub fn new_from_file(file_path: PathBuf) -> Result<Self, Error> {
|
pub fn new_from_file(file_path: PathBuf) -> Result<Self, Error> {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
_trusted_setup: KZGSettings::load_trusted_setup(file_path)
|
trusted_setup: KZGSettings::load_trusted_setup(file_path)
|
||||||
.map_err(|e| Error::InvalidTrustedSetup(e))?,
|
.map_err(Error::InvalidTrustedSetup)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify_aggregate_kzg_proof() {}
|
pub fn compute_aggregate_kzg_proof(&self, blobs: &[Blob]) -> Result<KzgProof, Error> {
|
||||||
|
if blobs.len() == 0 {
|
||||||
|
return Err(Error::EmptyBlobs);
|
||||||
|
}
|
||||||
|
c_kzg::KZGProof::compute_aggregate_kzg_proof(blobs, &self.trusted_setup)
|
||||||
|
.map_err(Error::KzgProofComputationFailed)
|
||||||
|
.map(|proof| KzgProof(proof.to_bytes()))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn blob_to_kzg_commitment() {}
|
pub fn verify_aggregate_kzg_proof(
|
||||||
|
&self,
|
||||||
|
blobs: &[Blob],
|
||||||
|
expected_kzg_commitments: &[KzgCommitment],
|
||||||
|
kzg_aggregated_proof: KzgProof,
|
||||||
|
) -> Result<bool, Error> {
|
||||||
|
if blobs.len() == 0 {
|
||||||
|
return Err(Error::EmptyBlobs);
|
||||||
|
}
|
||||||
|
if expected_kzg_commitments.len() == 0 {
|
||||||
|
return Err(Error::EmptyBlobs);
|
||||||
|
}
|
||||||
|
if blobs.len() != expected_kzg_commitments.len() {
|
||||||
|
return Err(Error::InvalidLength(
|
||||||
|
"blobs and expected_kzg_commitments should be of same size".to_string(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
let commitments = expected_kzg_commitments
|
||||||
|
.into_iter()
|
||||||
|
.map(|comm| {
|
||||||
|
c_kzg::KZGCommitment::from_bytes(&comm.0).map_err(Error::InvalidKzgCommitment)
|
||||||
|
})
|
||||||
|
.collect::<Result<Vec<c_kzg::KZGCommitment>, Error>>()?;
|
||||||
|
let proof =
|
||||||
|
c_kzg::KZGProof::from_bytes(&kzg_aggregated_proof.0).map_err(Error::InvalidKzgProof)?;
|
||||||
|
proof
|
||||||
|
.verify_aggregate_kzg_proof(blobs, &commitments, &self.trusted_setup)
|
||||||
|
.map_err(Error::InvalidKzgProof)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn blob_to_kzg_commitment(&self, blob: Blob) -> KzgCommitment {
|
||||||
|
KzgCommitment(
|
||||||
|
c_kzg::KZGCommitment::blob_to_kzg_commitment(blob, &self.trusted_setup).to_bytes(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user