mirror of
https://github.com/eosswedenorg/libantelope
synced 2026-06-16 11:44:55 +02:00
Compare commits
30 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4787573a76 | |||
| 11e086ee12 | |||
| cadb1ff984 | |||
| 1801c8424a | |||
| afc199e739 | |||
| 12e779c8cf | |||
| 9ad2e3cc00 | |||
| e15a5ede18 | |||
| 7e9bd41a83 | |||
| e0d0bcb0cb | |||
| 84645175c1 | |||
| 93f6b1b030 | |||
| ec7a67ad88 | |||
| c035a804b2 | |||
| 225a1947ae | |||
| 610c32c171 | |||
| 891d2e970d | |||
| be8096ed0f | |||
| 682ea069a2 | |||
| 596cf8c774 | |||
| b7a1298615 | |||
| ee4705e858 | |||
| 62b677d0e0 | |||
| 000876176a | |||
| fa7d3cb2e9 | |||
| b7063f3f3a | |||
| ac3facf30b | |||
| 7fc83991bc | |||
| c06846f7ed | |||
| a22825db9b |
21 changed files with 960 additions and 131 deletions
|
|
@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.15)
|
||||||
|
|
||||||
# Project name and version
|
# Project name and version
|
||||||
project(libantelope
|
project(libantelope
|
||||||
VERSION 0.2.0
|
VERSION 0.2.2
|
||||||
DESCRIPTION "C++ library for Antelope IO"
|
DESCRIPTION "C++ library for Antelope IO"
|
||||||
HOMEPAGE_URL "https://github.com/eosswedenorg/libantelope"
|
HOMEPAGE_URL "https://github.com/eosswedenorg/libantelope"
|
||||||
LANGUAGES C CXX
|
LANGUAGES C CXX
|
||||||
|
|
@ -34,6 +34,23 @@ set( CMAKE_CXX_STANDARD 11 )
|
||||||
set( CMAKE_CXX_STANDARD_REQUIRED ON )
|
set( CMAKE_CXX_STANDARD_REQUIRED ON )
|
||||||
set( CMAKE_CXX_EXTENSIONS OFF )
|
set( CMAKE_CXX_EXTENSIONS OFF )
|
||||||
|
|
||||||
|
add_compile_options(
|
||||||
|
"$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Wall;-Wconversion;-Wno-sign-conversion;-Wextra>"
|
||||||
|
"$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/W3;-D_CRT_SECURE_NO_WARNINGS=1>"
|
||||||
|
|
||||||
|
# Debug
|
||||||
|
"$<$<CONFIG:Debug>:$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-O0;-g>>"
|
||||||
|
"$<$<CONFIG:Debug>:$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/Od;/Zi>>"
|
||||||
|
|
||||||
|
# Release
|
||||||
|
"$<$<CONFIG:Release>:$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-O3>>"
|
||||||
|
"$<$<CONFIG:Release>:$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/O2>>"
|
||||||
|
|
||||||
|
# MinSizeRel
|
||||||
|
"$<$<CONFIG:MinSizeRel>:$<$<COMPILE_LANG_AND_ID:CXX,GNU>:-Os>>"
|
||||||
|
"$<$<CONFIG:MinSizeRel>:$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/O1>>"
|
||||||
|
)
|
||||||
|
|
||||||
# OpenSSL 3.0 deprecates some functions we use.
|
# OpenSSL 3.0 deprecates some functions we use.
|
||||||
# Adding this flag makes the compiler not spam warnings.
|
# Adding this flag makes the compiler not spam warnings.
|
||||||
add_compile_options(-D OPENSSL_API_COMPAT=0x10100000L)
|
add_compile_options(-D OPENSSL_API_COMPAT=0x10100000L)
|
||||||
|
|
@ -62,6 +79,7 @@ add_library( ${LIB_NAME} STATIC
|
||||||
target_include_directories( ${LIB_NAME}
|
target_include_directories( ${LIB_NAME}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include>
|
||||||
$<INSTALL_INTERFACE:include>
|
$<INSTALL_INTERFACE:include>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -74,6 +92,9 @@ endif()
|
||||||
include(OpenSSL)
|
include(OpenSSL)
|
||||||
target_link_libraries( ${LIB_NAME} PRIVATE OpenSSL::Crypto)
|
target_link_libraries( ${LIB_NAME} PRIVATE OpenSSL::Crypto)
|
||||||
|
|
||||||
|
# Hash implementation
|
||||||
|
set( LIBANTELOPE_HASHIMPL_OPENSSL 1 )
|
||||||
|
|
||||||
# EC Implementation
|
# EC Implementation
|
||||||
if (${EC_LIB} STREQUAL "libsecp256k1")
|
if (${EC_LIB} STREQUAL "libsecp256k1")
|
||||||
add_subdirectory( vendor/secp256k1 )
|
add_subdirectory( vendor/secp256k1 )
|
||||||
|
|
@ -107,6 +128,9 @@ endif()
|
||||||
|
|
||||||
message("-- Using Elliptic curve library: ${EC_LIB}")
|
message("-- Using Elliptic curve library: ${EC_LIB}")
|
||||||
|
|
||||||
|
# Generate config file
|
||||||
|
configure_file(src/config.in.h ${CMAKE_BINARY_DIR}/include/libantelope/config.h)
|
||||||
|
|
||||||
# --------------------------------
|
# --------------------------------
|
||||||
# Tests
|
# Tests
|
||||||
# --------------------------------
|
# --------------------------------
|
||||||
|
|
@ -143,7 +167,7 @@ install(TARGETS ${LIB_NAME} EXPORT ${PROJECT_NAME}Targets
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
)
|
)
|
||||||
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
install(DIRECTORY include/ ${CMAKE_BINARY_DIR}/include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
|
|
||||||
# Readme and license
|
# Readme and license
|
||||||
install(FILES README.md LICENSE LICENSE.bitcoin
|
install(FILES README.md LICENSE LICENSE.bitcoin
|
||||||
|
|
|
||||||
113
README.md
113
README.md
|
|
@ -1,133 +1,110 @@
|
||||||

|

|
||||||
[](https://github.com/eosswedenorg/libantelope/releases/latest)
|
[](https://github.com/eosswedenorg/libantelope/releases/latest)
|
||||||
[](https://opensource.org/licenses/MIT)
|
[](https://opensource.org/licenses/MIT)
|
||||||
|
|
||||||
# libleap
|
# libantelope
|
||||||
|
|
||||||
Independent C++ library for [Antelope IO](https://antelope.io) (former [libeosio](https://github.com/eosswedenorg/libeosio))
|
libantelope is an independent C++ library designed for Antelope IO (formerly known as libeosio). Please note that this repository is not affiliated with the official Antelope code.
|
||||||
|
|
||||||
NOTE: This repository has no connection to the official Antelope code.
|
|
||||||
|
|
||||||
## Compiling the library
|
## 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.
|
To compile this project, you will need the following:
|
||||||
|
|
||||||
|
- `openssl` development files (version 1.1 or later)
|
||||||
|
- `cmake 3.15` or later
|
||||||
|
|
||||||
### Elliptic curve backend
|
### Elliptic curve backend
|
||||||
|
|
||||||
There is two different backend implementation for the elliptic curve part of the library:
|
The library offers two different backend implementations for the elliptic curve functionality:
|
||||||
|
|
||||||
* `OpenSSL` as mentioned before. however you still need to link to openssl even if it is not used as the EC backend
|
- `libsecp256k1`
|
||||||
because more of the codebase uses it.
|
- `OpenSSL`: Although the default is to use `libsecp256k1` for optimization, you still need to link to OpenSSL as other parts of the codebase rely on it.
|
||||||
|
|
||||||
* `libsecp256k1`
|
To switch the implementation, modify the `EC_LIB` variable in the cmake.
|
||||||
|
|
||||||
Default is to use `libsecp256k1` as it is more optimized.
|
|
||||||
|
|
||||||
You can switch implementation by modifing the cmake variable `EC_LIB`.
|
|
||||||
|
|
||||||
### CMake
|
### CMake
|
||||||
|
|
||||||
You can install `cmake` by reading the [official guide](https://cmake.org/install).
|
You can install `cmake` by referring to the [official guide](https://cmake.org/install).
|
||||||
|
|
||||||
### Linux
|
### Linux
|
||||||
|
|
||||||
**NOTE:** Only Ubuntu `20.04` and `22.04` is officially supported.
|
**NOTE:** Only Ubuntu versions `20.04` and `22.04` are officially supported.
|
||||||
|
|
||||||
The project should compile fine on most versions/distros but it is only tested
|
While the project should compile fine on most versions/distros, it is only tested and distributed for Ubuntu `20.04` and `22.04` by [Sw/eden](https://www.eossweden.org).
|
||||||
and distributed for Ubuntu `20.04` and `22.04` by [Sw/eden](https://www.eossweden.org).
|
|
||||||
|
|
||||||
#### Dependencies
|
#### Dependencies
|
||||||
|
|
||||||
**Ubuntu (or other debian based distros)**
|
**Ubuntu (or other Debian-based distros)**
|
||||||
|
|
||||||
First you need to have a compiler, `openssl` and `cmake`. this can be installed with apt.
|
To install the necessary dependencies (compiler, `openssl`, and `cmake`), use the following `apt` command:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ apt-get install gcc g++ cmake libssl-dev
|
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/).
|
If you require a newer version of `cmake`, you can refer to the [official CMake APT repository](https://apt.kitware.com/).
|
||||||
|
|
||||||
**Other**
|
**Other**
|
||||||
|
|
||||||
Consult your package manager's manual for getting `openssl`,`g++` and `cmake` installed.
|
For other distros, please consult your package manager's manual to install `openssl`, `g++`, and `cmake`. If you need a newer version of `cmake`, you can follow the [official installation guide](https://cmake.org/install).
|
||||||
|
|
||||||
If you need a newer version of cmake then your package manager provides. checkout the [official guide](https://cmake.org/install).
|
|
||||||
|
|
||||||
### MacOS
|
### MacOS
|
||||||
|
|
||||||
#### Dependencies
|
#### Dependencies
|
||||||
|
|
||||||
You must have a compiler installed. This project is known to build with `Xcode 11.0` but other versions should work.
|
Ensure that you have a compiler installed. This project is known to build with `Xcode 11.0`, but other versions should work as well.
|
||||||
|
|
||||||
|
To install `openssl` and `cmake`, you can use the following `brew` command:
|
||||||
|
|
||||||
You need to have openssl and cmake installed also, this can be done with this `brew` command:
|
|
||||||
```sh
|
```sh
|
||||||
$ brew install openssl cmake
|
brew install openssl cmake
|
||||||
```
|
```
|
||||||
|
|
||||||
If you need a newer version of cmake then brew provides. checkout the [official guide](https://cmake.org/install)
|
If you require a newer version of `cmake`, refer to the [official installation guide](https://cmake.org/install).
|
||||||
|
|
||||||
#### Build
|
#### Build
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
$ mkdir build && cd build
|
mkdir build && cd build
|
||||||
$ cmake .. && make
|
cmake .. && make
|
||||||
```
|
```
|
||||||
|
|
||||||
**MacOS:** You may need to point `cmake` to `openssl` by passing the argument
|
**MacOS:** If your `openssl` installation is not located at `/usr/local/opt/openssl@1.1`, you may need to pass the argument `-D OPENSSL_ROOT_DIR=/path/to/openssl` to `cmake` and specify the correct path.
|
||||||
`-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
|
### Windows
|
||||||
|
|
||||||
#### Dependencies
|
#### Dependencies
|
||||||
|
|
||||||
First you will need a compiler.
|
First, ensure that you have a compiler installed.
|
||||||
|
|
||||||
[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.
|
It is recommended to use [Build Tools for Visual Studio 2019](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools&rel=16) and select C++ during installation.
|
||||||
|
|
||||||
By default `cmake` will use the bundled openssl package located at `vendor/openssl-1.1.1e-win-static.zip`
|
By default, `cmake` will utilize the bundled OpenSSL package located at `vendor/openssl-1.1.1e-win-static.zip`. If you prefer to use a different version of OpenSSL, set the `OPENSSL_ROOT_DIR` to the directory where OpenSSL is located on your system:
|
||||||
|
|
||||||
If you like to use an other version of OpenSSL then the static one bundled with this repo
|
```sh
|
||||||
you need to set `OPENSSL_ROOT_DIR` to the directory where OpenSSL is located on the system.
|
cmake -D OPENSSL_ROOT_DIR=C:/path/to/openssl -B build
|
||||||
|
|
||||||
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`
|
**NOTE:** `cmake` uses forward slashes `/` for paths, even on Windows, so ensure that you use them when setting
|
||||||
|
|
||||||
#### Build.
|
`OPENSSL_ROOT_DIR`.
|
||||||
|
|
||||||
Run cmake
|
#### Build
|
||||||
|
|
||||||
```
|
Run `cmake`:
|
||||||
C:\repo> cmake -B build
|
|
||||||
C:\repo> cmake --build build --config Release
|
```sh
|
||||||
|
cmake -B build
|
||||||
|
cmake --build build --config Release
|
||||||
```
|
```
|
||||||
|
|
||||||
## Security notice
|
## Security Notice
|
||||||
|
|
||||||
Elliptic curve crypthographic operations is done using either `OpenSSL` or `libsecp256k1` libraries.
|
The library performs elliptic curve cryptographic operations using either the `OpenSSL` or `libsecp256k1` libraries. The `libantelope` library ensures that sensitive cryptographic information is only stored in computer memory and not exposed to external sources. You are encouraged to inspect the source code and compile it yourself for verification purposes.
|
||||||
This library (libleap) will never expose sensitve cryptographic information
|
|
||||||
to anything but the computers memory.
|
|
||||||
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
|
However, please use this library at your own risk. While both OpenSSL and libsecp256k1 are widely used and considered safe, we cannot guarantee the cryptographic security of the keys as it depends on the elliptic curve implementation.
|
||||||
cryptographically secure as this depends on the elliptic curve
|
|
||||||
implementation (alto both OpenSSL and libsecp256k1 are widely used and should be safe)
|
|
||||||
|
|
||||||
Please read the `LICENSE` file.
|
Please refer to the `LICENSE` file for more information.
|
||||||
|
|
||||||
```
|
|
||||||
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
|
## Author
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,37 +24,7 @@
|
||||||
#ifndef LIBANTELOPE_HASH_H
|
#ifndef LIBANTELOPE_HASH_H
|
||||||
#define LIBANTELOPE_HASH_H
|
#define LIBANTELOPE_HASH_H
|
||||||
|
|
||||||
#include <cstddef>
|
#include <libantelope/hash/sha256.hpp>
|
||||||
|
#include <libantelope/hash/ripemd160.hpp>
|
||||||
namespace libantelope {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hashes
|
|
||||||
*/
|
|
||||||
typedef unsigned char ripemd160_t[20];
|
|
||||||
typedef unsigned char sha256_t[32];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* sha256 hashing function.
|
|
||||||
* Hashes the content in `data` up to `len` bytes. The result is stored in `out`.
|
|
||||||
* Returns the same pointer as `out`.
|
|
||||||
*/
|
|
||||||
sha256_t* sha256(const unsigned char *data, std::size_t len, sha256_t* out);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* sha256 double hashing function.
|
|
||||||
* Hashes the content in `data` up to `len` bytes. The result is stored in `out`.
|
|
||||||
* Returns the same pointer as `out`.
|
|
||||||
*/
|
|
||||||
sha256_t* sha256d(const unsigned char *data, std::size_t len, sha256_t* out);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* RipeMD160 hashing function.
|
|
||||||
* Hashes the content in `data` up to `len` bytes. The result is stored in `out`.
|
|
||||||
* Returns the same pointer as `out`.
|
|
||||||
*/
|
|
||||||
ripemd160_t* ripemd160(const unsigned char *data, std::size_t len, ripemd160_t* out);
|
|
||||||
|
|
||||||
} // namespace libantelope
|
|
||||||
|
|
||||||
#endif /* LIBANTELOPE_HASH_H */
|
#endif /* LIBANTELOPE_HASH_H */
|
||||||
|
|
|
||||||
62
include/libantelope/hash/ripemd160.hpp
Normal file
62
include/libantelope/hash/ripemd160.hpp
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019-2023 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 LIBANTELOPE_HASH_RIPEMD160_H
|
||||||
|
#define LIBANTELOPE_HASH_RIPEMD160_H
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <libantelope/internal/hash.hpp>
|
||||||
|
|
||||||
|
namespace libantelope {
|
||||||
|
|
||||||
|
typedef unsigned char ripemd160_t[20];
|
||||||
|
|
||||||
|
typedef internal::ripemd160_state ripemd160_ctx_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a ripmemd160_ctx_t structure
|
||||||
|
*/
|
||||||
|
int ripemd160_init(ripemd160_ctx_t* ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the RipeMD160 hash value with the contents in `data` up to `len` bytes.
|
||||||
|
* This can be called repeatedly to hash chunks of data.
|
||||||
|
*/
|
||||||
|
int ripemd160_update(ripemd160_ctx_t* ctx, const void *data, std::size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Places the RipeMD160 message digest in out variable.
|
||||||
|
* The ctx's internal state is reset after this operation.
|
||||||
|
*/
|
||||||
|
int ripemd160_final(ripemd160_ctx_t* ctx, ripemd160_t* out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RipeMD160 hashing function.
|
||||||
|
* Hashes the content in `data` up to `len` bytes. The result is stored in `out`.
|
||||||
|
* Returns the same pointer as `out`.
|
||||||
|
*/
|
||||||
|
ripemd160_t* ripemd160(const unsigned char *data, std::size_t len, ripemd160_t* out);
|
||||||
|
|
||||||
|
} // namespace libantelope
|
||||||
|
|
||||||
|
#endif /* LIBANTELOPE_RIPEMD160_H */
|
||||||
69
include/libantelope/hash/sha256.hpp
Normal file
69
include/libantelope/hash/sha256.hpp
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
/**
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019-2023 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 LIBANTELOPE_HASH_SHA256_H
|
||||||
|
#define LIBANTELOPE_HASH_SHA256_H
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <libantelope/internal/hash.hpp>
|
||||||
|
|
||||||
|
namespace libantelope {
|
||||||
|
|
||||||
|
typedef unsigned char sha256_t[32];
|
||||||
|
|
||||||
|
typedef internal::sha256_state sha256_ctx_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize a sha256_ctx_t structure
|
||||||
|
*/
|
||||||
|
int sha256_init(sha256_ctx_t* ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the sha256 hash value with the contents in `data` up to `len` bytes.
|
||||||
|
* This can be called repeatedly to hash chunks of data.
|
||||||
|
*/
|
||||||
|
int sha256_update(sha256_ctx_t* ctx, const void *data, std::size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Place the message digest in out variable.
|
||||||
|
* The ctx's internal state is reset after this operation.
|
||||||
|
*/
|
||||||
|
int sha256_final(sha256_ctx_t* ctx, sha256_t* out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sha256 hashing function.
|
||||||
|
* Hashes the content in `data` up to `len` bytes. The result is stored in `out`.
|
||||||
|
* Returns the same pointer as `out`.
|
||||||
|
*/
|
||||||
|
sha256_t* sha256(const unsigned char *data, std::size_t len, sha256_t* out);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sha256 double hashing function.
|
||||||
|
* Hashes the content in `data` up to `len` bytes. The result is stored in `out`.
|
||||||
|
* Returns the same pointer as `out`.
|
||||||
|
*/
|
||||||
|
sha256_t* sha256d(const unsigned char *data, std::size_t len, sha256_t* out);
|
||||||
|
|
||||||
|
} // namespace libantelope
|
||||||
|
|
||||||
|
#endif /* LIBANTELOPE_HASH_SHA256_H */
|
||||||
42
include/libantelope/internal/hash.hpp
Normal file
42
include/libantelope/internal/hash.hpp
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019-2023 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 LIBANTELOPE_INTERNAL_HASH_H
|
||||||
|
#define LIBANTELOPE_INTERNAL_HASH_H
|
||||||
|
|
||||||
|
#include <libantelope/config.h>
|
||||||
|
|
||||||
|
#ifdef LIBANTELOPE_HASHIMPL_OPENSSL
|
||||||
|
|
||||||
|
namespace libantelope { namespace internal {
|
||||||
|
|
||||||
|
typedef unsigned char sha256_state[112];
|
||||||
|
typedef unsigned char ripemd160_state[96];
|
||||||
|
} } // namespace libantelope::internal
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Missing hash implementation"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LIBANTELOPE_INTERNAL_INTERNAL_H */
|
||||||
|
|
@ -41,7 +41,6 @@ const wif_codec_t WIF_CODEC_LEG = wif_create_legacy_codec(WIF_PUB_LEG);
|
||||||
|
|
||||||
std::string wif_priv_encode(const ec_privkey_t& priv, const std::string& prefix) {
|
std::string wif_priv_encode(const ec_privkey_t& priv, const std::string& prefix) {
|
||||||
|
|
||||||
checksum_t check;
|
|
||||||
// 1 byte extra for legacy prefix prefix.
|
// 1 byte extra for legacy prefix prefix.
|
||||||
unsigned char buf[1 + EC_PRIVKEY_SIZE + CHECKSUM_SIZE] = { 0 };
|
unsigned char buf[1 + EC_PRIVKEY_SIZE + CHECKSUM_SIZE] = { 0 };
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|
@ -59,7 +58,7 @@ std::string wif_priv_encode(const ec_privkey_t& priv, const std::string& prefix)
|
||||||
|
|
||||||
bool wif_priv_decode(ec_privkey_t& priv, const std::string& data) {
|
bool wif_priv_decode(ec_privkey_t& priv, const std::string& data) {
|
||||||
|
|
||||||
uint8_t offset;
|
std::size_t offset;
|
||||||
std::vector<unsigned char> buf;
|
std::vector<unsigned char> buf;
|
||||||
internal::priv_decoder_t decoder = internal::priv_decoder_legacy;
|
internal::priv_decoder_t decoder = internal::priv_decoder_legacy;
|
||||||
|
|
||||||
|
|
@ -100,7 +99,7 @@ std::string wif_pub_encode(const ec_pubkey_t& pub, const std::string& prefix) {
|
||||||
bool wif_pub_decode(ec_pubkey_t& pub, const std::string& data) {
|
bool wif_pub_decode(ec_pubkey_t& pub, const std::string& data) {
|
||||||
|
|
||||||
internal::pub_decoder_t decoder = internal::pub_decoder_legacy;
|
internal::pub_decoder_t decoder = internal::pub_decoder_legacy;
|
||||||
int offset;
|
std::size_t offset;
|
||||||
std::vector<unsigned char> buf;
|
std::vector<unsigned char> buf;
|
||||||
|
|
||||||
// Check prefix
|
// Check prefix
|
||||||
|
|
@ -131,7 +130,6 @@ void wif_print_key(const struct ec_keypair *key, const wif_codec_t& codec) {
|
||||||
|
|
||||||
bool wif_sig_decode(ec_signature_t& sig, const std::string& data) {
|
bool wif_sig_decode(ec_signature_t& sig, const std::string& data) {
|
||||||
|
|
||||||
checksum_t checksum;
|
|
||||||
std::vector<unsigned char> buf;
|
std::vector<unsigned char> buf;
|
||||||
|
|
||||||
if (data.substr(0, WIF_SIG_K1.length()) != WIF_SIG_K1) {
|
if (data.substr(0, WIF_SIG_K1.length()) != WIF_SIG_K1) {
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,7 @@
|
||||||
* Based on code from https://github.com/bitcoin/bitcoin/blob/f1e2f2a85962c1664e4e55471061af0eaa798d40/src/base58.cpp
|
* Based on code from https://github.com/bitcoin/bitcoin/blob/f1e2f2a85962c1664e4e55471061af0eaa798d40/src/base58.cpp
|
||||||
*/
|
*/
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <cstdint>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
@ -120,7 +121,7 @@ bool base58_decode(const char* psz, std::vector<unsigned char>& out) {
|
||||||
psz++;
|
psz++;
|
||||||
}
|
}
|
||||||
// Allocate enough space in big-endian base256 representation.
|
// Allocate enough space in big-endian base256 representation.
|
||||||
int size = strlen(psz) * 733 /1000 + 1; // log(58) / log(256), rounded up.
|
std::size_t size = strlen(psz) * 733 /1000 + 1; // log(58) / log(256), rounded up.
|
||||||
std::vector<unsigned char> b256(size);
|
std::vector<unsigned char> b256(size);
|
||||||
// Process the characters.
|
// Process the characters.
|
||||||
|
|
||||||
|
|
@ -132,7 +133,7 @@ bool base58_decode(const char* psz, std::vector<unsigned char>& out) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); (carry != 0 || i < length) && (it != b256.rend()); ++it, ++i) {
|
for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); (carry != 0 || i < length) && (it != b256.rend()); ++it, ++i) {
|
||||||
carry += 58 * (*it);
|
carry += 58 * (*it);
|
||||||
*it = carry % 256;
|
*it = (unsigned char) (carry % 256);
|
||||||
carry /= 256;
|
carry /= 256;
|
||||||
}
|
}
|
||||||
assert(carry == 0);
|
assert(carry == 0);
|
||||||
|
|
|
||||||
38
src/config.in.h
Normal file
38
src/config.in.h
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* MIT License
|
||||||
|
*
|
||||||
|
* Copyright (c) 2019-2023 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 LIBANTELOPE_CONFIG_H
|
||||||
|
#define LIBANTELOPE_CONFIG_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Hash implementation */
|
||||||
|
#cmakedefine LIBANTELOPE_HASHIMPL_OPENSSL
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LIBANTELOPE_CONFIG_H */
|
||||||
|
|
@ -25,7 +25,7 @@
|
||||||
|
|
||||||
std::ostream& _hex(std::ostream& os, const unsigned char *b, std::size_t sz) {
|
std::ostream& _hex(std::ostream& os, const unsigned char *b, std::size_t sz) {
|
||||||
os << "[ " << std::hex;
|
os << "[ " << std::hex;
|
||||||
for (int i = 0; i < sz; i++) {
|
for (std::size_t i = 0; i < sz; i++) {
|
||||||
unsigned int v = b[i];
|
unsigned int v = b[i];
|
||||||
|
|
||||||
os << "0x";
|
os << "0x";
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@
|
||||||
#include <secp256k1.h>
|
#include <secp256k1.h>
|
||||||
#include <secp256k1_recovery.h>
|
#include <secp256k1_recovery.h>
|
||||||
#include <libantelope/ec.hpp>
|
#include <libantelope/ec.hpp>
|
||||||
#include "rng.h"
|
|
||||||
|
|
||||||
namespace libantelope {
|
namespace libantelope {
|
||||||
|
|
||||||
|
|
@ -40,6 +39,7 @@ int is_canonical(const unsigned char *d) {
|
||||||
static int extended_nonce_function( unsigned char *nonce32, const unsigned char *msg32,
|
static int extended_nonce_function( unsigned char *nonce32, const unsigned char *msg32,
|
||||||
const unsigned char *key32, const unsigned char* algo16,
|
const unsigned char *key32, const unsigned char* algo16,
|
||||||
void* data, unsigned int attempt ) {
|
void* data, unsigned int attempt ) {
|
||||||
|
(void)attempt; // "use" the variable here to shutup compiler about unsed variable.
|
||||||
return secp256k1_nonce_function_rfc6979(nonce32, msg32, key32, algo16, nullptr, *(unsigned int*) data);
|
return secp256k1_nonce_function_rfc6979(nonce32, msg32, key32, algo16, nullptr, *(unsigned int*) data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ int ecdsa_sign(const ec_privkey_t& key, const sha256_t* digest, ec_signature_t&
|
||||||
secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig.data() + 1, &v, &s);
|
secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig.data() + 1, &v, &s);
|
||||||
|
|
||||||
if (is_canonical(sig.data())) {
|
if (is_canonical(sig.data())) {
|
||||||
sig[0] = 27 + 4 + v;
|
sig[0] = (unsigned char) (27 + 4 + v);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -42,12 +42,17 @@
|
||||||
|
|
||||||
static int fill_random(unsigned char* data, size_t size) {
|
static int fill_random(unsigned char* data, size_t size) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
|
/* Disable C4267 Warning (dataloss when casting variable to smaller size) temporarily */
|
||||||
|
#pragma warning( push )
|
||||||
|
#pragma warning( disable: 4267 )
|
||||||
NTSTATUS res = BCryptGenRandom(NULL, data, size, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
NTSTATUS res = BCryptGenRandom(NULL, data, size, BCRYPT_USE_SYSTEM_PREFERRED_RNG);
|
||||||
|
#pragma warning( pop )
|
||||||
if (res != STATUS_SUCCESS || size > ULONG_MAX) {
|
if (res != STATUS_SUCCESS || size > ULONG_MAX) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__linux__) || defined(__FreeBSD__)
|
#elif defined(__linux__) || defined(__FreeBSD__)
|
||||||
/* If `getrandom(2)` is not available you should fallback to /dev/urandom */
|
/* If `getrandom(2)` is not available you should fallback to /dev/urandom */
|
||||||
ssize_t res = getrandom(data, size, 0);
|
ssize_t res = getrandom(data, size, 0);
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,18 @@
|
||||||
|
|
||||||
namespace libantelope {
|
namespace libantelope {
|
||||||
|
|
||||||
|
int sha256_init(sha256_ctx_t* ctx) {
|
||||||
|
return SHA256_Init((SHA256_CTX*)ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sha256_update(sha256_ctx_t* ctx, const void *data, std::size_t len) {
|
||||||
|
return SHA256_Update((SHA256_CTX*)ctx, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sha256_final(sha256_ctx_t* ctx, sha256_t* out) {
|
||||||
|
return SHA256_Final((unsigned char*) out, (SHA256_CTX*)ctx);
|
||||||
|
}
|
||||||
|
|
||||||
sha256_t* sha256(const unsigned char *data, std::size_t len, sha256_t* out) {
|
sha256_t* sha256(const unsigned char *data, std::size_t len, sha256_t* out) {
|
||||||
return (sha256_t *) SHA256(data, len, (unsigned char*) out);
|
return (sha256_t *) SHA256(data, len, (unsigned char*) out);
|
||||||
}
|
}
|
||||||
|
|
@ -36,6 +48,18 @@ sha256_t* sha256d(const unsigned char *data, std::size_t len, sha256_t* out) {
|
||||||
return (sha256_t *) SHA256((unsigned char*) out, 32, (unsigned char*) out);
|
return (sha256_t *) SHA256((unsigned char*) out, 32, (unsigned char*) out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ripemd160_init(ripemd160_ctx_t* ctx) {
|
||||||
|
return RIPEMD160_Init((RIPEMD160_CTX*)ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ripemd160_update(ripemd160_ctx_t* ctx, const void *data, std::size_t len) {
|
||||||
|
return RIPEMD160_Update((RIPEMD160_CTX*)ctx, data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ripemd160_final(ripemd160_ctx_t* ctx, ripemd160_t* out) {
|
||||||
|
return RIPEMD160_Final((unsigned char*) out, (RIPEMD160_CTX*)ctx);
|
||||||
|
}
|
||||||
|
|
||||||
ripemd160_t* ripemd160(const unsigned char *data, std::size_t len, ripemd160_t* out) {
|
ripemd160_t* ripemd160(const unsigned char *data, std::size_t len, ripemd160_t* out) {
|
||||||
return (ripemd160_t *) RIPEMD160(data, len, (unsigned char*) out);
|
return (ripemd160_t *) RIPEMD160(data, len, (unsigned char*) out);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libantelope/checksum.hpp>
|
#include <libantelope/checksum.hpp>
|
||||||
#include <vector>
|
#include <libantelope/hash/ripemd160.hpp>
|
||||||
#include "codec.hpp"
|
#include "codec.hpp"
|
||||||
|
|
||||||
namespace libantelope { namespace internal {
|
namespace libantelope { namespace internal {
|
||||||
|
|
@ -31,22 +31,23 @@ namespace libantelope { namespace internal {
|
||||||
// Just to make it "harder" the calculated checksum for a signature (k1) and pub/priv keys in k1/r1 format.
|
// Just to make it "harder" the calculated checksum for a signature (k1) and pub/priv keys in k1/r1 format.
|
||||||
// has a suffix that is not present in the WIF encoded string.
|
// has a suffix that is not present in the WIF encoded string.
|
||||||
// So this function is a quick hack to calculate it.
|
// So this function is a quick hack to calculate it.
|
||||||
//
|
void _checksum_suffix(const unsigned char *in, size_t size, checksum_t check) {
|
||||||
// Should implement and use Init/Update/Finalize hash functions to do it inplace.
|
ripemd160_ctx_t ctx;
|
||||||
void _checksum_suffix(const unsigned char *in, size_t size, const char *suffix, checksum_t check) {
|
ripemd160_t md;
|
||||||
std::vector<unsigned char> buf(size + 2);
|
|
||||||
|
|
||||||
memcpy(buf.data(), in, size);
|
ripemd160_init(&ctx);
|
||||||
memcpy(buf.data() + size, suffix, 2);
|
ripemd160_update(&ctx, in, size);
|
||||||
|
ripemd160_update(&ctx, "K1", 2);
|
||||||
|
ripemd160_final(&ctx, &md);
|
||||||
|
|
||||||
return checksum_ripemd160(buf.data(), buf.size(), (unsigned char*) check);
|
std::memcpy(check, md, CHECKSUM_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pub_encoder_k1(const ec_pubkey_t& key, unsigned char *buf) {
|
void pub_encoder_k1(const ec_pubkey_t& key, unsigned char *buf) {
|
||||||
|
|
||||||
checksum_t check;
|
checksum_t check;
|
||||||
|
|
||||||
_checksum_suffix(key.data(), EC_PUBKEY_SIZE, "K1", check);
|
_checksum_suffix(key.data(), EC_PUBKEY_SIZE, check);
|
||||||
|
|
||||||
memcpy(buf, key.data(), EC_PUBKEY_SIZE);
|
memcpy(buf, key.data(), EC_PUBKEY_SIZE);
|
||||||
memcpy(buf + EC_PUBKEY_SIZE, check, CHECKSUM_SIZE);
|
memcpy(buf + EC_PUBKEY_SIZE, check, CHECKSUM_SIZE);
|
||||||
|
|
@ -56,7 +57,7 @@ bool pub_decoder_k1(const std::vector<unsigned char>& buf, ec_pubkey_t& key) {
|
||||||
|
|
||||||
checksum_t check;
|
checksum_t check;
|
||||||
|
|
||||||
_checksum_suffix(buf.data(), EC_PUBKEY_SIZE, "K1", check);
|
_checksum_suffix(buf.data(), EC_PUBKEY_SIZE, check);
|
||||||
|
|
||||||
if (memcmp(buf.data() + EC_PUBKEY_SIZE, check, CHECKSUM_SIZE)) {
|
if (memcmp(buf.data() + EC_PUBKEY_SIZE, check, CHECKSUM_SIZE)) {
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -69,7 +70,7 @@ bool pub_decoder_k1(const std::vector<unsigned char>& buf, ec_pubkey_t& key) {
|
||||||
size_t priv_encoder_k1(const ec_privkey_t& priv, unsigned char *buf) {
|
size_t priv_encoder_k1(const ec_privkey_t& priv, unsigned char *buf) {
|
||||||
checksum_t check;
|
checksum_t check;
|
||||||
|
|
||||||
_checksum_suffix(priv.data(), EC_PRIVKEY_SIZE, "K1", check);
|
_checksum_suffix(priv.data(), EC_PRIVKEY_SIZE, check);
|
||||||
|
|
||||||
memcpy(buf, priv.data(), priv.size());
|
memcpy(buf, priv.data(), priv.size());
|
||||||
memcpy(buf + EC_PRIVKEY_SIZE, check, CHECKSUM_SIZE);
|
memcpy(buf + EC_PRIVKEY_SIZE, check, CHECKSUM_SIZE);
|
||||||
|
|
@ -84,7 +85,7 @@ bool priv_decoder_k1(const std::vector<unsigned char>& buf, ec_privkey_t& priv)
|
||||||
}
|
}
|
||||||
|
|
||||||
checksum_t check;
|
checksum_t check;
|
||||||
_checksum_suffix(buf.data(), EC_PRIVKEY_SIZE, "K1", check);
|
_checksum_suffix(buf.data(), EC_PRIVKEY_SIZE, check);
|
||||||
if (memcmp(buf.data() + EC_PRIVKEY_SIZE, check, CHECKSUM_SIZE)) {
|
if (memcmp(buf.data() + EC_PRIVKEY_SIZE, check, CHECKSUM_SIZE)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -97,7 +98,7 @@ void sig_encoder_k1(const ec_signature_t& sig, unsigned char *buf) {
|
||||||
|
|
||||||
checksum_t check;
|
checksum_t check;
|
||||||
|
|
||||||
_checksum_suffix(sig.data(), EC_SIGNATURE_SIZE, "K1", check);
|
_checksum_suffix(sig.data(), EC_SIGNATURE_SIZE, check);
|
||||||
|
|
||||||
memcpy(buf, sig.data(), sig.size());
|
memcpy(buf, sig.data(), sig.size());
|
||||||
memcpy(buf + EC_SIGNATURE_SIZE, check, CHECKSUM_SIZE);
|
memcpy(buf + EC_SIGNATURE_SIZE, check, CHECKSUM_SIZE);
|
||||||
|
|
@ -112,7 +113,7 @@ bool sig_decoder_k1(const std::vector<unsigned char>& buf, ec_signature_t& sig)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate checksum
|
// Calculate checksum
|
||||||
_checksum_suffix(buf.data(), EC_SIGNATURE_SIZE, "K1", check);
|
_checksum_suffix(buf.data(), EC_SIGNATURE_SIZE, check);
|
||||||
|
|
||||||
// And validate
|
// And validate
|
||||||
if (memcmp(buf.data() + EC_SIGNATURE_SIZE, check, CHECKSUM_SIZE)) {
|
if (memcmp(buf.data() + EC_SIGNATURE_SIZE, check, CHECKSUM_SIZE)) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,13 @@
|
||||||
|
|
||||||
|
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/doctest.cmake)
|
||||||
|
|
||||||
set(TEST_SRC
|
set(TEST_SRC
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|
||||||
|
# hash
|
||||||
|
hash/sha256.cpp
|
||||||
|
hash/ripemd160.cpp
|
||||||
|
|
||||||
# ec
|
# ec
|
||||||
ec/generate.cpp
|
ec/generate.cpp
|
||||||
ec/pubkey.cpp
|
ec/pubkey.cpp
|
||||||
|
|
@ -26,10 +32,7 @@ add_executable(doctest ${TEST_SRC})
|
||||||
target_link_libraries(doctest PRIVATE ${LIB_NAME})
|
target_link_libraries(doctest PRIVATE ${LIB_NAME})
|
||||||
target_include_directories(doctest PRIVATE ${CMAKE_CURRENT_LIST_DIR}/include)
|
target_include_directories(doctest PRIVATE ${CMAKE_CURRENT_LIST_DIR}/include)
|
||||||
|
|
||||||
add_test(
|
doctest_discover_tests(doctest)
|
||||||
NAME doctest
|
|
||||||
COMMAND $<TARGET_FILE:doctest> -ni -fc
|
|
||||||
)
|
|
||||||
|
|
||||||
if (WITH_BENCHMARK)
|
if (WITH_BENCHMARK)
|
||||||
add_subdirectory( benchmark )
|
add_subdirectory( benchmark )
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ TEST_CASE("base58::is_base58 [char]") {
|
||||||
|
|
||||||
SUBCASE("valid") {
|
SUBCASE("valid") {
|
||||||
|
|
||||||
for(int i = 0; i < valid_alphabet.length(); i++) {
|
for(std::size_t i = 0; i < valid_alphabet.length(); i++) {
|
||||||
char ch = valid_alphabet[i];
|
char ch = valid_alphabet[i];
|
||||||
|
|
||||||
CHECK(libantelope::is_base58(ch));
|
CHECK(libantelope::is_base58(ch));
|
||||||
|
|
@ -43,7 +43,7 @@ TEST_CASE("base58::is_base58 [char]") {
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBCASE("invalid") {
|
SUBCASE("invalid") {
|
||||||
for(int i = 0; i < invalid_alphabet.length(); i++) {
|
for(std::size_t i = 0; i < invalid_alphabet.length(); i++) {
|
||||||
char ch = invalid_alphabet[i];
|
char ch = invalid_alphabet[i];
|
||||||
|
|
||||||
CHECK_FALSE(libantelope::is_base58(ch));
|
CHECK_FALSE(libantelope::is_base58(ch));
|
||||||
|
|
|
||||||
189
tests/cmake/doctest.cmake
Normal file
189
tests/cmake/doctest.cmake
Normal file
|
|
@ -0,0 +1,189 @@
|
||||||
|
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||||
|
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||||
|
|
||||||
|
#[=======================================================================[.rst:
|
||||||
|
doctest
|
||||||
|
-----
|
||||||
|
|
||||||
|
This module defines a function to help use the doctest test framework.
|
||||||
|
|
||||||
|
The :command:`doctest_discover_tests` discovers tests by asking the compiled test
|
||||||
|
executable to enumerate its tests. This does not require CMake to be re-run
|
||||||
|
when tests change. However, it may not work in a cross-compiling environment,
|
||||||
|
and setting test properties is less convenient.
|
||||||
|
|
||||||
|
This command is intended to replace use of :command:`add_test` to register
|
||||||
|
tests, and will create a separate CTest test for each doctest test case. Note
|
||||||
|
that this is in some cases less efficient, as common set-up and tear-down logic
|
||||||
|
cannot be shared by multiple test cases executing in the same instance.
|
||||||
|
However, it provides more fine-grained pass/fail information to CTest, which is
|
||||||
|
usually considered as more beneficial. By default, the CTest test name is the
|
||||||
|
same as the doctest name; see also ``TEST_PREFIX`` and ``TEST_SUFFIX``.
|
||||||
|
|
||||||
|
.. command:: doctest_discover_tests
|
||||||
|
|
||||||
|
Automatically add tests with CTest by querying the compiled test executable
|
||||||
|
for available tests::
|
||||||
|
|
||||||
|
doctest_discover_tests(target
|
||||||
|
[TEST_SPEC arg1...]
|
||||||
|
[EXTRA_ARGS arg1...]
|
||||||
|
[WORKING_DIRECTORY dir]
|
||||||
|
[TEST_PREFIX prefix]
|
||||||
|
[TEST_SUFFIX suffix]
|
||||||
|
[PROPERTIES name1 value1...]
|
||||||
|
[ADD_LABELS value]
|
||||||
|
[TEST_LIST var]
|
||||||
|
[JUNIT_OUTPUT_DIR dir]
|
||||||
|
)
|
||||||
|
|
||||||
|
``doctest_discover_tests`` sets up a post-build command on the test executable
|
||||||
|
that generates the list of tests by parsing the output from running the test
|
||||||
|
with the ``--list-test-cases`` argument. This ensures that the full
|
||||||
|
list of tests is obtained. Since test discovery occurs at build time, it is
|
||||||
|
not necessary to re-run CMake when the list of tests changes.
|
||||||
|
However, it requires that :prop_tgt:`CROSSCOMPILING_EMULATOR` is properly set
|
||||||
|
in order to function in a cross-compiling environment.
|
||||||
|
|
||||||
|
Additionally, setting properties on tests is somewhat less convenient, since
|
||||||
|
the tests are not available at CMake time. Additional test properties may be
|
||||||
|
assigned to the set of tests as a whole using the ``PROPERTIES`` option. If
|
||||||
|
more fine-grained test control is needed, custom content may be provided
|
||||||
|
through an external CTest script using the :prop_dir:`TEST_INCLUDE_FILES`
|
||||||
|
directory property. The set of discovered tests is made accessible to such a
|
||||||
|
script via the ``<target>_TESTS`` variable.
|
||||||
|
|
||||||
|
The options are:
|
||||||
|
|
||||||
|
``target``
|
||||||
|
Specifies the doctest executable, which must be a known CMake executable
|
||||||
|
target. CMake will substitute the location of the built executable when
|
||||||
|
running the test.
|
||||||
|
|
||||||
|
``TEST_SPEC arg1...``
|
||||||
|
Specifies test cases, wildcarded test cases, tags and tag expressions to
|
||||||
|
pass to the doctest executable with the ``--list-test-cases`` argument.
|
||||||
|
|
||||||
|
``EXTRA_ARGS arg1...``
|
||||||
|
Any extra arguments to pass on the command line to each test case.
|
||||||
|
|
||||||
|
``WORKING_DIRECTORY dir``
|
||||||
|
Specifies the directory in which to run the discovered test cases. If this
|
||||||
|
option is not provided, the current binary directory is used.
|
||||||
|
|
||||||
|
``TEST_PREFIX prefix``
|
||||||
|
Specifies a ``prefix`` to be prepended to the name of each discovered test
|
||||||
|
case. This can be useful when the same test executable is being used in
|
||||||
|
multiple calls to ``doctest_discover_tests()`` but with different
|
||||||
|
``TEST_SPEC`` or ``EXTRA_ARGS``.
|
||||||
|
|
||||||
|
``TEST_SUFFIX suffix``
|
||||||
|
Similar to ``TEST_PREFIX`` except the ``suffix`` is appended to the name of
|
||||||
|
every discovered test case. Both ``TEST_PREFIX`` and ``TEST_SUFFIX`` may
|
||||||
|
be specified.
|
||||||
|
|
||||||
|
``PROPERTIES name1 value1...``
|
||||||
|
Specifies additional properties to be set on all tests discovered by this
|
||||||
|
invocation of ``doctest_discover_tests``.
|
||||||
|
|
||||||
|
``ADD_LABELS value``
|
||||||
|
Specifies if the test labels should be set automatically.
|
||||||
|
|
||||||
|
``TEST_LIST var``
|
||||||
|
Make the list of tests available in the variable ``var``, rather than the
|
||||||
|
default ``<target>_TESTS``. This can be useful when the same test
|
||||||
|
executable is being used in multiple calls to ``doctest_discover_tests()``.
|
||||||
|
Note that this variable is only available in CTest.
|
||||||
|
|
||||||
|
``JUNIT_OUTPUT_DIR dir``
|
||||||
|
If specified, the parameter is passed along with ``--reporters=junit``
|
||||||
|
and ``--out=`` to the test executable. The actual file name is the same
|
||||||
|
as the test target, including prefix and suffix. This should be used
|
||||||
|
instead of EXTRA_ARGS to avoid race conditions writing the XML result
|
||||||
|
output when using parallel test execution.
|
||||||
|
|
||||||
|
#]=======================================================================]
|
||||||
|
|
||||||
|
#------------------------------------------------------------------------------
|
||||||
|
function(doctest_discover_tests TARGET)
|
||||||
|
cmake_parse_arguments(
|
||||||
|
""
|
||||||
|
""
|
||||||
|
"TEST_PREFIX;TEST_SUFFIX;WORKING_DIRECTORY;TEST_LIST;JUNIT_OUTPUT_DIR"
|
||||||
|
"TEST_SPEC;EXTRA_ARGS;PROPERTIES;ADD_LABELS"
|
||||||
|
${ARGN}
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT _WORKING_DIRECTORY)
|
||||||
|
set(_WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
endif()
|
||||||
|
if(NOT _TEST_LIST)
|
||||||
|
set(_TEST_LIST ${TARGET}_TESTS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
## Generate a unique name based on the extra arguments
|
||||||
|
string(SHA1 args_hash "${_TEST_SPEC} ${_EXTRA_ARGS}")
|
||||||
|
string(SUBSTRING ${args_hash} 0 7 args_hash)
|
||||||
|
|
||||||
|
# Define rule to generate test list for aforementioned test executable
|
||||||
|
set(ctest_include_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_include-${args_hash}.cmake")
|
||||||
|
set(ctest_tests_file "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}_tests-${args_hash}.cmake")
|
||||||
|
get_property(crosscompiling_emulator
|
||||||
|
TARGET ${TARGET}
|
||||||
|
PROPERTY CROSSCOMPILING_EMULATOR
|
||||||
|
)
|
||||||
|
add_custom_command(
|
||||||
|
TARGET ${TARGET} POST_BUILD
|
||||||
|
BYPRODUCTS "${ctest_tests_file}"
|
||||||
|
COMMAND "${CMAKE_COMMAND}"
|
||||||
|
-D "TEST_TARGET=${TARGET}"
|
||||||
|
-D "TEST_EXECUTABLE=$<TARGET_FILE:${TARGET}>"
|
||||||
|
-D "TEST_EXECUTOR=${crosscompiling_emulator}"
|
||||||
|
-D "TEST_WORKING_DIR=${_WORKING_DIRECTORY}"
|
||||||
|
-D "TEST_SPEC=${_TEST_SPEC}"
|
||||||
|
-D "TEST_EXTRA_ARGS=${_EXTRA_ARGS}"
|
||||||
|
-D "TEST_PROPERTIES=${_PROPERTIES}"
|
||||||
|
-D "TEST_ADD_LABELS=${_ADD_LABELS}"
|
||||||
|
-D "TEST_PREFIX=${_TEST_PREFIX}"
|
||||||
|
-D "TEST_SUFFIX=${_TEST_SUFFIX}"
|
||||||
|
-D "TEST_LIST=${_TEST_LIST}"
|
||||||
|
-D "TEST_JUNIT_OUTPUT_DIR=${_JUNIT_OUTPUT_DIR}"
|
||||||
|
-D "CTEST_FILE=${ctest_tests_file}"
|
||||||
|
-P "${_DOCTEST_DISCOVER_TESTS_SCRIPT}"
|
||||||
|
VERBATIM
|
||||||
|
)
|
||||||
|
|
||||||
|
file(WRITE "${ctest_include_file}"
|
||||||
|
"if(EXISTS \"${ctest_tests_file}\")\n"
|
||||||
|
" include(\"${ctest_tests_file}\")\n"
|
||||||
|
"else()\n"
|
||||||
|
" add_test(${TARGET}_NOT_BUILT-${args_hash} ${TARGET}_NOT_BUILT-${args_hash})\n"
|
||||||
|
"endif()\n"
|
||||||
|
)
|
||||||
|
|
||||||
|
if(NOT CMAKE_VERSION VERSION_LESS 3.10)
|
||||||
|
# Add discovered tests to directory TEST_INCLUDE_FILES
|
||||||
|
set_property(DIRECTORY
|
||||||
|
APPEND PROPERTY TEST_INCLUDE_FILES "${ctest_include_file}"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
# Add discovered tests as directory TEST_INCLUDE_FILE if possible
|
||||||
|
get_property(test_include_file_set DIRECTORY PROPERTY TEST_INCLUDE_FILE SET)
|
||||||
|
if(NOT ${test_include_file_set})
|
||||||
|
set_property(DIRECTORY
|
||||||
|
PROPERTY TEST_INCLUDE_FILE "${ctest_include_file}"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Cannot set more than one TEST_INCLUDE_FILE"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
set(_DOCTEST_DISCOVER_TESTS_SCRIPT
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}/doctestAddTests.cmake
|
||||||
|
)
|
||||||
120
tests/cmake/doctestAddTests.cmake
Normal file
120
tests/cmake/doctestAddTests.cmake
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
|
||||||
|
# file Copyright.txt or https://cmake.org/licensing for details.
|
||||||
|
|
||||||
|
set(prefix "${TEST_PREFIX}")
|
||||||
|
set(suffix "${TEST_SUFFIX}")
|
||||||
|
set(spec ${TEST_SPEC})
|
||||||
|
set(extra_args ${TEST_EXTRA_ARGS})
|
||||||
|
set(properties ${TEST_PROPERTIES})
|
||||||
|
set(add_labels ${TEST_ADD_LABELS})
|
||||||
|
set(junit_output_dir "${TEST_JUNIT_OUTPUT_DIR}")
|
||||||
|
set(script)
|
||||||
|
set(suite)
|
||||||
|
set(tests)
|
||||||
|
|
||||||
|
function(add_command NAME)
|
||||||
|
set(_args "")
|
||||||
|
foreach(_arg ${ARGN})
|
||||||
|
if(_arg MATCHES "[^-./:a-zA-Z0-9_]")
|
||||||
|
set(_args "${_args} [==[${_arg}]==]") # form a bracket_argument
|
||||||
|
else()
|
||||||
|
set(_args "${_args} ${_arg}")
|
||||||
|
endif()
|
||||||
|
endforeach()
|
||||||
|
set(script "${script}${NAME}(${_args})\n" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Run test executable to get list of available tests
|
||||||
|
if(NOT EXISTS "${TEST_EXECUTABLE}")
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Specified test executable '${TEST_EXECUTABLE}' does not exist"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if("${spec}" MATCHES .)
|
||||||
|
set(spec "--test-case=${spec}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" ${spec} --list-test-cases
|
||||||
|
OUTPUT_VARIABLE output
|
||||||
|
RESULT_VARIABLE result
|
||||||
|
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
|
||||||
|
)
|
||||||
|
if(NOT ${result} EQUAL 0)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Error running test executable '${TEST_EXECUTABLE}':\n"
|
||||||
|
" Result: ${result}\n"
|
||||||
|
" Output: ${output}\n"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
string(REPLACE "\n" ";" output "${output}")
|
||||||
|
|
||||||
|
# Parse output
|
||||||
|
foreach(line ${output})
|
||||||
|
if("${line}" STREQUAL "===============================================================================" OR "${line}" MATCHES [==[^\[doctest\] ]==])
|
||||||
|
continue()
|
||||||
|
endif()
|
||||||
|
set(test ${line})
|
||||||
|
set(labels "")
|
||||||
|
if(${add_labels})
|
||||||
|
# get test suite that test belongs to
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${TEST_EXECUTOR} "${TEST_EXECUTABLE}" --test-case=${test} --list-test-suites
|
||||||
|
OUTPUT_VARIABLE labeloutput
|
||||||
|
RESULT_VARIABLE labelresult
|
||||||
|
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
|
||||||
|
)
|
||||||
|
if(NOT ${labelresult} EQUAL 0)
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Error running test executable '${TEST_EXECUTABLE}':\n"
|
||||||
|
" Result: ${labelresult}\n"
|
||||||
|
" Output: ${labeloutput}\n"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
string(REPLACE "\n" ";" labeloutput "${labeloutput}")
|
||||||
|
foreach(labelline ${labeloutput})
|
||||||
|
if("${labelline}" STREQUAL "===============================================================================" OR "${labelline}" MATCHES [==[^\[doctest\] ]==])
|
||||||
|
continue()
|
||||||
|
endif()
|
||||||
|
list(APPEND labels ${labelline})
|
||||||
|
endforeach()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT "${junit_output_dir}" STREQUAL "")
|
||||||
|
# turn testname into a valid filename by replacing all special characters with "-"
|
||||||
|
string(REGEX REPLACE "[/\\:\"|<>]" "-" test_filename "${test}")
|
||||||
|
set(TEST_JUNIT_OUTPUT_PARAM "--reporters=junit" "--out=${junit_output_dir}/${prefix}${test_filename}${suffix}.xml")
|
||||||
|
else()
|
||||||
|
unset(TEST_JUNIT_OUTPUT_PARAM)
|
||||||
|
endif()
|
||||||
|
# use escape commas to handle properly test cases with commas inside the name
|
||||||
|
string(REPLACE "," "\\," test_name ${test})
|
||||||
|
# ...and add to script
|
||||||
|
add_command(add_test
|
||||||
|
"${prefix}${test}${suffix}"
|
||||||
|
${TEST_EXECUTOR}
|
||||||
|
"${TEST_EXECUTABLE}"
|
||||||
|
"--test-case=${test_name}"
|
||||||
|
"${TEST_JUNIT_OUTPUT_PARAM}"
|
||||||
|
${extra_args}
|
||||||
|
)
|
||||||
|
add_command(set_tests_properties
|
||||||
|
"${prefix}${test}${suffix}"
|
||||||
|
PROPERTIES
|
||||||
|
WORKING_DIRECTORY "${TEST_WORKING_DIR}"
|
||||||
|
${properties}
|
||||||
|
LABELS ${labels}
|
||||||
|
)
|
||||||
|
unset(labels)
|
||||||
|
list(APPEND tests "${prefix}${test}${suffix}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
# Create a list of all discovered tests, which users may use to e.g. set
|
||||||
|
# properties on the tests
|
||||||
|
add_command(set ${TEST_LIST} ${tests})
|
||||||
|
|
||||||
|
# Write CTest script
|
||||||
|
file(WRITE "${CTEST_FILE}" "${script}")
|
||||||
118
tests/hash/ripemd160.cpp
Normal file
118
tests/hash/ripemd160.cpp
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
#include <libantelope/hash/ripemd160.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <testing.h>
|
||||||
|
|
||||||
|
TEST_CASE("hash::ripemd160::ripemd160") {
|
||||||
|
|
||||||
|
struct testcase {
|
||||||
|
const char *name;
|
||||||
|
std::string input;
|
||||||
|
libantelope::ripemd160_t expected;
|
||||||
|
bool valid;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<testcase> tests = {
|
||||||
|
{
|
||||||
|
"valid #1",
|
||||||
|
"Morbi at egestas risus. Praesent blandit pharetra urna, nec porttitor risus sodales eu. Cras et volutpat elit, porta dapibus ipsum. Donec facilisis, eros nec imperdiet tristique, purus eros malesuada neque, quis interdum nisl risus nec leo.",
|
||||||
|
{
|
||||||
|
0xd9, 0x6a, 0x48, 0xf8, 0x2b, 0x39, 0xa9, 0x9f,
|
||||||
|
0x22, 0xba, 0x3e, 0x01, 0x58, 0x5b, 0x15, 0xc7,
|
||||||
|
0x7b, 0x0e, 0x5f, 0x50,
|
||||||
|
},
|
||||||
|
true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid #2",
|
||||||
|
"Donec eget mattis velit, vel vulputate sem. Suspendisse vulputate dolor vel est facilisis congue. Nulla non leo nulla. Proin lorem elit, sagittis eget congue in, pellentesque sed nisi. In pulvinar tortor fermentum suscipit varius.",
|
||||||
|
{
|
||||||
|
0x87, 0x1b, 0x87, 0xde, 0x2e, 0xb6, 0x8b, 0xb6,
|
||||||
|
0xdc, 0x29, 0xe7, 0x40, 0xc3, 0xd1, 0x99, 0x42,
|
||||||
|
0xad, 0x1a, 0xe3, 0x57
|
||||||
|
},
|
||||||
|
true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for(auto it = tests.begin(); it != tests.end(); it++) {
|
||||||
|
SUBCASE(it->name) {
|
||||||
|
libantelope::ripemd160_t dgst;
|
||||||
|
|
||||||
|
CHECK( libantelope::ripemd160((const unsigned char*) it->input.c_str(), it->input.size(), &dgst) == &dgst );
|
||||||
|
|
||||||
|
CHECK_PRED(doctest::toString(dgst), doctest::toString(it->expected), it->valid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("hash::ripemd160::init/update/final") {
|
||||||
|
|
||||||
|
struct testcase {
|
||||||
|
const char *name;
|
||||||
|
std::vector<std::string> inputs;
|
||||||
|
libantelope::ripemd160_t expected;
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
char _; // ripemd160_t can't be last, wierd compiler bug on MSVC
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<testcase> tests = {
|
||||||
|
{
|
||||||
|
"valid #1",
|
||||||
|
{
|
||||||
|
"tortor in congue luctus, tortor sapien condimentum quam, ac congue enim lacus vitae erat. Mauris dapibus eros bibendum",
|
||||||
|
"Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x30, 0x77, 0xaf, 0x6b, 0x43, 0x0b, 0x94, 0x8d,
|
||||||
|
0x59, 0x4e, 0xc7, 0xbb, 0x1a, 0x2b, 0xc3, 0x08,
|
||||||
|
0xaa, 0xf0, 0x75, 0x3a
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid #2",
|
||||||
|
{
|
||||||
|
"Cras suscipit, mi sit amet pretium blandit, massa felis aliquet eros",
|
||||||
|
"Aenean efficitur nibh quis enim mollis blandit",
|
||||||
|
"Vestibulum posuere tempus mi nec cursus"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0xf1, 0xcf, 0xea, 0xf7, 0xef, 0x3a, 0x0f, 0x80,
|
||||||
|
0x26, 0x75, 0x40, 0x75, 0xe0, 0x9d, 0x89, 0x05,
|
||||||
|
0xd1, 0x29, 0xe5, 0xf6
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid #3",
|
||||||
|
{
|
||||||
|
"Donec nec blandit dui. Nulla et tempus odio, id fermentum neque. Nam vitae nunc leo. Aliquam dictum velit nec neque dignissim maximus nec at tellus",
|
||||||
|
"Proin elementum porttitor odio, ut ullamcorper justo rutrum in. Proin dignissim nec diam a eleifend. Duis consequat ultrices purus sed finibus",
|
||||||
|
"Donec eget ante dictum, scelerisque metus eget, mollis velit. Curabitur elementum fermentum lorem, a fringilla velit ultrices non"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0xbb, 0x25, 0x58, 0xa9, 0xd0, 0xc1, 0x23, 0xef,
|
||||||
|
0x55, 0xac, 0x2d, 0x8c, 0xd5, 0xd6, 0xe1, 0x49,
|
||||||
|
0x00, 0x5d, 0x86, 0xe8
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for(auto it = tests.begin(); it != tests.end(); it++) {
|
||||||
|
SUBCASE(it->name) {
|
||||||
|
libantelope::ripemd160_ctx_t ctx;
|
||||||
|
libantelope::ripemd160_t dgst;
|
||||||
|
|
||||||
|
CHECK_EQ(libantelope::ripemd160_init(&ctx), 1);
|
||||||
|
|
||||||
|
for (auto in_it = it->inputs.begin(); in_it != it->inputs.end(); in_it++ ) {
|
||||||
|
CHECK_EQ(libantelope::ripemd160_update(&ctx, (const unsigned char*) in_it->c_str(), in_it->size()), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_EQ(libantelope::ripemd160_final(&ctx, &dgst), 1);
|
||||||
|
|
||||||
|
CHECK( doctest::toString(dgst) == doctest::toString(it->expected) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
180
tests/hash/sha256.cpp
Normal file
180
tests/hash/sha256.cpp
Normal file
|
|
@ -0,0 +1,180 @@
|
||||||
|
#include <libantelope/hash/sha256.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <testing.h>
|
||||||
|
|
||||||
|
TEST_CASE("hash::sha256::sha256") {
|
||||||
|
|
||||||
|
struct testcase {
|
||||||
|
const char *name;
|
||||||
|
std::string input;
|
||||||
|
libantelope::sha256_t expected;
|
||||||
|
bool valid;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<testcase> tests = {
|
||||||
|
{
|
||||||
|
"valid #1",
|
||||||
|
"Suspendisse ut tincidunt quam. Praesent scelerisque risus vitae est consectetur, sed facilisis sem luctus. Praesent aliquet eros quis leo sodales, eget blandit diam scelerisque.",
|
||||||
|
{
|
||||||
|
0x1e, 0x54, 0x96, 0x86, 0x2f, 0x39, 0x44, 0xea,
|
||||||
|
0x42, 0xa9, 0x0f, 0xad, 0x56, 0x79, 0x4b, 0x77,
|
||||||
|
0x8f, 0xcc, 0x54, 0xf7, 0x7a, 0x32, 0x60, 0x37,
|
||||||
|
0x4b, 0xac, 0xd5, 0x65, 0x74, 0xf7, 0xcf, 0x6c
|
||||||
|
},
|
||||||
|
true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid #2",
|
||||||
|
"Phasellus consectetur augue vitae massa vulputate placerat. Pellentesque nec eros a velit bibendum venenatis sit amet et augue. Morbi malesuada facilisis consequat.",
|
||||||
|
{
|
||||||
|
0x7c, 0x79, 0x4a, 0xf4, 0x9b, 0x5b, 0xb4, 0x0c,
|
||||||
|
0xef, 0x4f, 0xaa, 0x65, 0xa4, 0x7c, 0x5f, 0xc5,
|
||||||
|
0x95, 0x69, 0x49, 0x99, 0x6b, 0x08, 0x9b, 0xc0,
|
||||||
|
0x40, 0x2d, 0x57, 0x8a, 0x90, 0x02, 0x42, 0x32,
|
||||||
|
},
|
||||||
|
true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for(auto it = tests.begin(); it != tests.end(); it++) {
|
||||||
|
SUBCASE(it->name) {
|
||||||
|
libantelope::sha256_t dgst;
|
||||||
|
|
||||||
|
CHECK( libantelope::sha256((const unsigned char*) it->input.c_str(), it->input.size(), &dgst) == &dgst );
|
||||||
|
|
||||||
|
CHECK_PRED(doctest::toString(dgst), doctest::toString(it->expected), it->valid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("hash::sha256::sha256d") {
|
||||||
|
|
||||||
|
struct testcase {
|
||||||
|
const char *name;
|
||||||
|
std::string input;
|
||||||
|
libantelope::sha256_t expected;
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
char _; // sha256_t can't be last, wierd compiler bug on MSVC
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<testcase> tests = {
|
||||||
|
{
|
||||||
|
"valid #1",
|
||||||
|
"Suspendisse ut tincidunt quam. Praesent scelerisque risus vitae est consectetur, sed facilisis sem luctus. Praesent aliquet eros quis leo sodales, eget blandit diam scelerisque.",
|
||||||
|
{
|
||||||
|
0x4b, 0x6f, 0xa1, 0xf6, 0x30, 0x1e, 0xbe, 0x4a,
|
||||||
|
0xc7, 0xef, 0x1e, 0x55, 0x3e, 0xdb, 0xc1, 0x31,
|
||||||
|
0x1f, 0x6b, 0xf5, 0xc8, 0x04, 0xe9, 0x0e, 0xe3,
|
||||||
|
0xbe, 0x66, 0x01, 0xbf, 0x70, 0x9f, 0x8e, 0x80,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid #2",
|
||||||
|
"Vivamus ut elementum justo. Vestibulum lobortis rutrum libero sollicitudin aliquet. Nullam tempor urna non odio iaculis, sed pretium quam porttitor. Pellentesque pretium, justo vitae tristique porttitor, diam massa pulvinar neque, sed lacinia mi nulla sed nisi.",
|
||||||
|
{
|
||||||
|
0x1f, 0x3f, 0x1c, 0x48, 0xf6, 0xee, 0x24, 0x1f,
|
||||||
|
0x6c, 0x41, 0x86, 0x69, 0xe3, 0x2f, 0x5e, 0x4d,
|
||||||
|
0xa5, 0x51, 0x04, 0x8b, 0x11, 0x35, 0x47, 0xad,
|
||||||
|
0x7e, 0xd9, 0xfb, 0x2e, 0x59, 0xee, 0x66, 0x21,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid #3",
|
||||||
|
"Praesent ultrices consequat risus luctus faucibus.",
|
||||||
|
{
|
||||||
|
0xd5, 0x5f, 0x9c, 0xda, 0x2d, 0x93, 0x32, 0xc2,
|
||||||
|
0x9b, 0xb1, 0xbb, 0x14, 0x55, 0x80, 0x72, 0xb7,
|
||||||
|
0xba, 0x13, 0xa8, 0xc6, 0xa6, 0xbc, 0x65, 0xfc,
|
||||||
|
0x49, 0xe0, 0x3b, 0x23, 0x04, 0x2a, 0x92, 0x8d,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for(auto it = tests.begin(); it != tests.end(); it++) {
|
||||||
|
SUBCASE(it->name) {
|
||||||
|
libantelope::sha256_t dgst;
|
||||||
|
|
||||||
|
CHECK( libantelope::sha256d((const unsigned char*) it->input.c_str(), it->input.size(), &dgst) == &dgst );
|
||||||
|
|
||||||
|
CHECK( doctest::toString(dgst) == doctest::toString(it->expected) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("hash::sha256::init/update/final") {
|
||||||
|
|
||||||
|
struct testcase {
|
||||||
|
const char *name;
|
||||||
|
std::vector<std::string> inputs;
|
||||||
|
libantelope::sha256_t expected;
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
char _; // sha256_t can't be last, wierd compiler bug on MSVC
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<testcase> tests = {
|
||||||
|
{
|
||||||
|
"valid #1",
|
||||||
|
{
|
||||||
|
"Donec vestibulum enim commodo, faucibus nisi non, mattis quam.",
|
||||||
|
"Nam sed nunc dapibus, auctor risus placerat, aliquet dolor",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x48, 0xc2, 0x34, 0x93, 0x3d, 0xae, 0x0d, 0xd0,
|
||||||
|
0x28, 0xff, 0x5c, 0xa0, 0xca, 0xb1, 0x0a, 0xa3,
|
||||||
|
0xe2, 0xa0, 0xa4, 0x7e, 0xb2, 0x71, 0xa5, 0x28,
|
||||||
|
0x41, 0x03, 0x72, 0x20, 0xb5, 0x23, 0xc3, 0x67,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid #2",
|
||||||
|
{
|
||||||
|
"In tempus, lectus ac molestie venenatis, enim purus suscipit tortor",
|
||||||
|
"sed sodales massa condimentum a",
|
||||||
|
"Integer sit amet pretium magna",
|
||||||
|
"Aenean non accumsan eros. Donec imperdiet justo tempor magna tincidunt malesuada",
|
||||||
|
"Duis eu tortor ac massa sagittis elementum"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0xfb, 0x12, 0x31, 0x9c, 0x2c, 0xe4, 0x94, 0x29,
|
||||||
|
0xc9, 0xd3, 0xc7, 0x84, 0x0c, 0x58, 0x3d, 0x4c,
|
||||||
|
0xde, 0xb5, 0x36, 0x59, 0x46, 0x69, 0xe1, 0x63,
|
||||||
|
0xc5, 0x75, 0xb6, 0x94, 0x41, 0x5a, 0xd4, 0x62,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"valid #3",
|
||||||
|
{
|
||||||
|
"Donec tempus pellentesque lobortis. Integer pellentesque feugiat enim ac suscipit. Curabitur urna quam, condimentum sed bibendum eu",
|
||||||
|
"Nullam lacinia ligula at ex gravida fermentum. Integer scelerisque accumsan iaculis. Suspendisse quis eros ut orci sollicitudin dignissim",
|
||||||
|
"Nulla ligula tortor, tristique eget feugiat non, vehicula sit amet velit. Proin fermentum sagittis tincidunt. Nullam condimentum dapibus magna",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
0x19, 0xfb, 0x71, 0xb1, 0x47, 0x01, 0x7f, 0xf5,
|
||||||
|
0xeb, 0xda, 0xc2, 0xd8, 0xe7, 0xab, 0xc9, 0xcb,
|
||||||
|
0xea, 0x7d, 0x13, 0xa0, 0x2e, 0xe8, 0x48, 0x94,
|
||||||
|
0x67, 0xc5, 0x14, 0xbf, 0x7d, 0x6f, 0x96, 0x83,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
for(auto it = tests.begin(); it != tests.end(); it++) {
|
||||||
|
SUBCASE(it->name) {
|
||||||
|
libantelope::sha256_ctx_t ctx;
|
||||||
|
libantelope::sha256_t dgst;
|
||||||
|
|
||||||
|
CHECK_EQ(libantelope::sha256_init(&ctx), 1);
|
||||||
|
|
||||||
|
for (auto in_it = it->inputs.begin(); in_it != it->inputs.end(); in_it++ ) {
|
||||||
|
CHECK_EQ(libantelope::sha256_update(&ctx, (const unsigned char*) in_it->c_str(), in_it->size()), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
CHECK_EQ(libantelope::sha256_final(&ctx, &dgst), 1);
|
||||||
|
|
||||||
|
CHECK( doctest::toString(dgst) == doctest::toString(it->expected) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
8
tests/include/testing.h
Normal file
8
tests/include/testing.h
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef LIBANTELOPE_TESTING_H
|
||||||
|
#define LIBANTELOPE_TESTING_H
|
||||||
|
|
||||||
|
#include <doctest.h>
|
||||||
|
|
||||||
|
#define CHECK_PRED(a,b,pred) if (pred) { CHECK_EQ((a), (b)); } else { CHECK_NE((a), (b)); }
|
||||||
|
|
||||||
|
#endif /* LIBANTELOPE_TESTING_H */
|
||||||
Loading…
Add table
Add a link
Reference in a new issue