Skip to content

Commit

Permalink
Added generic sha256 (#1544)
Browse files Browse the repository at this point in the history
* Added generic sha256

* Update sway-lib-std/src/hash.sw

Co-authored-by: John Adler <adlerjohn@users.noreply.github.com>

* Inlined comments and updated formatting

* Cleaned up asm

* Fixing import

* Updating tests, WIP

* Pushing up tests that fail to compile

* Updating docs

* Formatting

* Updating compiler intrinsics

* Saving before pulling master in

* Updated tests

* Fixed formatting

* Starting to add hash validation for testing

* Updated integers

* Added str hashing

* Added concrete tuple validation

* Added concrete array validation

* Added concrete enum validation

* Added b256 validation

* Formatting & core::num update

* Testing struct, WIP

* Hashing struct works

* Formatting

* Updating examples for mdbook

* Updating to buggy formatting and removed comment

* Updating import formatting

* Update sway-lib-std/src/hash.sw

Co-authored-by: John Adler <adlerjohn@users.noreply.github.com>

Co-authored-by: John Adler <adlerjohn@users.noreply.github.com>
  • Loading branch information
Braqzen and adlerjohn committed May 18, 2022
1 parent 74133d7 commit 8e3c174
Show file tree
Hide file tree
Showing 5 changed files with 502 additions and 3 deletions.
74 changes: 72 additions & 2 deletions examples/hashing/src/main.sw
@@ -1,11 +1,81 @@
script;

use std::chain::log_b256;
use std::hash::{HashMethod, hash_pair, hash_u64, hash_value};
use std::{
chain::log_b256,
constants::ZERO,
core::num::*,
hash::{HashMethod, hash_pair, hash_u64, hash_value, sha256}
};

const VALUE_A = 0x9280359a3b96819889d30614068715d634ad0cf9bba70c0f430a8c201138f79f;

enum Location {
Earth: (),
Mars: (),
}

struct Person {
name: str[4],
age: u64,
alive: bool,
location: Location,
stats: Stats,
some_tuple: (bool,
u64), some_array: [u64;
2],
some_b256: b256,
}

struct Stats {
strength: u64,
agility: u64,
}

fn main() {
// Use the generic sha256 to hash some integers
let sha_hashed_u8 = sha256(~u8::max());
let sha_hashed_u16 = sha256(~u16::max());
let sha_hashed_u32 = sha256(~u32::max());
let sha_hashed_u64 = sha256(~u64::max());

// Or hash a b256
let sha_hashed_b256 = sha256(VALUE_A);

// You can hash booleans too
let sha_hashed_bool = sha256(true);

// Strings are not a problem either
let sha_hashed_str = sha256( "Fastest Modular Execution Layer!");

// Tuples of any size work too
let sha_hashed_tuple = sha256((true, 7));

// As do arrays
let sha_hashed_array = sha256([4, 5, 6]);

// Enums work too
let sha_hashed_enum = sha256(Location::Earth);

// Complex structs are not a problem
let sha_hashed_struct = sha256(Person {
name: "John", age: 9000, alive: true, location: Location::Mars, stats: Stats {
strength: 10, agility: 9
},
some_tuple: (true, 8), some_array: [17, 76], some_b256: ZERO
});

log_b256(sha_hashed_u8);
log_b256(sha_hashed_u16);
log_b256(sha_hashed_u32);
log_b256(sha_hashed_u64);
log_b256(sha_hashed_b256);
log_b256(sha_hashed_bool);
log_b256(sha_hashed_str);
log_b256(sha_hashed_tuple);
log_b256(sha_hashed_array);
log_b256(sha_hashed_enum);
log_b256(sha_hashed_struct);

// Hash a single u64 value.
let hashed_u64 = hash_u64(100, HashMethod::Sha256);

Expand Down
23 changes: 23 additions & 0 deletions sway-lib-std/src/hash.sw
@@ -1,5 +1,7 @@
library hash;

use ::constants::ZERO;

// Should this be a trait eventually? Do we want to allow people to customize what `!` does?
// Scala says yes, Rust says perhaps...
pub fn not(a: bool) -> bool {
Expand Down Expand Up @@ -124,3 +126,24 @@ pub fn hash_pair(value_a: b256, value_b: b256, method: HashMethod) -> b256 {
}
}
}

/// Returns the SHA-2-256 hash of `param`.
pub fn sha256<T>(param: T) -> b256 {
let mut result_buffer: b256 = ZERO;
if !__is_reference_type::<T>() {
asm(buffer, ptr: param, eight_bytes: 8, hash: result_buffer) {
move buffer sp; // Make `buffer` point to the current top of the stack
cfei i8; // Grow stack by 1 word
sw buffer ptr i0; // Save value in register at "ptr" to memory at "buffer"
s256 hash buffer eight_bytes; // Hash the next eight bytes starting from "buffer" into "hash"
cfsi i8; // Shrink stack by 1 word
hash: b256 // Return
}
} else {
let size = __size_of::<T>();
asm(hash: result_buffer, ptr: param, bytes: size) {
s256 hash ptr bytes; // Hash the next "size" number of bytes starting from "ptr" into "hash"
hash: b256 // Return
}
}
}
1 change: 1 addition & 0 deletions test/src/sdk-harness/Cargo.toml
Expand Up @@ -15,6 +15,7 @@ fuels = "0.12"
fuels-abigen-macro = "0.12"
hex = "0.4.3"
rand = "0.8"
sha2 = "0.10"
tokio = { version = "1.12", features = ["rt", "macros"] }

[dev-dependencies]
Expand Down

0 comments on commit 8e3c174

Please sign in to comment.