1
0
Fork 0
mirror of https://github.com/eosswedenorg/libantelope synced 2026-06-16 03:34:56 +02:00

Compare commits

...

59 commits

Author SHA1 Message Date
4787573a76 Version 0.2.2 2023-08-16 15:52:14 +02:00
11e086ee12 src/base58.cpp: need to include cstdint for uint8_t type 2023-08-16 15:49:12 +02:00
cadb1ff984 Rework README.md 2023-06-01 14:46:35 +02:00
1801c8424a Version 0.2.1 2023-05-31 15:06:58 +02:00
afc199e739 tests/CMakeLists.txt: use doctest_discover_tests() macro to add all doctest test cases with a separate CTest test. 2023-05-31 15:05:35 +02:00
12e779c8cf Adding tests/cmake/doctestAddTests.cmake 2023-05-31 15:03:19 +02:00
9ad2e3cc00 Adding tests/cmake/doctest.cmake 2023-05-31 15:03:07 +02:00
e15a5ede18 tests/hash: fix bug in MSVC compiler. 2023-05-31 14:42:20 +02:00
7e9bd41a83 src/libsecp256k1/rng.h: fix C467 warning on MSVC compilers. 2023-05-31 10:48:52 +02:00
e0d0bcb0cb include/libantelope/internal/hash.hpp: don't include OpenSSL headers here. instead we declare the state variables as plain arrays. 2023-05-31 10:47:44 +02:00
84645175c1 tests: Adding tests for sha256 and ripemd160 hashing functions. 2023-05-31 10:46:14 +02:00
93f6b1b030 Adding tests/include/testing.h 2023-05-31 10:45:25 +02:00
ec7a67ad88 src/openssl/hash.cpp: fix sha256_init() signature. 2023-05-31 10:42:12 +02:00
c035a804b2 src/wif/k1.cpp: implement _checksum_suffix() using init/update/final ripemd160 functions. 2023-05-30 13:59:43 +02:00
225a1947ae include/libantelope/hash.hpp: split into hash/ripemd160.hpp and hash/sha256.hpp 2023-05-30 13:55:07 +02:00
610c32c171 Hash: Define init/update/final functions for sha256 and ripemd160 2023-05-30 13:48:46 +02:00
891d2e970d Adding include/libantelope/internal/hash.hpp 2023-05-30 13:47:02 +02:00
be8096ed0f CMakeLists.txt: set LIBANTELOPE_HASHIMPL_OPENSSL 2023-05-30 13:46:42 +02:00
682ea069a2 CMakeLists.txt: use src/config.in.h as configuration file. 2023-05-30 13:46:23 +02:00
596cf8c774 Adding src/config.in.h 2023-05-30 13:45:35 +02:00
b7a1298615 src/libsecp256k1/ecdsa.cpp: fix unused variable warning in extended_nonce_function() 2023-04-10 17:32:59 +02:00
ee4705e858 src/libsecp256k1/ecdsa.cpp: fix warning about assigning an int value to unsigned char. 2023-04-10 17:31:52 +02:00
62b677d0e0 tests/base58/is_base58.cpp: fix integer size comparison warning. 2023-04-10 17:29:12 +02:00
000876176a src/base58.cpp: fix integer size comparison warning. 2023-04-10 17:25:25 +02:00
fa7d3cb2e9 src/ec.cpp: fix integer size comparison warning. 2023-04-10 17:25:25 +02:00
b7063f3f3a src/libsecp256k1/ecdsa.cpp: don't include "rng.h" here. 2023-04-10 17:22:04 +02:00
ac3facf30b src/WIF.cpp: fix integer comparison between different sizes warning. 2023-04-10 16:50:38 +02:00
7fc83991bc src/WIF.cpp: Remove unused variables. 2023-04-10 16:50:38 +02:00
c06846f7ed CMakeLists.txt: configure compiler flags for different build types. 2023-04-10 16:47:30 +02:00
a22825db9b README.md: fix some places where "libleap" was used instead of "libantelope" 2023-04-10 16:42:32 +02:00
3e38c587d3 Version 0.2.0 2023-04-06 14:49:48 +02:00
98a1ce7fcc src/libsecp256k1/rng.h: add header guard. 2023-04-06 14:48:17 +02:00
aa6bff9a84 cmake/libantelopeConfig.cmake.in: minor style fix. 2023-04-06 14:45:30 +02:00
923384025a cmake/libantelopeConfig.cmake.in: fix a typo in the documentation. 2023-04-06 14:45:30 +02:00
6824a2f49e Change namespace and header guards from libeosio to libantelope 2023-04-06 14:45:30 +02:00
0cfd459c71 Change project name from libeosio to libantelope 2023-04-06 14:45:30 +02:00
9d11357490 Version 0.1.7 2023-04-04 19:00:45 +02:00
424fe4702d include/libeosio/WIF.hpp: Make wif_priv_encode and wif_pub_encode default to K1 prefix. 2023-04-04 13:30:39 +02:00
2f56e8b43d include/libeosio/WIF.hpp: pass wif_codec_t to wif_print_key() and make it default to K1. 2023-04-04 13:30:07 +02:00
18f35c66b5 include/libeosio/WIF.hpp: add wif_codec_t struct and related functions/constants. 2023-04-04 13:29:12 +02:00
86d75df2ec include/libeosio/WIF.hpp: declare all WIF_ constant strings as extern and set them in WIF.cpp 2023-04-04 13:26:45 +02:00
33d3440f53 include/libeosio/checksum.hpp: Use plain c-array instead of std::array 2023-03-27 15:20:10 +02:00
abecabba99 include/libeosio/hash.hpp: remove nested struct from ripemd160_t and sha256_t and just use a array directly. 2023-03-26 19:28:01 +02:00
6026114869 Merge branch '3-support-new-key-format' into devel 2023-03-26 15:08:01 +02:00
815ab2569f src/wif/k1.cpp: in _checksum_suffix() change array to std::vector as MSVC does not like variable size c-arrays. 2023-03-25 19:54:05 +01:00
9819b2b94d src/WIF.cpp: use signature encoder/decoder. 2023-03-25 18:23:27 +01:00
be6c98f1bd src/wif/k1.cpp: implement sig_encoder_k1 and sig_decoder_k1 2023-03-25 18:23:27 +01:00
abdd84f257 src/wif/codec.hpp: Adding signature encoders/decoders 2023-03-25 18:23:27 +01:00
171db63de4 include/libeosio/WIF.hpp: Adding WIF_SIG_K1 constant. 2023-03-25 18:23:27 +01:00
1aa6906ba2 WIF: Support PVT_K1 format. 2023-03-25 18:23:27 +01:00
ea411793a2 src/WIF.cpp: use wif/codec.hpp 2023-03-25 16:02:09 +01:00
053f91c74b Adding src/wif/k1.cpp 2023-03-25 15:24:57 +01:00
6793762fbb Adding src/wif/legacy.cpp 2023-03-25 15:24:49 +01:00
3abfc488e8 Adding src/wif/codec.hpp 2023-03-25 15:24:05 +01:00
ebb4219024 WIF: Support PUB_K1 format. 2023-03-23 19:15:25 +01:00
9114c17315 include/libeosio/WIF.hpp: adding prefixes constants. 2023-03-23 19:14:51 +01:00
f8630de098 tests/WIF/pub_decode.cpp: fix test name. 2023-03-23 18:26:55 +01:00
f606f7e263 README.md: Update to reflect the use of libsecp256k1 2023-03-23 17:17:43 +01:00
2b68d7ec32 src/WIF.cpp: move _calculate_sig_checksum() to top of file, so we dont need to add a function declaration. 2023-03-23 14:19:37 +01:00
48 changed files with 1704 additions and 489 deletions

View file

@ -62,7 +62,7 @@ jobs:
id: package
run: |
cmake --build build --config Release --target package
$FILE=(ls build/libeosio*.zip)
$FILE=(ls build/libantelope*.zip)
echo "::set-output name=filename::$FILE"
echo "::set-output name=name::$(([io.fileinfo]"$FILE").basename).zip"

View file

