From 137d5cbe31666a748954dd233e54c5703480ebbf Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 3 Apr 2020 15:49:41 +0200 Subject: [PATCH] Initial Commit --- .github/workflows/CI.yml | 43 ++++++++ .github/workflows/package.yml | 77 ++++++++++++++ .gitignore | 2 + CMakeLists.txt | 144 +++++++++++++++++++++++++++ LICENSE | 21 ++++ LICENSE.bitcoin | 22 ++++ README.md | 115 +++++++++++++++++++++ cmake/OpenSSL.cmake | 27 +++++ cmake/cpack_custom.cmake | 124 +++++++++++++++++++++++ cmake/libeosioConfig.cmake.in | 26 +++++ include/libeosio/WIF.h | 39 ++++++++ include/libeosio/base58.h | 46 +++++++++ include/libeosio/checksum.h | 54 ++++++++++ include/libeosio/ec.h | 39 ++++++++ include/libeosio/hash.h | 41 ++++++++ include/libeosio/types.h | 55 ++++++++++ src/WIF.cpp | 66 ++++++++++++ src/base58.cpp | 113 +++++++++++++++++++++ src/openssl/ec.cpp | 70 +++++++++++++ src/openssl/hash.cpp | 43 ++++++++ vendor/.gitignore | 1 + vendor/openssl-1.1.1e-win-static.zip | Bin 0 -> 80844191 bytes 22 files changed, 1168 insertions(+) create mode 100644 .github/workflows/CI.yml create mode 100644 .github/workflows/package.yml create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 LICENSE.bitcoin create mode 100644 README.md create mode 100644 cmake/OpenSSL.cmake create mode 100644 cmake/cpack_custom.cmake create mode 100644 cmake/libeosioConfig.cmake.in create mode 100644 include/libeosio/WIF.h create mode 100644 include/libeosio/base58.h create mode 100644 include/libeosio/checksum.h create mode 100644 include/libeosio/ec.h create mode 100644 include/libeosio/hash.h create mode 100644 include/libeosio/types.h create mode 100644 src/WIF.cpp create mode 100644 src/base58.cpp create mode 100644 src/openssl/ec.cpp create mode 100644 src/openssl/hash.cpp create mode 100644 vendor/.gitignore create mode 100644 vendor/openssl-1.1.1e-win-static.zip diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml new file mode 100644 index 0000000..98a1f5b --- /dev/null +++ b/.github/workflows/CI.yml @@ -0,0 +1,43 @@ +name: CI + +on: + push: + branches: + - '*' + - '*/*' + - '!master' + +jobs: + compile: + strategy: + matrix: + os: [ ubuntu-16.04, ubuntu-18.04, macos-latest, windows-latest ] + + name: ${{matrix.os}} + runs-on: ${{matrix.os}} + + steps: + - uses: actions/checkout@v1 + + - name: Dependancies (mac) + if: runner.os == 'macOS' + shell: bash + run: brew install openssl@1.1 + + - name: Configure + shell: bash + run: | + if [ "$RUNNER_OS" == "macOS" ]; then + SSL_OPTS="-D OPENSSL_ROOT_DIR=/usr/local/opt/openssl@1.1" + fi + cmake ${SSL_OPTS} -B build + + - name: Build + shell: bash + run: cmake --build build + + - name: Upload artifact + uses: actions/upload-artifact@v1 + with: + name: ${{matrix.os}}-build + path: build diff --git a/.github/workflows/package.yml b/.github/workflows/package.yml new file mode 100644 index 0000000..33efd3d --- /dev/null +++ b/.github/workflows/package.yml @@ -0,0 +1,77 @@ +name: Package + +on: + release: + types: [ created ] + +jobs: + # Debian package for ubuntu. + ubuntu: + strategy: + matrix: + os: [ ubuntu-16.04, ubuntu-18.04 ] + name: ${{matrix.os}} + runs-on: ${{matrix.os}} + steps: + - uses: actions/checkout@v1 + + - name: Configure + run: cmake -DCPACK_GENERATOR=DEB -B build + + - name: Package + id: package + run: | + cmake --build build --target package + FILE=$(ls build/*.deb | head -1) + echo "::set-output name=filename::$FILE" + echo "::set-output name=name::$(basename $FILE)" + + - name: Upload + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_name: ${{ steps.package.outputs.name }} + asset_path: ${{ steps.package.outputs.filename }} + asset_content_type: application/x-deb + + # Windows zip file + windows: + strategy: + matrix: + arch: [ x86, x64 ] + name: Windows (${{matrix.arch}}) + runs-on: windows-latest + steps: + - uses: actions/checkout@v1 + + - name: Configure + run: | + if ("${{matrix.arch}}" -eq "x86") { + $PLATFORM="Win32" + } else { + $PLATFORM="${{matrix.arch}}" + } + cmake -A $PLATFORM -S . -B build + + - name: Build + run: cmake --build build --config Release + + - name: Package + id: package + run: | + cmake --build build --config Release --target package + $FILE=(ls build/libeoskeygen*.zip) + echo "::set-output name=filename::$FILE" + echo "::set-output name=name::$(([io.fileinfo]"$FILE").basename).zip" + + - name: Upload + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ github.event.release.upload_url }} + asset_name: ${{ steps.package.outputs.name }} + asset_path: ${{ steps.package.outputs.filename }} + asset_content_type: application/zip diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..64aaea4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build/* +.vscode/ diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..2c5c77c --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,144 @@ +cmake_minimum_required(VERSION 3.15) + +# -------------------------------- +# Info +# -------------------------------- + +# Project name and version +project(libeosio + VERSION 0.1.0 + DESCRIPTION "C++ library for EOSIO" + HOMEPAGE_URL "https://github.com/eosswedenorg/libeosio" + LANGUAGES CXX +) + +set( PROJECT_MAINTAINER "Henrik Hautakoski ") + +# -------------------------------- +# Includes +# -------------------------------- + +set( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_LIST_DIR}/cmake" ) + +# -------------------------------- +# Compiler +# -------------------------------- + +set( CMAKE_CXX_STANDARD 11 ) +set( CMAKE_CXX_STANDARD_REQUIRED ON ) +set( CMAKE_CXX_EXTENSIONS OFF ) + +# -------------------------------- +# Library +# -------------------------------- + +set( LIB_NAME ${PROJECT_NAME} ) + +set( LIB_SOURCE + src/base58.cpp + src/WIF.cpp +) + +# OpenSSL +include(OpenSSL) +set (LIB_SOURCE ${LIB_SOURCE} + src/openssl/ec.cpp + src/openssl/hash.cpp +) + +add_library( ${LIB_NAME} STATIC ${LIB_SOURCE} ) + +# Skip prefix on unix. +if (UNIX) + set_target_properties(${LIB_NAME} PROPERTIES PREFIX "") +endif() + + +target_link_libraries( ${LIB_NAME} + INTERFACE + ${OPENSSL_CRYPTO_LIBRARY} +) + +target_include_directories( ${LIB_NAME} + PUBLIC + $ + $ + PRIVATE + ${OPENSSL_INCLUDE_DIR} +) + +# -------------------------------- +# Install +# -------------------------------- + +# Use installpath from GNUInstallDirs as default. +include(GNUInstallDirs) + +if (WIN32) + # "Flat" install on windows. + set( CMAKE_INSTALL_BINDIR "." ) + set( CMAKE_INSTALL_DATADIR "." ) + set( CMAKE_INSTALL_SHAREDIR "." ) + set( CMAKE_INSTALL_MANDIR "." ) +else() + set( CMAKE_INSTALL_SHAREDIR ${CMAKE_INSTALL_DATADIR}/${PROJECT_NAME} ) +endif (WIN32) + +set( CMAKE_INSTALL_CMAKEMODULEDIR ${CMAKE_INSTALL_SHAREDIR}/cmake ) + +install(TARGETS ${LIB_NAME} EXPORT ${PROJECT_NAME}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} +) +install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +# Readme and license +install(FILES README.md LICENSE LICENSE.bitcoin + DESTINATION ${CMAKE_INSTALL_SHAREDIR}) + +# -------------------------------- +# CMake Package Export +# -------------------------------- + +set_property(TARGET ${LIB_NAME} + PROPERTY VERSION ${PROJECT_VERSION}) + +include(CMakePackageConfigHelpers) + +# Version file. +write_basic_package_version_file( + "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + VERSION ${PROJECT_VERSION} + COMPATIBILITY SameMajorVersion +) + +# Export targets +export(EXPORT ${PROJECT_NAME}Targets + FILE "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake" +) +list (APPEND LIBEOSKEYGEN_CONFIG_INCLUDES Targets) + +# Generate config file. +configure_file(cmake/${PROJECT_NAME}Config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + @ONLY +) + +# Install config and targets +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_CMAKEMODULEDIR} ) + +install(EXPORT ${PROJECT_NAME}Targets DESTINATION ${CMAKE_INSTALL_CMAKEMODULEDIR}) + +# -------------------------------- +# CMake Package Export +# -------------------------------- + +set( CPACK_PACKAGE_NAME ${PROJECT_NAME}-dev ) +set( CPACK_DEBIAN_PACKAGE_PRIORITY "optional" ) +set( CPACK_DEBIAN_PACKAGE_SECTION "devel" ) +set( CPACK_DEBIAN_PACKAGE_RECOMMENDS "libssl1.1" ) + +include(cpack_custom) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ea09337 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2019-2020 EOS Sw/eden + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/LICENSE.bitcoin b/LICENSE.bitcoin new file mode 100644 index 0000000..9d54ecb --- /dev/null +++ b/LICENSE.bitcoin @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2009-2019 The Bitcoin Core developers +Copyright (c) 2009-2019 Bitcoin Developers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..23bd26f --- /dev/null +++ b/README.md @@ -0,0 +1,115 @@ +![](https://github.com/eosswedenorg/libeosio/workflows/CI/badge.svg) +[![GitHub release](https://img.shields.io/github/v/release/eosswedenorg/libeosio?include_prereleases)](https://github.com/eosswedenorg/libeosio/releases/latest) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) + +# libeosio + +Independent C++ library for [EOS](https://eos.io/) + +NOTE: This repository has no connection to the official EOS code. + +## Compiling the library + +You will need `openssl` development files (version 1.1 or later) to compile and `cmake 3.15` or later to compile this project. + +### CMake + +You can install `cmake` by reading the [official guide](https://cmake.org/install). + +### Linux + +#### Dependencies + +**Ubuntu (or other debian based distros)** + +First you need to have a compiler, `openssl` and `cmake`. this can be installed with apt. + +```sh +$ apt-get install gcc g++ cmake libssl-dev +``` +If you need a newer version of cmake then apt provides. +Checkout the official [CMake APT repository](https://apt.kitware.com/). + +**Other** + +Consult your package manager's manual for getting `openssl`,`g++` and `cmake` installed. + +If you need a newer version of cmake then your package manager provides. checkout the [official guide](https://cmake.org/install). + +### MacOS + +#### Dependencies + +You must have a compiler installed. This project is known to build with `Xcode 11.0` but other versions should work. + +You need to have openssl and cmake installed also, this can be done with this `brew` command: +```sh +$ brew install openssl cmake +``` + +If you need a newer version of cmake then brew provides. checkout the [official guide](https://cmake.org/install) + +#### Build + +```sh +$ mkdir build && cd build +$ cmake .. && make +``` + +**MacOS:** You may need to point `cmake` to `openssl` by passing the argument +`-D OPENSSL_ROOT_DIR=/usr/local/opt/openssl@1.1` if openssl is not under `/usr/local/opt/openssl@1.1` you need to find the correct path. + +### Windows + +#### Dependencies + +First you will need a compiler. + +[Build Tools for Visual Studio 2019](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools&rel=16) (Selecting C++ during installation) is recommended. + +By default `cmake` will use the bundled openssl package located at `vendor/openssl-1.1.1e-win-static.zip` + +If you like to use an other version of OpenSSL then the static one bundled with this repo +you need to set `OPENSSL_ROOT_DIR` to the directory where OpenSSL is located on the system. + +For example: + +``` +C:\repo> cmake -D OPENSSL_ROOT_DIR=C:/path/to/openssl -B build +``` + +**NOTE:** `cmake` uses forward slash `/` for path even for windows. so make sure you use that when setting `OPENSSL_ROOT_DIR` + +#### Build. + +Run cmake + +``` +C:\repo> cmake -B build +C:\repo> cmake --build build --config Release +``` + +## Security notice + +Keys are generated by `OpenSSL`'s `EC_KEY_generate_key` function. The program will +never expose your keys to anything but the computers memory and output of the +program. You are free to inspect the source code and compile yourself to verify. + +However, use this at your own risk. we cannot guarantee that the keys are +cryptographically secure as this depends on OpenSSL's implementation (alto it is +widely used and should be safe) + +Please read the `LICENSE` file. + +``` +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF +CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +``` + +## Author + +Henrik Hautakoski - [henrik@eossweden.org](mailto:henrik@eossweden.org) diff --git a/cmake/OpenSSL.cmake b/cmake/OpenSSL.cmake new file mode 100644 index 0000000..5fe070e --- /dev/null +++ b/cmake/OpenSSL.cmake @@ -0,0 +1,27 @@ + +# On Windows if OPENSSL_ROOT_DIR is not explicitly set +# we use a local static version. +if (WIN32 AND NOT OPENSSL_ROOT_DIR) + set( VENDOR_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor) + set( OPENSSL_ZIP_FILE ${VENDOR_DIR}/openssl-1.1.1e-win-static.zip ) + set( OPENSSL_ROOT_DIR ${VENDOR_DIR}/openssl-1.1.1e ) + # Force static. + set( OPENSSL_USE_STATIC_LIBS TRUE ) + + if (NOT EXISTS ${OPENSSL_ROOT_DIR}) + message( "Unpacking ${OPENSSL_ZIP_FILE} to ${OPENSSL_ROOT_DIR}" ) + execute_process( COMMAND ${CMAKE_COMMAND} -E make_directory ${OPENSSL_ROOT_DIR} ) + execute_process( + COMMAND ${CMAKE_COMMAND} -E tar -xf ${OPENSSL_ZIP_FILE} + WORKING_DIRECTORY ${OPENSSL_ROOT_DIR} + ) + endif() +endif() + +# OpenSSL +find_package(OpenSSL 1.1 REQUIRED) + +# Bug in FindOpenSSL. Win needs to link to these if static libs are used. +if (WIN32 AND OPENSSL_USE_STATIC_LIBS) + set (OPENSSL_CRYPTO_LIBRARY "${OPENSSL_CRYPTO_LIBRARY};Crypt32;ws2_32") +endif() diff --git a/cmake/cpack_custom.cmake b/cmake/cpack_custom.cmake new file mode 100644 index 0000000..9ce4e7f --- /dev/null +++ b/cmake/cpack_custom.cmake @@ -0,0 +1,124 @@ +# Custom script to setup cpack properly. + +# -------------------------------- +# System variables +# -------------------------------- + +# check CMAKE_SIZEOF_VOID_P to know if we are 32 or 64 bit. +set( CPACK_SYSTEM_ARCH "x86" ) +if (CMAKE_SIZEOF_VOID_P EQUAL 8) + set( CPACK_SYSTEM_ARCH "${CPACK_SYSTEM_ARCH}_64" ) +endif() + +if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + + # Set CPACK_SYSTEM_NAME, CPACK_SYSTEM_VERSION + # and CPACK_DEBIAN_PACKAGE_ARCHITECTURE correctly for debian based systems. + execute_process(COMMAND lsb_release -is OUTPUT_VARIABLE SYS OUTPUT_STRIP_TRAILING_WHITESPACE) + if (SYS) + string(TOLOWER "${SYS}" CPACK_SYSTEM_NAME ) + + # Set CPACK_SYSTEM_VERSION + execute_process(COMMAND lsb_release -rs OUTPUT_VARIABLE SYS_VER OUTPUT_STRIP_TRAILING_WHITESPACE) + if (SYS_VER) + set( CPACK_SYSTEM_VERSION ${SYS_VER} ) + endif(SYS_VER) + + # Try setting CPACK_DEBIAN_PACKAGE_ARCHITECTURE based on dpkg + if (NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE) + execute_process( + COMMAND dpkg --print-architecture + OUTPUT_VARIABLE ARCH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if (ARCH) + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${ARCH}) + endif() + endif() + endif(SYS) + + + # set CPACK_DEBIAN_PACKAGE_ARCHITECTURE to somthing sane by default. + if (NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE) + + # debian uses different names for 32/64 bit. + if (CPACK_SYSTEM_ARCH STREQUAL "x86") + set( ARCH "i386" ) + else() + set( ARCH "amd64" ) + endif() + + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${ARCH}) + endif() + +endif() + +# CPACK_SYSTEM_NAME defaults are weird. so we set good default here. +if (NOT CPACK_SYSTEM_NAME) + set (CPACK_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}) +endif() + +# CPACK_SYSTEM_VERSION does not exist in original CPack. so we set a default here. +if (NOT CPACK_SYSTEM_VERSION) + set (CPACK_SYSTEM_VERSION ${CMAKE_SYSTEM_VERSION}) +endif() + + +# -------------------------------- +# Package variables +# -------------------------------- + +if (NOT CPACK_PACKAGE_NAME) + set( CPACK_PACKAGE_NAME ${PROJECT_NAME} ) +endif() + +# Forward some variables not handled by CPack. +if (NOT CPACK_PACKAGE_CONTACT AND PROJECT_MAINTAINER) + set( CPACK_PACKAGE_CONTACT ${PROJECT_MAINTAINER} ) +endif() + +# Set "correct" filename that also include system version. +if (CPACK_SYSTEM_VERSION) + set( CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}_${CPACK_SYSTEM_NAME}-${CPACK_SYSTEM_VERSION}_${CPACK_SYSTEM_ARCH}" ) +else() + set( CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}_${CPACK_SYSTEM_NAME}_${CPACK_SYSTEM_ARCH}" ) +endif() + + +# .deb specific + +# Set release version default 1. +set( CPACK_DEBIAN_PACKAGE_RELEASE "1" CACHE STRING "Debian package release version" ) + +# For some reason CPackDeb does not honor CPACK_PACKAGE_HOMEPAGE_URL (that is set correctly) +# if CPACK_DEBIAN_PACKAGE_HOMEPAGE (that the docs says it should.) +# So we have to do it here. +set( CPACK_DEBIAN_PACKAGE_HOMEPAGE "${PROJECT_HOMEPAGE_URL}" ) + +# Set "correct" filename that also include system version and architecture. +set( CPACK_DEBIAN_FILE_NAME + "${CPACK_PACKAGE_NAME}-${PROJECT_VERSION}-${CPACK_DEBIAN_PACKAGE_RELEASE}-${CPACK_SYSTEM_NAME}-${CPACK_SYSTEM_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb" +) + + +# -------------------------------- +# Generator default +# -------------------------------- + + +# Default to gzip tar on unix. zip otherwise. +if (NOT CPACK_GENERATOR) + if (UNIX) + set( CPACK_GENERATOR "TGZ" ) + else() + set( CPACK_GENERATOR "ZIP" ) + endif() +endif() + + +# -------------------------------- +# Include original CPack module. +# -------------------------------- + +include( CPack ) diff --git a/cmake/libeosioConfig.cmake.in b/cmake/libeosioConfig.cmake.in new file mode 100644 index 0000000..dfc2ca9 --- /dev/null +++ b/cmake/libeosioConfig.cmake.in @@ -0,0 +1,26 @@ +# This script provides the libeosio as an import target +# ---------------------------------------------------------- +# +# Use find_package() so cmake will find libeosio: +# +# find_package(libeosio) # No specific version +# find_package(libeosio REQUIRED) # No specific version, but the library must be found. +# find_package(libeosio 0.1) # any 0.1.x, but the library is optional. +# find_package(libeosio 0.1.0) # 0.1.0 or greater, but the library is optional. +# +# Then you just link the you target with eoskeygen target: +# +# target_link_libraries( ${PROGRAM_EXE} PUBLIC libeosio ) +# +# if you do not specify REQUIRED. you must check the variable libeosio_FOUND +# and and only link to it if it's defined: +# +# if (libeosio_FOUND) +# ... +# target_link_libraries( ${PROGRAM_EXE} PUBLIC libeosio ) +# .. +# endif() + +set(LIBEOSIO_VERSION "@PROJECT_VERSION@") + +include ( "${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake" ) diff --git a/include/libeosio/WIF.h b/include/libeosio/WIF.h new file mode 100644 index 0000000..1c7bdfd --- /dev/null +++ b/include/libeosio/WIF.h @@ -0,0 +1,39 @@ +/** + * MIT License + * + * Copyright (c) 2019-2020 EOS Sw/eden + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef LIBEOSIO_WIF_H +#define LIBEOSIO_WIF_H + +#include + +namespace libeosio { + +std::string wif_priv_encode(ec_privkey_t priv); + +std::string wif_pub_encode(ec_pubkey_t pub); + +void wif_print_key(const struct ec_keypair *key); + +} // namespace libeosio + +#endif /* LIBEOSIO_WIF_H */ diff --git a/include/libeosio/base58.h b/include/libeosio/base58.h new file mode 100644 index 0000000..f0e5d6e --- /dev/null +++ b/include/libeosio/base58.h @@ -0,0 +1,46 @@ +/** + * MIT License + * + * Copyright (c) 2019-2020 EOS Sw/eden + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef LIBEOSIO_BASE58_H +#define LIBEOSIO_BASE58_H + +#include +#include + +namespace libeosio { + +std::string base58_encode(const std::string& str); +std::string base58_encode(const std::vector& vch); +std::string base58_encode(const unsigned char* pbegin, const unsigned char* pend); + +bool is_base58(char ch); + +// Returns std::string::npos if the string contains only base58 characters +// Otherwise the position of the first non base58 character is returned. +size_t is_base58(const std::string& str); + +std::string& base58_strip(std::string& str); + +} //namespace eoskeygen + +#endif /* LIBEOSIO_BASE58_H */ diff --git a/include/libeosio/checksum.h b/include/libeosio/checksum.h new file mode 100644 index 0000000..db518a3 --- /dev/null +++ b/include/libeosio/checksum.h @@ -0,0 +1,54 @@ +/** + * MIT License + * + * Copyright (c) 2019-2020 EOS Sw/eden + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef LIBEOSIO_CHECKSUM_H +#define LIBEOSIO_CHECKSUM_H + +#include +#include +#include +#include + +namespace libeosio { + +#define CHECKSUM_SIZE 4 + +typedef std::array checksum_t; + +template +inline checksum_t checksum(const unsigned char* data, std::size_t len) { + checksum_t crc; + T hash; + + F(data, len, &hash); + std::memcpy(crc.data(), &hash, crc.size()); + return crc; +} + +#define checksum_sha256 checksum +#define checksum_sha256d checksum +#define checksum_ripemd160 checksum + +} // namespace libeosio + +#endif /* LIBEOSIO_CHECKSUM_H */ diff --git a/include/libeosio/ec.h b/include/libeosio/ec.h new file mode 100644 index 0000000..756f5d4 --- /dev/null +++ b/include/libeosio/ec.h @@ -0,0 +1,39 @@ +/** + * MIT License + * + * Copyright (c) 2019-2020 EOS Sw/eden + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef LIBEOSIO_EC_H +#define LIBEOSIO_EC_H + +#include + +namespace libeosio { + +/** + * Generates a keypair using the secp256k1 curve. + * public key is in compressed format. + */ +int ec_generate_key(struct ec_keypair *pair); + +} // namespace eoskeygen + +#endif /* LIBEOSIO_EC_H */ diff --git a/include/libeosio/hash.h b/include/libeosio/hash.h new file mode 100644 index 0000000..fa038d4 --- /dev/null +++ b/include/libeosio/hash.h @@ -0,0 +1,41 @@ +/** + * MIT License + * + * Copyright (c) 2019-2020 EOS Sw/eden + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef LIBEOSIO_HASH_H +#define LIBEOSIO_HASH_H + +#include +#include + +namespace libeosio { + +sha256_t* sha256(const unsigned char *data, std::size_t len, sha256_t* out); + +// sha256 double. +sha256_t* sha256d(const unsigned char *data, std::size_t len, sha256_t* out); + +ripemd160_t* ripemd160(const unsigned char *data, std::size_t len, ripemd160_t* out); + +} // namespace libeosio + +#endif /* LIBEOSIO_HASH_H */ diff --git a/include/libeosio/types.h b/include/libeosio/types.h new file mode 100644 index 0000000..b1f8a45 --- /dev/null +++ b/include/libeosio/types.h @@ -0,0 +1,55 @@ +/** + * MIT License + * + * Copyright (c) 2019-2020 EOS Sw/eden + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef LIBEOSIO_TYPES_H +#define LIBEOSIO_TYPES_H + +#include + +namespace libeosio { + +#define EC_PRIVKEY_SIZE 32 + +/* + * Compressed format! + * z||x, where byte z specifies which (of the 2) solutions of the quadratic equation y is. + * Each cordinate is 32 bytes. + */ +#define EC_PUBKEY_SIZE (32 + 1) + +typedef std::array ec_privkey_t; +typedef std::array ec_pubkey_t; + +struct ec_keypair { + ec_privkey_t secret; + ec_pubkey_t pub; +}; + +// Hashes. + +typedef struct { unsigned char data[20]; } ripemd160_t; +typedef struct { unsigned char data[32]; } sha256_t; + +} // namespace libeosio + +#endif /* LIBEOSIO_TYPES_H */ diff --git a/src/WIF.cpp b/src/WIF.cpp new file mode 100644 index 0000000..cbc0554 --- /dev/null +++ b/src/WIF.cpp @@ -0,0 +1,66 @@ +/** + * MIT License + * + * Copyright (c) 2019-2020 EOS Sw/eden + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#include +#include +#include +#include +#include + +namespace libeosio { + +#define PRIV_KEY_PREFIX 0x80 /* 0x80 for "Bitcoin mainnet". Always used by EOS. */ + +std::string wif_priv_encode(ec_privkey_t priv) { + + checksum_t check; + // 1 byte extra for prefix. + unsigned char buf[1 + EC_PRIVKEY_SIZE + CHECKSUM_SIZE] = { PRIV_KEY_PREFIX }; + + memcpy(buf + 1, priv.data(), priv.size()); + + // Checksum + check = checksum_sha256d(buf, 1 + EC_PRIVKEY_SIZE); + memcpy(buf + 1 + EC_PRIVKEY_SIZE, check.data(), check.size()); + + return base58_encode(buf, buf + sizeof(buf)); +} + +std::string wif_pub_encode(ec_pubkey_t pub) { + + checksum_t check = checksum_ripemd160(pub.data(), pub.size()); + unsigned char buf[EC_PUBKEY_SIZE + CHECKSUM_SIZE]; + + memcpy(buf, pub.data(), pub.size()); + memcpy(buf + EC_PUBKEY_SIZE, check.data(), check.size()); + + return "EOS" + base58_encode(buf, buf + sizeof(buf)); +} + +void wif_print_key(const struct ec_keypair *key) { + + std::cout << "Public: " << wif_pub_encode(key->pub) << std::endl; + std::cout << "Private: " << wif_priv_encode(key->secret) << std::endl; +} + +} // namespace libeosio diff --git a/src/base58.cpp b/src/base58.cpp new file mode 100644 index 0000000..73f060b --- /dev/null +++ b/src/base58.cpp @@ -0,0 +1,113 @@ +/** + * The MIT License (MIT) + * + * Copyright (c) 2009-2019 The Bitcoin Core developers + * Copyright (c) 2009-2019 Bitcoin Developers + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * Based on code from https://github.com/bitcoin/bitcoin/blob/f1e2f2a85962c1664e4e55471061af0eaa798d40/src/base58.cpp + */ +#include +#include +#include +#include + +namespace libeosio { + +static const char charmap[59] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; + +std::string base58_encode(const unsigned char* pbegin, const unsigned char* pend) { + + // Skip & count leading zeroes. + int zeroes = 0; + int length = 0; + while (pbegin != pend && *pbegin == 0) { + pbegin++; + zeroes++; + } + // Allocate enough space in big-endian base58 representation. + std::size_t size = (pend - pbegin) * 138 / 100 + 1; // log(256) / log(58), rounded up. + std::vector b58(size); + // Process the bytes. + while (pbegin != pend) { + int carry = *pbegin; + int i = 0; + // Apply "b58 = b58 * 256 + ch". + for (std::vector::reverse_iterator it = b58.rbegin(); (carry != 0 || i < length) && (it != b58.rend()); it++, i++) { + carry += 256 * (*it); + *it = static_cast(carry % 58); + carry /= 58; + } + + assert(carry == 0); + length = i; + pbegin++; + } + // Skip leading zeroes in base58 result. + std::vector::iterator it = b58.begin() + (size - length); + while (it != b58.end() && *it == 0) + it++; + // Translate the result into a string. + std::string str; + str.reserve(zeroes + (b58.end() - it)); + str.assign(zeroes, '1'); + while (it != b58.end()) + str += charmap[*(it++)]; + return str; +} + +std::string base58_encode(const std::string& str) { + + const unsigned char *ptr = (const unsigned char *) str.c_str(); + return base58_encode(ptr, ptr + str.length()); +} + +std::string base58_encode(const std::vector& vch) { + + return base58_encode(vch.data(), vch.data() + vch.size()); +} + +bool is_base58(char ch) { + for(unsigned int i=0; i < sizeof(charmap); i++) { + if (ch == charmap[i]) { + return true; + } + } + return false; +} + +size_t is_base58(const std::string& str) { + + auto p = std::find_if_not(str.begin(), str.end(), static_cast(is_base58)); + + if (p == str.end()) { + return std::string::npos; + } + return p - str.begin(); +} + +std::string& base58_strip(std::string &str) { + str.erase(std::remove_if(str.begin(), str.end(), [] (std::string::value_type ch) + { return is_base58(ch) == false; } + ), str.end()); + return str; +} + +} // namespace libeosio diff --git a/src/openssl/ec.cpp b/src/openssl/ec.cpp new file mode 100644 index 0000000..5f0f9f7 --- /dev/null +++ b/src/openssl/ec.cpp @@ -0,0 +1,70 @@ +/** + * MIT License + * + * Copyright (c) 2019-2020 EOS Sw/eden + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following