Skip to content

Commit

Permalink
Merge pull request #10 from Doy-lee/msys2-build
Browse files Browse the repository at this point in the history
Support MSYS2 build, fix Linux build and document build steps
  • Loading branch information
darcys22 authored Apr 15, 2024
2 parents 1ae5c8f + 5aa19ff commit d650323
Show file tree
Hide file tree
Showing 11 changed files with 126 additions and 68 deletions.
2 changes: 0 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ endif()

# Find all headers and implementation files
include(cmake/SourcesAndHeaders.cmake)

find_package(Boost 1.62 QUIET REQUIRED COMPONENTS system thread serialization program_options)
if(${PROJECT_NAME}_ENABLE_CRYPTO_LIBRARY)
add_subdirectory(src/crypto)
endif()
Expand Down
48 changes: 32 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,49 @@
# Ethyl
C++ library for communicating with Ethereum

C++ library for communicating with Ethereum.

## Building

### Prerequisites
Clone the repository `git clone --recursive` or if already cloned, `git
submodule update --init --recursive` at the root to ensure all source code is
retrieved.

Then run the following commands from the root of this repository:

**Linux**

```
apt install cmake build-essential libboost-all-dev libssl-dev libcurl4-openssl-dev libsodium-dev
# Install dependencies
apt install cmake build-essential libssl-dev libcurl4-openssl-dev
# Build
cmake -B build -S .
cmake --build build --parallel --verbose
```

### Building from Source
**Windows via MSYS2 (MinGW, UCRT64, e.t.c)**

