Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file added .cargo-ok
Empty file.
7 changes: 3 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
fail-fast: false
matrix:
rust: ["stable", "beta", "nightly"]
flags: ["--no-default-features", "", "--all-features"]
flags: ["--no-default-features", "", "--features taiko"]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@master
Expand All @@ -38,7 +38,7 @@ jobs:
strategy:
fail-fast: false
matrix:
features: ["", "optimism,kzg-rs"]
features: ["", "taiko,optimism,kzg-rs"]
steps:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
Expand Down Expand Up @@ -79,7 +79,7 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
components: rust-docs
- run: cargo doc --workspace --all-features --no-deps --document-private-items
- run: cargo doc --workspace --features taiko --no-deps --document-private-items
env:
RUSTDOCFLAGS: "--cfg docsrs -D warnings"

Expand All @@ -104,4 +104,3 @@ jobs:
with:
config: ./Typos.toml
isolated: true

2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -421,7 +421,7 @@ date: 20.1.2022

# v3 tag

* revm: v1.0.0
* revm: v1.0.0
* revme: v0.1.0

# v2 tag
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

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

9 changes: 6 additions & 3 deletions bins/revme/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ microbench = "0.5"
plain_hasher = "0.2"
revm = { path = "../../crates/revm", version = "18.0.0", default-features = false, features = [
"ethersdb",
"std",
"serde-json",
"c-kzg",
"blst",
Expand All @@ -25,10 +24,14 @@ alloy-rlp = { version = "0.3", default-features = false, features = [
"arrayvec",
"derive",
] }
serde = { version = "1.0", features = ["derive", "rc"] }
serde_json = { version = "1.0", features = ["preserve_order"] }
serde = { version = "1.0", default-features = false, features = ["derive", "rc"] }
serde_json = { version = "1.0", default-features = false, features = ["alloc"]}
structopt = "0.3"
thiserror = "1.0"
triehash = "0.8"
walkdir = "2.5"
k256 = { version = "0.13.3", features = ["ecdsa"] }

[features]
default = ["std"]
std = ["serde/std", "serde_json/std", "alloy-rlp/std", "revm/std"]
14 changes: 5 additions & 9 deletions crates/interpreter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,11 @@ asm-keccak = ["revm-primitives/asm-keccak"]
portable = ["revm-primitives/portable"]
parse = ["dep:paste", "dep:phf"]

optimism = ["revm-primitives/optimism"]
# Optimism default handler enabled Optimism handler register by default in EvmBuilder.
optimism-default-handler = [
"optimism",
"revm-primitives/optimism-default-handler",
]
negate-optimism-default-handler = [
"revm-primitives/negate-optimism-default-handler",
]
optimism = []
taiko = ["revm-primitives/taiko"]
# taiko default handler enabled taiko handler register by default in EvmBuilder.
taiko-default-handler = ["taiko", "revm-primitives/taiko-default-handler"]
negate-taiko-default-handler = ["revm-primitives/negate-taiko-default-handler"]

dev = [
"memory_limit",
Expand Down
20 changes: 9 additions & 11 deletions crates/precompile/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ all = "warn"
revm-primitives = { path = "../primitives", version = "14.0.0", default-features = false }
once_cell = { version = "1.19", default-features = false, features = ["alloc"] }

# ecRecover
# ecRecover precompile
k256 = { version = "0.13.3", default-features = false, features = ["ecdsa"] }
secp256k1 = { version = ">=0.28, <=0.29", default-features = false, features = [
secp256k1 = { version = "0.29", default-features = false, features = [
"alloc",
"recovery",
"rand",
Expand All @@ -44,6 +44,7 @@ aurora-engine-modexp = { version = "1.1", default-features = false }
# ecAdd, ecMul, ecPairing
bn = { package = "substrate-bn", version = "0.6", default-features = false }


# KZG point evaluation precompile
c-kzg = { version = "1.0.3", default-features = false, optional = true, features = [
"ethereum_kzg_settings",
Expand Down Expand Up @@ -86,15 +87,11 @@ std = [
hashbrown = ["revm-primitives/hashbrown"]
asm-keccak = ["revm-primitives/asm-keccak"]

optimism = ["revm-primitives/optimism", "secp256r1"]
# Optimism default handler enabled Optimism handler register by default in EvmBuilder.
optimism-default-handler = [
"optimism",
"revm-primitives/optimism-default-handler",
]
negate-optimism-default-handler = [
"revm-primitives/negate-optimism-default-handler",
]
optimism = []
taiko = ["revm-primitives/taiko"]
# taiko default handler enabled taiko handler register by default in EvmBuilder.
taiko-default-handler = ["taiko", "revm-primitives/taiko-default-handler"]
negate-taiko-default-handler = ["revm-primitives/negate-taiko-default-handler"]

# Enables the p256verify precompile.
secp256r1 = ["dep:p256"]
Expand All @@ -113,6 +110,7 @@ portable = ["revm-primitives/portable", "c-kzg?/portable"]
# In Linux it passes. If you don't require to build wasm on win/mac, it is safe to use it and it is enabled by default.
secp256k1 = ["dep:secp256k1"]

sp1-cycle-tracker = []
# Enables the BLS12-381 precompiles.
blst = ["dep:blst"]

Expand Down
62 changes: 39 additions & 23 deletions crates/precompile/src/blake2.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::zk_op::{self, ZkOperation};
use crate::{Error, Precompile, PrecompileResult, PrecompileWithAddress};
use revm_primitives::{Bytes, PrecompileOutput};

Expand All @@ -11,45 +12,60 @@ pub const FUN: PrecompileWithAddress =
/// input format:
/// [4 bytes for rounds][64 bytes for h][128 bytes for m][8 bytes for t_0][8 bytes for t_1][1 byte for f]
pub fn run(input: &Bytes, gas_limit: u64) -> PrecompileResult {
#[cfg(feature = "sp1-cycle-tracker")]
println!("cycle-tracker-start: blake2");

let input = &input[..];

if input.len() != INPUT_LENGTH {
return Err(Error::Blake2WrongLength.into());
}

let f = match input[212] {
1 => true,
0 => false,
_ => return Err(Error::Blake2WrongFinalIndicatorFlag.into()),
};

// rounds 4 bytes
let rounds = u32::from_be_bytes(input[..4].try_into().unwrap()) as usize;
let gas_used = rounds as u64 * F_ROUND;
if gas_used > gas_limit {
return Err(Error::OutOfGas.into());
}

let f = match input[212] {
1 => true,
0 => false,
_ => return Err(Error::Blake2WrongFinalIndicatorFlag.into()),
};

let mut h = [0u64; 8];
let mut m = [0u64; 16];
let out = if zk_op::contains_operation(&ZkOperation::Blake2) {
zk_op::ZKVM_OPERATOR
.get()
.unwrap()
.blake2_run(input)
.unwrap()
} else {
let mut h = [0u64; 8];
let mut m = [0u64; 16];

for (i, pos) in (4..68).step_by(8).enumerate() {
h[i] = u64::from_le_bytes(input[pos..pos + 8].try_into().unwrap());
}
for (i, pos) in (68..196).step_by(8).enumerate() {
m[i] = u64::from_le_bytes(input[pos..pos + 8].try_into().unwrap());
}
let t = [
u64::from_le_bytes(input[196..196 + 8].try_into().unwrap()),
u64::from_le_bytes(input[204..204 + 8].try_into().unwrap()),
];

for (i, pos) in (4..68).step_by(8).enumerate() {
h[i] = u64::from_le_bytes(input[pos..pos + 8].try_into().unwrap());
}
for (i, pos) in (68..196).step_by(8).enumerate() {
m[i] = u64::from_le_bytes(input[pos..pos + 8].try_into().unwrap());
}
let t = [
u64::from_le_bytes(input[196..196 + 8].try_into().unwrap()),
u64::from_le_bytes(input[204..204 + 8].try_into().unwrap()),
];
algo::compress(rounds, &mut h, m, t, f);

algo::compress(rounds, &mut h, m, t, f);
let mut out = [0u8; 64];
for (i, h) in (0..64).step_by(8).zip(h.iter()) {
out[i..i + 8].copy_from_slice(&h.to_le_bytes());
}

let mut out = [0u8; 64];
for (i, h) in (0..64).step_by(8).zip(h.iter()) {
out[i..i + 8].copy_from_slice(&h.to_le_bytes());
}
out
};
#[cfg(feature = "sp1-cycle-tracker")]
println!("cycle-tracker-end: blake2");

Ok(PrecompileOutput::new(gas_used, out.into()))
}
Expand Down
82 changes: 64 additions & 18 deletions crates/precompile/src/bn128.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::zk_op::{self, ZkOperation};
use crate::{
utilities::{bool_to_bytes32, right_pad},
Address, Error, Precompile, PrecompileResult, PrecompileWithAddress,
Expand Down Expand Up @@ -123,40 +124,74 @@ pub fn new_g1_point(px: Fq, py: Fq) -> Result<G1, Error> {
}

pub fn run_add(input: &[u8], gas_cost: u64, gas_limit: u64) -> PrecompileResult {
#[cfg(feature = "sp1-cycle-tracker")]
println!("cycle-tracker-start: bn-add");

if gas_cost > gas_limit {
return Err(Error::OutOfGas.into());
}

let input = right_pad::<ADD_INPUT_LEN>(input);
let output = if zk_op::contains_operation(&ZkOperation::Bn128Add) {
zk_op::ZKVM_OPERATOR
.get()
.unwrap()
.bn128_run_add(input)
.unwrap()
} else {
let input = right_pad::<ADD_INPUT_LEN>(input);

let p1 = read_point(&input[..64])?;
let p2 = read_point(&input[64..])?;
let p1 = read_point(&input[..64])?;
let p2 = read_point(&input[64..])?;

let mut output = [0u8; 64];
if let Some(sum) = AffineG1::from_jacobian(p1 + p2) {
sum.x().to_big_endian(&mut output[..32]).unwrap();
sum.y().to_big_endian(&mut output[32..]).unwrap();
}

output
};

#[cfg(feature = "sp1-cycle-tracker")]
println!("cycle-tracker-end: bn-add");

let mut output = [0u8; 64];
if let Some(sum) = AffineG1::from_jacobian(p1 + p2) {
sum.x().to_big_endian(&mut output[..32]).unwrap();
sum.y().to_big_endian(&mut output[32..]).unwrap();
}
Ok(PrecompileOutput::new(gas_cost, output.into()))
}

pub fn run_mul(input: &[u8], gas_cost: u64, gas_limit: u64) -> PrecompileResult {
#[cfg(feature = "sp1-cycle-tracker")]
println!("cycle-tracker-start: bn-mul");

if gas_cost > gas_limit {
return Err(Error::OutOfGas.into());
}

let input = right_pad::<MUL_INPUT_LEN>(input);
let output = if zk_op::contains_operation(&ZkOperation::Bn128Mul) {
zk_op::ZKVM_OPERATOR
.get()
.unwrap()
.bn128_run_mul(input)
.unwrap()
} else {
let input = right_pad::<MUL_INPUT_LEN>(input);

let p = read_point(&input[..64])?;
let p = read_point(&input[..64])?;

// `Fr::from_slice` can only fail when the length is not 32.
let fr = bn::Fr::from_slice(&input[64..96]).unwrap();
// `Fr::from_slice` can only fail when the length is not 32.
let fr = bn::Fr::from_slice(&input[64..96]).unwrap();

let mut output = [0u8; 64];
if let Some(mul) = AffineG1::from_jacobian(p * fr) {
mul.x().to_big_endian(&mut output[..32]).unwrap();
mul.y().to_big_endian(&mut output[32..]).unwrap();
}

output
};

#[cfg(feature = "sp1-cycle-tracker")]
println!("cycle-tracker-end: bn-mul");

let mut output = [0u8; 64];
if let Some(mul) = AffineG1::from_jacobian(p * fr) {
mul.x().to_big_endian(&mut output[..32]).unwrap();
mul.y().to_big_endian(&mut output[32..]).unwrap();
}
Ok(PrecompileOutput::new(gas_cost, output.into()))
}

Expand All @@ -166,6 +201,8 @@ pub fn run_pair(
pair_base_cost: u64,
gas_limit: u64,
) -> PrecompileResult {
#[cfg(feature = "sp1-cycle-tracker")]
println!("cycle-tracker-start: bn-pair");
let gas_used = (input.len() / PAIR_ELEMENT_LEN) as u64 * pair_per_point_cost + pair_base_cost;
if gas_used > gas_limit {
return Err(Error::OutOfGas.into());
Expand All @@ -175,7 +212,13 @@ pub fn run_pair(
return Err(Error::Bn128PairLength.into());
}

let success = if input.is_empty() {
let success = if zk_op::contains_operation(&ZkOperation::Bn128Pairing) {
zk_op::ZKVM_OPERATOR
.get()
.unwrap()
.bn128_run_pairing(input)
.unwrap()
} else if input.is_empty() {
true
} else {
let elements = input.len() / PAIR_ELEMENT_LEN;
Expand Down Expand Up @@ -218,6 +261,9 @@ pub fn run_pair(

mul == Gt::one()
};
#[cfg(feature = "sp1-cycle-tracker")]
println!("cycle-tracker-end: bn-pair");

Ok(PrecompileOutput::new(gas_used, bool_to_bytes32(success)))
}

Expand Down
Loading