Skip to content
Merged
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
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ jobs:
with:
toolchain: ${{ matrix.rust }}
- uses: Swatinem/rust-cache@v2
- name: Install GMP (all-features)
if: contains(matrix.flags, '--all-features')
run: |
sudo apt-get update
sudo apt-get install -y libgmp-dev
- run: cargo test --workspace ${{ matrix.flags }}

check-no-std:
Expand Down Expand Up @@ -74,6 +79,10 @@ jobs:
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- name: Install GMP
run: |
sudo apt-get update
sudo apt-get install -y libgmp-dev
- name: cargo hack
run: cargo hack check --feature-powerset --depth 1

Expand All @@ -86,6 +95,10 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- name: Install GMP
run: |
sudo apt-get update
sudo apt-get install -y libgmp-dev
- run: cargo clippy --workspace --all-targets --all-features
env:
RUSTFLAGS: -Dwarnings
Expand All @@ -99,6 +112,10 @@ jobs:
- uses: dtolnay/rust-toolchain@stable
with:
components: rust-docs
- name: Install GMP
run: |
sudo apt-get update
sudo apt-get install -y libgmp-dev
- run: cargo doc --workspace --all-features --no-deps --document-private-items
env:
RUSTDOCFLAGS: "--cfg docsrs -D warnings"
Expand Down
20 changes: 1 addition & 19 deletions Cargo.lock

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

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ ark-ff = { version = "0.5", default-features = false }
ark-serialize = { version = "0.5", default-features = false }
ark-std = { version = "0.5", default-features = false }
aurora-engine-modexp = { version = "1.2", default-features = false }
rug = { version = "1.28.0", default-features = false }
gmp-mpfr-sys = { version = "1.6", default-features = false }
blst = "0.3.15"
bn = { package = "substrate-bn", version = "0.6", default-features = false }
c-kzg = { version = "2.1.4", default-features = false }
Expand Down
12 changes: 6 additions & 6 deletions crates/precompile/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ primitives.workspace = true

# modexp precompiles
aurora-engine-modexp.workspace = true
# gmp wrapper
rug = { workspace = true, features = ["integer"], optional = true }
# gmp ffi
gmp-mpfr-sys = { workspace = true, default-features = false, optional = true }

# ecRecover
k256 = { workspace = true, features = ["ecdsa"] }
Expand Down Expand Up @@ -75,6 +75,7 @@ rstest.workspace = true

[features]
default = ["std", "secp256k1", "blst", "c-kzg", "portable"]

std = [
"primitives/std",
"k256/std",
Expand All @@ -90,7 +91,6 @@ std = [
"ark-serialize/std",
"ark-std/std",
"p256/std",
"rug?/std",
]
hashbrown = ["primitives/hashbrown"]
asm-keccak = ["primitives/asm-keccak"]
Expand All @@ -115,9 +115,9 @@ blst = ["dep:blst"]
# Enables the substrate implementation of eip1962
bn = ["dep:bn"]

# Use rug (that wraps gmp) for modexp precompile.
# It is faster library but licences as GPL code, if enabled please make sure to follow the license.
gmp = ["dep:rug"]
# Use GMP (LGPL) for modexp precompile via gmp-mpfr-sys.
# This feature links to system GMP using the experimental `use-system-libs` flag.
gmp = ["dep:gmp-mpfr-sys", "gmp-mpfr-sys/use-system-libs"]

[[bench]]
name = "bench"
Expand Down
111 changes: 97 additions & 14 deletions crates/precompile/src/modexp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,103 @@ pub const OSAKA: Precompile =
#[cfg(feature = "gmp")]
/// GMP-based modular exponentiation implementation
pub(crate) fn modexp(base: &[u8], exponent: &[u8], modulus: &[u8]) -> Vec<u8> {
use rug::{integer::Order::Msf, Integer};
// Convert byte slices to GMP integers
let base_int = Integer::from_digits(base, Msf);
let exp_int = Integer::from_digits(exponent, Msf);
let mod_int = Integer::from_digits(modulus, Msf);

// Perform modular exponentiation using GMP's pow_mod
let result = base_int.pow_mod(&exp_int, &mod_int).unwrap_or_default();

// Convert result back to bytes
let byte_count = result.significant_bits().div_ceil(8);
let mut output = vec![0u8; byte_count as usize];
result.write_digits(&mut output, Msf);
output
use core::ffi::c_void;
use core::mem::MaybeUninit;
use gmp_mpfr_sys::gmp;

struct Mpz(gmp::mpz_t);

impl Mpz {
fn new() -> Self {
unsafe {
let mut inner = MaybeUninit::<gmp::mpz_t>::uninit();
gmp::mpz_init(inner.as_mut_ptr());
Self(inner.assume_init())
}
}

fn as_ptr(&self) -> *const gmp::mpz_t {
&self.0
}

fn as_mut_ptr(&mut self) -> *mut gmp::mpz_t {
&mut self.0
}

fn set_from_be_bytes(&mut self, bytes: &[u8]) {
unsafe {
if bytes.is_empty() {
gmp::mpz_set_ui(self.as_mut_ptr(), 0);
return;
}

gmp::mpz_import(
self.as_mut_ptr(),
bytes.len(),
1,
1,
1,
0,
bytes.as_ptr() as *const c_void,
);
}
}

fn to_be_bytes(&self) -> Vec<u8> {
unsafe {
if gmp::mpz_sgn(self.as_ptr()) == 0 {
return Vec::new();
}

let bits = gmp::mpz_sizeinbase(self.as_ptr(), 2);
let mut output = vec![0u8; bits.div_ceil(8)];
let mut count: usize = 0;
gmp::mpz_export(
output.as_mut_ptr() as *mut c_void,
&mut count,
1,
1,
1,
0,
self.as_ptr(),
);
output.truncate(count);
output
}
}
}

impl Drop for Mpz {
fn drop(&mut self) {
unsafe {
gmp::mpz_clear(self.as_mut_ptr());
}
}
}

let mut base_int = Mpz::new();
let mut exp_int = Mpz::new();
let mut mod_int = Mpz::new();
let mut result = Mpz::new();

base_int.set_from_be_bytes(base);
exp_int.set_from_be_bytes(exponent);
mod_int.set_from_be_bytes(modulus);

unsafe {
if gmp::mpz_sgn(mod_int.as_ptr()) == 0 {
return Vec::new();
}

gmp::mpz_powm(
result.as_mut_ptr(),
base_int.as_ptr(),
exp_int.as_ptr(),
mod_int.as_ptr(),
);
}

result.to_be_bytes()
}

#[cfg(not(feature = "gmp"))]
Expand Down
3 changes: 1 addition & 2 deletions crates/revm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,7 @@ asm-sha2 = ["precompile/asm-sha2"]
# Binary can be executed on all systems.
portable = ["precompile/portable"]

# use gmp for modexp precompile.
# It is faster library but licenced as GPL code, if enabled please make sure to follow the license.
# Use GMP for modexp precompile (LGPL; dynamically linked via system libs).
gmp = ["precompile/gmp"]

# Statetest types for running ethereum tests
Expand Down
Loading