Skip to content

Commit

Permalink
[feat] openvm sha2 (#14)
Browse files Browse the repository at this point in the history
* feat: open-vm sha2

* feat: openvm-sha2 feature + test

* fix wip

* fix

* address comments

* fix

* debug

* toolchain

---------

Co-authored-by: Arayi <[email protected]>
  • Loading branch information
luffykai and arayikhalatyan authored Jan 8, 2025
1 parent 57f2151 commit 0457ae5
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 4 deletions.
Empty file added .cargo/config.toml
Empty file.
33 changes: 33 additions & 0 deletions .github/workflows/openvm-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: OpenVM Tests

on:
push:
branches: ["v43-openvm"]
pull_request:
branches: ["**"]

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true

jobs:
tests:
name: OpenVM Tests
runs-on:
- runs-on=${{ github.run_id }}
- runner=8cpu-linux-x64
- extras=s3-cache
steps:
- uses: runs-on/action@v1
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true
- uses: taiki-e/install-action@nextest
- name: Rust toolchain
run: rustup component add rust-src --toolchain nightly-2024-10-30-x86_64-unknown-linux-gnu

- name: Run tests
working-directory: tests/openvm/tests
run: RUST_BACKTRACE=1 cargo nextest run
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ openvm = { git = "https://github.com/openvm-org/openvm.git", tag = "v0.1.1-alpha
openvm-ecc-guest = { git = "https://github.com/openvm-org/openvm.git", tag = "v0.1.1-alpha" }
openvm-pairing-guest = { git = "https://github.com/openvm-org/openvm.git", tag = "v0.1.1-alpha" }
openvm-keccak256-guest = { git = "https://github.com/openvm-org/openvm.git", tag = "v0.1.1-alpha" }
openvm-sha256-guest = { git = "https://github.com/openvm-org/openvm.git", tag = "v0.1.1-alpha" }
openvm-sdk = { git = "https://github.com/openvm-org/openvm.git", tag = "v0.1.1-alpha" }
openvm-build = { git = "https://github.com/openvm-org/openvm.git", tag = "v0.1.1-alpha" }
openvm-pairing-transpiler = { git = "https://github.com/openvm-org/openvm.git", tag = "v0.1.1-alpha" }
Expand Down
5 changes: 4 additions & 1 deletion crates/precompile/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ all = "warn"
[dependencies]
revm-primitives = { path = "../primitives", version = "9.0.1", default-features = false }

# static precompile sets.
once_cell = { version = "1.19", default-features = false, features = ["alloc"] }

# ecRecover
Expand Down Expand Up @@ -68,6 +69,7 @@ cfg-if = { version = "1.0", default-features = false }
openvm = { workspace = true, optional = true }
openvm-ecc-guest = { workspace = true, optional = true }
openvm-keccak256-guest = { workspace = true, optional = true }
openvm-sha256-guest = { workspace = true, optional = true }
openvm-pairing-guest = { workspace = true, optional = true }

[dev-dependencies]
Expand Down Expand Up @@ -123,9 +125,10 @@ secp256k1 = ["dep:secp256k1"]
# Enables the BLS12-381 precompiles.
blst = ["dep:blst"]

openvm = ["dep:openvm", "openvm-k256", "openvm-bn"]
openvm = ["dep:openvm", "openvm-k256", "openvm-bn", "openvm-sha2"]
openvm-k256 = ["dep:openvm", "openvm-ecc-guest/k256", "openvm-keccak256-guest"]
openvm-bn = ["dep:openvm", "openvm-ecc-guest", "openvm-pairing-guest/bn254"]
openvm-sha2 = ["dep:openvm-sha256-guest"]

[[bench]]
name = "bench"
Expand Down
15 changes: 12 additions & 3 deletions crates/precompile/src/hash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,24 @@ pub const RIPEMD160: PrecompileWithAddress = PrecompileWithAddress(
Precompile::Standard(ripemd160_run),
);

/// See: <https://ethereum.github.io/yellowpaper/paper.pdf>
/// See: <https://docs.soliditylang.org/en/develop/units-and-global-variables.html#mathematical-and-cryptographic-functions>
/// See: <https://etherscan.io/address/0000000000000000000000000000000000000002>
#[cfg(feature = "openvm-sha2")]
use openvm_sha256_guest::sha256;

/// Computes the SHA-256 hash of the input data.
///
/// This function follows specifications defined in the following references:
/// - [Ethereum Yellow Paper](https://ethereum.github.io/yellowpaper/paper.pdf)
/// - [Solidity Documentation on Mathematical and Cryptographic Functions](https://docs.soliditylang.org/en/develop/units-and-global-variables.html#mathematical-and-cryptographic-functions)
/// - [Address 0x02](https://etherscan.io/address/0000000000000000000000000000000000000002)
pub fn sha256_run(input: &Bytes, gas_limit: u64) -> PrecompileResult {
let cost = calc_linear_cost_u32(input.len(), 60, 12);
if cost > gas_limit {
Err(Error::OutOfGas.into())
} else {
#[cfg(not(feature = "openvm-sha2"))]
let output = sha2::Sha256::digest(input);
#[cfg(feature = "openvm-sha2")]
let output = sha256(input);
Ok(PrecompileOutput::new(cost, output.to_vec().into()))
}
}
Expand Down
12 changes: 12 additions & 0 deletions tests/openvm/programs/sha256/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[workspace]
[package]
name = "sha256-program"
version = "0.1.0"
edition = "2021"

[dependencies]
openvm = { git = "https://github.com/openvm-org/openvm.git", tag = "v0.1.1-alpha" }
openvm-sha256-guest = { git = "https://github.com/openvm-org/openvm.git", tag = "v0.1.1-alpha" }
revm-precompile = { path = "../../../../crates/precompile", default-features = false, features = [
"openvm-sha2",
] }
16 changes: 16 additions & 0 deletions tests/openvm/programs/sha256/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#![no_std]
#![no_main]

extern crate alloc;

use openvm::io::read_vec;
use revm_precompile::hash::sha256_run;
openvm::entry!(main);

pub fn main() {
let input = read_vec();
let expected = read_vec();

let outcome = sha256_run(&input.into(), 260_000).unwrap();
assert_eq!(outcome.bytes, expected);
}
3 changes: 3 additions & 0 deletions tests/openvm/tests/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
#[cfg(test)]
pub mod ec_precompile;

#[cfg(test)]
pub mod sha256_precompile;
57 changes: 57 additions & 0 deletions tests/openvm/tests/src/sha256_precompile.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use std::path::PathBuf;

use openvm_build::GuestOptions;
use openvm_circuit::arch::SystemConfig;
use openvm_circuit::utils::air_test_with_min_segments;
use openvm_sdk::{config::SdkVmConfig, Sdk};
use openvm_stark_sdk::openvm_stark_backend::p3_field::AbstractField;
use openvm_stark_sdk::p3_baby_bear::BabyBear;
use revm_primitives::hex;

type F = BabyBear;

#[test]
fn test_sha256_precompile() {
let sdk = Sdk;
let guest_opts = GuestOptions::default();
let mut pkg_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).to_path_buf();
pkg_dir.push("../programs/sha256");
let sha256_precompile = sdk.build(guest_opts.clone(), &pkg_dir, &None).unwrap();

let vm_config = SdkVmConfig::builder()
.system(SystemConfig::default().with_continuations().into())
.rv32i(Default::default())
.rv32m(Default::default())
.io(Default::default())
.keccak(Default::default())
.sha256(Default::default())
.build();
let exe = sdk
.transpile(sha256_precompile, vm_config.transpiler())
.unwrap();

let input = hex::decode(
"\
1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f59\
3034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41\
209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf7\
04bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a41678\
2bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d\
120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550\
111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c\
2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411\
198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c2\
1800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed\
090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b\
12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa",
)
.unwrap();
let expected =
hex::decode("5f4e768d9faaf07a8c7264b937d60ff0b2fd52458e60a235f79c54bea68979dc").unwrap();

let io = [input, expected]
.into_iter()
.map(|w| w.into_iter().map(F::from_canonical_u8).collect::<Vec<_>>())
.collect::<Vec<_>>();
air_test_with_min_segments(vm_config, exe, io, 1);
}

0 comments on commit 0457ae5

Please sign in to comment.