From a3c370ae351784894535b61f137ab82f5fb94c21 Mon Sep 17 00:00:00 2001 From: Trevor Gross Date: Tue, 12 Sep 2023 17:42:03 -0400 Subject: [PATCH] Add rust to cmake build system --- .gitignore | 1 + CMakeLists.txt | 63 +++++++++++++++++++++++++++++++++++++ main.cpp | 57 +++++++++++++++++++++++++++++++++ rust-hashes/.gitignore | 0 rust-hashes/test-bindings.c | 43 +++++++++++++++++++++++++ 5 files changed, 164 insertions(+) delete mode 100644 rust-hashes/.gitignore create mode 100644 rust-hashes/test-bindings.c diff --git a/.gitignore b/.gitignore index 4a7cde77..3a937d9e 100644 --- a/.gitignore +++ b/.gitignore @@ -39,5 +39,6 @@ prof.h # rust outputs target/ +rust-hashes/**.out *.swp diff --git a/CMakeLists.txt b/CMakeLists.txt index b5a51991..9946ae21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -630,6 +630,64 @@ endif() # "${CMAKE_CURRENT_SOURCE_DIR}/fanom_hash.h") set(CMAKE_CXX_FLAGS # "${CMAKE_CXX_FLAGS} -DHAVE_FANOM_HASH") ENDIF() +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(not_debug false) +else() + set(not_debug true) +endif() + +set(RUST_ENABLED true CACHE boolean "enable rust support (requires cargo)") +set(RUST_TARGET "" CACHE string "set target for cross compiling (blank for current)") +set(RUST_CPU_NATIVE not_debug CACHE boolean + "enable all native features (e.g. non-portable SIMD instructions)") + +if(RUST_ENABLED) + message(STATUS "Rust enabled") + set(rust_toolchain "") # use the default + set(cargo_path "--manifest-path=${CMAKE_CURRENT_SOURCE_DIR}/rust-hashes/Cargo.toml") + set(rust_lib_path "${CMAKE_CURRENT_SOURCE_DIR}/rust-hashes/target") + + if(NOT RUST_TARGET STREQUAL "") # set target arch if needed + message(STATUS "Cross compiling Rust to ${RUST_TARGET}") + set(cargo_target "--target=${RUST_TARGET}") + set(rust_lib_path "${rust_lib_path}/${RUST_TARGET}") + endif() + + if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug") + set(cargo_profile "--release") + set(rust_lib_path "${rust_lib_path}/release") + else() + set(rust_lib_path "${rust_lib_path}/debug") + endif() + + if(CMAKE_BUILD_TYPE STREQUAL "asan") + set(RUSTFLAGS "${RUSTFLAGS} -Zsanitizer=address") + set(rust_toolchain "+nightly") # sanitizers are unstable and require nightly + endif() + + if(RUST_CPU_NATIVE) # enable all CPU features + set(RUSTFLAGS "${RUSTFLAGS} -Ctarget-cpu=native") + endif() + + if(CMAKE_POSITION_INDEPENDENT_CODE) + set(RUSTFLAGS "${RUSTFLAGS} -Crelocation-model=pic") + endif() + + # enable the faster dependency protocol for < 1.70 (no runtime effect) + set(ENV{CARGO_REGISTRIES_CRATES_IO_PROTOCOL} "sparse") + set(ENV{RUSTFLAGS} "${RUSTFLAGS}") + set(rust_lib_path "${rust_lib_path}/librust_hashes.a") + + message(STATUS "RUSTFLAGS: $ENV{RUSTFLAGS}") + add_custom_target( + librust_hashes + COMMAND cargo ${rust_toolchain} build --quiet ${cargo_path} + ${cargo_target} ${cargo_profile} + ) + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DRUST_ENABLED") +endif() + if((CMAKE_MAJOR_VERSION EQUAL 3 AND CMAKE_MINOR_VERSION GREATER_EQUAL 9) AND (CMAKE_BUILD_TYPE STREQUAL "Release")) cmake_policy(SET CMP0069 NEW) @@ -735,6 +793,11 @@ target_link_libraries(SMHasher SMHasherSupport ${HIGHWAY_LIB} ${BLAKE3_LIB} ${AHASH_C_LIB} ${CMAKE_THREAD_LIBS_INIT}) +if (RUST_ENABLED) + add_dependencies(SMHasher librust_hashes) + target_link_libraries(SMHasher ${rust_lib_path}) +endif() + SET(exectargets ${exectargets} SMHasher) # add_executable( bittest bittest.cpp ) # diff --git a/main.cpp b/main.cpp index 4fb0a932..00c24b67 100644 --- a/main.cpp +++ b/main.cpp @@ -6,6 +6,9 @@ #include "AvalancheTest.h" #include "DifferentialTest.h" #include "HashMapTest.h" +#ifdef RUST_ENABLED +#include "rust-hashes/rust_hashes.h" +#endif #if NCPU > 1 // disable with -DNCPU=0 or 1 #include @@ -757,6 +760,60 @@ HashInfo g_hashes[] = #endif { komihash_test, 64, 0x8157FF6D, "komihash", "komihash 5.7", GOOD, {} }, { polymur_test, 64, 0x4F894810, "polymur", "github.com/orlp/polymur-hash v1", GOOD, {} }, +#ifdef RUST_ENABLED +{ adler_rs, 32, 0x00000000, "Adler_rs", "Adler-32 checksum implementation (used by `zlib`, crate `adler`)", GOOD, {} }, +{ ahash_rs, 64, 0x00000000, "aHash_rs", "aHash keyed hash function (crate `ahash`)", GOOD, {} }, +{ ascon_rs, 256, 0x00000000, "Ascon_rs", "Ascon hash (crate `ascon-hash`)", GOOD, {} }, +{ ascona_rs, 256, 0x00000000, "AsconA_rs", "AsconA hash (crate `ascon-hash`)", GOOD, {} }, +{ blake2b512_rs, 512, 0x00000000, "BLAKE2b-512_rs", "BLAKE2b-512 (crate `blake2`)", GOOD , {} }, +{ blake2s256_rs, 256, 0x00000000, "BLAKE2s-256_rs", "BLAKE2s-256 (crate `blake2`)", GOOD, {} }, +{ blake3_rs, 256, 0x00000000, "BLAKE3_rs", "BLAKE3 (crate `blake3`)", GOOD, {} }, +{ crc32fast_rs, 32, 0x00000000, "CRC32_rs", "CRC32 (crate `crc32fast`)", GOOD, {} }, +{ fnvhash_rs, 64, 0x00000000, "FNV_rs", "Fowler-Noll-Vo hash function (crate `fnv`)", GOOD, {} }, +{ fxhash32_rs, 32, 0x00000000, "FxHash32", "FxHash (FireFox hash) with 32 bits (crate `fxhash`)", GOOD, {} }, +{ fxhash64_rs, 64, 0x00000000, "FxHash64", "FxHash (FireFox hash) with 64 bits (crate `fxhash`)", GOOD, {} }, +{ hash_hasher_rs, 64, 0x00000000, "hash_hasher_rs", "A hasher designed to work on already hashed or hash-like data (crate `hash_hasher`)", GOOD, {} }, +{ highway_rs, 64, 0x00000000, "Highway_rs", "An implementation of Google's HighwayHash (crate `highway`)", GOOD, {} }, +{ md5_rs, 128, 0x00000000, "MD5_rs", "MD5 algorithm (crate `md-5`)", GOOD, {} }, +{ ripemd128_rs, 128, 0x00000000, "RIPEMD-128_rs", "RIPEMD-128 algorithm (crate `ripemd`)", GOOD, {} }, +{ ripemd160_rs, 160, 0x00000000, "RIPEMD-160_rs", "RIPEMD-160 algorithm (crate `ripemd`)", GOOD, {} }, +{ ripemd256_rs, 256, 0x00000000, "RIPEMD-256_rs", "RIPEMD-256 algorithm (crate `ripemd`)", GOOD, {} }, +{ ripemd320_rs, 320, 0x00000000, "RIPEMD-320_rs", "RIPEMD-320 algorithm (crate `ripemd`)", GOOD, {} }, +{ sha1_rs, 160, 0x00000000, "SHA-1_rs", "SHA-1 algorithm (crate `sha1`)", GOOD, {} }, +{ sha224_rs, 224, 0x00000000, "SHA-224_rs", "SHA-224 algorithm (crate `sha2`)", GOOD, {} }, +{ sha256_rs, 256, 0x00000000, "SHA-256_rs", "SHA-256 algorithm (crate `sha2`)", GOOD, {} }, +{ sha384_rs, 384, 0x00000000, "SHA-384_rs", "SHA-384 algorithm (crate `sha2`)", GOOD, {} }, +{ sha512_rs, 512, 0x00000000, "SHA-512_rs", "SHA-512 algorithm (crate `sha2`)", GOOD, {} }, +{ sha512_224_rs, 224, 0x00000000, "SHA-512/224_rs", "SHA-512 algorithm with 224-bit output (crate `sha2`)", GOOD, {} }, +{ sha512_256_rs, 256, 0x00000000, "SHA-512/256_rs", "SHA-512 algorithm with 256-bit output (crate `sha2`)", GOOD, {} }, +{ cshake128_rs, 128, 0x00000000, "CSHAKE128_rs", "CSHAKE128 algorithm with variable-length output (128 bits for test, crate `sha3`)", GOOD, {} }, +{ cshake256_rs, 256, 0x00000000, "CSHAKE256_rs", "CSHAKE256 algorithm with variable-length output (256 bits for test, crate `sha3`)", GOOD, {} }, +{ keccak224_rs, 224, 0x00000000, "Keccak-224_rs", "Keccak-224 algorithm (crate `sha3`)", GOOD, {} }, +{ keccak256_rs, 256, 0x00000000, "Keccak-256_rs", "Keccak-256 algorithm (crate `sha3`)", GOOD, {} }, +{ keccak256full_rs, 1600, 0x00000000, "Keccak-256_CryptoNight_rs","Keccak-256 hash algorithm, SHA-3 CryptoNight with 1600-bit output (crate `sha3`)", GOOD, {} }, +{ keccak384_rs, 384, 0x00000000, "Keccak-384_rs", "Keccak-384 algorithm (crate `sha3`)", GOOD, {} }, +{ keccak512_rs, 512, 0x00000000, "Keccak-512_rs", "Keccak-512 algorithm (crate `sha3`)", GOOD, {} }, +{ sha3_224_rs, 224, 0x00000000, "SHA-3-224_rs", "SHA-3 algorithm with 224-bit output (crate `sha3`)", GOOD, {} }, +{ sha3_256_rs, 256, 0x00000000, "SHA-3-256_rs", "SHA-3 algorithm with 256-bit output (crate `sha3`)", GOOD, {} }, +{ sha3_384_rs, 384, 0x00000000, "SHA-3-384_rs", "SHA-3 algorithm with 384-bit output (crate `sha3`)", GOOD, {} }, +{ sha3_512_rs, 512, 0x00000000, "SHA-3-512_rs", "SHA-3 algorithm with 512-bit output (crate `sha3`)", GOOD, {} }, +{ shake128_rs, 123, 0x00000000, "SHAKE128_rs", "SHAKE128 algorithm with variable-length output (128 bits for test, crate `sha3`)", GOOD, {} }, +{ shake256_rs, 256, 0x00000000, "SHAKE256_rs", "SHAKE256 algorithm with variable-length output (256 bits for test, crate `sha3`)", GOOD, {} }, +{ turboshake128_1f_rs, 128, 0x00000000, "TurboSHAKE128_rs", "turboshake128 algorithm with variable-length output (128 bits for test, domain separation 0x1f, crate `sha3`)", GOOD, {} }, +{ turboshake256_1f_rs, 256, 0x00000000, "TurboSHAKE256_rs", "turboshake256 algorithm with variable-length output (256 bits for test, domain separation 0x1f, crate `sha3`)", GOOD, {} }, +{ twox_xxhash32_rs, 32, 0x00000000, "xxHash32_twox_rs", "32-bit xxHash implementation (crate `twox_hash`)", GOOD, {} }, +{ twox_xxhash64_rs, 64, 0x00000000, "xxHash64_twox_rs", "64-bit xxHash implementation (crate `twox_hash`)", GOOD, {} }, +{ siphash13_rs, 64, 0x00000000, "SipHash_1-3_rs", "SipHash with 1 round and 3 finalization rounds (crate `siphasher`)", GOOD, {} }, +{ siphash24_rs, 64, 0x00000000, "SipHash_2-4_rs", "SipHash with 2 rounds and 4 finalization rounds (crate `siphasher`)", GOOD, {} }, +{ siphash128_13_rs, 64, 0x00000000, "SipHash128_1-3_rs", "SipHash128 with 1 round and 3 finalization rounds (crate `siphasher`)", GOOD, {} }, +{ siphash128_24_rs, 64, 0x00000000, "SipHash128_2-4_rs", "SipHash128 with 2 rounds and 4 finalization rounds (crate `siphasher`)", GOOD, {} }, +{ whirlpool_rs, 512, 0x00000000, "Whirlpool_rs", "Whirlpool algorithm (crate `whirlpool`)", GOOD, {} }, +{ wyhash_rs, 64, 0x00000000, "WyHash_rs", "WyHash algorithm (crate `wyhash`)", GOOD, {} }, +{ xxhash3_rs, 64, 0x00000000, "xxHash3_rs", "64-bit xxHash implementation (crate `xxhash-rust`)", GOOD, {} }, +{ xxhash128_rs, 128, 0x00000000, "xxHash128_rs", "128-bit xxHash implementation (crate `xxhash-rust`)", GOOD, {} }, +{ xxhash32_rs, 32, 0x00000000, "xxHash32_rs", "32-bit xxHash implementation (crate `xxhash-rust`)", GOOD, {} }, +{ xxhash64_rs, 64, 0x00000000, "xxHash64_rs", "64-bit xxHash implementation (crate `xxhash-rust`)", GOOD, {} }, +#endif }; HashInfo * findHash ( const char * name ) diff --git a/rust-hashes/.gitignore b/rust-hashes/.gitignore deleted file mode 100644 index e69de29b..00000000 diff --git a/rust-hashes/test-bindings.c b/rust-hashes/test-bindings.c new file mode 100644 index 00000000..4adfb8a1 --- /dev/null +++ b/rust-hashes/test-bindings.c @@ -0,0 +1,43 @@ +/* +* Quick file to test the bindings to C without building the whole project +* Run with `cargo build && gcc test-bindings.c target/debug/librust_hashes.a && ./a.out` +* Make sure to generate hashes if bindings have changes +* (`RUST_GENERATE_HASHES=1 cargo +nightly build`) +*/ + +#include +#include +#include "rust_hashes.h" + +int print_clear(char* name, char* out, int bits) { + printf("%s: ", name); + + for(int i=0; i < (bits >> 3); ++i) { + printf("%02x", out[i] & 0xff); + out[i] = 0; + } + + printf("\n"); +} + +int main() { + char *x = "Hello, world!"; + char out[1000] = {0}; + + printf("hashing '%s' (len %ld)\n", x, strlen(x)); + + ahash_rstest(x, strlen(x), 0, out); + print_clear("ahash", out, 64); + + sha256_rstest(x, strlen(x), 0, &out); + print_clear("sha256", out, 256); + + blake2s256_rstest(x, strlen(x), 0, &out); + print_clear("blake2s256", out, 256); + + blake3_rstest(x, strlen(x), 0, &out); + print_clear("blake3", out, 256); + + keccak256full_rstest(x, strlen(x), 0, &out); + print_clear("keccak256_full", out, 1600); +}