Skip to content

Commit

Permalink
feat: use kzg-rs for kzg point evaluation (#1558)
Browse files Browse the repository at this point in the history
* feat: use `kzg-rs`

* fix: use `c-kzg` by default in std env

* refactor: feature gate by `c-kzg`

* fix: use published crate

* fix: `kzg-rs` import

* feat: use `cfg_if` for `kzg-rs` imports

* feat: use `kzg-rs`

* fix: `kzg-rs` import

* chore: add `kzg-rs` feature to revm-interpreter

* fix: check kzg-rs enable in revm/precompile

* fix: kzg-rs include once_cell and derive_more in primitives, update feature tags

* Update crates/primitives/src/lib.rs

* Update crates/precompile/src/lib.rs

* Update crates/primitives/Cargo.toml

* Update crates/revm/Cargo.toml

* Update crates/precompile/Cargo.toml

* Update crates/primitives/src/lib.rs

---------

Co-authored-by: rakita <rakita@users.noreply.github.com>
  • Loading branch information
0xWOLAND and rakita authored Jul 10, 2024
1 parent 0bf2d56 commit 2b25469
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 35 deletions.
59 changes: 59 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/interpreter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,5 @@ optional_eip3607 = ["revm-primitives/optional_eip3607"]
optional_gas_refund = ["revm-primitives/optional_gas_refund"]
optional_no_base_fee = ["revm-primitives/optional_no_base_fee"]
optional_beneficiary_reward = ["revm-primitives/optional_beneficiary_reward"]

kzg-rs = ["revm-primitives/kzg-rs"]
8 changes: 8 additions & 0 deletions crates/precompile/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ bn = { package = "substrate-bn", version = "0.6", default-features = false }
# KZG point evaluation precompile
c-kzg = { version = "1.0.2", default-features = false, optional = true }

# Optionally use `kzg-rs` for a pure Rust implementation of KZG point evaluation.
kzg-rs = { version = "0.1", default-features = false, features = [
'cache',
], optional = true }

# BLS12-381 precompiles
blst = { version = "0.3.12", optional = true }

Expand Down Expand Up @@ -98,6 +103,9 @@ secp256r1 = ["dep:p256"]

# Enables the KZG point evaluation precompile.
c-kzg = ["dep:c-kzg", "revm-primitives/c-kzg"]
# `kzg-rs` is not audited but useful for `no_std` environment, use it with causing and default to `c-kzg` if possible.
kzg-rs = ["dep:kzg-rs", "revm-primitives/kzg-rs"]

portable = ["revm-primitives/portable", "c-kzg?/portable"]

# Use `secp256k1` as a faster alternative to `k256`.
Expand Down
8 changes: 7 additions & 1 deletion crates/precompile/src/kzg_point_evaluation.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
use crate::{Address, Error, Precompile, PrecompileResult, PrecompileWithAddress};
use c_kzg::{Bytes32, Bytes48, KzgProof, KzgSettings};
cfg_if::cfg_if! {
if #[cfg(feature = "c-kzg")] {
use c_kzg::{Bytes32, Bytes48, KzgProof, KzgSettings};
} else if #[cfg(feature = "kzg-rs")] {
use kzg_rs::{Bytes32, Bytes48, KzgProof, KzgSettings};
}
}
use revm_primitives::{hex_literal::hex, Bytes, Env, PrecompileOutput};
use sha2::{Digest, Sha256};

Expand Down
7 changes: 5 additions & 2 deletions crates/precompile/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ pub mod bn128;
pub mod fatal_precompile;
pub mod hash;
pub mod identity;
#[cfg(feature = "c-kzg")]
#[cfg(any(feature = "c-kzg", feature = "kzg-rs"))]
pub mod kzg_point_evaluation;
pub mod modexp;
pub mod secp256k1;
Expand All @@ -25,6 +25,9 @@ pub mod utilities;

pub use fatal_precompile::fatal_precompile;

