Skip to content

Commit

Permalink
add keccak (#47)
Browse files Browse the repository at this point in the history
* add keccak

* rollback dylibs
  • Loading branch information
sh-cha authored May 14, 2024
1 parent 67b63e7 commit 4a02be4
Show file tree
Hide file tree
Showing 12 changed files with 162 additions and 1 deletion.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ base64 = "0.21.7"
bigdecimal = "0.4"
bech32 = "0.11"
triomphe = "0.1.9"
tiny-keccak = { version = "2.0.2", features = ["keccak", "sha3"] }

# Note: the BEGIN and END comments below are required for external tooling. Do not remove.
# BEGIN MOVE DEPENDENCIES
Expand Down
12 changes: 12 additions & 0 deletions crates/gas/src/gas_params/keccak.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use move_core_types::gas_algebra::{InternalGas, InternalGasPerByte};

#[derive(Debug, Clone)]
pub struct Keccak256GasParameters {
pub base: InternalGas,
pub per_byte: InternalGasPerByte,
}

#[derive(Debug, Clone)]
pub struct GasParameters {
pub keccak256: Keccak256GasParameters,
}
1 change: 1 addition & 0 deletions crates/gas/src/gas_params/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod crypto;
pub mod event;
pub mod from_bcs;
pub mod json;
pub mod keccak;
pub mod object;
pub mod oracle;
pub mod query;
Expand Down
10 changes: 10 additions & 0 deletions crates/gas/src/initia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ crate::natives::define_gas_parameters_for_natives!(GasParameters, "initia", [
// TODO(Gas): the on-chain name is wrong...
[.event.write_module_event_to_store.per_abstract_value_unit, "event.write_module_event_to_store.per_abstract_memory_unit", 61],

[.keccak.keccak256.base, "keccak.keccak256.base", 14704],
[.keccak.keccak256.per_byte, "keccak.keccak256.per_byte", 165],

[.object.exists_at.base, "object.exists_at.base", 919],
[.object.exists_at.per_byte_loaded, "object.exists_at.per_byte_loaded", 183],
[.object.exists_at.per_item_loaded, "object.exists_at.per_item_loaded", 1470],
Expand Down Expand Up @@ -134,6 +137,7 @@ pub struct GasParameters {
pub base64: base64::GasParameters,
pub crypto: crypto::GasParameters,
pub event: event::GasParameters,
pub keccak: keccak::GasParameters,
pub object: object::GasParameters,
pub transaction_context: transaction_context::GasParameters,
pub staking: staking::GasParameters,
Expand Down Expand Up @@ -329,6 +333,12 @@ impl GasParameters {
per_byte: 0.into(),
},
},
keccak: keccak::GasParameters {
keccak256: keccak::Keccak256GasParameters {
base: 0.into(),
per_byte: 0.into(),
},
},
object: object::GasParameters {
exists_at: object::ExistsAtGasParameters {
base: 0.into(),
Expand Down
1 change: 1 addition & 0 deletions crates/natives/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ move-stdlib = { workspace = true }

bigdecimal = { workspace = true }
base64 = { workspace = true }
tiny-keccak = { workspace = true }

[dev-dependencies]
serial_test = { workspace = true }
Expand Down
56 changes: 56 additions & 0 deletions crates/natives/src/keccak.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright © Aptos Foundation

// Copyright (c) The Diem Core Contributors
// Copyright (c) The Move Contributors
// SPDX-License-Identifier: Apache-2.0

use move_core_types::gas_algebra::NumBytes;
use move_vm_runtime::native_functions::NativeFunction;
use move_vm_types::{loaded_data::runtime_types::Type, values::Value};
use smallvec::{smallvec, SmallVec};
use std::collections::VecDeque;
use tiny_keccak::{Hasher as KeccakHasher, Keccak};

use crate::{
interface::{RawSafeNative, SafeNativeBuilder, SafeNativeContext, SafeNativeResult},
safely_pop_arg,
};

/***************************************************************************************************
* native fun keccak256
*
* gas cost: base_cost + unit_cost * input_length
*
**************************************************************************************************/

fn native_keccak256(
context: &mut SafeNativeContext,
mut _ty_args: Vec<Type>,
mut args: VecDeque<Value>,
) -> SafeNativeResult<SmallVec<[Value; 1]>> {
debug_assert!(_ty_args.is_empty());
debug_assert!(args.len() == 1);

let gas_params = &context.native_gas_params.initia_stdlib.keccak.keccak256;

let bytes = safely_pop_arg!(args, Vec<u8>);

context.charge(gas_params.base + gas_params.per_byte * NumBytes::new(bytes.len() as u64))?;

let mut hasher = Keccak::v256();
hasher.update(&bytes);
let mut output = [0u8; 32];
hasher.finalize(&mut output);

Ok(smallvec![Value::vector_u8(output)])
}
/***************************************************************************************************
* module
**************************************************************************************************/
pub fn make_all(
builder: &SafeNativeBuilder,
) -> impl Iterator<Item = (String, NativeFunction)> + '_ {
let natives = [("keccak256", native_keccak256 as RawSafeNative)];

builder.make_named_natives(natives)
}
2 changes: 2 additions & 0 deletions crates/natives/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub mod debug;
pub mod event;
pub mod from_bcs;
pub mod json;
pub mod keccak;
pub mod move_stdlib;
pub mod object;
pub mod oracle;
Expand Down Expand Up @@ -58,6 +59,7 @@ pub fn initia_move_natives(
add_natives_from_module!("type_info", type_info::make_all(builder));
add_natives_from_module!("from_bcs", from_bcs::make_all(builder));
add_natives_from_module!("base64", base64::make_all(builder));
add_natives_from_module!("keccak", keccak::make_all(builder));
add_natives_from_module!("staking", staking::make_all(builder));
add_natives_from_module!("cosmos", cosmos::make_all(builder));
add_natives_from_module!("object", object::make_all(builder));
Expand Down
8 changes: 7 additions & 1 deletion crates/types/src/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,13 @@ impl ModuleBundle {
let mut order = vec![];
let mut order_set = BTreeSet::new();
for id in map.keys() {
sort_by_deps(&map, &mut order, &mut order_set, &mut BTreeSet::new(), id.clone())?;
sort_by_deps(
&map,
&mut order,
&mut order_set,
&mut BTreeSet::new(),
id.clone(),
)?;
}

let mut codes = vec![];
Expand Down
Binary file added precompile/binaries/minlib/keccak.mv
Binary file not shown.
Binary file added precompile/binaries/stdlib/keccak.mv
Binary file not shown.
36 changes: 36 additions & 0 deletions precompile/modules/initia_stdlib/sources/keccak.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/// Cryptographic hashes:
/// - Keccak-256: see https://keccak.team/keccak.html
///
/// In addition, SHA2-256 and SHA3-256 are available in `std::hash`. Note that SHA3-256 is a variant of Keccak: it is
/// NOT the same as Keccak-256.
module initia_std::keccak {
/// Returns the Keccak-256 hash of `bytes`.
native public fun keccak256(byte: vector<u8>): vector<u8>;
//
// Testing
//

#[test]
fun keccak256_test() {
let inputs = vector[
b"testing",
b"",
];

let outputs = vector[
x"5f16f4c7f149ac4f9510d9cf8cf384038ad348b3bcdc01915f95de12df9d1b02",
x"c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
];

let i = 0;
while (i < std::vector::length(&inputs)) {
let input = *std::vector::borrow(&inputs, i);
let hash_expected = *std::vector::borrow(&outputs, i);
let hash = keccak256(input);

assert!(hash_expected == hash, 1);

i = i + 1;
};
}
}
36 changes: 36 additions & 0 deletions precompile/modules/minitia_stdlib/sources/keccak.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/// Cryptographic hashes:
/// - Keccak-256: see https://keccak.team/keccak.html
///
/// In addition, SHA2-256 and SHA3-256 are available in `std::hash`. Note that SHA3-256 is a variant of Keccak: it is
/// NOT the same as Keccak-256.
module minitia_std::keccak {
/// Returns the Keccak-256 hash of `bytes`.
native public fun keccak256(byte: vector<u8>): vector<u8>;
//
// Testing
//

#[test]
fun keccak256_test() {
let inputs = vector[
b"testing",
b"",
];

let outputs = vector[
x"5f16f4c7f149ac4f9510d9cf8cf384038ad348b3bcdc01915f95de12df9d1b02",
x"c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470",
];

let i = 0;
while (i < std::vector::length(&inputs)) {
let input = *std::vector::borrow(&inputs, i);
let hash_expected = *std::vector::borrow(&outputs, i);
let hash = keccak256(input);

assert!(hash_expected == hash, 1);

i = i + 1;
};
}
}

0 comments on commit 4a02be4

Please sign in to comment.