Clone the repository as usual, including submodules (either by passing `--recurse-submodules` to
`git clone`, or else running `git submodule update --init --recursive` the top-level project
directory).
```
# Update pacman and install dependencies
pacman -Syuu # Terminal may prompt to restart before proceeding
pacman -S git base-devel libargp-devel cmake gcc libcurl-devel gmp-devel autoconf automake libtool
To compile the library run the following commands from the project source directory:
# MSYS packages libargp with a .dll suffix which breaks rlpvalue's autotool
# script so we patch it up
ln -s /usr/lib/libargp.dll.a /usr/lib/libargp.a
```
mkdir -p build
cd build
cmake ..
make -j8 # Tweak as needed for the desired build parallelism
# Build
cmake -B build -S .
cmake --build build --parallel --verbose
```

Various options can be added to the `cmake ..` line; some common options are:
- `-DCMAKE_BUILD_TYPE=Release` to make a release build

## Testing

Unit tests use [Catch2](https://github.com/catchorg/Catch2) as a formal unit-test framework. Unit
tests are built by default as part of the standard CMake build logic (unless being built as a
subdirectory of another CMake project) and can be invoked through the `make test` or running the test binaries build in `build/tests`.
Unit tests use [Catch2](https://github.com/catchorg/Catch2) as a formal
unit-test framework. Unit tests are built by default as part of the standard
CMake build logic (unless being built as a subdirectory of another CMake
project) and can be invoked through the `make test` or running the test binaries
build in `build/tests`.
1 change: 0 additions & 1 deletion cmake/CompilerWarnings.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ function(set_project_warnings project_name)
-Wnon-virtual-dtor # warn the user if a class with virtual functions has a
# non-virtual destructor. This helps catch hard to
# track down memory errors
-Wold-style-cast # warn for c-style casts
-Wcast-align # warn for potential performance problem casts
-Wunused # warn on anything being unused
-Woverloaded-virtual # warn if you overload (not override) a virtual
Expand Down
12 changes: 12 additions & 0 deletions cmake/rlpvalue-001-infint-missing-limits-h.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
diff --git a/src/InfInt.h b/src/InfInt.h
index 14ff215..60bac4f 100644
--- a/src/InfInt.h
+++ b/src/InfInt.h
@@ -40,6 +40,7 @@
#include <sstream>
#include <iomanip>
#include <climits>
+#include <limits>

//#include <limits.h>
//#include <stdlib.h>
63 changes: 42 additions & 21 deletions external/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
#
# CPR
#
if(NOT TARGET cpr)
set(CPR_USE_SYSTEM_CURL ON CACHE BOOL "" FORCE)
set(CPR_USE_SYSTEM_CURL ON CACHE BOOL "")
add_subdirectory(cpr)
endif()

#
# SECP256k1
#
if(NOT TARGET secp256k1)
set(SECP256K1_ENABLE_MODULE_RECOVERY ON CACHE BOOL "" FORCE)
set(SECP256K1_VALGRIND OFF CACHE BOOL "" FORCE)
Expand All @@ -14,44 +20,59 @@ if(NOT TARGET secp256k1)
add_subdirectory(secp256k1)
endif()

#
# Catch2
#
if(NOT TARGET Catch2)
add_subdirectory(Catch2)
endif()

# RLPValue is built using autotools
#
# rlpvalue is built using autotools
#
include(ExternalProject)

set(RLP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/rlpvalue)
set(RLP_BIN ${CMAKE_CURRENT_BINARY_DIR}/librlpvalue)
set(RLP_SHARED_LIB ${RLP_BIN}/lib/librlpvalue.so)
set(RLP_INCLUDES ${RLP_BIN}/include)

set(RLP_DIR ${CMAKE_CURRENT_SOURCE_DIR}/rlpvalue)
set(RLP_BIN ${CMAKE_CURRENT_BINARY_DIR}/librlpvalue)
set(RLP_STATIC_LIB ${RLP_BIN}/lib/librlpvalue.a)
set(RLP_INCLUDES ${RLP_BIN}/include)
file(MAKE_DIRECTORY ${RLP_INCLUDES})

# NOTE: rlpvalue includes a sub-project, univalue which it configures from the
# top level script. Passing in the `--prefix` at the top-level does not
# propagate down to the bottom level causing `make install` to install to the
# system level prefix.
#
# We override this by specifying prefix at the last step ensuring that both
# `rlpvalue` and `univalue` are installed to the same prefix.
ExternalProject_Add(
librlpvalue
PREFIX ${RLP_BIN}
SOURCE_DIR ${RLP_DIR}
DOWNLOAD_COMMAND cd ${RLP_DIR} && git clean -dfX && ${RLP_DIR}/autogen.sh
CONFIGURE_COMMAND ${RLP_DIR}/configure --srcdir=${RLP_DIR} --prefix=${RLP_BIN} --enable-shared=yes --disable-static
BUILD_COMMAND make
INSTALL_COMMAND make install
BUILD_BYPRODUCTS ${RLP_SHARED_LIB}
PREFIX ${RLP_BIN}
SOURCE_DIR ${RLP_DIR}
DOWNLOAD_COMMAND cd ${RLP_DIR} && git clean -dfX
CONFIGURE_COMMAND bash -c ${RLP_DIR}/autogen.sh && bash -c ${RLP_DIR}/configure --srcdir=${RLP_DIR} --disable-shared --enable-static=yes
PATCH_COMMAND git checkout -- src/InfInt.h &&
git apply --ignore-whitespace ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/rlpvalue-001-infint-missing-limits-h.patch
BUILD_COMMAND make
INSTALL_COMMAND make install prefix=${RLP_BIN}
BUILD_BYPRODUCTS ${RLP_STATIC_LIB} ${RLP_BIN}/lib/libunivalue.a
)

add_library(rlpvalue SHARED IMPORTED GLOBAL)

add_dependencies(rlpvalue librlpvalue)

set_target_properties(rlpvalue PROPERTIES IMPORTED_LOCATION ${RLP_SHARED_LIB})
add_library (rlpvalue STATIC IMPORTED GLOBAL)
add_dependencies (rlpvalue librlpvalue)
set_target_properties(rlpvalue PROPERTIES IMPORTED_LOCATION ${RLP_STATIC_LIB})
set_target_properties(rlpvalue PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${RLP_INCLUDES})

#
# nlohmann_json
#
if(NOT TARGET nlohmann_json)
set(JSON_BuildTests OFF CACHE INTERNAL "")
set(JSON_MultipleHeaders ON CACHE BOOL "") # Allows multi-header nlohmann use
add_subdirectory(json EXCLUDE_FROM_ALL)
endif()

#
# GMP
#
find_library(gmp gmp)
if(NOT gmp)
message(FATAL_ERROR "gmp not found")
Expand Down
14 changes: 7 additions & 7 deletions include/ethyl/ecdsa_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* Windows -> `BCryptGenRandom`(`bcrypt.h`). https://docs.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom
*/

#if defined(_WIN32)
#if defined(_WIN32) || defined(__CYGWIN__)
/*
* The defined WIN32_NO_STATUS macro disables return code definitions in
* windows.h, which avoids "macro redefinition" MSVC warnings in ntstatus.h.
Expand All @@ -37,13 +37,13 @@
#include <stddef.h>
#include <limits.h>
#include <stdio.h>
#include <cstring>
#include <string.h>


/* Returns 1 on success, and 0 on failure. */
[[maybe_unused]] static int fill_random(unsigned char* data, size_t size) {
#if defined(_WIN32)
NTSTATUS res = BCryptGenRandom(NULL, data, size, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
#if defined(_WIN32) || defined(__CYGWIN__)
NTSTATUS res = BCryptGenRandom(NULL, data, (ULONG)size, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
if (res != STATUS_SUCCESS || size > ULONG_MAX) {
return 0;
} else {
Expand All @@ -52,7 +52,7 @@
#elif defined(__linux__) || defined(__FreeBSD__)
/* If `getrandom(2)` is not available you should fallback to /dev/urandom */
ssize_t res = getrandom(data, size, 0);
if (res < 0 || static_cast<size_t>(res) != size ) {
if (res < 0 || (size_t)res != size ) {
return 0;
} else {
return 1;
Expand All @@ -79,13 +79,13 @@
printf("\n");
}

#if defined(_MSC_VER)
#if defined(_MSC_VER) || defined(__CYGWIN__)
// For SecureZeroMemory
#include <Windows.h>
#endif
/* Cleanses memory to prevent leaking sensitive info. Won't be optimized out. */
[[maybe_unused]] static void secure_erase(void *ptr, size_t len) {
#if defined(_MSC_VER)
#if defined(_MSC_VER) || defined(__CYGWIN__)
/* SecureZeroMemory is guaranteed not to be optimized out by MSVC. */
SecureZeroMemory(ptr, len);
#elif defined(__GNUC__)
Expand Down
9 changes: 3 additions & 6 deletions src/crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,9 @@ add_library(cncrypto
cn_turtle_hash.c
tree-hash.c)

target_link_libraries(cncrypto
PUBLIC
Boost::thread
sodium
PRIVATE
)
if (WIN32 OR CYGWIN)
target_link_libraries(cncrypto PUBLIC bcrypt)
endif()

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
Expand Down
9 changes: 5 additions & 4 deletions src/crypto/blake256.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
*/

#include "blake256.h"
#include "../../include/ethyl/ecdsa_util.h"

#include <stdint.h>
#include <string.h>
Expand Down Expand Up @@ -296,7 +297,7 @@ void hmac_blake256_init(hmac_state* S, const uint8_t* _key, uint64_t keylen) {
}
blake256_update(&S->outer, pad, 512);

memwipe(keyhash, sizeof(keyhash));
secure_erase(keyhash, sizeof(keyhash));
}

// keylen = number of bytes
Expand Down Expand Up @@ -326,7 +327,7 @@ void hmac_blake224_init(hmac_state* S, const uint8_t* _key, uint64_t keylen) {
}
blake224_update(&S->outer, pad, 512);

memwipe(keyhash, sizeof(keyhash));
secure_erase(keyhash, sizeof(keyhash));
}

// datalen = number of bits
Expand All @@ -346,15 +347,15 @@ void hmac_blake256_final(hmac_state* S, uint8_t* digest) {
blake256_final(&S->inner, ihash);
blake256_update(&S->outer, ihash, 256);
blake256_final(&S->outer, digest);
memwipe(ihash, sizeof(ihash));
secure_erase(ihash, sizeof(ihash));
}

void hmac_blake224_final(hmac_state* S, uint8_t* digest) {
uint8_t ihash[32];
blake224_final(&S->inner, ihash);
blake224_update(&S->outer, ihash, 224);
blake224_final(&S->outer, digest);
memwipe(ihash, sizeof(ihash));
secure_erase(ihash, sizeof(ihash));
}

// keylen = number of bytes; inlen = number of bytes
Expand Down
23 changes: 18 additions & 5 deletions src/crypto/cn_heavy_hash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,26 @@

#pragma once

#include <boost/align/aligned_alloc.hpp>
#include <cassert>
#include <cinttypes>
#include <cstddef>
#include <cstdlib>
#include <cstring>

// NOTE: std::aligned_alloc is not supported in Microsoft C Runtime library
// because its implementation of std::free is unable to handle aligned
// allocations of any kind. Instead, MS CRT provides _aligned_malloc (to be
// freed with _aligned_free).
// https://en.cppreference.com/w/cpp/memory/c/aligned_alloc
#if defined(_MSC_VER) || defined(__MINGW64__)
#include <malloc.h>
#define CNHH_ALIGNED_ALLOC(align, size) _aligned_malloc(size, align)
#define CNHH_ALIGNED_FREE(ptr) _aligned_free(ptr)
#else
#define CNHH_ALIGNED_ALLOC(align, size) std::aligned_alloc(align, size)
#define CNHH_ALIGNED_FREE(ptr) std::free(ptr)
#endif

#if defined(__x86_64__) || defined(__i386__) || defined(_M_X86) || defined(_M_X64)
#define HAS_INTEL_HW
#elif defined(__aarch64__)
Expand Down Expand Up @@ -93,8 +106,8 @@ template <size_t MEMORY, size_t ITER, size_t VERSION>
class cn_heavy_hash {
public:
cn_heavy_hash() : borrowed_pad(false) {
lpad.set(boost::alignment::aligned_alloc(4096, MEMORY));
spad.set(boost::alignment::aligned_alloc(4096, 4096));
lpad.set(CNHH_ALIGNED_ALLOC(4096, MEMORY));
spad.set(CNHH_ALIGNED_ALLOC(4096, 4096));
}

// Factory function enabling to temporaliy turn v2 object into v1
Expand Down Expand Up @@ -144,9 +157,9 @@ class cn_heavy_hash {
inline void free_mem() {
if (!borrowed_pad) {
if (lpad.as_void() != nullptr)
boost::alignment::aligned_free(lpad.as_void());
CNHH_ALIGNED_FREE(lpad.as_void());
if (lpad.as_void() != nullptr)
boost::alignment::aligned_free(spad.as_void());
CNHH_ALIGNED_FREE(spad.as_void());
}

lpad.set(nullptr);
Expand Down
8 changes: 4 additions & 4 deletions src/crypto/cn_turtle_hash-amd64.inl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// before actually calling any AES code, and otherwise fall back to more portable code.

#include <emmintrin.h>
#if defined(_MSC_VER) || defined(__MINGW32__)
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)
# include <intrin.h>
# include <windows.h>
#else
Expand Down Expand Up @@ -282,7 +282,7 @@ STATIC INLINE void aes_pseudo_round_xor(const uint8_t *in, uint8_t *out,
}
}

#if defined(_MSC_VER) || defined(__MINGW32__)
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)
BOOL SetLockPagesPrivilege(HANDLE hProcess, BOOL bEnable)
{
struct
Expand Down Expand Up @@ -330,7 +330,7 @@ void slow_hash_allocate_state(uint32_t page_size)
if(hp_state != NULL)
return;

#if defined(_MSC_VER) || defined(__MINGW32__)
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)
SetLockPagesPrivilege(GetCurrentProcess(), TRUE);
hp_state = (uint8_t *) VirtualAlloc(hp_state, page_size, MEM_LARGE_PAGES |
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
Expand Down Expand Up @@ -367,7 +367,7 @@ void slow_hash_free_state(uint32_t page_size)
free(hp_state);
else
{
#if defined(_MSC_VER) || defined(__MINGW32__)
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__CYGWIN__)
VirtualFree(hp_state, 0, MEM_RELEASE);
#else
munmap(hp_state, page_size);
Expand Down
Loading

0 comments on commit d650323

Please sign in to comment.