#[cfg(all(feature = "c-kzg", feature = "kzg-rs"))]
// silence kzg-rs lint as c-kzg will be used as default if both are enabled.
use kzg_rs as _;
pub use primitives::{
precompile::{PrecompileError as Error, *},
Address, Bytes, HashMap, HashSet, Log, B256,
Expand Down Expand Up @@ -142,7 +145,7 @@ impl Precompiles {

// EIP-4844: Shard Blob Transactions
cfg_if! {
if #[cfg(feature = "c-kzg")] {
if #[cfg(any(feature = "c-kzg", feature = "kzg-rs"))] {
let precompile = kzg_point_evaluation::POINT_EVALUATION.clone();
} else {
// TODO move constants to separate file.
Expand Down
12 changes: 10 additions & 2 deletions crates/primitives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ rust_2018_idioms = "deny"
all = "warn"

[dependencies]
alloy-eips = { version = "0.1", default-features = false, features = ["k256"]}
alloy-eips = { version = "0.1", default-features = false, features = ["k256"] }
alloy-primitives = { version = "0.7.2", default-features = false, features = [
"rlp",
] }
Expand All @@ -35,6 +35,11 @@ bitflags = { version = "2.6.0", default-features = false }
c-kzg = { version = "1.0.2", default-features = false, optional = true }
once_cell = { version = "1.19", default-features = false, optional = true }

# Optionally use `kzg-rs` for a pure Rust implementation of KZG.
kzg-rs = { version = "0.1", default-features = false, features = [
'cache',
], optional = true }

# utility
enumn = "0.1"
derive_more = { version = "0.99", optional = true }
Expand Down Expand Up @@ -70,12 +75,13 @@ serde = [
"bitvec/serde",
"bitflags/serde",
"c-kzg?/serde",
"kzg-rs?/serde",
]
arbitrary = [
"std",
"alloy-eips/arbitrary",
"alloy-primitives/arbitrary",
"bitflags/arbitrary"
"bitflags/arbitrary",
]
asm-keccak = ["alloy-primitives/asm-keccak"]
portable = ["c-kzg?/portable"]
Expand Down Expand Up @@ -105,3 +111,5 @@ rand = ["alloy-primitives/rand"]

# See comments in `revm-precompile`
c-kzg = ["dep:c-kzg", "dep:once_cell", "dep:derive_more"]
# `kzg-rs` is not audited but useful for `no_std` environment, use it with causing and default to `c-kzg` if possible.
kzg-rs = ["dep:kzg-rs", "dep:once_cell", "dep:derive_more"]
2 changes: 1 addition & 1 deletion crates/primitives/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ pub struct CfgEnv {
/// Chain ID is introduced EIP-155
pub chain_id: u64,
/// KZG Settings for point evaluation precompile. By default, this is loaded from the ethereum mainnet trusted setup.
#[cfg(feature = "c-kzg")]
#[cfg(any(feature = "c-kzg", feature = "kzg-rs"))]
#[cfg_attr(feature = "serde", serde(skip))]
pub kzg_settings: crate::kzg::EnvKzgSettings,
/// Bytecode that is created with CREATE/CREATE2 is by default analysed and jumptable is created.
Expand Down
9 changes: 8 additions & 1 deletion crates/primitives/src/kzg.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
mod env_settings;
mod trusted_setup_points;

pub use c_kzg::KzgSettings;
cfg_if::cfg_if! {
if #[cfg(feature = "c-kzg")] {
pub use c_kzg::KzgSettings;
} else if #[cfg(feature = "kzg-rs")] {
pub use kzg_rs::KzgSettings;
}
}

pub use env_settings::EnvKzgSettings;
pub use trusted_setup_points::{
parse_kzg_trusted_setup, G1Points, G2Points, KzgErrors, BYTES_PER_G1_POINT, BYTES_PER_G2_POINT,
Expand Down
56 changes: 31 additions & 25 deletions crates/primitives/src/kzg/env_settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,39 @@ use super::{
use once_cell::race::OnceBox;
use std::{boxed::Box, sync::Arc};

/// KZG Settings that allow us to specify a custom trusted setup.
/// or use hardcoded default settings.
#[derive(Debug, Clone, Default, PartialEq, Eq, Hash)]
pub enum EnvKzgSettings {
/// Default mainnet trusted setup
#[default]
Default,
/// Custom trusted setup.
Custom(Arc<c_kzg::KzgSettings>),
}
cfg_if::cfg_if! {
if #[cfg(feature = "c-kzg")] {
/// KZG Settings that allow us to specify a custom trusted setup.
/// or use hardcoded default settings.
#[derive(Debug, Clone, Default, PartialEq, Eq )]
pub enum EnvKzgSettings {
/// Default mainnet trusted setup
#[default]
Default,
/// Custom trusted setup.
Custom(Arc<c_kzg::KzgSettings>),
}

impl EnvKzgSettings {
/// Return set KZG settings.
///
/// In will initialize the default settings if it is not already loaded.
pub fn get(&self) -> &KzgSettings {
match self {
Self::Default => {
static DEFAULT: OnceBox<KzgSettings> = OnceBox::new();
DEFAULT.get_or_init(|| {
let settings =
KzgSettings::load_trusted_setup(G1_POINTS.as_ref(), G2_POINTS.as_ref())
.expect("failed to load default trusted setup");
Box::new(settings)
})
impl EnvKzgSettings {
/// Return set KZG settings.
///
/// In will initialize the default settings if it is not already loaded.
pub fn get(&self) -> &KzgSettings {
match self {
Self::Default => {
static DEFAULT: OnceBox<KzgSettings> = OnceBox::new();
DEFAULT.get_or_init(|| {
let settings =
KzgSettings::load_trusted_setup(G1_POINTS.as_ref(), G2_POINTS.as_ref())
.expect("failed to load default trusted setup");
Box::new(settings)
})
}
Self::Custom(settings) => settings,
}
}
Self::Custom(settings) => settings,
}
} else if #[cfg(feature = "kzg-rs")] {
pub use kzg_rs::EnvKzgSettings;
}
}
8 changes: 7 additions & 1 deletion crates/primitives/src/kzg/trusted_setup_points.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ use core::fmt;
use derive_more::{AsMut, AsRef, Deref, DerefMut};
use std::boxed::Box;

pub use c_kzg::{BYTES_PER_G1_POINT, BYTES_PER_G2_POINT};
cfg_if::cfg_if! {
if #[cfg(feature = "c-kzg")] {
pub use c_kzg::{BYTES_PER_G1_POINT, BYTES_PER_G2_POINT};
} else if #[cfg(feature = "kzg-rs")] {
pub use kzg_rs::{BYTES_PER_G1_POINT, BYTES_PER_G2_POINT};
}
}

/// Number of G1 Points.
pub const NUM_G1_POINTS: usize = 4096;
Expand Down
8 changes: 6 additions & 2 deletions crates/primitives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ mod constants;
pub mod db;
pub mod env;

#[cfg(feature = "c-kzg")]
#[cfg(any(feature = "c-kzg", feature = "kzg-rs"))]
pub mod kzg;
pub mod precompile;
pub mod result;
Expand All @@ -38,10 +38,14 @@ cfg_if::cfg_if! {
}
}

#[cfg(feature = "c-kzg")]
#[cfg(any(feature = "c-kzg", feature = "kzg-rs"))]
pub use kzg::{EnvKzgSettings, KzgSettings};
pub use precompile::*;
pub use result::*;
pub use specification::*;
pub use state::*;
pub use utilities::*;

#[cfg(all(feature = "c-kzg", feature = "kzg-rs"))]
// silence kzg-rs lint as c-kzg will be used as default if both are enabled.
use kzg_rs as _;
2 changes: 2 additions & 0 deletions crates/revm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ optional_beneficiary_reward = ["revm-interpreter/optional_beneficiary_reward"]
# See comments in `revm-precompile`
secp256k1 = ["revm-precompile/secp256k1"]
c-kzg = ["revm-precompile/c-kzg"]
# `kzg-rs` is not audited but useful for `no_std` environment, use it with causing and default to `c-kzg` if possible.
kzg-rs = ["revm-precompile/kzg-rs"]
blst = ["revm-precompile/blst"]

[[example]]
Expand Down

0 comments on commit 2b25469

Please sign in to comment.