@ -5,10 +5,10 @@ cmake_minimum_required(VERSION 3.15)
# --------------------------------
# Project name and version
project(libeosio
VERSION 0.1.6
DESCRIPTION "C++ library for EOSIO"
HOMEPAGE_URL "https://github.com/eosswedenorg/libeosio"
project(libantelope
VERSION 0.2.2
DESCRIPTION "C++ library for Antelope IO"
HOMEPAGE_URL "https://github.com/eosswedenorg/libantelope"
LANGUAGES C CXX
)
@ -34,6 +34,23 @@ set( CMAKE_CXX_STANDARD 11 )
set( CMAKE_CXX_STANDARD_REQUIRED ON )
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.
# Adding this flag makes the compiler not spam warnings.
add_compile_options(-D OPENSSL_API_COMPAT=0x10100000L)
@ -53,6 +70,8 @@ add_library( ${LIB_NAME} STATIC
src/base58.cpp
src/ec.cpp
src/WIF.cpp
src/wif/k1.cpp
src/wif/legacy.cpp
src/openssl/hash.cpp
)
@ -60,6 +79,7 @@ add_library( ${LIB_NAME} STATIC
target_include_directories( ${LIB_NAME}
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
)
@ -72,6 +92,9 @@ endif()
include(OpenSSL)
target_link_libraries( ${LIB_NAME} PRIVATE OpenSSL::Crypto)
# Hash implementation
set( LIBANTELOPE_HASHIMPL_OPENSSL 1 )
# EC Implementation
if (${EC_LIB} STREQUAL "libsecp256k1")
add_subdirectory( vendor/secp256k1 )
@ -105,6 +128,9 @@ endif()
message("-- Using Elliptic curve library: ${EC_LIB}")
# Generate config file
configure_file(src/config.in.h ${CMAKE_BINARY_DIR}/include/libantelope/config.h)
# --------------------------------
# Tests
# --------------------------------
@ -141,7 +167,7 @@ install(TARGETS ${LIB_NAME} EXPORT ${PROJECT_NAME}Targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
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
install(FILES README.md LICENSE LICENSE.bitcoin

111
README.md
View file

@ -1,119 +1,110 @@
![](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)
![](https://github.com/eosswedenorg/libantelope/workflows/CI/badge.svg)
[![GitHub release](https://img.shields.io/github/v/release/eosswedenorg/libantelope?include_prereleases)](https://github.com/eosswedenorg/libantelope/releases/latest)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
# libeosio
# libantelope
Independent C++ library for [EOS](https://eos.io/)
NOTE: This repository has no connection to the official EOS code.
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.
## 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
The library offers two different backend implementations for the elliptic curve functionality:
- `libsecp256k1`
- `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.
To switch the implementation, modify the `EC_LIB` variable in the 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
**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
and distributed for Ubuntu `20.04` and `22.04` by [Sw/eden](https://www.eossweden.org).
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).
#### 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
$ 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**
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).
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).
### MacOS
#### 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
$ 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
```sh
$ mkdir build && cd build
$ cmake .. && make
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.
**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.
### Windows
#### 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
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
```sh
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
```
C:\repo> cmake -B build
C:\repo> cmake --build build --config Release
Run `cmake`:
```sh
cmake -B build
cmake --build build --config Release
```
## Security notice
## Security Notice
Keys are generated by `OpenSSL`'s `EC_KEY_generate_key` function. The library will
never expose keys to anything but the computers memory (and standard output if you call such a function of course).
You are free to inspect the source code and compile yourself to verify.
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.
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)
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.
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.
```
Please refer to the `LICENSE` file for more information.
## Author

View file

@ -0,0 +1,26 @@
# This script provides the libantelope as an import target
# ----------------------------------------------------------
#
# Use find_package() so cmake will find libantelope:
#
# find_package(libantelope) # No specific version
# find_package(libantelope REQUIRED) # No specific version, but the library must be found.
# find_package(libantelope 0.1) # any 0.1.x, but the library is optional.
# find_package(libeantelope 0.1.0) # 0.1.0 or greater, but the library is optional.
#
# Then you just link the you target with libantelope target:
#
# target_link_libraries( ${PROGRAM_EXE} PUBLIC libantelope )
#
# if you do not specify REQUIRED. you must check the variable libantelope_FOUND
# and and only link to it if it's defined:
#
# if (libantelope_FOUND)
# ...
# target_link_libraries( ${PROGRAM_EXE} PUBLIC libantelope )
# ..
# endif()
set( LIBANTELOPE_VERSION "@PROJECT_VERSION@" )
include ( "${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake" )

View file

@ -1,26 +0,0 @@
# 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" )

View file

@ -21,18 +21,44 @@
* 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
#ifndef LIBANTELOPE_WIF_H
#define LIBANTELOPE_WIF_H
#include <string>
#include <libeosio/ec.hpp>
#include <libantelope/ec.hpp>
namespace libeosio {
namespace libantelope {
/**
* Key prefixes. (strings that is not equal to these prefixes are treated as legacy format.)
*/
extern const std::string WIF_PUB_LEG;
extern const std::string WIF_PUB_K1;
extern const std::string WIF_PVT_LEG;
extern const std::string WIF_PVT_K1;
extern const std::string WIF_SIG_K1;
/**
* Codecs
*/
// A WIF Codec is an public and private key prefix pair.
typedef struct {
std::string pub;
std::string pvt;
} wif_codec_t;
extern const wif_codec_t WIF_CODEC_K1;
extern const wif_codec_t WIF_CODEC_LEG;
inline wif_codec_t wif_create_legacy_codec(const std::string& pub_prefix) {
return { pub_prefix, WIF_PVT_LEG };
}
/**
* Encode an EC private key to WIF String.
*/
std::string wif_priv_encode(const ec_privkey_t& priv);
std::string wif_priv_encode(const ec_privkey_t& priv, const std::string& prefix = WIF_PVT_K1);
/**
* Decode an WIF String to EC private key
@ -42,17 +68,17 @@ bool wif_priv_decode(ec_privkey_t& priv, const std::string& data);
/**
* Encode an EC public key to WIF String.
*/
std::string wif_pub_encode(const ec_pubkey_t& pub, const std::string& prefix = "EOS");
std::string wif_pub_encode(const ec_pubkey_t& pub, const std::string& prefix = WIF_PUB_K1);
/**
* Decode an WIF String to EC public key
*/
bool wif_pub_decode(ec_pubkey_t& pub, const std::string& data, size_t prefix_length = 3);
bool wif_pub_decode(ec_pubkey_t& pub, const std::string& data);
/**
* Prints an EC keypair in WIF format to standard out.
*/
void wif_print_key(const struct ec_keypair *key, const std::string& prefix = "EOS");
void wif_print_key(const struct ec_keypair *key, const wif_codec_t& codec = WIF_CODEC_K1);
/**
* Signatures
@ -68,6 +94,6 @@ std::string wif_sig_encode(const ec_signature_t& sig);
*/
bool wif_sig_decode(ec_signature_t& sig, const std::string& data);
} // namespace libeosio
} // namespace libantelope
#endif /* LIBEOSIO_WIF_H */
#endif /* LIBANTELOPE_WIF_H */

View file

@ -21,13 +21,13 @@
* 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
#ifndef LIBANTELOPE_BASE58_H
#define LIBANTELOPE_BASE58_H
#include <string>
#include <vector>
namespace libeosio {
namespace libantelope {
/**
* Base58 Encoding functions.
@ -61,6 +61,6 @@ size_t is_base58(const std::string& str);
*/
std::string& base58_strip(std::string& str);
} //namespace libeosio
} //namespace libantelope
#endif /* LIBEOSIO_BASE58_H */
#endif /* LIBANTELOPE_BASE58_H */

View file

@ -21,15 +21,14 @@
* 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
#ifndef LIBANTELOPE_CHECKSUM_H
#define LIBANTELOPE_CHECKSUM_H
#include <cstdint>
#include <cstring>
#include <array>
#include <libeosio/hash.hpp>
#include <libantelope/hash.hpp>
namespace libeosio {
namespace libantelope {
/**
* Checksum size (in bytes)
@ -39,7 +38,7 @@ namespace libeosio {
/**
* Checksum datatype
*/
typedef std::array<unsigned char, CHECKSUM_SIZE> checksum_t;
typedef unsigned char checksum_t[CHECKSUM_SIZE];
/**
* Checksum template function.
@ -48,19 +47,18 @@ typedef std::array<unsigned char, CHECKSUM_SIZE> checksum_t;
* - F: Hash calculation function, should have the signature `T* F(const unsigned char *, std::size_t, T*)`
*/
template <typename T, T* (*F)(const unsigned char *, std::size_t, T*)>
inline checksum_t checksum(const unsigned char* data, std::size_t len) {
checksum_t crc;
inline void 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;
std::memcpy(crc, &hash, CHECKSUM_SIZE);
}
template <checksum_t (*F)(const unsigned char *, std::size_t)>
template <void (*F)(const unsigned char *, std::size_t, checksum_t)>
inline bool checksum_validate(const unsigned char* data, std::size_t len) {
checksum_t check = F(data, len - CHECKSUM_SIZE);
return !memcmp(check.data(), data + (len - CHECKSUM_SIZE), CHECKSUM_SIZE);
checksum_t crc;
F(data, len - CHECKSUM_SIZE, crc);
return !memcmp(crc, data + (len - CHECKSUM_SIZE), CHECKSUM_SIZE);
}
/**
@ -70,6 +68,6 @@ inline bool checksum_validate(const unsigned char* data, std::size_t len) {
#define checksum_sha256d checksum<sha256_t, sha256d>
#define checksum_ripemd160 checksum<ripemd160_t, ripemd160>
} // namespace libeosio
} // namespace libantelope
#endif /* LIBEOSIO_CHECKSUM_H */
#endif /* LIBANTELOPE_CHECKSUM_H */

View file

@ -21,14 +21,14 @@
* 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
#ifndef LIBANTELOPE_EC_H
#define LIBANTELOPE_EC_H
#include <libeosio/hash.hpp>
#include <libantelope/hash.hpp>
#include <iostream>
#include <array>
namespace libeosio {
namespace libantelope {
/**
* Elliptic curve private key size (in bytes)
@ -128,13 +128,13 @@ int ecdsa_recover(const sha256_t* digest, const ec_signature_t& sig, ec_pubkey_t
*/
void ec_shutdown();
} // namespace libeosio
} // namespace libantelope
// Stream operators
std::ostream& operator<<(std::ostream& os, const libeosio::ec_privkey_t& pk);
std::ostream& operator<<(std::ostream& os, const libantelope::ec_privkey_t& pk);
std::ostream& operator<<(std::ostream& os, const libeosio::ec_pubkey_t& pk);
std::ostream& operator<<(std::ostream& os, const libantelope::ec_pubkey_t& pk);
#endif /* LIBEOSIO_EC_H */
#endif /* LIBANTELOPE_EC_H */

View file

@ -0,0 +1,30 @@
/**
* MIT License
*
* Copyright (c) 2019-2021 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_H
#define LIBANTELOPE_HASH_H
#include <libantelope/hash/sha256.hpp>
#include <libantelope/hash/ripemd160.hpp>
#endif /* LIBANTELOPE_HASH_H */

View 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 */

View file

@ -1,7 +1,7 @@
/**
* MIT License
*
* Copyright (c) 2019-2021 EOS Sw/eden
* 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
@ -21,18 +21,34 @@
* 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
#ifndef LIBANTELOPE_HASH_SHA256_H
#define LIBANTELOPE_HASH_SHA256_H
#include <cstddef>
#include <libantelope/internal/hash.hpp>
namespace libeosio {
namespace libantelope {
typedef unsigned char sha256_t[32];
typedef internal::sha256_state sha256_ctx_t;
/**
* Hashes
* Initialize a sha256_ctx_t structure
*/
typedef struct { unsigned char data[20]; } ripemd160_t;
typedef struct { unsigned char data[32]; } sha256_t;
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.
@ -48,13 +64,6 @@ sha256_t* sha256(const unsigned char *data, std::size_t len, sha256_t* 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
} // namespace libeosio
#endif /* LIBEOSIO_HASH_H */
#endif /* LIBANTELOPE_HASH_SHA256_H */

View 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 */

View file

@ -23,72 +23,95 @@
*/
#include <iostream>
#include <cstring>
#include <libeosio/base58.hpp>
#include <libeosio/checksum.hpp>
#include <libeosio/WIF.hpp>
#include <libantelope/base58.hpp>
#include <libantelope/checksum.hpp>
#include <libantelope/WIF.hpp>
#include "wif/codec.hpp"
namespace libeosio {
namespace libantelope {
#define PRIV_KEY_PREFIX 0x80 /* 0x80 for "Bitcoin mainnet". Always used by EOS. */
const std::string WIF_PUB_LEG = "EOS";
const std::string WIF_PUB_K1 = "PUB_K1_";
const std::string WIF_PVT_LEG = "";
const std::string WIF_PVT_K1 = "PVT_K1_";
const std::string WIF_SIG_K1 = "SIG_K1_";
std::string wif_priv_encode(const ec_privkey_t& priv) {
const wif_codec_t WIF_CODEC_K1 = { WIF_PUB_K1, WIF_PVT_K1 };
const wif_codec_t WIF_CODEC_LEG = wif_create_legacy_codec(WIF_PUB_LEG);
checksum_t check;
// 1 byte extra for prefix.
unsigned char buf[1 + EC_PRIVKEY_SIZE + CHECKSUM_SIZE] = { PRIV_KEY_PREFIX };
std::string wif_priv_encode(const ec_privkey_t& priv, const std::string& prefix) {
memcpy(buf + 1, priv.data(), priv.size());
// 1 byte extra for legacy prefix prefix.
unsigned char buf[1 + EC_PRIVKEY_SIZE + CHECKSUM_SIZE] = { 0 };
size_t len;
// Checksum
check = checksum_sha256d(buf, 1 + EC_PRIVKEY_SIZE);
memcpy(buf + 1 + EC_PRIVKEY_SIZE, check.data(), check.size());
if (prefix == WIF_PVT_K1) {
len = internal::priv_encoder_k1(priv, buf);
} else if (prefix == WIF_PVT_LEG) {
len = internal::priv_encoder_legacy(priv, buf);
} else {
return "";
}
return base58_encode(buf, buf + sizeof(buf));
return prefix + base58_encode(buf, buf + len);
}
bool wif_priv_decode(ec_privkey_t& priv, const std::string& data) {
std::size_t offset;
std::vector<unsigned char> buf;
internal::priv_decoder_t decoder = internal::priv_decoder_legacy;
if (!base58_decode(data, buf)) {
// Check prefix
if (data.substr(0, WIF_PVT_K1.size()) == WIF_PVT_K1) {
offset = WIF_PVT_K1.size();
decoder = internal::priv_decoder_k1;
} else {
// Legacy
offset = 0;
}
if (!base58_decode(data.c_str() + offset, buf)) {
return false;
}
if (buf.size() != 1 + EC_PRIVKEY_SIZE + CHECKSUM_SIZE) {
return false;
}
// First byte is the prefix
if (buf[0] != PRIV_KEY_PREFIX) {
return false;
}
// Calculate and validate checksum
if (!checksum_validate<checksum_sha256d>(buf.data(), buf.size())) {
return false;
}
// Copy data to output
memcpy(priv.data(), buf.data() + 1, priv.size());
return true;
return decoder(buf, priv);
}
std::string wif_pub_encode(const ec_pubkey_t& pub, const std::string& prefix) {
checksum_t check = checksum_ripemd160(pub.data(), pub.size());
unsigned char buf[EC_PUBKEY_SIZE + CHECKSUM_SIZE];
internal::pub_encoder_t encoder;
memcpy(buf, pub.data(), pub.size());
memcpy(buf + EC_PUBKEY_SIZE, check.data(), check.size());
if (prefix == WIF_PUB_K1) {
encoder = internal::pub_encoder_k1;
}
// Legacy
else {
encoder = internal::pub_encoder_legacy;
}
return prefix.substr(0, 3) + base58_encode(buf, buf + sizeof(buf));
encoder(pub, buf);
return prefix + base58_encode(buf, buf + sizeof(buf));
}
bool wif_pub_decode(ec_pubkey_t& pub, const std::string& data, size_t prefix_length) {
bool wif_pub_decode(ec_pubkey_t& pub, const std::string& data) {
internal::pub_decoder_t decoder = internal::pub_decoder_legacy;
std::size_t offset;
std::vector<unsigned char> buf;
if (!base58_decode(data.c_str() + prefix_length, buf)) {
// Check prefix
if (data.substr(0, WIF_PUB_K1.size()) == WIF_PUB_K1) {
decoder = internal::pub_decoder_k1;
offset = WIF_PUB_K1.size();
} else {
// Legacy
offset = 3;
}
if (!base58_decode(data.c_str() + offset, buf)) {
return false;
}
@ -96,76 +119,37 @@ bool wif_pub_decode(ec_pubkey_t& pub, const std::string& data, size_t prefix_len
return false;
}
// Calculate and validate checksum
if (!checksum_validate<checksum_ripemd160>(buf.data(), buf.size())) {
return false;
}
// Copy data to output
memcpy(pub.data(), buf.data(), pub.size());
return true;
return decoder(buf, pub);
}
void wif_print_key(const struct ec_keypair *key, const std::string& prefix) {
void wif_print_key(const struct ec_keypair *key, const wif_codec_t& codec) {
std::cout << "Public: " << wif_pub_encode(key->pub, prefix) << std::endl;
std::cout << "Private: " << wif_priv_encode(key->secret) << std::endl;
}
// Just to make it "harder" the calculated checksum for a signature
// has a "K1" suffix that is not present in the WIF encoded string.
// So this function is a quick hack to calculate it.
//
// Should implement and use Init/Update/Finalize hash functions to do it inplace.
checksum_t _calculate_sig_checksum(const unsigned char *in) {
unsigned char buf[EC_SIGNATURE_SIZE + 2];
memcpy(buf, in, EC_SIGNATURE_SIZE);
memcpy(buf + EC_SIGNATURE_SIZE, "K1", 2);
return checksum_ripemd160(buf, EC_SIGNATURE_SIZE + 2);
std::cout << "Public: " << wif_pub_encode(key->pub, codec.pub) << std::endl;
std::cout << "Private: " << wif_priv_encode(key->secret, codec.pvt) << std::endl;
}
bool wif_sig_decode(ec_signature_t& sig, const std::string& data) {
checksum_t checksum;
std::vector<unsigned char> buf;
if (data.substr(0, 7) != "SIG_K1_") {
if (data.substr(0, WIF_SIG_K1.length()) != WIF_SIG_K1) {
// Invalid prefix
return false;
}
if (!base58_decode(data.c_str() + 7, buf)) {
if (!base58_decode(data.c_str() + WIF_SIG_K1.length(), buf)) {
return false;
}
if (buf.size() != EC_SIGNATURE_SIZE + CHECKSUM_SIZE) {
return false;
}
// Calculate checksum
checksum = _calculate_sig_checksum(buf.data());
// And validate
if (memcmp(buf.data() + EC_SIGNATURE_SIZE, checksum.data(), CHECKSUM_SIZE)) {
return false;
}
// Copy data to output
memcpy(sig.data(), buf.data(), sig.size());
return true;
return internal::sig_decoder_k1(buf, sig);
}
std::string wif_sig_encode(const ec_signature_t& sig) {
unsigned char buf[EC_SIGNATURE_SIZE + CHECKSUM_SIZE];
checksum_t check = _calculate_sig_checksum(sig.data());
internal::sig_encoder_k1(sig, buf);
memcpy(buf, sig.data(), sig.size());
memcpy(buf + EC_SIGNATURE_SIZE, check.data(), check.size());
return "SIG_K1_" + base58_encode(buf, buf + sizeof(buf));
return WIF_SIG_K1 + base58_encode(buf, buf + sizeof(buf));
}
} // namespace libeosio
} // namespace libantelope

View file

@ -25,12 +25,13 @@
* Based on code from https://github.com/bitcoin/bitcoin/blob/f1e2f2a85962c1664e4e55471061af0eaa798d40/src/base58.cpp
*/
#include <algorithm>
#include <cstdint>
#include <cstddef>
#include <cassert>
#include <cstring>
#include <libeosio/base58.hpp>
#include <libantelope/base58.hpp>
namespace libeosio {
namespace libantelope {
static const char charmap[59] = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
static const int8_t table[256] = {
@ -120,7 +121,7 @@ bool base58_decode(const char* psz, std::vector<unsigned char>& out) {
psz++;
}
// 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);
// Process the characters.
@ -132,7 +133,7 @@ bool base58_decode(const char* psz, std::vector<unsigned char>& out) {
int i = 0;
for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); (carry != 0 || i < length) && (it != b256.rend()); ++it, ++i) {
carry += 58 * (*it);
*it = carry % 256;
*it = (unsigned char) (carry % 256);
carry /= 256;
}
assert(carry == 0);
@ -190,4 +191,4 @@ std::string& base58_strip(std::string &str) {
return str;
}
} // namespace libeosio
} // namespace libantelope

38
src/config.in.h Normal file
View 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 */

View file

@ -21,11 +21,11 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
#include <libeosio/ec.hpp>
#include <libantelope/ec.hpp>
std::ostream& _hex(std::ostream& os, const unsigned char *b, std::size_t sz) {
os << "[ " << std::hex;
for (int i = 0; i < sz; i++) {
for (std::size_t i = 0; i < sz; i++) {
unsigned int v = b[i];
os << "0x";
@ -38,10 +38,10 @@ std::ostream& _hex(std::ostream& os, const unsigned char *b, std::size_t sz) {
return os << std::oct << " ]";
}
std::ostream& operator<<(std::ostream& os, const libeosio::ec_privkey_t& k) {
std::ostream& operator<<(std::ostream& os, const libantelope::ec_privkey_t& k) {
return _hex(os, k.data(), k.size());
}
std::ostream& operator<<(std::ostream& os, const libeosio::ec_pubkey_t& k) {
std::ostream& operator<<(std::ostream& os, const libantelope::ec_pubkey_t& k) {
return _hex(os, k.data(), k.size());
}

View file

@ -23,10 +23,10 @@
*/
#include <secp256k1.h>
#include <secp256k1_ecdh.h>
#include <libeosio/ec.hpp>
#include <libantelope/ec.hpp>
#include "rng.h"
namespace libeosio {
namespace libantelope {
secp256k1_context* ctx;
@ -90,4 +90,4 @@ int ec_generate_key(struct ec_keypair *pair) {
return ec_get_publickey(&pair->secret, &pair->pub);
}
} // namespace libeosio
} // namespace libantelope

View file

@ -23,10 +23,9 @@
*/
#include <secp256k1.h>
#include <secp256k1_recovery.h>
#include <libeosio/ec.hpp>
#include "rng.h"
#include <libantelope/ec.hpp>
namespace libeosio {
namespace libantelope {
extern secp256k1_context* ctx;
@ -40,6 +39,7 @@ int is_canonical(const unsigned char *d) {
static int extended_nonce_function( unsigned char *nonce32, const unsigned char *msg32,
const unsigned char *key32, const unsigned char* algo16,
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);
}
@ -50,14 +50,14 @@ int ecdsa_sign(const ec_privkey_t& key, const sha256_t* digest, ec_signature_t&
int v = 0;
secp256k1_ecdsa_recoverable_signature s;
if (!secp256k1_ecdsa_sign_recoverable(ctx, &s, digest->data, key.data(), extended_nonce_function, &counter)) {
if (!secp256k1_ecdsa_sign_recoverable(ctx, &s, (const unsigned char*) digest, key.data(), extended_nonce_function, &counter)) {
return -1;
}
secp256k1_ecdsa_recoverable_signature_serialize_compact(ctx, sig.data() + 1, &v, &s);
if (is_canonical(sig.data())) {
sig[0] = 27 + 4 + v;
sig[0] = (unsigned char) (27 + 4 + v);
return 0;
}
}
@ -86,7 +86,7 @@ int ecdsa_verify(const sha256_t* digest, const ec_signature_t& sig, const ec_pub
// Verify
secp256k1_ecdsa_recoverable_signature_convert(ctx, &ec_sig, &ec_rec_sig);
return secp256k1_ecdsa_verify(ctx, &ec_sig, digest->data, &pubkey) > 0 ? 0 : -1;
return secp256k1_ecdsa_verify(ctx, &ec_sig, (const unsigned char*) digest, &pubkey) > 0 ? 0 : -1;
}
int ecdsa_recover(const sha256_t* digest, const ec_signature_t& sig, ec_pubkey_t& pubkey) {
@ -106,7 +106,7 @@ int ecdsa_recover(const sha256_t* digest, const ec_signature_t& sig, ec_pubkey_t
// Recover public key
if (!secp256k1_ecdsa_recover(ctx, &ec_pubkey, &ec_sig, digest->data)) {
if (!secp256k1_ecdsa_recover(ctx, &ec_pubkey, &ec_sig, (const unsigned char*) digest)) {
return -1;
}
@ -115,4 +115,4 @@ int ecdsa_recover(const sha256_t* digest, const ec_signature_t& sig, ec_pubkey_t
return len != EC_PUBKEY_SIZE ? -1 : 0;
}
} // namespace libeosio
} // namespace libantelope

View file

@ -4,6 +4,9 @@
* EXAMPLES_COPYING or https://creativecommons.org/publicdomain/zero/1.0 *
*************************************************************************/
#ifndef LIBANTELOPE_LIBSECP256K1_RNG_H
#define LIBANTELOPE_LIBSECP256K1_RNG_H
/*
* This file is an attempt at collecting best practice methods for obtaining randomness with different operating systems.
* It may be out-of-date. Consult the documentation of the operating system before considering to use the methods below.
@ -39,12 +42,17 @@
static int fill_random(unsigned char* data, size_t size) {
#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);
#pragma warning( pop )
if (res != STATUS_SUCCESS || size > ULONG_MAX) {
return 0;
} else {
return 1;
}
#elif defined(__linux__) || defined(__FreeBSD__)
/* If `getrandom(2)` is not available you should fallback to /dev/urandom */
ssize_t res = getrandom(data, size, 0);
@ -64,4 +72,6 @@ static int fill_random(unsigned char* data, size_t size) {
}
#endif
return 0;
}
}
#endif /* LIBANTELOPE_LIBSECP256K1_RNG_H */

View file

@ -24,10 +24,10 @@
#include <openssl/ec.h>
#include <openssl/bn.h>
#include <openssl/hmac.h>
#include <libeosio/ec.hpp>
#include <libantelope/ec.hpp>
#include "internal.h"
namespace libeosio {
namespace libantelope {
BN_CTX *ctx = NULL;
EC_KEY *k = NULL;
@ -121,4 +121,4 @@ int ec_generate_key(struct ec_keypair *pair) {
return 0;
}
} // namespace libeosio
} // namespace libantelope

View file

@ -24,10 +24,10 @@
#include <openssl/ec.h>
#include <openssl/bn.h>
#include <openssl/ecdsa.h>
#include <libeosio/ec.hpp>
#include <libantelope/ec.hpp>
#include "internal.h"
namespace libeosio {
namespace libantelope {
extern BN_CTX *ctx;
@ -61,7 +61,7 @@ int ecdsa_sign(const ec_privkey_t& key, const sha256_t* digest, ec_signature_t&
const BIGNUM *r, *s;
EC_KEY* tmpk;
ecdsa_sig = ECDSA_do_sign(digest->data, 32, ec_key);
ecdsa_sig = ECDSA_do_sign((const unsigned char*) digest, 32, ec_key);
if (ecdsa_sig == NULL) {
goto err2;
}
@ -72,7 +72,7 @@ int ecdsa_sign(const ec_privkey_t& key, const sha256_t* digest, ec_signature_t&
tmpk = EC_KEY_new_by_curve_name( NID_secp256k1 );
for (int i = 0; i < 4; i++) {
if (ECDSA_SIG_recover_key_GFp(tmpk, r, s, digest->data, sizeof(digest->data), i, 1) == 1) {
if (ECDSA_SIG_recover_key_GFp(tmpk, r, s, (const unsigned char*) digest, 32, i, 1) == 1) {
const EC_POINT *p = EC_KEY_get0_public_key(tmpk);
// Compare public keys
@ -140,7 +140,7 @@ int ecdsa_verify(const sha256_t* digest, const ec_signature_t& sig, const ec_pub
goto err3;
}
if (ECDSA_do_verify(digest->data, 32, ecdsa_sig, ec_key) == 1) {
if (ECDSA_do_verify((const unsigned char*) digest, 32, ecdsa_sig, ec_key) == 1) {
ret = 0;
}
@ -164,7 +164,7 @@ int ecdsa_recover(const sha256_t* digest, const ec_signature_t& sig, ec_pubkey_t
ECDSA_SIG_unserialize_rs(sig.data(), &r, &s, &recid);
// Recover public key.
if (ECDSA_SIG_recover_key_GFp(ec_key, r, s, digest->data, 32, recid, 1) == 1) {
if (ECDSA_SIG_recover_key_GFp(ec_key, r, s, (const unsigned char*) digest, 32, recid, 1) == 1) {
// Encode point to binary compressed format.
const EC_POINT *p = EC_KEY_get0_public_key(ec_key);
@ -182,4 +182,4 @@ err2: EC_KEY_free(ec_key);
err1: return ret;
}
} // namespace libeosio
} // namespace libantelope

View file

@ -23,21 +23,45 @@
*/
#include <openssl/sha.h>
#include <openssl/ripemd.h>
#include <libeosio/hash.hpp>
#include <libantelope/hash.hpp>
namespace libeosio {
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) {
return (sha256_t *) SHA256(data, len, out->data);
return (sha256_t *) SHA256(data, len, (unsigned char*) out);
}
sha256_t* sha256d(const unsigned char *data, std::size_t len, sha256_t* out) {
SHA256(data, len, out->data);
return (sha256_t *) SHA256(out->data, 32, out->data);
SHA256(data, len, (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) {
return (ripemd160_t *) RIPEMD160(data, len, out->data);
return (ripemd160_t *) RIPEMD160(data, len, (unsigned char*) out);
}
} // namespace libeosio
} // namespace libantelope

View file

@ -24,8 +24,8 @@
#include <openssl/ec.h>
#include <openssl/hmac.h>
#ifndef LIBEOSIO_OPENSSL_INTERNAL_H
#define LIBEOSIO_OPENSSL_INTERNAL_H
#ifndef LIBANTELOPE_OPENSSL_INTERNAL_H
#define LIBANTELOPE_OPENSSL_INTERNAL_H
#define EC_KEY_new_secp256k1() (EC_KEY_new_by_curve_name( NID_secp256k1 ))
@ -62,4 +62,4 @@ int ECDSA_SIG_unserialize_rs(const unsigned char *sig, BIGNUM **r, BIGNUM **s, i
}
#endif
#endif /* LIBEOSIO_OPENSSL_INTERNAL_H */
#endif /* LIBANTELOPE_OPENSSL_INTERNAL_H */

84
src/wif/codec.hpp Normal file
View file

@ -0,0 +1,84 @@
/**
* MIT License
*
* Copyright (c) 2019-2021 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_CODEC_H
#define LIBANTELOPE_CODEC_H
#include <libantelope/WIF.hpp>
#include <vector>
namespace libantelope { namespace internal {
/**
* Public-key encoders
*/
typedef void (*pub_encoder_t)(const ec_pubkey_t& key, unsigned char *buf);
void pub_encoder_legacy(const ec_pubkey_t& key, unsigned char *buf);
void pub_encoder_k1(const ec_pubkey_t& key, unsigned char *buf);
/**
* Public-key decoders
*/
typedef bool (*pub_decoder_t)(const std::vector<unsigned char>& buf, ec_pubkey_t& key);
bool pub_decoder_legacy(const std::vector<unsigned char>& buf, ec_pubkey_t& key);
bool pub_decoder_k1(const std::vector<unsigned char>& buf, ec_pubkey_t& key);
/**
* Private-key encoders
*/
typedef size_t (*priv_encoder_t)(const ec_privkey_t&, unsigned char *);
size_t priv_encoder_legacy(const ec_privkey_t& priv, unsigned char *buf);
size_t priv_encoder_k1(const ec_privkey_t& priv, unsigned char *buf);
/**
* Private-key decoders
*/
typedef bool (*priv_decoder_t)(const std::vector<unsigned char>&, ec_privkey_t&);
bool priv_decoder_legacy(const std::vector<unsigned char>& buf, ec_privkey_t& priv);
bool priv_decoder_k1(const std::vector<unsigned char>& buf, ec_privkey_t& priv);
/**
* Signature encoders
*/
typedef void (*sig_encoder_t)(const ec_signature_t& sig, unsigned char *buf);
void sig_encoder_k1(const ec_signature_t& sig, unsigned char *buf);
/**
* Signature decoders
*/
typedef bool (*sig_decoder_t)(const std::vector<unsigned char>& buf, ec_signature_t& sig);
bool sig_decoder_k1(const std::vector<unsigned char>& buf, ec_signature_t& sig);
}} // namespace libantelope::internal
#endif /* LIBANTELOPE_CODEC_H */

129
src/wif/k1.cpp Normal file
View file

@ -0,0 +1,129 @@
/**
* MIT License
*
* Copyright (c) 2019-2021 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 <libantelope/checksum.hpp>
#include <libantelope/hash/ripemd160.hpp>
#include "codec.hpp"
namespace libantelope { namespace internal {
// 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.
// So this function is a quick hack to calculate it.
void _checksum_suffix(const unsigned char *in, size_t size, checksum_t check) {
ripemd160_ctx_t ctx;
ripemd160_t md;
ripemd160_init(&ctx);
ripemd160_update(&ctx, in, size);
ripemd160_update(&ctx, "K1", 2);
ripemd160_final(&ctx, &md);
std::memcpy(check, md, CHECKSUM_SIZE);
}
void pub_encoder_k1(const ec_pubkey_t& key, unsigned char *buf) {
checksum_t check;
_checksum_suffix(key.data(), EC_PUBKEY_SIZE, check);
memcpy(buf, key.data(), EC_PUBKEY_SIZE);
memcpy(buf + EC_PUBKEY_SIZE, check, CHECKSUM_SIZE);
}
bool pub_decoder_k1(const std::vector<unsigned char>& buf, ec_pubkey_t& key) {
checksum_t check;
_checksum_suffix(buf.data(), EC_PUBKEY_SIZE, check);
if (memcmp(buf.data() + EC_PUBKEY_SIZE, check, CHECKSUM_SIZE)) {
return false;
}
memcpy(key.data(), buf.data(), EC_PUBKEY_SIZE);
return true;
}
size_t priv_encoder_k1(const ec_privkey_t& priv, unsigned char *buf) {
checksum_t check;
_checksum_suffix(priv.data(), EC_PRIVKEY_SIZE, check);
memcpy(buf, priv.data(), priv.size());
memcpy(buf + EC_PRIVKEY_SIZE, check, CHECKSUM_SIZE);
return EC_PRIVKEY_SIZE + CHECKSUM_SIZE;
}
bool priv_decoder_k1(const std::vector<unsigned char>& buf, ec_privkey_t& priv) {
if (buf.size() != EC_PRIVKEY_SIZE + CHECKSUM_SIZE) {
return false;
}
checksum_t check;
_checksum_suffix(buf.data(), EC_PRIVKEY_SIZE, check);
if (memcmp(buf.data() + EC_PRIVKEY_SIZE, check, CHECKSUM_SIZE)) {
return false;
}
memcpy(priv.data(), buf.data(), priv.size());
return true;
}
void sig_encoder_k1(const ec_signature_t& sig, unsigned char *buf) {
checksum_t check;
_checksum_suffix(sig.data(), EC_SIGNATURE_SIZE, check);
memcpy(buf, sig.data(), sig.size());
memcpy(buf + EC_SIGNATURE_SIZE, check, CHECKSUM_SIZE);
}
bool sig_decoder_k1(const std::vector<unsigned char>& buf, ec_signature_t& sig) {
checksum_t check;
if (buf.size() != EC_SIGNATURE_SIZE + CHECKSUM_SIZE) {
return false;
}
// Calculate checksum
_checksum_suffix(buf.data(), EC_SIGNATURE_SIZE, check);
// And validate
if (memcmp(buf.data() + EC_SIGNATURE_SIZE, check, CHECKSUM_SIZE)) {
return false;
}
// Copy data to output
memcpy(sig.data(), buf.data(), sig.size());
return true;
}
}} // namespace libantelope::internal

80
src/wif/legacy.cpp Normal file
View file

@ -0,0 +1,80 @@
/**
* MIT License
*
* Copyright (c) 2019-2021 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 <libantelope/checksum.hpp>
#include "codec.hpp"
namespace libantelope { namespace internal {
#define PRIV_KEY_PREFIX 0x80 /* 0x80 for "Bitcoin mainnet". Always used by EOS. */
void pub_encoder_legacy(const ec_pubkey_t& key, unsigned char *buf) {
checksum_t check;
checksum_ripemd160(key.data(), EC_PUBKEY_SIZE, check);
memcpy(buf, key.data(), EC_PUBKEY_SIZE);
memcpy(buf + EC_PUBKEY_SIZE, check, CHECKSUM_SIZE);
}
bool pub_decoder_legacy(const std::vector<unsigned char>& buf, ec_pubkey_t& key) {
if (!checksum_validate<checksum_ripemd160>(buf.data(), buf.size())) {
return false;
}
memcpy(key.data(), buf.data(), EC_PUBKEY_SIZE);
return true;
}
size_t priv_encoder_legacy(const ec_privkey_t& priv, unsigned char *buf) {
checksum_t check;
buf[0] = PRIV_KEY_PREFIX;
memcpy(buf + 1, priv.data(), EC_PRIVKEY_SIZE);
checksum_sha256d(buf, 1 + EC_PRIVKEY_SIZE, check);
memcpy(buf + 1 + EC_PRIVKEY_SIZE, check, CHECKSUM_SIZE);
return 1 + EC_PRIVKEY_SIZE + CHECKSUM_SIZE;
}
bool priv_decoder_legacy(const std::vector<unsigned char>& buf, ec_privkey_t& priv) {
if (buf[0] != PRIV_KEY_PREFIX) {
return false;
}
if (buf.size() != 1 + EC_PRIVKEY_SIZE + CHECKSUM_SIZE) {
return false;
}
if (!checksum_validate<checksum_sha256d>(buf.data(), buf.size())) {
return false;
}
memcpy(priv.data(), buf.data() + 1, priv.size());
return true;
}
}} // namespace libantelope::internal

View file

@ -1,7 +1,13 @@
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/doctest.cmake)
set(TEST_SRC
main.cpp
# hash
hash/sha256.cpp
hash/ripemd160.cpp
# ec
ec/generate.cpp
ec/pubkey.cpp
@ -26,10 +32,7 @@ add_executable(doctest ${TEST_SRC})
target_link_libraries(doctest PRIVATE ${LIB_NAME})
target_include_directories(doctest PRIVATE ${CMAKE_CURRENT_LIST_DIR}/include)
add_test(
NAME doctest
COMMAND $<TARGET_FILE:doctest> -ni -fc
)
doctest_discover_tests(doctest)
if (WITH_BENCHMARK)
add_subdirectory( benchmark )

View file

@ -1,14 +1,14 @@
#include <libeosio/WIF.hpp>
#include <libeosio/ec.hpp>
#include <libantelope/WIF.hpp>
#include <libantelope/ec.hpp>
#include <iostream>
#include <vector>
#include <doctest.h>
TEST_CASE("WIF::wif_priv_decode") {
TEST_CASE("WIF::wif_priv_decode [legacy]") {
struct testcase {
std::string name;
std::string key;
libeosio::ec_privkey_t expected;
libantelope::ec_privkey_t expected;
};
@ -22,9 +22,36 @@ TEST_CASE("WIF::wif_priv_decode") {
SUBCASE(it->name.c_str()) {
libeosio::ec_privkey_t result;
libantelope::ec_privkey_t result;
CHECK( libeosio::wif_priv_decode(result, it->key) );
CHECK( libantelope::wif_priv_decode(result, it->key) );
CHECK( result == it->expected );
}
}
}
TEST_CASE("WIF::wif_priv_decode [K1]") {
struct testcase {
std::string name;
std::string key;
libantelope::ec_privkey_t expected;
};
std::vector<struct testcase> tests {
{ "one", "PVT_K1_6Mcb23muAxyXaSMhmB6B1mqkvLdWhtuFZmnZsxDczHRvQdp32", { 0x0C, 0x28, 0xFC, 0xA3, 0x86, 0xC7, 0xA2, 0x27, 0x60, 0x0B, 0x2F, 0xE5, 0x0B, 0x7C, 0xAE, 0x11, 0xEC, 0x86, 0xD3, 0xBF, 0x1F, 0xBE, 0x47, 0x1B, 0xE8, 0x98, 0x27, 0xE1, 0x9D, 0x72, 0xAA, 0x1D } },
{ "two", "PVT_K1_2DRBT8jmXT8k9ywNSSbufvhk1hLFhPzWJBpsE2jo12CDoFhcc1", { 0x9F, 0xE3, 0xE3, 0x2B, 0x3C, 0x4B, 0x6B, 0x91, 0x6E, 0x20, 0x6C, 0xB0, 0x91, 0xDF, 0x1F, 0x5E, 0x34, 0x32, 0x88, 0x0B, 0x41, 0x33, 0x86, 0xBD, 0xF2, 0x92, 0xFF, 0x23, 0x06, 0x43, 0xF2, 0x8C } },
{ "three", "PVT_K1_gJCsP4CwMv4gTkDXiZT8QFhs3NrSB7Sv22ANGrc8Svun9uC9C", { 0x59, 0x3A, 0x51, 0xB5, 0x5D, 0x56, 0xAA, 0xF0, 0x5B, 0xD9, 0xD1, 0x0E, 0x6B, 0x88, 0x6D, 0xF9, 0xC4, 0x37, 0x09, 0xB2, 0x4C, 0xEC, 0xBB, 0x63, 0x68, 0x92, 0xC2, 0x94, 0x31, 0x48, 0x71, 0x8C } }
};
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name.c_str()) {
libantelope::ec_privkey_t result;
CHECK( libantelope::wif_priv_decode(result, it->key) );
CHECK( result == it->expected );
}
}

View file

@ -1,27 +1,51 @@
#include <libeosio/WIF.hpp>
#include <libeosio/ec.hpp>
#include <libantelope/WIF.hpp>
#include <libantelope/ec.hpp>
#include <iostream>
#include <vector>
#include <doctest.h>
TEST_CASE("WIF::wif_priv_encode") {
TEST_CASE("WIF::wif_priv_encode [Legacy]") {
struct testcase {
std::string name;
libeosio::ec_privkey_t key;
const std::string prefix;
libantelope::ec_privkey_t key;
std::string expected;
};
std::vector<struct testcase> tests {
{ "one", { 0x0C, 0x28, 0xFC, 0xA3, 0x86, 0xC7, 0xA2, 0x27, 0x60, 0x0B, 0x2F, 0xE5, 0x0B, 0x7C, 0xAE, 0x11, 0xEC, 0x86, 0xD3, 0xBF, 0x1F, 0xBE, 0x47, 0x1B, 0xE8, 0x98, 0x27, 0xE1, 0x9D,0x72,0xAA,0x1D}, "5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ" },
{ "two", { 0x9F, 0xE3, 0xE3, 0x2B, 0x3C, 0x4B, 0x6B, 0x91, 0x6E, 0x20, 0x6C, 0xB0, 0x91, 0xDF, 0x1F, 0x5E, 0x34, 0x32, 0x88, 0x0B, 0x41, 0x33, 0x86, 0xBD, 0xF2, 0x92, 0xFF, 0x23, 0x06, 0x43, 0xF2, 0x8C}, "5K2hm8apqz281ANDQdtVzifpxcXFTqG5E7Fc6Q5V2ssqPRQ3urJ" },
{ "three", { 0x59, 0x3A, 0x51, 0xB5, 0x5D, 0x56, 0xAA, 0xF0, 0x5B, 0xD9, 0xD1, 0x0E, 0x6B, 0x88, 0x6D, 0xF9, 0xC4, 0x37, 0x09, 0xB2, 0x4C, 0xEC, 0xBB, 0x63, 0x68, 0x92, 0xC2, 0x94, 0x31, 0x48, 0x71, 0x8C}, "5JVanYq9HPvuKgr2FjATYB9NvTsJ4a3CAj5oPYKbr1Ja5MRLsZX" }
{ "one", libantelope::WIF_PVT_LEG, { 0x0C, 0x28, 0xFC, 0xA3, 0x86, 0xC7, 0xA2, 0x27, 0x60, 0x0B, 0x2F, 0xE5, 0x0B, 0x7C, 0xAE, 0x11, 0xEC, 0x86, 0xD3, 0xBF, 0x1F, 0xBE, 0x47, 0x1B, 0xE8, 0x98, 0x27, 0xE1, 0x9D,0x72,0xAA,0x1D}, "5HueCGU8rMjxEXxiPuD5BDku4MkFqeZyd4dZ1jvhTVqvbTLvyTJ" },
{ "two", libantelope::WIF_PVT_LEG, { 0x9F, 0xE3, 0xE3, 0x2B, 0x3C, 0x4B, 0x6B, 0x91, 0x6E, 0x20, 0x6C, 0xB0, 0x91, 0xDF, 0x1F, 0x5E, 0x34, 0x32, 0x88, 0x0B, 0x41, 0x33, 0x86, 0xBD, 0xF2, 0x92, 0xFF, 0x23, 0x06, 0x43, 0xF2, 0x8C}, "5K2hm8apqz281ANDQdtVzifpxcXFTqG5E7Fc6Q5V2ssqPRQ3urJ" },
{ "three", libantelope::WIF_PVT_LEG, { 0x59, 0x3A, 0x51, 0xB5, 0x5D, 0x56, 0xAA, 0xF0, 0x5B, 0xD9, 0xD1, 0x0E, 0x6B, 0x88, 0x6D, 0xF9, 0xC4, 0x37, 0x09, 0xB2, 0x4C, 0xEC, 0xBB, 0x63, 0x68, 0x92, 0xC2, 0x94, 0x31, 0x48, 0x71, 0x8C}, "5JVanYq9HPvuKgr2FjATYB9NvTsJ4a3CAj5oPYKbr1Ja5MRLsZX" }
};
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name.c_str()) {
CHECK( libeosio::wif_priv_encode(it->key) == it->expected );
CHECK( libantelope::wif_priv_encode(it->key, it->prefix) == it->expected );
}
}
}
TEST_CASE("WIF::wif_priv_encode [K1]") {
struct testcase {
std::string name;
const std::string prefix;
libantelope::ec_privkey_t key;
std::string expected;
};
std::vector<struct testcase> tests {
{ "one", libantelope::WIF_PVT_K1, { 0x0C, 0x28, 0xFC, 0xA3, 0x86, 0xC7, 0xA2, 0x27, 0x60, 0x0B, 0x2F, 0xE5, 0x0B, 0x7C, 0xAE, 0x11, 0xEC, 0x86, 0xD3, 0xBF, 0x1F, 0xBE, 0x47, 0x1B, 0xE8, 0x98, 0x27, 0xE1, 0x9D,0x72,0xAA,0x1D}, "PVT_K1_6Mcb23muAxyXaSMhmB6B1mqkvLdWhtuFZmnZsxDczHRvQdp32" },
{ "two", libantelope::WIF_PVT_K1, { 0x9F, 0xE3, 0xE3, 0x2B, 0x3C, 0x4B, 0x6B, 0x91, 0x6E, 0x20, 0x6C, 0xB0, 0x91, 0xDF, 0x1F, 0x5E, 0x34, 0x32, 0x88, 0x0B, 0x41, 0x33, 0x86, 0xBD, 0xF2, 0x92, 0xFF, 0x23, 0x06, 0x43, 0xF2, 0x8C}, "PVT_K1_2DRBT8jmXT8k9ywNSSbufvhk1hLFhPzWJBpsE2jo12CDoFhcc1" },
{ "three", libantelope::WIF_PVT_K1, { 0x59, 0x3A, 0x51, 0xB5, 0x5D, 0x56, 0xAA, 0xF0, 0x5B, 0xD9, 0xD1, 0x0E, 0x6B, 0x88, 0x6D, 0xF9, 0xC4, 0x37, 0x09, 0xB2, 0x4C, 0xEC, 0xBB, 0x63, 0x68, 0x92, 0xC2, 0x94, 0x31, 0x48, 0x71, 0x8C}, "PVT_K1_gJCsP4CwMv4gTkDXiZT8QFhs3NrSB7Sv22ANGrc8Svun9uC9C" }
};
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name.c_str()) {
CHECK( libantelope::wif_priv_encode(it->key, it->prefix) == it->expected );
}
}
}

View file

@ -1,14 +1,14 @@
#include <libeosio/WIF.hpp>
#include <libeosio/ec.hpp>
#include <libantelope/WIF.hpp>
#include <libantelope/ec.hpp>
#include <iostream>
#include <vector>
#include <doctest.h>
TEST_CASE("WIF::wif_pub_encode") {
TEST_CASE("WIF::wif_pub_decode [legacy]") {
struct testcase {
const char* name;
std::string key;
libeosio::ec_pubkey_t expected;
libantelope::ec_pubkey_t expected;
bool expectedRet;
};
@ -24,9 +24,37 @@ TEST_CASE("WIF::wif_pub_encode") {
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name) {
libeosio::ec_pubkey_t result = { 0x0 };
libantelope::ec_pubkey_t result = { 0x0 };
CHECK( libeosio::wif_pub_decode(result, it->key) == it->expectedRet );
CHECK( libantelope::wif_pub_decode(result, it->key) == it->expectedRet );
CHECK( result == it->expected );
}
}
}
TEST_CASE("WIF::wif_pub_decode [k1]") {
struct testcase {
const char* name;
std::string key;
libantelope::ec_pubkey_t expected;
bool expectedRet;
};
std::vector<struct testcase> tests {
{ "one", "PUB_K1_7kzJ5iFBmQWWT1LiWgAiocESD7TTNuuPCdYREUQysruq7AxzWu", { 0x03, 0x7a, 0x0e, 0x6b, 0xfd, 0xe4, 0xf1, 0xad, 0x36, 0x3f, 0x3a, 0xf9, 0xe0, 0x93, 0x63, 0x5a, 0xa9, 0x99, 0x21, 0x15, 0xbc, 0x23, 0x35, 0x75, 0x13, 0x69, 0x55, 0xee, 0x3f, 0xf8, 0xfd, 0x97, 0xec }, true },
{ "two", "PUB_K1_5c9HkNCJLDebe2Wvapp8bpB38Pf1QWNpkrsFy3mshg7DViSUUa", { 0x02, 0x5e, 0x94, 0xa5, 0xe7, 0x9f, 0x66, 0x37, 0x55, 0x7e, 0xc2, 0x28, 0x30, 0x40, 0x82, 0x9a, 0x38, 0x72, 0x10, 0x96, 0x6e, 0x15, 0xb7, 0xa5, 0x8a, 0x27, 0x9a, 0x71, 0x06, 0xa7, 0x64, 0x23, 0x30 }, true },
{ "three", "PUB_K1_8SwZMY8DChbbmRKS3wdHCAbv1VWgTRmQEDSaLyJk8pG4wKBXpw", { 0x03, 0xd4, 0xc6, 0x2a, 0xdc, 0x11, 0x1c, 0x65, 0x7a, 0x9f, 0x5b, 0xba, 0x96, 0x3f, 0xbb, 0x2a, 0x69, 0x2e, 0xc5, 0x4a, 0x48, 0x3b, 0xa3, 0x5f, 0x2a, 0x37, 0x6c, 0x59, 0x95, 0xb1, 0x95, 0x1c, 0xc9 }, true },
{ "wrong_checksum", "PUB_K1_8SwZMY8DChbbmRKS3wdHCAbv1VWgTRmQEDSaLyJk8pG4wKBXgE", { 0x0 }, false },
{ "wrong_length", "PUB_K1_7kzJ5iFBmQWWT1LiWgAiocESD7TT", { 0x0 }, false },
{ "not_base58", "PUB_K1_7IIIIIOOOO", { 0x0 }, false }
};
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name) {
libantelope::ec_pubkey_t result = { 0x0 };
CHECK( libantelope::wif_pub_decode(result, it->key) == it->expectedRet );
CHECK( result == it->expected );
}
}

View file

@ -1,36 +1,36 @@
#include <libeosio/WIF.hpp>
#include <libeosio/ec.hpp>
#include <libantelope/WIF.hpp>
#include <libantelope/ec.hpp>
#include <iostream>
#include <vector>
#include <doctest.h>
TEST_CASE("WIF::wif_pub_encode") {
TEST_CASE("WIF::wif_pub_encode [legacy]") {
struct testcase {
std::string name;
libeosio::ec_pubkey_t key;
const std::string prefix;
libantelope::ec_pubkey_t key;
std::string expected;
};
std::vector<struct testcase> tests {
{ "one", { 0x03, 0x7a, 0x0e, 0x6b, 0xfd, 0xe4, 0xf1, 0xad, 0x36, 0x3f, 0x3a, 0xf9, 0xe0, 0x93, 0x63, 0x5a, 0xa9, 0x99, 0x21, 0x15, 0xbc, 0x23, 0x35, 0x75, 0x13, 0x69, 0x55, 0xee, 0x3f, 0xf8, 0xfd, 0x97, 0xec }, "EOS7kzJ5iFBmQWWT1LiWgAiocESD7TTNuuPCdYREUQysruq8VeFKy" },
{ "two", { 0x02, 0x5e, 0x94, 0xa5, 0xe7, 0x9f, 0x66, 0x37, 0x55, 0x7e, 0xc2, 0x28, 0x30, 0x40, 0x82, 0x9a, 0x38, 0x72, 0x10, 0x96, 0x6e, 0x15, 0xb7, 0xa5, 0x8a, 0x27, 0x9a, 0x71, 0x06, 0xa7, 0x64, 0x23, 0x30 }, "EOS5c9HkNCJLDebe2Wvapp8bpB38Pf1QWNpkrsFy3mshg7DZfPNeA" },
{ "three", { 0x03, 0xd4, 0xc6, 0x2a, 0xdc, 0x11, 0x1c, 0x65, 0x7a, 0x9f, 0x5b, 0xba, 0x96, 0x3f, 0xbb, 0x2a, 0x69, 0x2e, 0xc5, 0x4a, 0x48, 0x3b, 0xa3, 0x5f, 0x2a, 0x37, 0x6c, 0x59, 0x95, 0xb1, 0x95, 0x1c, 0xc9 }, "EOS8SwZMY8DChbbmRKS3wdHCAbv1VWgTRmQEDSaLyJk8pG4wm8BJF" }
{ "one", libantelope::WIF_PUB_LEG, { 0x03, 0x7a, 0x0e, 0x6b, 0xfd, 0xe4, 0xf1, 0xad, 0x36, 0x3f, 0x3a, 0xf9, 0xe0, 0x93, 0x63, 0x5a, 0xa9, 0x99, 0x21, 0x15, 0xbc, 0x23, 0x35, 0x75, 0x13, 0x69, 0x55, 0xee, 0x3f, 0xf8, 0xfd, 0x97, 0xec }, "EOS7kzJ5iFBmQWWT1LiWgAiocESD7TTNuuPCdYREUQysruq8VeFKy" },
{ "two", libantelope::WIF_PUB_LEG, { 0x02, 0x5e, 0x94, 0xa5, 0xe7, 0x9f, 0x66, 0x37, 0x55, 0x7e, 0xc2, 0x28, 0x30, 0x40, 0x82, 0x9a, 0x38, 0x72, 0x10, 0x96, 0x6e, 0x15, 0xb7, 0xa5, 0x8a, 0x27, 0x9a, 0x71, 0x06, 0xa7, 0x64, 0x23, 0x30 }, "EOS5c9HkNCJLDebe2Wvapp8bpB38Pf1QWNpkrsFy3mshg7DZfPNeA" },
{ "three", libantelope::WIF_PUB_LEG, { 0x03, 0xd4, 0xc6, 0x2a, 0xdc, 0x11, 0x1c, 0x65, 0x7a, 0x9f, 0x5b, 0xba, 0x96, 0x3f, 0xbb, 0x2a, 0x69, 0x2e, 0xc5, 0x4a, 0x48, 0x3b, 0xa3, 0x5f, 0x2a, 0x37, 0x6c, 0x59, 0x95, 0xb1, 0x95, 0x1c, 0xc9 }, "EOS8SwZMY8DChbbmRKS3wdHCAbv1VWgTRmQEDSaLyJk8pG4wm8BJF" }
};
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name.c_str()) {
CHECK( libeosio::wif_pub_encode(it->key) == it->expected );
CHECK( libantelope::wif_pub_encode(it->key, it->prefix) == it->expected );
}
}
}
TEST_CASE("WIF::wif_pub_encode [prefix]") {
TEST_CASE("WIF::wif_pub_encode [custom prefix]") {
struct testcase {
std::string name;
libeosio::ec_pubkey_t key;
libantelope::ec_pubkey_t key;
std::string expected;
};
@ -43,7 +43,29 @@ TEST_CASE("WIF::wif_pub_encode [prefix]") {
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name.c_str()) {
CHECK( libeosio::wif_pub_encode(it->key, "ZYX") == it->expected );
CHECK( libantelope::wif_pub_encode(it->key, "ZYX") == it->expected );
}
}
}
TEST_CASE("WIF::wif_pub_encode [k1]") {
struct testcase {
std::string name;
const std::string prefix;
libantelope::ec_pubkey_t key;
std::string expected;
};
std::vector<struct testcase> tests {
{ "one", libantelope::WIF_PUB_K1, { 0x03, 0x7a, 0x0e, 0x6b, 0xfd, 0xe4, 0xf1, 0xad, 0x36, 0x3f, 0x3a, 0xf9, 0xe0, 0x93, 0x63, 0x5a, 0xa9, 0x99, 0x21, 0x15, 0xbc, 0x23, 0x35, 0x75, 0x13, 0x69, 0x55, 0xee, 0x3f, 0xf8, 0xfd, 0x97, 0xec }, "PUB_K1_7kzJ5iFBmQWWT1LiWgAiocESD7TTNuuPCdYREUQysruq7AxzWu" },
{ "two", libantelope::WIF_PUB_K1, { 0x02, 0x5e, 0x94, 0xa5, 0xe7, 0x9f, 0x66, 0x37, 0x55, 0x7e, 0xc2, 0x28, 0x30, 0x40, 0x82, 0x9a, 0x38, 0x72, 0x10, 0x96, 0x6e, 0x15, 0xb7, 0xa5, 0x8a, 0x27, 0x9a, 0x71, 0x06, 0xa7, 0x64, 0x23, 0x30 }, "PUB_K1_5c9HkNCJLDebe2Wvapp8bpB38Pf1QWNpkrsFy3mshg7DViSUUa" },
{ "three", libantelope::WIF_PUB_K1, { 0x03, 0xd4, 0xc6, 0x2a, 0xdc, 0x11, 0x1c, 0x65, 0x7a, 0x9f, 0x5b, 0xba, 0x96, 0x3f, 0xbb, 0x2a, 0x69, 0x2e, 0xc5, 0x4a, 0x48, 0x3b, 0xa3, 0x5f, 0x2a, 0x37, 0x6c, 0x59, 0x95, 0xb1, 0x95, 0x1c, 0xc9 }, "PUB_K1_8SwZMY8DChbbmRKS3wdHCAbv1VWgTRmQEDSaLyJk8pG4wKBXpw" }
};
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name.c_str()) {
CHECK( libantelope::wif_pub_encode(it->key, it->prefix) == it->expected );
}
}
}

View file

@ -1,5 +1,5 @@
#include <libeosio/WIF.hpp>
#include <libeosio/ec.hpp>
#include <libantelope/WIF.hpp>
#include <libantelope/ec.hpp>
#include <vector>
#include <doctest.h>
@ -8,7 +8,7 @@ TEST_CASE("WIF::wif_sig_decode") {
struct testcase {
const char *name;
std::string input;
libeosio::ec_signature_t expected;
libantelope::ec_signature_t expected;
bool expectedRet;
};
@ -87,9 +87,9 @@ TEST_CASE("WIF::wif_sig_decode") {
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name) {
libeosio::ec_signature_t result;
libantelope::ec_signature_t result;
CHECK( libeosio::wif_sig_decode(result, it->input) == it->expectedRet );
CHECK( libantelope::wif_sig_decode(result, it->input) == it->expectedRet );
if (it->expectedRet == true) {
CHECK( result == it->expected );

View file

@ -1,5 +1,5 @@
#include <libeosio/WIF.hpp>
#include <libeosio/ec.hpp>
#include <libantelope/WIF.hpp>
#include <libantelope/ec.hpp>
#include <vector>
#include <doctest.h>
@ -7,7 +7,7 @@ TEST_CASE("WIF::wif_sig_encode") {
struct testcase {
const char *name;
libeosio::ec_signature_t sig;
libantelope::ec_signature_t sig;
std::string expected;
};
@ -47,7 +47,7 @@ TEST_CASE("WIF::wif_sig_encode") {
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name) {
CHECK( libeosio::wif_sig_encode(it->sig) == it->expected );
CHECK( libantelope::wif_sig_encode(it->sig) == it->expected );
}
}
}

View file

@ -1,4 +1,4 @@
#include <libeosio/base58.hpp>
#include <libantelope/base58.hpp>
#include <iostream>
#include <vector>
#include <doctest.h>
@ -41,7 +41,7 @@ TEST_CASE("base58_decode") {
std::vector<unsigned char> expectedOut(it->expectedOut.begin(), it->expectedOut.end());
CHECK( libeosio::base58_decode(it->in, result) == it->expectedReturn );
CHECK( libantelope::base58_decode(it->in, result) == it->expectedReturn );
CHECK( result == expectedOut );
}
}

View file

@ -1,4 +1,4 @@
#include <libeosio/base58.hpp>
#include <libantelope/base58.hpp>
#include <iostream>
#include <vector>
#include <doctest.h>
@ -28,7 +28,7 @@ TEST_CASE("base58::base58_encode") {
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name) {
CHECK( libeosio::base58_encode(it->in) == it->expected );
CHECK( libantelope::base58_encode(it->in) == it->expected );
}
}
}

View file

@ -1,4 +1,4 @@
#include <libeosio/base58.hpp>
#include <libantelope/base58.hpp>
#include <iostream>
#include <vector>
#include <doctest.h>
@ -23,7 +23,7 @@ TEST_CASE("base58::is_base58 [string]") {
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name) {
CHECK(libeosio::is_base58(it->input) == it->expected);
CHECK(libantelope::is_base58(it->input) == it->expected);
}
}
@ -35,18 +35,18 @@ TEST_CASE("base58::is_base58 [char]") {
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];
CHECK(libeosio::is_base58(ch));
CHECK(libantelope::is_base58(ch));
}
}
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];
CHECK_FALSE(libeosio::is_base58(ch));
CHECK_FALSE(libantelope::is_base58(ch));
}
}
}

View file

@ -22,15 +22,15 @@
* SOFTWARE.
*/
#include <chrono>
#include <libeosio/ec.hpp>
#include <libeosio/WIF.hpp>
#include <libantelope/ec.hpp>
#include <libantelope/WIF.hpp>
std::chrono::duration<float> _run(size_t num_keys) {
auto start = std::chrono::steady_clock::now();
for(size_t i = 0; i < num_keys; i++) {
struct libeosio::ec_keypair k;
libeosio::ec_generate_key(&k);
struct libantelope::ec_keypair k;
libantelope::ec_generate_key(&k);
}
return std::chrono::steady_clock::now() - start;
}
@ -48,13 +48,13 @@ void test(size_t num_keys) {
}
int main() {
libeosio::ec_init();
libantelope::ec_init();
test(1000);
test(10000);
test(100000);
libeosio::ec_shutdown();
libantelope::ec_shutdown();
return 0;
}

189
tests/cmake/doctest.cmake Normal file
View 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
)

View 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}")

View file

@ -1,4 +1,4 @@
#include <libeosio/ec.hpp>
#include <libantelope/ec.hpp>
#include <vector>
#include <doctest.h>
@ -6,9 +6,9 @@ TEST_CASE("ec::ecdsa_recover") {
struct testcase {
const char *name;
libeosio::sha256_t dgst;
libeosio::ec_signature_t sig;
libeosio::ec_pubkey_t expected;
libantelope::sha256_t dgst;
libantelope::ec_signature_t sig;
libantelope::ec_pubkey_t expected;
int expectedRet;
};
@ -16,12 +16,10 @@ TEST_CASE("ec::ecdsa_recover") {
{
"valid #1",
{
{
0xab, 0x53, 0x0a, 0x13, 0xe4, 0x59, 0x14, 0x98,
0x2b, 0x79, 0xf9, 0xb7, 0xe3, 0xfb, 0xa9, 0x94,
0xcf, 0xd1, 0xf3, 0xfb, 0x22, 0xf7, 0x1c, 0xea,
0x1a, 0xfb, 0xf0, 0x2b, 0x46, 0x0c, 0x6d, 0x1d
},
0xab, 0x53, 0x0a, 0x13, 0xe4, 0x59, 0x14, 0x98,
0x2b, 0x79, 0xf9, 0xb7, 0xe3, 0xfb, 0xa9, 0x94,
0xcf, 0xd1, 0xf3, 0xfb, 0x22, 0xf7, 0x1c, 0xea,
0x1a, 0xfb, 0xf0, 0x2b, 0x46, 0x0c, 0x6d, 0x1d
},
// SIG_K1_KdgBih1poWj8DYZXwLxMdjaHMzYhuAVp7XshR9ZjrZSubZwsgSpiyUKXu44NmCtKgRFswmqKaioWLTuGZrXwYPsSNCSyyr
{
@ -36,12 +34,10 @@ TEST_CASE("ec::ecdsa_recover") {
{
"valid #2",
{
{
0x19, 0xd3, 0xe0, 0x8b, 0xbb, 0xad, 0x5f, 0x02,
0x35, 0xa8, 0xa8, 0xf8, 0x1a, 0x7f, 0xa1, 0xe0,
0xf8, 0x50, 0xdd, 0x39, 0x12, 0xe3, 0xc6, 0x55,
0xb4, 0x35, 0xd4, 0x78, 0x6b, 0x93, 0x64, 0xa6
},
0x19, 0xd3, 0xe0, 0x8b, 0xbb, 0xad, 0x5f, 0x02,
0x35, 0xa8, 0xa8, 0xf8, 0x1a, 0x7f, 0xa1, 0xe0,
0xf8, 0x50, 0xdd, 0x39, 0x12, 0xe3, 0xc6, 0x55,
0xb4, 0x35, 0xd4, 0x78, 0x6b, 0x93, 0x64, 0xa6
},
// SIG_K1_K4XXx6oSYBzcwzscMstvSxruxdkTCinyN9dnRo4DuBkCCpQbCJQcJmbE7aAmNueBYCccHyyDK5JDfMpvewRF2rGUFtSE2y
{
@ -56,12 +52,10 @@ TEST_CASE("ec::ecdsa_recover") {
{
"valid #3",
{
{
0x1b, 0x01, 0x0b, 0xe5, 0xce, 0x6a, 0x49, 0xc7,
0xcd, 0x04, 0x86, 0x0d, 0xef, 0x63, 0x1c, 0x6a,
0xcc, 0xd5, 0x17, 0x47, 0x2e, 0x74, 0x5b, 0xa6,
0xc8, 0xaf, 0x26, 0x1b, 0x15, 0x7e, 0x11, 0xec
},
0x1b, 0x01, 0x0b, 0xe5, 0xce, 0x6a, 0x49, 0xc7,
0xcd, 0x04, 0x86, 0x0d, 0xef, 0x63, 0x1c, 0x6a,
0xcc, 0xd5, 0x17, 0x47, 0x2e, 0x74, 0x5b, 0xa6,
0xc8, 0xaf, 0x26, 0x1b, 0x15, 0x7e, 0x11, 0xec
},
// SIG_K1_K54CVeQjFREm9Z92jutWESZWb9WQfCRZ2KfMtisfsnxedppeSMxTrZ9fYDLiJTfE79zvLCHb5NysAEcNdh7HiBvtU4Ahhh
{
@ -76,12 +70,10 @@ TEST_CASE("ec::ecdsa_recover") {
{
"not valid #1 (non valid signature)",
{
{
0xde, 0x01, 0x64, 0x03, 0x39, 0x01, 0x66, 0x8b,
0xa0, 0x39, 0xef, 0x31, 0x61, 0xc7, 0xc8, 0x9d,
0x15, 0x4b, 0xc6, 0x7b, 0x99, 0x5c, 0xba, 0x9b,
0x23, 0x8a, 0x76, 0x4b, 0x81, 0xf2, 0xff, 0xeb
},
0xde, 0x01, 0x64, 0x03, 0x39, 0x01, 0x66, 0x8b,
0xa0, 0x39, 0xef, 0x31, 0x61, 0xc7, 0xc8, 0x9d,
0x15, 0x4b, 0xc6, 0x7b, 0x99, 0x5c, 0xba, 0x9b,
0x23, 0x8a, 0x76, 0x4b, 0x81, 0xf2, 0xff, 0xeb
},
{
0x1f, 0x4b, 0xe9, 0x04, 0x20, 0xfa, 0x7b, 0x9d, 0x56, 0xc6, 0x00, 0x5c, 0x83, 0x70, 0xa9, 0x26, 0x41, 0x7d, 0xe8, 0xeb, 0xe7, 0x75, 0xea, 0x6f, 0x75, 0xa7, 0x7c, 0x98, 0x10, 0x27, 0xbf, 0xce,
@ -93,19 +85,19 @@ TEST_CASE("ec::ecdsa_recover") {
},
};
libeosio::ec_init();
libantelope::ec_init();
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name) {
libeosio::ec_pubkey_t result;
libantelope::ec_pubkey_t result;
CHECK( libeosio::ecdsa_recover(&it->dgst, it->sig, result) == it->expectedRet );
CHECK( libantelope::ecdsa_recover(&it->dgst, it->sig, result) == it->expectedRet );
if (it->expectedRet == 0) {
CHECK( result == it->expected );
}
}
}
libeosio::ec_shutdown();
libantelope::ec_shutdown();
}

View file

@ -1,4 +1,4 @@
#include <libeosio/ec.hpp>
#include <libantelope/ec.hpp>
#include <vector>
#include <doctest.h>
@ -6,9 +6,9 @@ TEST_CASE("ec::ecdsa_sign") {
struct testcase {
const char *name;
libeosio::ec_privkey_t key;
libeosio::ec_pubkey_t pub;
libeosio::sha256_t dgst;
libantelope::ec_privkey_t key;
libantelope::ec_pubkey_t pub;
libantelope::sha256_t dgst;
};
std::vector<testcase> tests = {
@ -19,12 +19,10 @@ TEST_CASE("ec::ecdsa_sign") {
// Public key: EOS6zjfj9Xjk9CYoucZDptdDZ6317eZd622pVvaYtv5q6gwEs9icD
{ 0x03, 0x15, 0x93, 0x8a, 0x8e, 0x1d, 0x57, 0x84, 0x9f, 0xab, 0x07, 0x18, 0x67, 0xb5, 0x0c, 0xda, 0xb0, 0x77, 0x62, 0x29, 0xb6, 0x43, 0xb8, 0x67, 0x56, 0xc7, 0xb3, 0xe8, 0x7f, 0xe6, 0x08, 0xf8, 0x4b },
{
{
0xab, 0x53, 0x0a, 0x13, 0xe4, 0x59, 0x14, 0x98,
0x2b, 0x79, 0xf9, 0xb7, 0xe3, 0xfb, 0xa9, 0x94,
0xcf, 0xd1, 0xf3, 0xfb, 0x22, 0xf7, 0x1c, 0xea,
0x1a, 0xfb, 0xf0, 0x2b, 0x46, 0x0c, 0x6d, 0x1d
},
0xab, 0x53, 0x0a, 0x13, 0xe4, 0x59, 0x14, 0x98,
0x2b, 0x79, 0xf9, 0xb7, 0xe3, 0xfb, 0xa9, 0x94,
0xcf, 0xd1, 0xf3, 0xfb, 0x22, 0xf7, 0x1c, 0xea,
0x1a, 0xfb, 0xf0, 0x2b, 0x46, 0x0c, 0x6d, 0x1d
},
},
{
@ -34,12 +32,10 @@ TEST_CASE("ec::ecdsa_sign") {
// Public key: EOS6tVtKhTpM6yU7kkiRz1AecDJPcBQo2w4x4oytJbJi5PMV2Rcw2
{ 0x03, 0x07, 0x69, 0xbb, 0xa5, 0x2c, 0xd2, 0xe1, 0x3b, 0x3e, 0x0a, 0x40, 0xb3, 0xa2, 0x44, 0xad, 0x71, 0x6e, 0x32, 0x64, 0x9c, 0x3a, 0x64, 0x27, 0x4f, 0x31, 0x86, 0x8a, 0x4c, 0x69, 0x58, 0x86, 0x49 },
{
{
0x19, 0xd3, 0xe0, 0x8b, 0xbb, 0xad, 0x5f, 0x02,
0x35, 0xa8, 0xa8, 0xf8, 0x1a, 0x7f, 0xa1, 0xe0,
0xf8, 0x50, 0xdd, 0x39, 0x12, 0xe3, 0xc6, 0x55,
0xb4, 0x35, 0xd4, 0x78, 0x6b, 0x93, 0x64, 0xa6
},
0x19, 0xd3, 0xe0, 0x8b, 0xbb, 0xad, 0x5f, 0x02,
0x35, 0xa8, 0xa8, 0xf8, 0x1a, 0x7f, 0xa1, 0xe0,
0xf8, 0x50, 0xdd, 0x39, 0x12, 0xe3, 0xc6, 0x55,
0xb4, 0x35, 0xd4, 0x78, 0x6b, 0x93, 0x64, 0xa6
},
},
{
@ -49,12 +45,10 @@ TEST_CASE("ec::ecdsa_sign") {
// Public key: EOS7Xtaa4y44gYapth4MH5bdtCvdtQvVLdsW7a8thVAuvNAkj8X7i
{ 0x03, 0x5c, 0x50, 0x81, 0xef, 0xa6, 0x46, 0x00, 0x5a, 0xb9, 0xd8, 0x2b, 0xfe, 0xd8, 0xe1, 0x6d, 0x15, 0x42, 0x9e, 0x9a, 0xcb, 0xc9, 0xd6, 0xb3, 0x2e, 0x5a, 0xe3, 0xed, 0xa5, 0x8d, 0x6a, 0x42, 0x6c },
{
{
0x1b, 0x01, 0x0b, 0xe5, 0xce, 0x6a, 0x49, 0xc7,
0xcd, 0x04, 0x86, 0x0d, 0xef, 0x63, 0x1c, 0x6a,
0xcc, 0xd5, 0x17, 0x47, 0x2e, 0x74, 0x5b, 0xa6,
0xc8, 0xaf, 0x26, 0x1b, 0x15, 0x7e, 0x11, 0xec
},
0x1b, 0x01, 0x0b, 0xe5, 0xce, 0x6a, 0x49, 0xc7,
0xcd, 0x04, 0x86, 0x0d, 0xef, 0x63, 0x1c, 0x6a,
0xcc, 0xd5, 0x17, 0x47, 0x2e, 0x74, 0x5b, 0xa6,
0xc8, 0xaf, 0x26, 0x1b, 0x15, 0x7e, 0x11, 0xec
},
},
{
@ -64,12 +58,10 @@ TEST_CASE("ec::ecdsa_sign") {
// Public key: EOS6E12fqQqWLYJS32ffB6LaQYxyDXUQSPfMTMnj6tc5bgntZKcBy
{ 0x02, 0xaf, 0xff, 0xeb, 0xef, 0x47, 0x70, 0x58, 0x2f, 0x9b, 0x66, 0x6c, 0xe0, 0xea, 0x84, 0x32, 0x41, 0xa0, 0x94, 0x36, 0x30, 0x9b, 0xfc, 0xdb, 0x9a, 0x58, 0xdd, 0x0e, 0xe6, 0x3e, 0xd4, 0x5a, 0xcd },
{
{
0xbc, 0x83, 0xbe, 0xe1, 0x73, 0x82, 0xfb, 0x02,
0x71, 0x25, 0x3b, 0xf5, 0x39, 0x32, 0x55, 0x4e,
0x01, 0x28, 0x5d, 0xf4, 0x02, 0xe8, 0xa2, 0x92,
0x04, 0xf2, 0x95, 0xbc, 0xfa, 0xed, 0x8f, 0xaa
},
0xbc, 0x83, 0xbe, 0xe1, 0x73, 0x82, 0xfb, 0x02,
0x71, 0x25, 0x3b, 0xf5, 0x39, 0x32, 0x55, 0x4e,
0x01, 0x28, 0x5d, 0xf4, 0x02, 0xe8, 0xa2, 0x92,
0x04, 0xf2, 0x95, 0xbc, 0xfa, 0xed, 0x8f, 0xaa
},
},
{
@ -79,12 +71,10 @@ TEST_CASE("ec::ecdsa_sign") {
// Public key: EOS6uqJC6F7eEMq7SHREhTzRoAT7uumrmHDDYC595CJKeBgPvPojd
{ 0x03, 0x0a, 0x71, 0x8e, 0x48, 0x1a, 0x7a, 0x55, 0x84, 0xb9, 0xaf, 0x24, 0xca, 0x8f, 0x85, 0xcd, 0x0f, 0x55, 0x5c, 0xcf, 0xb3, 0x7b, 0x39, 0x5b, 0xa5, 0xfc, 0xb9, 0xaf, 0x26, 0xc7, 0xc7, 0x88, 0x7b },
{
{
0xfc, 0xb2, 0x0d, 0xa1, 0x22, 0x6c, 0xcc, 0x59,
0x26, 0x66, 0xba, 0x57, 0xeb, 0x4a, 0xfa, 0x20,
0xff, 0x40, 0x7b, 0xc7, 0x3c, 0x35, 0xb8, 0xaa,
0x72, 0x3e, 0x94, 0xcc, 0x05, 0xe1, 0x51, 0xc7
},
0xfc, 0xb2, 0x0d, 0xa1, 0x22, 0x6c, 0xcc, 0x59,
0x26, 0x66, 0xba, 0x57, 0xeb, 0x4a, 0xfa, 0x20,
0xff, 0x40, 0x7b, 0xc7, 0x3c, 0x35, 0xb8, 0xaa,
0x72, 0x3e, 0x94, 0xcc, 0x05, 0xe1, 0x51, 0xc7
},
},
{
@ -94,34 +84,32 @@ TEST_CASE("ec::ecdsa_sign") {
// Public key: EOS5YiBwqnFXqeb5hCmwV9bLHp6Jg5hVnRjzYVApf2DXyRGr7B7kZ
{ 0x02, 0x56, 0xc9, 0x41, 0x90, 0x44, 0x8a, 0xcc, 0x89, 0x91, 0x79, 0xaf, 0x4e, 0x3a, 0x72, 0xa7, 0x24, 0x86, 0x7f, 0xd8, 0x03, 0x07, 0x04, 0x30, 0xd3, 0xf3, 0x6b, 0x20, 0x94, 0x85, 0x78, 0xfc, 0x38 },
{
{
0xd2, 0xfa, 0xa6, 0x97, 0x12, 0xd7, 0x04, 0x05,
0xe8, 0x60, 0x7e, 0x86, 0x73, 0x69, 0x05, 0x90,
0x97, 0xa2, 0x57, 0xee, 0x12, 0x4b, 0x80, 0x13,
0x04, 0xfa, 0x7d, 0x70, 0xe7, 0xdc, 0x86, 0xb2
},
0xd2, 0xfa, 0xa6, 0x97, 0x12, 0xd7, 0x04, 0x05,
0xe8, 0x60, 0x7e, 0x86, 0x73, 0x69, 0x05, 0x90,
0x97, 0xa2, 0x57, 0xee, 0x12, 0x4b, 0x80, 0x13,
0x04, 0xfa, 0x7d, 0x70, 0xe7, 0xdc, 0x86, 0xb2
},
},
};
libeosio::ec_init();
libantelope::ec_init();
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name) {
libeosio::ec_signature_t result;
libantelope::ec_signature_t result;
CHECK( libeosio::ecdsa_sign(it->key, &it->dgst, result) == 0 );
CHECK( libantelope::ecdsa_sign(it->key, &it->dgst, result) == 0 );
// Need to use verify here as different implemententations produces different signatures.
// (i have tested eosjs, eos-go and ofc libeosio)
// (i have tested eosjs, eos-go and ofc libantelope)
// However, the signatures are correct and can be validated by all implementations.
//
// Now, how do we know that ecdsa_verify is correct?
// well, in escdsa_verify.cpp there are tests that checks hardcoded signatures generated by different implementations and should be fine.
CHECK( libeosio::ecdsa_verify(&it->dgst, result, it->pub) == 0);
CHECK( libantelope::ecdsa_verify(&it->dgst, result, it->pub) == 0);
}
}
libeosio::ec_shutdown();
libantelope::ec_shutdown();
}

View file

@ -1,4 +1,4 @@
#include <libeosio/ec.hpp>
#include <libantelope/ec.hpp>
#include <vector>
#include <doctest.h>
@ -6,9 +6,9 @@ TEST_CASE("ec::ecdsa_verify") {
struct testcase {
const char *name;
libeosio::sha256_t dgst;
libeosio::ec_pubkey_t pubkey;
libeosio::ec_signature_t sig;
libantelope::sha256_t dgst;
libantelope::ec_pubkey_t pubkey;
libantelope::ec_signature_t sig;
int expected;
};
@ -16,12 +16,10 @@ TEST_CASE("ec::ecdsa_verify") {
{
"valid #1",
{
{
0xab, 0x53, 0x0a, 0x13, 0xe4, 0x59, 0x14, 0x98,
0x2b, 0x79, 0xf9, 0xb7, 0xe3, 0xfb, 0xa9, 0x94,
0xcf, 0xd1, 0xf3, 0xfb, 0x22, 0xf7, 0x1c, 0xea,
0x1a, 0xfb, 0xf0, 0x2b, 0x46, 0x0c, 0x6d, 0x1d
},
0xab, 0x53, 0x0a, 0x13, 0xe4, 0x59, 0x14, 0x98,
0x2b, 0x79, 0xf9, 0xb7, 0xe3, 0xfb, 0xa9, 0x94,
0xcf, 0xd1, 0xf3, 0xfb, 0x22, 0xf7, 0x1c, 0xea,
0x1a, 0xfb, 0xf0, 0x2b, 0x46, 0x0c, 0x6d, 0x1d
},
// Public Key: EOS6zjfj9Xjk9CYoucZDptdDZ6317eZd622pVvaYtv5q6gwEs9icD
{ 0x03, 0x15, 0x93, 0x8a, 0x8e, 0x1d, 0x57, 0x84, 0x9f, 0xab, 0x07, 0x18, 0x67, 0xb5, 0x0c, 0xda, 0xb0, 0x77, 0x62, 0x29, 0xb6, 0x43, 0xb8, 0x67, 0x56, 0xc7, 0xb3, 0xe8, 0x7f, 0xe6, 0x08, 0xf8, 0x4b },
@ -36,12 +34,10 @@ TEST_CASE("ec::ecdsa_verify") {
{
"valid #2 (generated by openssl)",
{
{
0xab, 0x53, 0x0a, 0x13, 0xe4, 0x59, 0x14, 0x98,
0x2b, 0x79, 0xf9, 0xb7, 0xe3, 0xfb, 0xa9, 0x94,
0xcf, 0xd1, 0xf3, 0xfb, 0x22, 0xf7, 0x1c, 0xea,
0x1a, 0xfb, 0xf0, 0x2b, 0x46, 0x0c, 0x6d, 0x1d
},
0xab, 0x53, 0x0a, 0x13, 0xe4, 0x59, 0x14, 0x98,
0x2b, 0x79, 0xf9, 0xb7, 0xe3, 0xfb, 0xa9, 0x94,
0xcf, 0xd1, 0xf3, 0xfb, 0x22, 0xf7, 0x1c, 0xea,
0x1a, 0xfb, 0xf0, 0x2b, 0x46, 0x0c, 0x6d, 0x1d
},
// Public Key: EOS6zjfj9Xjk9CYoucZDptdDZ6317eZd622pVvaYtv5q6gwEs9icD
{ 0x03, 0x15, 0x93, 0x8a, 0x8e, 0x1d, 0x57, 0x84, 0x9f, 0xab, 0x07, 0x18, 0x67, 0xb5, 0x0c, 0xda, 0xb0, 0x77, 0x62, 0x29, 0xb6, 0x43, 0xb8, 0x67, 0x56, 0xc7, 0xb3, 0xe8, 0x7f, 0xe6, 0x08, 0xf8, 0x4b },
@ -56,12 +52,10 @@ TEST_CASE("ec::ecdsa_verify") {
{
"valid #3 (generated by eos-go)",
{
{
0xab, 0x53, 0x0a, 0x13, 0xe4, 0x59, 0x14, 0x98,
0x2b, 0x79, 0xf9, 0xb7, 0xe3, 0xfb, 0xa9, 0x94,
0xcf, 0xd1, 0xf3, 0xfb, 0x22, 0xf7, 0x1c, 0xea,
0x1a, 0xfb, 0xf0, 0x2b, 0x46, 0x0c, 0x6d, 0x1d
},
0xab, 0x53, 0x0a, 0x13, 0xe4, 0x59, 0x14, 0x98,
0x2b, 0x79, 0xf9, 0xb7, 0xe3, 0xfb, 0xa9, 0x94,
0xcf, 0xd1, 0xf3, 0xfb, 0x22, 0xf7, 0x1c, 0xea,
0x1a, 0xfb, 0xf0, 0x2b, 0x46, 0x0c, 0x6d, 0x1d
},
// Public Key: EOS6zjfj9Xjk9CYoucZDptdDZ6317eZd622pVvaYtv5q6gwEs9icD
{ 0x03, 0x15, 0x93, 0x8a, 0x8e, 0x1d, 0x57, 0x84, 0x9f, 0xab, 0x07, 0x18, 0x67, 0xb5, 0x0c, 0xda, 0xb0, 0x77, 0x62, 0x29, 0xb6, 0x43, 0xb8, 0x67, 0x56, 0xc7, 0xb3, 0xe8, 0x7f, 0xe6, 0x08, 0xf8, 0x4b },
@ -76,12 +70,10 @@ TEST_CASE("ec::ecdsa_verify") {
{
"valid #4 (generated by eosjs)",
{
{
0xab, 0x53, 0x0a, 0x13, 0xe4, 0x59, 0x14, 0x98,
0x2b, 0x79, 0xf9, 0xb7, 0xe3, 0xfb, 0xa9, 0x94,
0xcf, 0xd1, 0xf3, 0xfb, 0x22, 0xf7, 0x1c, 0xea,
0x1a, 0xfb, 0xf0, 0x2b, 0x46, 0x0c, 0x6d, 0x1d
},
0xab, 0x53, 0x0a, 0x13, 0xe4, 0x59, 0x14, 0x98,
0x2b, 0x79, 0xf9, 0xb7, 0xe3, 0xfb, 0xa9, 0x94,
0xcf, 0xd1, 0xf3, 0xfb, 0x22, 0xf7, 0x1c, 0xea,
0x1a, 0xfb, 0xf0, 0x2b, 0x46, 0x0c, 0x6d, 0x1d
},
// Public Key: EOS6zjfj9Xjk9CYoucZDptdDZ6317eZd622pVvaYtv5q6gwEs9icD
{ 0x03, 0x15, 0x93, 0x8a, 0x8e, 0x1d, 0x57, 0x84, 0x9f, 0xab, 0x07, 0x18, 0x67, 0xb5, 0x0c, 0xda, 0xb0, 0x77, 0x62, 0x29, 0xb6, 0x43, 0xb8, 0x67, 0x56, 0xc7, 0xb3, 0xe8, 0x7f, 0xe6, 0x08, 0xf8, 0x4b },
@ -95,12 +87,10 @@ TEST_CASE("ec::ecdsa_verify") {
{
"valid #4",
{
{
0x19, 0xd3, 0xe0, 0x8b, 0xbb, 0xad, 0x5f, 0x02,
0x35, 0xa8, 0xa8, 0xf8, 0x1a, 0x7f, 0xa1, 0xe0,
0xf8, 0x50, 0xdd, 0x39, 0x12, 0xe3, 0xc6, 0x55,
0xb4, 0x35, 0xd4, 0x78, 0x6b, 0x93, 0x64, 0xa6
},
0x19, 0xd3, 0xe0, 0x8b, 0xbb, 0xad, 0x5f, 0x02,
0x35, 0xa8, 0xa8, 0xf8, 0x1a, 0x7f, 0xa1, 0xe0,
0xf8, 0x50, 0xdd, 0x39, 0x12, 0xe3, 0xc6, 0x55,
0xb4, 0x35, 0xd4, 0x78, 0x6b, 0x93, 0x64, 0xa6
},
// Public Key: EOS6tVtKhTpM6yU7kkiRz1AecDJPcBQo2w4x4oytJbJi5PMV2Rcw2
{ 0x03, 0x07, 0x69, 0xbb, 0xa5, 0x2c, 0xd2, 0xe1, 0x3b, 0x3e, 0x0a, 0x40, 0xb3, 0xa2, 0x44, 0xad, 0x71, 0x6e, 0x32, 0x64, 0x9c, 0x3a, 0x64, 0x27, 0x4f, 0x31, 0x86, 0x8a, 0x4c, 0x69, 0x58, 0x86, 0x49 },
@ -115,12 +105,10 @@ TEST_CASE("ec::ecdsa_verify") {
{
"valid #5",
{
{
0x1b, 0x01, 0x0b, 0xe5, 0xce, 0x6a, 0x49, 0xc7,
0xcd, 0x04, 0x86, 0x0d, 0xef, 0x63, 0x1c, 0x6a,
0xcc, 0xd5, 0x17, 0x47, 0x2e, 0x74, 0x5b, 0xa6,
0xc8, 0xaf, 0x26, 0x1b, 0x15, 0x7e, 0x11, 0xec
},
0x1b, 0x01, 0x0b, 0xe5, 0xce, 0x6a, 0x49, 0xc7,
0xcd, 0x04, 0x86, 0x0d, 0xef, 0x63, 0x1c, 0x6a,
0xcc, 0xd5, 0x17, 0x47, 0x2e, 0x74, 0x5b, 0xa6,
0xc8, 0xaf, 0x26, 0x1b, 0x15, 0x7e, 0x11, 0xec
},
// Public Key: EOS7Xtaa4y44gYapth4MH5bdtCvdtQvVLdsW7a8thVAuvNAkj8X7i
{ 0x03, 0x5c, 0x50, 0x81, 0xef, 0xa6, 0x46, 0x00, 0x5a, 0xb9, 0xd8, 0x2b, 0xfe, 0xd8, 0xe1, 0x6d, 0x15, 0x42, 0x9e, 0x9a, 0xcb, 0xc9, 0xd6, 0xb3, 0x2e, 0x5a, 0xe3, 0xed, 0xa5, 0x8d, 0x6a, 0x42, 0x6c },
@ -135,12 +123,10 @@ TEST_CASE("ec::ecdsa_verify") {
{
"not valid #1",
{
{
0xde, 0x01, 0x64, 0x03, 0x39, 0x01, 0x66, 0x8b,
0xa0, 0x39, 0xef, 0x31, 0x61, 0xc7, 0xc8, 0x9d,
0x15, 0x4b, 0xc6, 0x7b, 0x99, 0x5c, 0xba, 0x9b,
0x23, 0x8a, 0x76, 0x4b, 0x81, 0xf2, 0xff, 0xeb
},
0xde, 0x01, 0x64, 0x03, 0x39, 0x01, 0x66, 0x8b,
0xa0, 0x39, 0xef, 0x31, 0x61, 0xc7, 0xc8, 0x9d,
0x15, 0x4b, 0xc6, 0x7b, 0x99, 0x5c, 0xba, 0x9b,
0x23, 0x8a, 0x76, 0x4b, 0x81, 0xf2, 0xff, 0xeb
},
// Public Key: EOS7Xtaa4y44gYapth4MH5bdtCvdtQvVLdsW7a8thVAuvNAkj8X7i
{ 0x03, 0x5c, 0x50, 0x81, 0xef, 0xa6, 0x46, 0x00, 0x5a, 0xb9, 0xd8, 0x2b, 0xfe, 0xd8, 0xe1, 0x6d, 0x15, 0x42, 0x9e, 0x9a, 0xcb, 0xc9, 0xd6, 0xb3, 0x2e, 0x5a, 0xe3, 0xed, 0xa5, 0x8d, 0x6a, 0x42, 0x6c },
@ -155,12 +141,10 @@ TEST_CASE("ec::ecdsa_verify") {
{
"not valid #2",
{
{
0xa7, 0xf7, 0x89, 0x36, 0xea, 0xb7, 0x95, 0xa7,
0x71, 0xaa, 0x73, 0xb5, 0xf6, 0xb8, 0xa0, 0x40,
0xe5, 0x4f, 0xb3, 0x87, 0xff, 0xd9, 0xb6, 0x4e,
0x30, 0x4c, 0xa3, 0x78, 0xab, 0x68, 0x86, 0x24
},
0xa7, 0xf7, 0x89, 0x36, 0xea, 0xb7, 0x95, 0xa7,
0x71, 0xaa, 0x73, 0xb5, 0xf6, 0xb8, 0xa0, 0x40,
0xe5, 0x4f, 0xb3, 0x87, 0xff, 0xd9, 0xb6, 0x4e,
0x30, 0x4c, 0xa3, 0x78, 0xab, 0x68, 0x86, 0x24
},
// EOS5AxTzvLZ7mRPvo1Ju9nCdB31PruYHE9uar8pF6D3CvZQGWcHq8
{ 0x02, 0x25, 0x64, 0x31, 0x9d, 0x41, 0x46, 0x82, 0xeb, 0x60, 0xed, 0x17, 0xe9, 0x8a, 0xd1, 0x21, 0x60, 0xc4, 0x65, 0xe7, 0x7e, 0x73, 0x2e, 0x45, 0xf0, 0x78, 0x8b, 0x7f, 0x43, 0x30, 0x71, 0xbc, 0x34 },
@ -175,12 +159,10 @@ TEST_CASE("ec::ecdsa_verify") {
{
"not valid #3",
{
{
0x48, 0xd7, 0xd3, 0x83,0x9c, 0xa2, 0x82, 0xde,
0xb6, 0x9a, 0xb8, 0x34,0x36, 0xb0, 0x9f, 0x19,
0xbb, 0xdf, 0x2b, 0xb5,0x39, 0x42, 0x92, 0x32,
0x33, 0x34, 0x84, 0xdd,0xba, 0xbd, 0x95, 0x43
},
0x48, 0xd7, 0xd3, 0x83,0x9c, 0xa2, 0x82, 0xde,
0xb6, 0x9a, 0xb8, 0x34,0x36, 0xb0, 0x9f, 0x19,
0xbb, 0xdf, 0x2b, 0xb5,0x39, 0x42, 0x92, 0x32,
0x33, 0x34, 0x84, 0xdd,0xba, 0xbd, 0x95, 0x43
},
// EOS5vhJWLeBjQAiTZxWdnFkttUDWANurEka69La2nu8fp2gSi5eQk
{ 0x02, 0x88, 0xb4, 0x83, 0x3a, 0x86, 0x18, 0xd3, 0xb2, 0x2b, 0xbe, 0xe6, 0x59, 0x3d, 0xf2, 0x41, 0xf6, 0xed, 0x86, 0x40, 0xe6, 0x19, 0xc8, 0x45, 0x03, 0x78, 0x57, 0xde, 0xcb, 0x2a, 0xd7, 0xc2, 0xf0 },
@ -194,14 +176,14 @@ TEST_CASE("ec::ecdsa_verify") {
},
};
libeosio::ec_init();
libantelope::ec_init();
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name) {
CHECK( libeosio::ecdsa_verify(&it->dgst, it->sig, it->pubkey) == it->expected );
CHECK( libantelope::ecdsa_verify(&it->dgst, it->sig, it->pubkey) == it->expected );
}
}
libeosio::ec_shutdown();
libantelope::ec_shutdown();
}

View file

@ -1,18 +1,18 @@
#include <libeosio/ec.hpp>
#include <libantelope/ec.hpp>
#include <doctest.h>
TEST_CASE("ec::generate") {
libeosio::ec_init();
libantelope::ec_init();
libeosio::ec_pubkey_t result;
libeosio::ec_keypair pair;
CHECK(libeosio::ec_generate_key(&pair) == 0);
libantelope::ec_pubkey_t result;
libantelope::ec_keypair pair;
CHECK(libantelope::ec_generate_key(&pair) == 0);
// Can't test much because... well the private key should be random :)
// But alteast verify that the public key belongs to the private key.
CHECK(libeosio::ec_get_publickey(&pair.secret, &result) == 0);
CHECK(libantelope::ec_get_publickey(&pair.secret, &result) == 0);
CHECK( result == pair.pub );
libeosio::ec_shutdown();
libantelope::ec_shutdown();
}

View file

@ -1,5 +1,5 @@
#include <libeosio/ec.hpp>
#include <libeosio/WIF.hpp>
#include <libantelope/ec.hpp>
#include <libantelope/WIF.hpp>
#include <vector>
#include <doctest.h>
@ -8,8 +8,8 @@ TEST_CASE("ec::pubkey") {
struct testcase {
std::string name;
libeosio::ec_privkey_t priv;
libeosio::ec_pubkey_t expected;
libantelope::ec_privkey_t priv;
libantelope::ec_pubkey_t expected;
};
std::vector<struct testcase> tests {
@ -125,16 +125,16 @@ TEST_CASE("ec::pubkey") {
}
};
libeosio::ec_init();
libantelope::ec_init();
for(auto it = tests.begin(); it != tests.end(); it++) {
SUBCASE(it->name.c_str()) {
libeosio::ec_pubkey_t result;
CHECK( libeosio::ec_get_publickey(&it->priv, &result) == 0 );
libantelope::ec_pubkey_t result;
CHECK( libantelope::ec_get_publickey(&it->priv, &result) == 0 );
CHECK( result == it->expected );
}
}
libeosio::ec_shutdown();
libantelope::ec_shutdown();
}

118
tests/hash/ripemd160.cpp Normal file
View 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
View 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
View 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 */