Skip to content

Commit

Permalink
Implement precompiles for SHA-256 and RIPEMD-160. (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
artob committed Mar 20, 2021
1 parent b184b46 commit 67799aa
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 15 deletions.
36 changes: 34 additions & 2 deletions Cargo.lock

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

4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,16 @@ evm = { git = "https://github.com/aurora-is-near/sputnikvm", rev = "85631ce", de
lazy_static = { version = "1.4.0", default-features = false }
libsecp256k1 = { version = "0.3.5", default-features = false }
primitive-types = { version = "0.9.0", default-features = false, features = ["rlp"] }
ripemd160 = { version = "0.9.1", default-features = false }
rlp = { version = "0.5.0", default-features = false }
sha2 = { version = "0.9.3", default-features = false, optional = true }
sha3 = { version = "0.9.1", default-features = false }
wee_alloc = { version = "0.4.5", default-features = false }

[dev-dependencies]
hex = { version = "0.4.3", default-features = false }

[features]
default = ["std"]
default = ["sha2", "std"]
std = ["borsh/std", "evm/std", "primitive-types/std", "rlp/std", "sha3/std"]
contract = ["lazy_static/spin_no_std"]
49 changes: 41 additions & 8 deletions src/precompiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@ pub fn no_precompiles(
#[allow(dead_code)]
pub fn istanbul_precompiles(
address: Address,
_input: &[u8],
input: &[u8],
_target_gas: Option<u64>,
_context: &Context,
) -> Option<PrecompileResult> {
if address == Address::from_low_u64_be(1) {
None // TODO: implement ecrecover()
} else if address == Address::from_low_u64_be(2) {
None // TODO: implement sha256()
Some(Ok((ExitSucceed::Returned, sha256(input).as_bytes().to_vec(), 0)))
} else if address == Address::from_low_u64_be(3) {
None // TODO: implement ripemd160()
Some(Ok((ExitSucceed::Returned, ripemd160(input).as_bytes().to_vec(), 0)))
} else if address == Address::from_low_u64_be(4) {
None // TODO: implement identity()
} else if address == Address::from_low_u64_be(5) {
Expand All @@ -50,15 +50,30 @@ fn ecrecover(_hash: H256, _v: u8, _r: H256, _s: H256) -> Address {
}

/// 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/0x0000000000000000000000000000000000000002
#[cfg(not(feature = "contract"))]
#[allow(dead_code)]
fn sha256(input: &[u8]) -> H256 {
use sha2::Digest;
let hash = sha2::Sha256::digest(input);
H256::from_slice(&hash)
}
#[cfg(feature = "contract")]
#[allow(dead_code)]
fn sha256(_input: Vec<u8>) -> H256 {
H256::zero() // TODO: implement SHA-256
fn sha256(input: &[u8]) -> H256 {
use crate::sdk;
sdk::sha256(input)
}

/// 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/0x0000000000000000000000000000000000000003
#[allow(dead_code)]
fn ripemd160(_input: Vec<u8>) -> H160 {
H160::zero() // TODO: implement RIPEMD-160
fn ripemd160(input: &[u8]) -> H160 {
use ripemd160::Digest;
let hash = ripemd160::Ripemd160::digest(input);
H160::from_slice(&hash)
}

/// See: https://ethereum.github.io/yellowpaper/paper.pdf
Expand Down Expand Up @@ -98,4 +113,22 @@ fn blake2f(_rounds: u32, _h: [U256; 2], _m: [U256; 4], _t: [u64; 2], _f: bool) -
}

#[cfg(test)]
mod tests {}
mod tests {
use super::*;

#[test]
fn test_sha256() {
assert_eq!(
sha256(b""),
H256::from_slice(&hex::decode("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855").unwrap())
);
}

#[test]
fn test_ripemd160() {
assert_eq!(
ripemd160(b""),
H160::from_slice(&hex::decode("9c1185a5c5e9fc54612808977ee8f548b2258d31").unwrap())
);
}
}
19 changes: 15 additions & 4 deletions src/sdk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ mod exports {
// # Math API #
// ############
fn random_seed(register_id: u64);
fn sha256(value_len: u64, value_ptr: u64, register_id: u64);
pub(crate) fn sha256(value_len: u64, value_ptr: u64, register_id: u64);
pub(crate) fn keccak256(value_len: u64, value_ptr: u64, register_id: u64);
// #####################
// # Miscellaneous API #
Expand Down Expand Up @@ -249,11 +249,22 @@ pub fn predecessor_account_id() -> Vec<u8> {
}
}

/// Calls environment keccak256 on given data.
/// Calls environment sha256 on given input.
#[allow(dead_code)]
pub fn keccak(data: &[u8]) -> H256 {
pub fn sha256(input: &[u8]) -> H256 {
unsafe {
exports::keccak256(data.len() as u64, data.as_ptr() as u64, 1);
exports::sha256(input.len() as u64, input.as_ptr() as u64, 1);
let bytes = H256::zero();
exports::read_register(1, bytes.0.as_ptr() as *const u64 as u64);
bytes
}
}

/// Calls environment keccak256 on given input.
#[allow(dead_code)]
pub fn keccak(input: &[u8]) -> H256 {
unsafe {
exports::keccak256(input.len() as u64, input.as_ptr() as u64, 1);
let bytes = H256::zero();
exports::read_register(1, bytes.0.as_ptr() as *const u64 as u64);
bytes
Expand Down

0 comments on commit 67799aa

Please sign in to comment.