├── LICENCE.txt ├── lib ├── libnakasendo.a ├── libnakasendo_java.so └── libnakasendo_shared.so ├── include ├── impl │ ├── memory │ │ ├── SecureAllocatorSelector.h │ │ ├── SecureString.h │ │ ├── IArrayAlloc.h │ │ ├── SecureArrayAlloc.h │ │ ├── KeyMeta.h │ │ ├── SecureAllocatorAction.h │ │ ├── SecureVector.h │ │ ├── ArrayAlloc.h │ │ ├── APageLocker.h │ │ ├── Array.h │ │ ├── SecureArray.h │ │ ├── KeyExport.h │ │ ├── SecureByteAlloc.h │ │ └── KeyStorage.h │ ├── utils │ │ ├── Utils.h │ │ ├── Error.h │ │ ├── Exceptions.h │ │ ├── UInt.h │ │ ├── Hashers.h │ │ ├── FNV1aHash.h │ │ ├── Status.h │ │ ├── HexToBytes.h │ │ └── EnumCast.h │ ├── RNGAdapter.h │ ├── Context.h │ ├── Base58DataT.h │ ├── MetaDataDefinitions.h │ ├── MetaDataCollectionImpl.h │ ├── JSONSecretBackingStore.h │ ├── ContextAction.h │ ├── Base58Data.h │ └── SecretStoreImpl.h ├── secp256k1 │ ├── src │ │ ├── scalar_low.h │ │ ├── java │ │ │ ├── org_bitcoin_Secp256k1Context.h │ │ │ └── org_bitcoin_NativeSecp256k1.h │ │ ├── ecmult_const.h │ │ ├── num_gmp.h │ │ ├── num_impl.h │ │ ├── scalar_8x32.h │ │ ├── scalar_4x64.h │ │ ├── basic-config.h │ │ ├── ecdsa.h │ │ ├── eckey.h │ │ ├── ecmult.h │ │ ├── testrand.h │ │ ├── hash.h │ │ ├── field_5x52.h │ │ ├── bench.h │ │ ├── field_10x26.h │ │ ├── modules │ │ │ └── ecdh │ │ │ │ ├── main_impl.h │ │ │ │ └── tests_impl.h │ │ ├── ecmult_gen.h │ │ ├── num.h │ │ ├── util.h │ │ ├── eckey_impl.h │ │ ├── scalar_low_impl.h │ │ ├── testrand_impl.h │ │ ├── scalar.h │ │ └── field.h │ ├── include │ │ ├── secp256k1_ecdh.h │ │ └── secp256k1_recovery.h │ └── contrib │ │ ├── lax_der_privatekey_parsing.h │ │ └── lax_der_parsing.h ├── interface │ ├── MetaData.h │ ├── Types.h │ ├── BlockChainAddress.h │ ├── ContextObject.h │ ├── KeyFragment.h │ ├── JSONSerialisable.h │ ├── SerialisationFormat.h │ ├── MetaDataCollection.h │ ├── SecretBackingStore.h │ ├── PubKey.h │ ├── SecretStore.h │ ├── Key.h │ └── RandomRangeGenerator.h └── native │ ├── EccontextSecp256k1.h │ ├── Ecc.h │ ├── BCHPublicKeyAddress.h │ ├── KeyFragmentECSecp256k1.h │ ├── KeyConverter.h │ ├── contrib │ └── lax_der_privatekey_parsing.h │ └── PubKeyECSecp256k1.h ├── examples ├── c++ │ └── testapp │ │ ├── TestApp.sln │ │ ├── testapp.cpp │ │ └── Makefile └── java │ └── testapp │ └── testapp.java ├── Dockerfile └── README.md /LICENCE.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dymurray/nakasandbox/HEAD/LICENCE.txt -------------------------------------------------------------------------------- /lib/libnakasendo.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dymurray/nakasandbox/HEAD/lib/libnakasendo.a -------------------------------------------------------------------------------- /lib/libnakasendo_java.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dymurray/nakasandbox/HEAD/lib/libnakasendo_java.so -------------------------------------------------------------------------------- /lib/libnakasendo_shared.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dymurray/nakasandbox/HEAD/lib/libnakasendo_shared.so -------------------------------------------------------------------------------- /include/impl/memory/SecureAllocatorSelector.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef SECUREALLOCATORSELECTOR_H 5 | #define SECUREALLOCATORSELECTOR_H 6 | 7 | namespace nakasendo { 8 | namespace impl { 9 | 10 | enum class SecureAllocatorSelector{ 11 | NO_ACTION = 10, 12 | DEBUG, 13 | RELEASE 14 | }; 15 | } 16 | } 17 | 18 | 19 | #endif // SECUREALLOCATORSELECTOR_H 20 | -------------------------------------------------------------------------------- /include/impl/memory/SecureString.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef SECURESTRING_H 5 | #define SECURESTRING_H 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace nakasendo{ namespace impl{ namespace memory{ 12 | 13 | template 14 | using SecureBasicString = std::basic_string, SecureAllocator>; 15 | 16 | using SecureString = std::basic_string, SecureAllocator>; 17 | 18 | } } } 19 | 20 | #endif // SECURESTRING_H 21 | -------------------------------------------------------------------------------- /include/secp256k1/src/scalar_low.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_H 8 | #define SECP256K1_SCALAR_REPR_H 9 | 10 | #include 11 | 12 | /** A scalar modulo the group order of the secp256k1 curve. */ 13 | typedef uint32_t secp256k1_scalar; 14 | 15 | #endif /* SECP256K1_SCALAR_REPR_H */ 16 | -------------------------------------------------------------------------------- /include/secp256k1/src/java/org_bitcoin_Secp256k1Context.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | #include "include/secp256k1.h" 4 | /* Header for class org_bitcoin_Secp256k1Context */ 5 | 6 | #ifndef _Included_org_bitcoin_Secp256k1Context 7 | #define _Included_org_bitcoin_Secp256k1Context 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | /* 12 | * Class: org_bitcoin_Secp256k1Context 13 | * Method: secp256k1_init_context 14 | * Signature: ()J 15 | */ 16 | SECP256K1_API jlong JNICALL Java_org_bitcoin_Secp256k1Context_secp256k1_1init_1context 17 | (JNIEnv *, jclass); 18 | 19 | #ifdef __cplusplus 20 | } 21 | #endif 22 | #endif 23 | -------------------------------------------------------------------------------- /include/secp256k1/src/ecmult_const.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECMULT_CONST_H 8 | #define SECP256K1_ECMULT_CONST_H 9 | 10 | #include "scalar.h" 11 | #include "group.h" 12 | 13 | static void secp256k1_ecmult_const(secp256k1_gej *r, const secp256k1_ge *a, const secp256k1_scalar *q); 14 | 15 | #endif /* SECP256K1_ECMULT_CONST_H */ 16 | -------------------------------------------------------------------------------- /include/secp256k1/src/num_gmp.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_NUM_REPR_H 8 | #define SECP256K1_NUM_REPR_H 9 | 10 | #include 11 | 12 | #define NUM_LIMBS ((256+GMP_NUMB_BITS-1)/GMP_NUMB_BITS) 13 | 14 | typedef struct { 15 | mp_limb_t data[2*NUM_LIMBS]; 16 | int neg; 17 | int limbs; 18 | } secp256k1_num; 19 | 20 | #endif /* SECP256K1_NUM_REPR_H */ 21 | -------------------------------------------------------------------------------- /include/impl/memory/IArrayAlloc.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef IARRAYALLOC_H 5 | #define IARRAYALLOC_H 6 | 7 | #include 8 | 9 | namespace nakasendo{ namespace impl{ namespace memory{ 10 | 11 | class IArrayAlloc{ 12 | public: 13 | virtual void* byteAlloc(size_t n) = 0; 14 | virtual void* byteAlloc(size_t n, void* allocated) = 0; 15 | virtual void byteFree(void* ptr) = 0; 16 | virtual void byteFree(void* ptr, void* allocated) = 0; 17 | virtual size_t size(void* ptr) const noexcept = 0; 18 | virtual void getException() = 0; 19 | 20 | virtual ~IArrayAlloc(){} 21 | }; 22 | } } } 23 | #endif // SECUREUNIQUEPTR_H 24 | -------------------------------------------------------------------------------- /include/interface/MetaData.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * Meta data to be associated with a supporting object. For maximum 6 | * flexibility meta data is simply a key,value pair, where both are 7 | * strings. 8 | */ 9 | 10 | #ifndef _NCHAIN_SDK_META_DATA_H_ 11 | #define _NCHAIN_SDK_META_DATA_H_ 12 | 13 | #include 14 | #include 15 | 16 | namespace nakasendo 17 | { 18 | 19 | /// Metadata key type 20 | using MetaDataKey = std::string; 21 | 22 | /// Metadata value type 23 | using MetaDataValue = std::string; 24 | 25 | /// A single item of metadata 26 | using MetaData = std::pair; 27 | 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /include/impl/memory/SecureArrayAlloc.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef SECUREARRAYALLOC_H 5 | #define SECUREARRAYALLOC_H 6 | 7 | #include 8 | 9 | namespace nakasendo{ namespace impl{ namespace memory{ 10 | 11 | class SecureArrayAlloc : public IArrayAlloc { 12 | // ArrayAlloc interface 13 | public: 14 | void *byteAlloc(size_t n) override; 15 | void *byteAlloc(size_t n, void *allocated) override; 16 | void byteFree(void *ptr) override; 17 | void byteFree(void *ptr, void *allocated) override; 18 | size_t size(void* ptr) const noexcept override; 19 | void getException() override; 20 | }; 21 | 22 | } } } 23 | #endif // SECUREARRAYALLOC_H 24 | -------------------------------------------------------------------------------- /include/impl/utils/Utils.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * Generic utility functions that are small enough not to warrant 6 | * their own dedicated files. 7 | */ 8 | 9 | #ifndef _NCHAIN_SDK_UTILS_H_ 10 | #define _NCHAIN_SDK_UTILS_H_ 11 | 12 | #include 13 | 14 | namespace nakasendo { namespace impl { namespace utils 15 | { 16 | 17 | /// Convert an enum class value to its underlying type (for example, to print it) 18 | template 19 | auto EnumAsUnderlying(Enumeration value) 20 | -> typename std::underlying_type::type 21 | { 22 | return static_cast::type>(value); 23 | } 24 | 25 | }}} 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /include/secp256k1/src/num_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_NUM_IMPL_H 8 | #define SECP256K1_NUM_IMPL_H 9 | 10 | #if defined HAVE_CONFIG_H 11 | #include "libsecp256k1-config.h" 12 | #endif 13 | 14 | #include "num.h" 15 | 16 | #if defined(USE_NUM_GMP) 17 | #include "num_gmp_impl.h" 18 | #elif defined(USE_NUM_NONE) 19 | /* Nothing. */ 20 | #else 21 | #error "Please select num implementation" 22 | #endif 23 | 24 | #endif /* SECP256K1_NUM_IMPL_H */ 25 | -------------------------------------------------------------------------------- /include/secp256k1/src/scalar_8x32.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_H 8 | #define SECP256K1_SCALAR_REPR_H 9 | 10 | #include 11 | 12 | /** A scalar modulo the group order of the secp256k1 curve. */ 13 | typedef struct { 14 | uint32_t d[8]; 15 | } secp256k1_scalar; 16 | 17 | #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{(d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7)}} 18 | 19 | #endif /* SECP256K1_SCALAR_REPR_H */ 20 | -------------------------------------------------------------------------------- /examples/c++/testapp/TestApp.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 14 4 | VisualStudioVersion = 14.0.25420.1 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestApp", "TestApp.vcxproj", "{DE0AE2B8-81CD-4665-936D-201B43747416}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Release|x64 = Release|x64 11 | EndGlobalSection 12 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 13 | {DE0AE2B8-81CD-4665-936D-201B43747416}.Release|x64.ActiveCfg = Release|x64 14 | {DE0AE2B8-81CD-4665-936D-201B43747416}.Release|x64.Build.0 = Release|x64 15 | EndGlobalSection 16 | GlobalSection(SolutionProperties) = preSolution 17 | HideSolutionNode = FALSE 18 | EndGlobalSection 19 | EndGlobal 20 | -------------------------------------------------------------------------------- /include/impl/memory/KeyMeta.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef KEYMETA_H 5 | #define KEYMETA_H 6 | 7 | #include 8 | #include 9 | 10 | namespace nakasendo { 11 | 12 | namespace impl { 13 | 14 | class KeyMeta{ 15 | public: 16 | KeyMeta() = default; 17 | KeyMeta(const MetaData& metaData); 18 | KeyMeta(const MetaDataKey& metaKey, const MetaDataValue& metaValue); 19 | 20 | const std::string& name() const; 21 | size_t size() const; 22 | void setName(const std::string& name); 23 | 24 | std::string toStr()const; 25 | 26 | private: 27 | void removePattern(const char pattern, std::string& value); 28 | 29 | std::string mName; 30 | MetaData mMetaData; 31 | }; 32 | } 33 | } 34 | 35 | 36 | #endif // KEYMETA_H 37 | -------------------------------------------------------------------------------- /include/secp256k1/src/scalar_4x64.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_H 8 | #define SECP256K1_SCALAR_REPR_H 9 | 10 | #include 11 | 12 | /** A scalar modulo the group order of the secp256k1 curve. */ 13 | typedef struct { 14 | uint64_t d[4]; 15 | } secp256k1_scalar; 16 | 17 | #define SECP256K1_SCALAR_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{((uint64_t)(d1)) << 32 | (d0), ((uint64_t)(d3)) << 32 | (d2), ((uint64_t)(d5)) << 32 | (d4), ((uint64_t)(d7)) << 32 | (d6)}} 18 | 19 | #endif /* SECP256K1_SCALAR_REPR_H */ 20 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM centos/devtoolset-7-toolchain-centos7 2 | USER 0 3 | WORKDIR /home/nakamoto 4 | ENV USER_NAME=nakasendo \ 5 | USER_UID=1001 \ 6 | BASE_DIR=/home/nakasendo 7 | ENV HOME=${BASE_DIR} 8 | 9 | RUN yum update -y && \ 10 | # yum install -y epel-release cryptopp-devel cryptopp keyutils-libs git which boost boost-devel python python-devel make gmp-devel mpfr-devel libmpc-devel glibc-devel.i686 libcc.i686 gcc-c++ 11 | yum install -y epel-release && \ 12 | yum install -y cryptopp-devel cryptopp git which python python-devel make && \ 13 | git clone https://github.com/boostorg/boost --recursive && \ 14 | cd boost && \ 15 | ./bootstrap.sh --prefix=/usr/ && \ 16 | ./b2 && \ 17 | ./b2 install && \ 18 | cd .. && \ 19 | rm -rf boost 20 | # cp -r include/ /usr/ && \ 21 | # cp -r lib/ /usr/ 22 | 23 | COPY include/ /usr/include/ 24 | COPY lib/ /usr/lib/ 25 | WORKDIR /home/nakasendo 26 | USER 1000 27 | ENTRYPOINT ["/bin/sh"] 28 | -------------------------------------------------------------------------------- /include/interface/Types.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | 5 | #ifndef _NCHAIN_SDK_TYPES_H_ 6 | #define _NCHAIN_SDK_TYPES_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | //#include 15 | 16 | namespace nakasendo 17 | { 18 | 19 | //using SecureVec = std::vector>; 20 | //using SecureVecUINT32 = std::vector>; 21 | //using SecureVecIter = SecureVec::iterator; 22 | using SecureOstringStream = std::basic_ostringstream, impl::memory::SecureAllocator>; 23 | 24 | template 25 | using is_vector = std::is_same >; 27 | } 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /include/secp256k1/src/basic-config.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_BASIC_CONFIG_H 8 | #define SECP256K1_BASIC_CONFIG_H 9 | 10 | #ifdef USE_BASIC_CONFIG 11 | 12 | #undef USE_ASM_X86_64 13 | #undef USE_ENDOMORPHISM 14 | #undef USE_FIELD_10X26 15 | #undef USE_FIELD_5X52 16 | #undef USE_FIELD_INV_BUILTIN 17 | #undef USE_FIELD_INV_NUM 18 | #undef USE_NUM_GMP 19 | #undef USE_NUM_NONE 20 | #undef USE_SCALAR_4X64 21 | #undef USE_SCALAR_8X32 22 | #undef USE_SCALAR_INV_BUILTIN 23 | #undef USE_SCALAR_INV_NUM 24 | 25 | #define USE_NUM_NONE 1 26 | #define USE_FIELD_INV_BUILTIN 1 27 | #define USE_SCALAR_INV_BUILTIN 1 28 | #define USE_FIELD_10X26 1 29 | #define USE_SCALAR_8X32 1 30 | 31 | #endif /* USE_BASIC_CONFIG */ 32 | 33 | #endif /* SECP256K1_BASIC_CONFIG_H */ 34 | -------------------------------------------------------------------------------- /include/impl/memory/SecureAllocatorAction.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef SECUREALLOCATIONACTION_H 5 | #define SECUREALLOCATIONACTION_H 6 | 7 | #include 8 | 9 | namespace nakasendo { namespace impl { namespace memory { 10 | /** 11 | * @brief The SecureAllocatorAction struct is a set of generic callback actions that are 12 | * being called from various stages of secure memory management classes 13 | */ 14 | struct SecureAllocatorAction 15 | { 16 | template 17 | static size_t checkSize(Args...) noexcept; 18 | 19 | template 20 | static bool execOnAlloc(Args...); 21 | 22 | template 23 | static bool execOnDeAlloc(Args...); 24 | 25 | template 26 | static bool execOnError(Args...); 27 | 28 | template 29 | static bool execOnUnlock(Args...); 30 | }; 31 | } } } 32 | #endif // SECUREALLOCATIONACTION_H 33 | -------------------------------------------------------------------------------- /include/impl/memory/SecureVector.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef SECUREVECTOR_H 5 | #define SECUREVECTOR_H 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace nakasendo{ namespace impl{ namespace memory{ 12 | 13 | template 14 | using SecureVec = std::vector>; 15 | 16 | using SecureByteVec = SecureVec; 17 | using CSecureByteVec = const SecureVec; 18 | using SecureUIntVec = SecureVec; 19 | using CSecureUIntVec = const SecureVec; 20 | 21 | //template 22 | //using SecureVecIter = typename std::vector>::iterator; 23 | 24 | using SecureByteVecIter = SecureByteVec::iterator; 25 | using CSecureByteVecIter = CSecureByteVec::iterator; 26 | using SecureUIntVecIter = SecureUIntVec::iterator; 27 | 28 | template 29 | using is_vector = std::is_same >; 31 | 32 | } } } 33 | 34 | #endif // SECUREVECTOR_H 35 | -------------------------------------------------------------------------------- /include/impl/memory/ArrayAlloc.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef ARRAYALLOC_H 5 | #define ARRAYALLOC_H 6 | 7 | #include 8 | 9 | namespace nakasendo{ namespace impl{ namespace memory{ 10 | 11 | class ArrayAlloc : public IArrayAlloc{ 12 | // IArrayAlloc interface 13 | public: 14 | ArrayAlloc() = default; 15 | 16 | ArrayAlloc(const ArrayAlloc& other): mSize(other.mSize){} 17 | ArrayAlloc(ArrayAlloc&& other): mSize(other.mSize){ other.mSize = 0; } 18 | 19 | ArrayAlloc& operator=(const ArrayAlloc& other); 20 | ArrayAlloc& operator=(ArrayAlloc&& other); 21 | 22 | virtual ~ArrayAlloc(){} 23 | 24 | void *byteAlloc(size_t n) override; 25 | void *byteAlloc(size_t n, void *allocated) override; 26 | void byteFree(void *ptr) override; 27 | void byteFree(void *ptr, void *allocated) override; 28 | inline size_t size(void* ptr = nullptr) const noexcept override{ 29 | return mSize; 30 | } 31 | void getException() override; 32 | 33 | private: 34 | size_t mSize = 0; 35 | }; 36 | 37 | } } } 38 | #endif // ARRAYALLOC_H 39 | -------------------------------------------------------------------------------- /include/secp256k1/include/secp256k1_ecdh.h: -------------------------------------------------------------------------------- 1 | #ifndef SECP256K1_ECDH_H 2 | #define SECP256K1_ECDH_H 3 | 4 | #include "secp256k1.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /** Compute an EC Diffie-Hellman secret in constant time 11 | * Returns: 1: exponentiation was successful 12 | * 0: scalar was invalid (zero or overflow) 13 | * Args: ctx: pointer to a context object (cannot be NULL) 14 | * Out: result: a 32-byte array which will be populated by an ECDH 15 | * secret computed from the point and scalar 16 | * In: pubkey: a pointer to a secp256k1_pubkey containing an 17 | * initialized public key 18 | * privkey: a 32-byte scalar with which to multiply the point 19 | */ 20 | SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdh( 21 | const secp256k1_context* ctx, 22 | unsigned char *result, 23 | const secp256k1_pubkey *pubkey, 24 | const unsigned char *privkey 25 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); 26 | 27 | #ifdef __cplusplus 28 | } 29 | #endif 30 | 31 | #endif /* SECP256K1_ECDH_H */ 32 | -------------------------------------------------------------------------------- /include/interface/BlockChainAddress.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /** 5 | * Encapsulate a logical blockchain address used within the SDK 6 | */ 7 | 8 | #ifndef _NCHAIN_SDK_BLOCK_CHAIN_ADDRESS_H_ 9 | #define _NCHAIN_SDK_BLOCK_CHAIN_ADDRESS_H_ 10 | 11 | #include "Types.h" 12 | 13 | namespace nakasendo 14 | { 15 | /// Forward declaration of BlockChainAddress pointer type 16 | class BlockChainAddress; 17 | /// Unique pointer type 18 | using BlockChainAddressPtr = std::unique_ptr; 19 | /// Shared pointer type 20 | using BlockChainAddressSPtr = std::shared_ptr; 21 | 22 | /// Encapsulate a logical blockchain address used within the SDK 23 | class BlockChainAddress 24 | { 25 | public: 26 | /// Default destructor 27 | virtual ~BlockChainAddress() = default; 28 | 29 | public: 30 | 31 | /** 32 | * Get a blockchain address. 33 | * @return A string containing blockchain address. 34 | */ 35 | virtual std::string getAddress() const = 0; 36 | }; 37 | } // end of namespace nakasendo 38 | 39 | #endif //_NCHAIN_SDK_BLOCK_CHAIN_ADDRESS_H_ 40 | -------------------------------------------------------------------------------- /include/impl/RNGAdapter.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * An adapter class to make our seedable RNGs usable in a CryptoPP context. 6 | */ 7 | 8 | #ifndef _NCHAIN_SDK_RNG_ADAPTER_H_ 9 | #define _NCHAIN_SDK_RNG_ADAPTER_H_ 10 | 11 | #include 12 | #include 13 | 14 | namespace nakasendo { namespace impl 15 | { 16 | 17 | // A CryptoPP compatible RNG that works with our Seeder. 18 | template 19 | class RNGAdapter : public CryptoPP::RandomNumberGenerator 20 | { 21 | public: 22 | 23 | /// Constructor 24 | RNGAdapter(RNG& rng) : mRNG{rng} {} 25 | 26 | /// Override GenerateBlock from CryptoPP::RandomNumberGenerator 27 | void GenerateBlock(byte* output, size_t size) override 28 | { 29 | impl::memory::SecureByteVec randBytes(size); 30 | mRNG.generate(randBytes); 31 | 32 | size_t numToCopy { randBytes.size() }; 33 | if(size < numToCopy) 34 | { 35 | numToCopy = size; 36 | } 37 | memcpy(output, randBytes.data(), numToCopy); 38 | } 39 | 40 | private: 41 | 42 | /// The RNG we adapt 43 | RNG& mRNG; 44 | }; 45 | 46 | }} 47 | 48 | #endif 49 | -------------------------------------------------------------------------------- /include/secp256k1/src/ecdsa.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECDSA_H 8 | #define SECP256K1_ECDSA_H 9 | 10 | #include 11 | 12 | #include "scalar.h" 13 | #include "group.h" 14 | #include "ecmult.h" 15 | 16 | static int secp256k1_ecdsa_sig_parse(secp256k1_scalar *r, secp256k1_scalar *s, const unsigned char *sig, size_t size); 17 | static int secp256k1_ecdsa_sig_serialize(unsigned char *sig, size_t *size, const secp256k1_scalar *r, const secp256k1_scalar *s); 18 | static int secp256k1_ecdsa_sig_verify(const secp256k1_ecmult_context *ctx, const secp256k1_scalar* r, const secp256k1_scalar* s, const secp256k1_ge *pubkey, const secp256k1_scalar *message); 19 | static int secp256k1_ecdsa_sig_sign(const secp256k1_ecmult_gen_context *ctx, secp256k1_scalar* r, secp256k1_scalar* s, const secp256k1_scalar *seckey, const secp256k1_scalar *message, const secp256k1_scalar *nonce, int *recid); 20 | 21 | #endif /* SECP256K1_ECDSA_H */ 22 | -------------------------------------------------------------------------------- /include/native/EccontextSecp256k1.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * Base class for things that require the Secp256k1 context to be 6 | * setup and cleared down at construction / destruction time. 7 | */ 8 | 9 | #ifndef _NCHAIN_SDK_ECCONTEXT_SECP256K1_H_ 10 | #define _NCHAIN_SDK_ECCONTEXT_SECP256K1_H_ 11 | 12 | #include 13 | 14 | #include "Ecc.h" 15 | 16 | namespace nakasendo { namespace native 17 | { 18 | 19 | /// Base class that initialises and clears down the Secp256k1 context. 20 | class EccontextSecp256k1 : public ContextObject 21 | { 22 | public: 23 | 24 | /// Constructor 25 | EccontextSecp256k1(); 26 | 27 | /// Destructor 28 | ~EccontextSecp256k1() override; 29 | 30 | protected: 31 | 32 | /// Fetch the underlying context 33 | const secp256k1_context* getEccContext() const; 34 | 35 | private: 36 | 37 | /// An alias for a context function. 38 | using ContextFunc = std::function; 39 | 40 | /// Define start context. 41 | ContextFunc ctxStart = []() { EccContext::getInstance().ECC_Start(); }; 42 | /// Define stop context. 43 | ContextFunc ctxStop = []() { EccContext::getInstance().ECC_Stop(); }; 44 | 45 | }; 46 | 47 | }} 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /include/secp256k1/src/eckey.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECKEY_H 8 | #define SECP256K1_ECKEY_H 9 | 10 | #include 11 | 12 | #include "group.h" 13 | #include "scalar.h" 14 | #include "ecmult.h" 15 | #include "ecmult_gen.h" 16 | 17 | static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size); 18 | static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed); 19 | 20 | static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak); 21 | static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); 22 | static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak); 23 | static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak); 24 | 25 | #endif /* SECP256K1_ECKEY_H */ 26 | -------------------------------------------------------------------------------- /examples/c++/testapp/testapp.cpp: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace nakasendo; 12 | using namespace nakasendo::native; 13 | 14 | int main() 15 | { 16 | /* Sign and verify a message */ 17 | 18 | // Get an arbitrary message for signing 19 | // (The contents are unimportant for this example) 20 | std::string msg = "dylan terrence nakamoto"; 21 | 22 | std::vector message(msg.begin(), msg.end()); 23 | message.push_back('\0'); 24 | // Get public and private keys 25 | KeyPtr key { std::make_unique>() }; 26 | PubKeyPtr pubKey { key->getPubKey() }; 27 | 28 | KeyPtr newKey = key->derive(message); 29 | PubKeyPtr newPubKey = pubKey->derive(message); 30 | 31 | // Sign the message using our private key 32 | std::vector signature { key->sign(message) }; 33 | 34 | // Verify the signed message using the corresponding public key 35 | bool signatureOk { pubKey->verify(message, signature) }; 36 | 37 | assert(newPubKey->getContent() == newKey->getPubKey()->getContent()); 38 | 39 | if(signatureOk) 40 | std::cerr << "Signature verified ok" << std::endl; 41 | } 42 | -------------------------------------------------------------------------------- /include/impl/Context.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef CONTEXT_H 5 | #define CONTEXT_H 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | namespace nakasendo { 16 | namespace impl { 17 | 18 | class Context{ 19 | public: 20 | static Context* init(std::unique_ptr &&contextAction); 21 | 22 | void add(const ContextObject& pContextObj); 23 | void remove(const ContextObject& pContextObj); 24 | 25 | size_t size() const; 26 | 27 | virtual ~Context(); 28 | 29 | private: 30 | Context(std::unique_ptr&& contextAction); 31 | 32 | Context() = delete; 33 | Context(const Context& ) = delete; 34 | Context(Context&& ) = delete; 35 | Context& operator=(const Context& ) = delete; 36 | Context& operator=(Context&& ) = delete; 37 | 38 | 39 | static Context* mInstance; 40 | 41 | std::mutex mMutex; 42 | std::set, LessContextObject> mRegister; 43 | 44 | std::unique_ptr mContextAction; 45 | 46 | }; 47 | 48 | } 49 | } 50 | 51 | #endif // CONTEXT_H 52 | -------------------------------------------------------------------------------- /include/impl/utils/Error.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef UTILS_ERROR_H 5 | #define UTILS_ERROR_H 6 | 7 | #include 8 | #include 9 | 10 | namespace nakasendo { namespace impl { namespace utils { 11 | 12 | /** 13 | * @brief The Error struct provide platform independent access to the last system error for a thread from which 14 | * #lastError static function was called. It is possible to check if an error actually happend by clling #isError method 15 | * @struct Error contains error code converted to int and human readable error description converted to std::string 16 | */ 17 | struct Error { 18 | int id = 0; /**< Error id which might be provided by platform and this library */ 19 | std::string desc; /**< Error description which could be provided by platform and this library*/ 20 | 21 | /** 22 | * @brief isError Checks if the current #Error instance is an error 23 | * @return True if struct #Error instance is not actually an error 24 | */ 25 | inline bool isError()const noexcept { return id != 0; } 26 | 27 | /** 28 | * @brief lastError 29 | * @param errorMessageID 30 | * @return Instance of #Error struct containing information about the last error as reported by a platform 31 | */ 32 | template 33 | static Error lastError(T errorMessageID) noexcept; 34 | 35 | }; 36 | 37 | } } } 38 | #endif // STATUSMESSAGES_H 39 | -------------------------------------------------------------------------------- /examples/java/testapp/testapp.java: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | package testapp; 5 | 6 | import com.nakasendo.Platform; 7 | import com.nakasendo.PubKey; 8 | import com.nakasendo.Key; 9 | import com.nakasendo.KeyECSecp256k1; 10 | import com.nakasendo.JniException; 11 | 12 | public class testapp { 13 | private static final Platform platform = Platform.create(); 14 | 15 | public static void main(String[] args) { 16 | try { 17 | /* Sign and verify a message */ 18 | 19 | // Get an arbitrary message for signing 20 | // (The contents are unimportant for this example) 21 | final String message = "Sample message for signing"; 22 | 23 | // Get public and private keys 24 | Key key = KeyECSecp256k1.create(); 25 | PubKey pubKey = key.getPubKey(); 26 | 27 | // Sign the message using our private key 28 | final byte[] signature = key.sign(message.getBytes()); 29 | 30 | // Verify the signed message using the corresponding public key 31 | if(pubKey.verify(message.getBytes(), signature)) { 32 | System.out.println("Signature verified ok"); 33 | } 34 | } catch (JniException e) { 35 | // TODO Auto-generated catch block 36 | e.printStackTrace(); 37 | } 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /include/interface/ContextObject.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef CONTEXTOBJECT_H 5 | #define CONTEXTOBJECT_H 6 | 7 | #include 8 | 9 | namespace nakasendo{ 10 | namespace impl { 11 | class Context; 12 | } 13 | } 14 | 15 | 16 | namespace nakasendo { 17 | 18 | /// A wrapper for a Context 19 | class ContextObject 20 | { 21 | public: 22 | /// Destructor 23 | virtual ~ContextObject(){} 24 | 25 | protected: 26 | /// Pointer to the context we wrap 27 | nakasendo::impl::Context* mContext; 28 | }; 29 | 30 | /// Hash functor for ContextObject 31 | class HashContextObject{ 32 | public: 33 | /// Functor operator 34 | size_t operator() ( const std::reference_wrapper ctx )const{ 35 | const ContextObject& lCtx = ctx; 36 | return std::hash{}(&lCtx); 37 | } 38 | }; 39 | 40 | /// Comparator for ContextObject 41 | class LessContextObject{ 42 | public: 43 | /// Functor operator 44 | bool operator() ( const std::reference_wrapper lhs, 45 | const std::reference_wrapper rhs )const{ 46 | const ContextObject& slhs = lhs, &srhs = rhs; 47 | return &slhs < &srhs; 48 | } 49 | }; 50 | 51 | } 52 | 53 | 54 | #endif // CONTEXTOBJECT_H 55 | -------------------------------------------------------------------------------- /include/interface/KeyFragment.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /** 5 | * Encapsulate a logical key fragment used within the SDK 6 | */ 7 | 8 | #ifndef _NCHAIN_SDK_KEY_FRAGMENT_H_ 9 | #define _NCHAIN_SDK_KEY_FRAGMENT_H_ 10 | 11 | #include "Secret.h" 12 | #include 13 | 14 | namespace nakasendo 15 | { 16 | /// Forward declaration of KeyFragment 17 | class KeyFragment; 18 | /// Unique pointer type 19 | using KeyFragmentPtr = std::unique_ptr; 20 | /// Shared pointer type 21 | using KeyFragmentSPtr = std::shared_ptr; 22 | /// A list of KeyFragments 23 | using KeyFragments = std::vector>; // non-owner 24 | 25 | /// Encapsulate a logical key fragment used within the SDK 26 | class KeyFragment : public Secret 27 | { 28 | public: 29 | /// Default constructor. 30 | KeyFragment() = default; 31 | 32 | /// Move construct from an existing Secret. 33 | KeyFragment(Secret&& secret) : Secret{std::move(secret)} {} 34 | 35 | /// Default destructor 36 | virtual ~KeyFragment() = default; 37 | 38 | public: 39 | 40 | /** 41 | * Get public key as string. 42 | * @return Public key as hex string. 43 | */ 44 | virtual std::string getPubKeyAsHexString() const = 0; 45 | 46 | }; 47 | 48 | } // end of namespace nakasendo 49 | 50 | #endif //_NCHAIN_SDK_KEY_FRAGMENT_H_ 51 | -------------------------------------------------------------------------------- /examples/c++/testapp/Makefile: -------------------------------------------------------------------------------- 1 | # Simple makefile for a simple SDK test application. 2 | 3 | # Change this to point to where the SDK was installed 4 | NCHAINDIR= ../../.. 5 | 6 | CC= g++ 7 | 8 | OBJS= testapp.o 9 | APPNAME= testapp 10 | 11 | BOOSTLIBS= -lboost_system -lboost_thread 12 | 13 | CRYPTOLIBS= -lcryptopp 14 | CRYPTOINCLUDES= -I/usr/include/cryptopp 15 | 16 | #NCHAINLIBS= $(NCHAINDIR)/lib/libnakasendo_shared.so 17 | NCHAINLIBS= /usr/lib/libnakasendo.a 18 | NCHAININCLUDES= -I$(NCHAINDIR)/include 19 | 20 | #INCLUDES= -I. $(CRYPTOINCLUDES) $(NCHAININCLUDES) 21 | #CCFLAGS= $(INCLUDES) 22 | LNFLAGS= -Wl,-rpath,$(NCHAINDIR)/lib 23 | LIBS= $(CRYPTOLIBS) $(NCHAINLIBS) $(BOOSTLIBS) 24 | 25 | # Dependencies 26 | GLOBALDEPS= Makefile 27 | DEPENDS= $(patsubst %.o,%.d,$(OBJS)) 28 | 29 | ############# 30 | # Build rules 31 | ############# 32 | 33 | # Top level 34 | .PHONY: all 35 | all: depend $(APPNAME) 36 | 37 | # Dependencies 38 | include $(DEPENDS) 39 | 40 | %.d: %.cpp 41 | @echo -- makedepend $@ 42 | @bash -c '$(CC) $(CCFLAGS) -M $($(*F).d; \ 43 | [ -s $(*F).d ] || rm -f $(*F).d '; \ 44 | exit_status=$$? ; \ 45 | if [ $${exit_status} -ne 0 ]; then exit $${exit_status}; fi 46 | 47 | .PHONY: depend 48 | depend: $(DEPENDS) 49 | 50 | # Application 51 | $(APPNAME): $(OBJS) 52 | $(CC) $(LNFLAGS) -o $(APPNAME) $(OBJS) $(LIBS) 53 | 54 | %.o: %.cpp $(GLOBALDEPS) 55 | $(CC) -c $(CCFLAGS) $*.cpp 56 | 57 | #################### 58 | # Other useful rules 59 | #################### 60 | 61 | .PHONY: clean 62 | clean: 63 | rm -f $(APPNAME) *.o *.d 64 | -------------------------------------------------------------------------------- /include/secp256k1/src/ecmult.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECMULT_H 8 | #define SECP256K1_ECMULT_H 9 | 10 | #include "num.h" 11 | #include "group.h" 12 | 13 | typedef struct { 14 | /* For accelerating the computation of a*P + b*G: */ 15 | secp256k1_ge_storage (*pre_g)[]; /* odd multiples of the generator */ 16 | #ifdef USE_ENDOMORPHISM 17 | secp256k1_ge_storage (*pre_g_128)[]; /* odd multiples of 2^128*generator */ 18 | #endif 19 | } secp256k1_ecmult_context; 20 | 21 | static void secp256k1_ecmult_context_init(secp256k1_ecmult_context *ctx); 22 | static void secp256k1_ecmult_context_build(secp256k1_ecmult_context *ctx, const secp256k1_callback *cb); 23 | static void secp256k1_ecmult_context_clone(secp256k1_ecmult_context *dst, 24 | const secp256k1_ecmult_context *src, const secp256k1_callback *cb); 25 | static void secp256k1_ecmult_context_clear(secp256k1_ecmult_context *ctx); 26 | static int secp256k1_ecmult_context_is_built(const secp256k1_ecmult_context *ctx); 27 | 28 | /** Double multiply: R = na*A + ng*G */ 29 | static void secp256k1_ecmult(const secp256k1_ecmult_context *ctx, secp256k1_gej *r, const secp256k1_gej *a, const secp256k1_scalar *na, const secp256k1_scalar *ng); 30 | 31 | #endif /* SECP256K1_ECMULT_H */ 32 | -------------------------------------------------------------------------------- /include/native/Ecc.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef _NCHAIN_SDK_ECC_H_ 5 | #define _NCHAIN_SDK_ECC_H_ 6 | 7 | #include 8 | 9 | namespace nakasendo 10 | { 11 | namespace native { 12 | 13 | /* 14 | * Singelton class for ECC secp256k1 support. 15 | */ 16 | class EccContext 17 | { 18 | secp256k1_context *secp256k1_context_both = nullptr; 19 | 20 | private: 21 | EccContext(){} 22 | 23 | public: 24 | EccContext(const EccContext&) = delete; 25 | void operator=(const EccContext&) = delete; 26 | 27 | /* 28 | * Create an instance of ECC. 29 | */ 30 | static EccContext& getInstance() 31 | { 32 | static EccContext instance; 33 | return instance; 34 | } 35 | 36 | /* 37 | * Initialize the elliptic curve support. May not be called twice without calling ECC_Stop first. 38 | */ 39 | void ECC_Start(); 40 | 41 | /* 42 | * Deinitialize the elliptic curve support. No-op if ECC_Start wasn't called first. 43 | */ 44 | void ECC_Stop(); 45 | 46 | /* 47 | * Get a pointer to the context. 48 | */ 49 | const secp256k1_context* GetECContext() const; 50 | 51 | /// Check that required EC support is available at runtime. 52 | //bool ECC_InitSanityCheck(void); 53 | }; 54 | } 55 | } 56 | 57 | #endif //_NCHAIN_SDK_ECC_H_ 58 | -------------------------------------------------------------------------------- /include/secp256k1/src/testrand.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_TESTRAND_H 8 | #define SECP256K1_TESTRAND_H 9 | 10 | #if defined HAVE_CONFIG_H 11 | #include "libsecp256k1-config.h" 12 | #endif 13 | 14 | /* A non-cryptographic RNG used only for test infrastructure. */ 15 | 16 | /** Seed the pseudorandom number generator for testing. */ 17 | SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16); 18 | 19 | /** Generate a pseudorandom number in the range [0..2**32-1]. */ 20 | static uint32_t secp256k1_rand32(void); 21 | 22 | /** Generate a pseudorandom number in the range [0..2**bits-1]. Bits must be 1 or 23 | * more. */ 24 | static uint32_t secp256k1_rand_bits(int bits); 25 | 26 | /** Generate a pseudorandom number in the range [0..range-1]. */ 27 | static uint32_t secp256k1_rand_int(uint32_t range); 28 | 29 | /** Generate a pseudorandom 32-byte array. */ 30 | static void secp256k1_rand256(unsigned char *b32); 31 | 32 | /** Generate a pseudorandom 32-byte array with long sequences of zero and one bits. */ 33 | static void secp256k1_rand256_test(unsigned char *b32); 34 | 35 | /** Generate pseudorandom bytes with long sequences of zero and one bits. */ 36 | static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len); 37 | 38 | #endif /* SECP256K1_TESTRAND_H */ 39 | -------------------------------------------------------------------------------- /include/impl/utils/Exceptions.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef NCHAIN_EXCEPTIONS_H 5 | #define NCHAIN_EXCEPTIONS_H 6 | 7 | #include 8 | 9 | namespace nakasendo { namespace impl { namespace utils 10 | { 11 | class secure_bad_alloc : public std::bad_alloc 12 | { 13 | public: 14 | secure_bad_alloc(std::string msg): mMessage(msg) { } 15 | 16 | virtual ~secure_bad_alloc() {} 17 | 18 | const char* what() const throw() /*gcc 6.3 requires throw()*/ override { 19 | return mMessage.c_str(); 20 | } 21 | 22 | private: 23 | std::string mMessage; 24 | }; 25 | 26 | class secure_bad_dealloc : public std::bad_alloc 27 | { 28 | public: 29 | secure_bad_dealloc(std::string msg): mMessage(msg) { } 30 | 31 | virtual ~secure_bad_dealloc() {} 32 | 33 | const char* what() const throw() /*gcc 6.3 requires throw()*/ override { 34 | return mMessage.c_str(); 35 | } 36 | 37 | private: 38 | std::string mMessage; 39 | }; 40 | 41 | class secure_bad_convert : public std::bad_alloc 42 | { 43 | public: 44 | secure_bad_convert(std::string msg): mMessage(msg) { } 45 | 46 | virtual ~secure_bad_convert() {} 47 | 48 | const char* what() const throw() /*gcc 6.3 requires throw()*/ override { 49 | return mMessage.c_str(); 50 | } 51 | 52 | private: 53 | std::string mMessage; 54 | }; 55 | }}} 56 | 57 | #endif // SECUREALLOCATOR_H 58 | 59 | -------------------------------------------------------------------------------- /include/interface/JSONSerialisable.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * Interface definition for objects which are JSON serialisable/deserialisable. 6 | */ 7 | 8 | #ifndef _NCHAIN_SDK_JSON_SERIALISABLE_H_ 9 | #define _NCHAIN_SDK_JSON_SERIALISABLE_H_ 10 | 11 | #include "SerialisationFormat.h" 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | namespace nakasendo 18 | { 19 | 20 | /// Interface for JSON serialisation/deserialisation. 21 | class JSONSerialisable 22 | { 23 | public: 24 | 25 | virtual ~JSONSerialisable(){} 26 | /** 27 | * Get a unique identifer for this JSONSerialisable type. 28 | * @return A unique identifer of objects of this JSONSerialisable type. 29 | */ 30 | virtual const std::string jsonObjectType() const = 0; 31 | 32 | /** 33 | * Construct a boost::property_tree representation of ourselves. 34 | * @param fmt Describes the format to serialise in. 35 | * @return A boost::property_tree representation of ourselves. 36 | */ 37 | virtual boost::property_tree::ptree toJson(const SerialisationFormat& fmt) const = 0; 38 | 39 | /** 40 | * Set ourselves from the given boost::property_tree. 41 | * @param root The JSON boost::property_tree that describes our requried 42 | * state. 43 | * @param fmt Describes the format to deserialise from. 44 | */ 45 | virtual void fromJson(const boost::property_tree::ptree& root, 46 | const SerialisationFormat& fmt) = 0; 47 | }; 48 | 49 | /// JSONSerialisable pointer type. 50 | using JSONSerialisablePtr = std::shared_ptr; 51 | 52 | } 53 | 54 | #endif 55 | 56 | -------------------------------------------------------------------------------- /include/secp256k1/src/hash.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_HASH_H 8 | #define SECP256K1_HASH_H 9 | 10 | #include 11 | #include 12 | 13 | typedef struct { 14 | uint32_t s[8]; 15 | uint32_t buf[16]; /* In big endian */ 16 | size_t bytes; 17 | } secp256k1_sha256; 18 | 19 | static void secp256k1_sha256_initialize(secp256k1_sha256 *hash); 20 | static void secp256k1_sha256_write(secp256k1_sha256 *hash, const unsigned char *data, size_t size); 21 | static void secp256k1_sha256_finalize(secp256k1_sha256 *hash, unsigned char *out32); 22 | 23 | typedef struct { 24 | secp256k1_sha256 inner, outer; 25 | } secp256k1_hmac_sha256; 26 | 27 | static void secp256k1_hmac_sha256_initialize(secp256k1_hmac_sha256 *hash, const unsigned char *key, size_t size); 28 | static void secp256k1_hmac_sha256_write(secp256k1_hmac_sha256 *hash, const unsigned char *data, size_t size); 29 | static void secp256k1_hmac_sha256_finalize(secp256k1_hmac_sha256 *hash, unsigned char *out32); 30 | 31 | typedef struct { 32 | unsigned char v[32]; 33 | unsigned char k[32]; 34 | int retry; 35 | } secp256k1_rfc6979_hmac_sha256; 36 | 37 | static void secp256k1_rfc6979_hmac_sha256_initialize(secp256k1_rfc6979_hmac_sha256 *rng, const unsigned char *key, size_t keylen); 38 | static void secp256k1_rfc6979_hmac_sha256_generate(secp256k1_rfc6979_hmac_sha256 *rng, unsigned char *out, size_t outlen); 39 | static void secp256k1_rfc6979_hmac_sha256_finalize(secp256k1_rfc6979_hmac_sha256 *rng); 40 | 41 | #endif /* SECP256K1_HASH_H */ 42 | -------------------------------------------------------------------------------- /include/secp256k1/src/field_5x52.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_FIELD_REPR_H 8 | #define SECP256K1_FIELD_REPR_H 9 | 10 | #include 11 | 12 | typedef struct { 13 | /* X = sum(i=0..4, elem[i]*2^52) mod n */ 14 | uint64_t n[5]; 15 | #ifdef VERIFY 16 | int magnitude; 17 | int normalized; 18 | #endif 19 | } secp256k1_fe; 20 | 21 | /* Unpacks a constant into a overlapping multi-limbed FE element. */ 22 | #define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ 23 | (d0) | (((uint64_t)(d1) & 0xFFFFFUL) << 32), \ 24 | ((uint64_t)(d1) >> 20) | (((uint64_t)(d2)) << 12) | (((uint64_t)(d3) & 0xFFUL) << 44), \ 25 | ((uint64_t)(d3) >> 8) | (((uint64_t)(d4) & 0xFFFFFFFUL) << 24), \ 26 | ((uint64_t)(d4) >> 28) | (((uint64_t)(d5)) << 4) | (((uint64_t)(d6) & 0xFFFFUL) << 36), \ 27 | ((uint64_t)(d6) >> 16) | (((uint64_t)(d7)) << 16) \ 28 | } 29 | 30 | #ifdef VERIFY 31 | #define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1} 32 | #else 33 | #define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} 34 | #endif 35 | 36 | typedef struct { 37 | uint64_t n[4]; 38 | } secp256k1_fe_storage; 39 | 40 | #define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ \ 41 | (d0) | (((uint64_t)(d1)) << 32), \ 42 | (d2) | (((uint64_t)(d3)) << 32), \ 43 | (d4) | (((uint64_t)(d5)) << 32), \ 44 | (d6) | (((uint64_t)(d7)) << 32) \ 45 | }} 46 | 47 | #endif /* SECP256K1_FIELD_REPR_H */ 48 | -------------------------------------------------------------------------------- /include/impl/utils/UInt.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * Long (256 and 160 bit) unsigned int class. 6 | */ 7 | 8 | #ifndef _NCHAIN_SDK_UINT_H_ 9 | #define _NCHAIN_SDK_UINT_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace nakasendo { namespace impl { namespace utils { 18 | 19 | /// Long (256 and 160 bit) unsigned int class. 20 | template 21 | class UIntArray 22 | { 23 | public: 24 | /// Constructor 25 | UIntArray(const std::vector& bytes) 26 | { 27 | // Check sizes 28 | if(bytes.size() != sizeof(mBytes)) 29 | { 30 | throw std::invalid_argument("Bad size for UintArray " + std::to_string(bytes.size())); 31 | } 32 | 33 | memcpy(mBytes, bytes.data(), sizeof(mBytes)); 34 | } 35 | 36 | /// Get iterator to start 37 | const uint8_t* begin() const { return &mBytes[0]; } 38 | 39 | /// Get size 40 | size_t size() const { return sizeof(mBytes); } 41 | 42 | /// Return as a vector 43 | std::vector toVector() const 44 | { 45 | return std::vector {begin(), begin() + size()}; 46 | } 47 | 48 | /// Equality 49 | bool operator==(const UIntArray& that) const 50 | { 51 | return (sizeof(mBytes) == sizeof(that.mBytes)) && 52 | (memcmp(mBytes, that.mBytes, sizeof(mBytes)) == 0); 53 | } 54 | 55 | /// Non-equality 56 | bool operator!=(const UIntArray& that) const 57 | { 58 | return !(*this == that); 59 | } 60 | 61 | private: 62 | 63 | /// Underlying array 64 | uint8_t mBytes[Bits/8] {}; 65 | 66 | }; 67 | 68 | /// uint256 type 69 | using uint256 = UIntArray<256>; 70 | 71 | /// uint160 type 72 | using uint160 = UIntArray<160>; 73 | 74 | }}} 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /include/impl/utils/Hashers.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * Useful hashing functions. 6 | */ 7 | 8 | #ifndef _NCHAIN_SDK_BITCOIN_CASH_HASHERS_H_ 9 | #define _NCHAIN_SDK_BITCOIN_CASH_HASHERS_H_ 10 | 11 | #include "UInt.h" 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | namespace nakasendo { namespace impl { namespace utils 19 | { 20 | 21 | /// Bitcoin cash style double SHA-256 22 | template 23 | uint256 Hash256(const T begin, const T end) 24 | { 25 | // Make sure we never dereference an end() iterator 26 | auto dist = std::distance(begin, end); 27 | const uint8_t* byte { dist? reinterpret_cast(&begin[0]) : nullptr }; 28 | 29 | // Hash once 30 | std::vector hash1(CryptoPP::SHA256::DIGESTSIZE, 0); 31 | CryptoPP::SHA256().CalculateDigest(hash1.data(), byte, dist); 32 | 33 | // Hash twice 34 | std::vector hash2(CryptoPP::SHA256::DIGESTSIZE, 0); 35 | CryptoPP::SHA256().CalculateDigest(hash2.data(), hash1.data(), hash1.size()); 36 | 37 | // Return result 38 | return uint256 {hash2}; 39 | } 40 | 41 | /// Bitcoin cash style SHA-256 + RIPEMD-160 42 | template 43 | uint160 Hash160(const T begin, const T end) 44 | { 45 | // Make sure we never dereference an end() iterator 46 | auto dist = std::distance(begin, end); 47 | const uint8_t* byte { dist? reinterpret_cast(&begin[0]) : nullptr }; 48 | 49 | // Hash with SHA-256 50 | std::vector hash1(CryptoPP::SHA256::DIGESTSIZE, 0); 51 | CryptoPP::SHA256().CalculateDigest(hash1.data(), byte, dist); 52 | 53 | // Hash with RIPEMD-160 54 | std::vector hash2(CryptoPP::RIPEMD160::DIGESTSIZE, 0); 55 | CryptoPP::RIPEMD160().CalculateDigest(hash2.data(), hash1.data(), hash1.size()); 56 | 57 | // Return result 58 | return uint160 {hash2}; 59 | } 60 | 61 | }}} 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /include/impl/utils/FNV1aHash.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef COMPILE_TIME_HASH_HPP 5 | #define COMPILE_TIME_HASH_HPP 6 | 7 | #include 8 | 9 | 10 | namespace nakasendo { namespace impl { namespace utils { 11 | // code license: public domain or equivalent 12 | //http://www.isthe.com/chongo/tech/comp/fnv/index.html 13 | 14 | /** 15 | * Fowler–Noll–Vo hash function FNV-1a hash calculation implemented as a constexpr 16 | */ 17 | namespace { 18 | constexpr uint32_t cVal32 = 0x811c9dc5; 19 | constexpr uint32_t cPrime32 = 0x1000193; 20 | constexpr uint64_t cVal64 = 0xcbf29ce484222325; 21 | constexpr uint64_t cPrime64 = 0x100000001b3; 22 | } 23 | 24 | class Hash{ 25 | public: 26 | /** 27 | * @brief fnv1a32 32 bit hash calculated as FNV-1a 28 | * @param str Source string 29 | * @param value Initial 32 bit value 30 | * @return 32 bit hash value for a string 31 | */ 32 | inline static constexpr uint32_t fnv1a32(const char* const str, const uint32_t value = cVal32) noexcept { 33 | return (str[0] == '\0') ? value : fnv1a32(&str[1], static_cast((value ^ str[0]) * 34 | static_cast(cPrime32))); 35 | } 36 | 37 | /** 38 | * @brief fnv1a64 64 bit hash calculated as FNV-1a 39 | * @param str Source string 40 | * @param value Initial 64 bit value 41 | * @return 64 bit hash value for a string 42 | */ 43 | inline static constexpr uint64_t fnv1a64(const char* const str, const uint64_t value = cVal64) noexcept { 44 | return (str[0] == '\0') ? value : fnv1a64(&str[1], static_cast((value ^ str[0]) * cPrime64)); 45 | } 46 | }; 47 | }}} 48 | #endif // COUNTER_HPP 49 | -------------------------------------------------------------------------------- /include/secp256k1/src/bench.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_BENCH_H 8 | #define SECP256K1_BENCH_H 9 | 10 | #include 11 | #include 12 | #include "sys/time.h" 13 | 14 | static double gettimedouble(void) { 15 | struct timeval tv; 16 | gettimeofday(&tv, NULL); 17 | return tv.tv_usec * 0.000001 + tv.tv_sec; 18 | } 19 | 20 | void print_number(double x) { 21 | double y = x; 22 | int c = 0; 23 | if (y < 0.0) { 24 | y = -y; 25 | } 26 | while (y > 0 && y < 100.0) { 27 | y *= 10.0; 28 | c++; 29 | } 30 | printf("%.*f", c, x); 31 | } 32 | 33 | void run_benchmark(char *name, void (*benchmark)(void*), void (*setup)(void*), void (*teardown)(void*), void* data, int count, int iter) { 34 | int i; 35 | double min = HUGE_VAL; 36 | double sum = 0.0; 37 | double max = 0.0; 38 | for (i = 0; i < count; i++) { 39 | double begin, total; 40 | if (setup != NULL) { 41 | setup(data); 42 | } 43 | begin = gettimedouble(); 44 | benchmark(data); 45 | total = gettimedouble() - begin; 46 | if (teardown != NULL) { 47 | teardown(data); 48 | } 49 | if (total < min) { 50 | min = total; 51 | } 52 | if (total > max) { 53 | max = total; 54 | } 55 | sum += total; 56 | } 57 | printf("%s: min ", name); 58 | print_number(min * 1000000.0 / iter); 59 | printf("us / avg "); 60 | print_number((sum / count) * 1000000.0 / iter); 61 | printf("us / max "); 62 | print_number(max * 1000000.0 / iter); 63 | printf("us\n"); 64 | } 65 | 66 | #endif /* SECP256K1_BENCH_H */ 67 | -------------------------------------------------------------------------------- /include/impl/utils/Status.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef STATUSMESSAGES_H 5 | #define STATUSMESSAGES_H 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace nakasendo { namespace impl { namespace utils { 13 | 14 | constexpr auto StatusHash(const char* const value){ 15 | return utils::Hash::fnv1a32(value); 16 | } 17 | using StatusType = std::remove_reference::type; 18 | 19 | /** 20 | * @brief The Status struct is designed to be initialised as a constexpr 21 | */ 22 | struct Status{ 23 | const StatusType id; /**< Status id which should be unique */ 24 | const char *desc; /**< Readable description */ 25 | 26 | /** 27 | * @brief operator == Compare two statuses 28 | * @param rhs Another instance of #Status 29 | * @return if the corresponding comparison holds, false otherwise 30 | */ 31 | bool operator==(const Status& rhs) const noexcept{ 32 | return id == rhs.id; 33 | } 34 | 35 | /** 36 | * @brief operator != Compare two statuses 37 | * @param rhs Another instance of #Status 38 | * @return if the corresponding comparison holds, false otherwise 39 | */ 40 | bool operator!=(const Status& rhs) const noexcept{ 41 | return id != rhs.id; 42 | } 43 | 44 | /** 45 | * @brief operator << performs stream output on #Status 46 | * @param out output stream 47 | * @param data instance of #Status to be inserted 48 | * @return reference to output stream #out 49 | * @throw output stream related exceptions 50 | */ 51 | friend std::ostream& operator<<(std::ostream& out, const Status& data){ 52 | out << data.desc; 53 | return out; 54 | } 55 | }; 56 | 57 | /* General */ 58 | constexpr Status SUCCESS { 0, "Success" }; 59 | constexpr Status FAILURE { 1, "Failure was detected at some point" }; 60 | 61 | } } } 62 | #endif // STATUSMESSAGES_H 63 | -------------------------------------------------------------------------------- /include/interface/SerialisationFormat.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * Helper for controlling the format objects are serialised in. 6 | */ 7 | 8 | #ifndef _NCHAIN_SDK_SERIALISATION_FORMAT_H_ 9 | #define _NCHAIN_SDK_SERIALISATION_FORMAT_H_ 10 | 11 | #include 12 | 13 | namespace nakasendo 14 | { 15 | 16 | /// A simple class for describing the required serialisation format. 17 | struct SerialisationFormat 18 | { 19 | /// Enumerate the possible serialisation styles. 20 | enum class Style 21 | { 22 | DEFAULT, 23 | WIF 24 | }; 25 | 26 | /// Enumerate the serialisation versions. 27 | enum class Version 28 | { 29 | SDK1 30 | }; 31 | 32 | /** 33 | * Constructor required for non-standards compliant Windows compiler. 34 | * @param style The serialisation style. 35 | * @param version The serialisation format version. 36 | */ 37 | SerialisationFormat(Style style = Style::DEFAULT, Version version = Version::SDK1) 38 | : mStyle{style}, mVersion{version} {} 39 | 40 | /// The style to use. 41 | Style mStyle { Style::DEFAULT }; 42 | 43 | /// The version. 44 | Version mVersion { Version::SDK1 }; 45 | }; 46 | 47 | /// Enable enum_cast for Style 48 | inline const impl::utils::enumTableT& 49 | enumTable(SerialisationFormat::Style) 50 | { 51 | static impl::utils::enumTableT table 52 | { 53 | {SerialisationFormat::Style::DEFAULT, "Default"}, 54 | {SerialisationFormat::Style::WIF, "Wif"} 55 | }; 56 | return table; 57 | } 58 | 59 | /// Enable enum_cast for Version 60 | inline const impl::utils::enumTableT& 61 | enumTable(SerialisationFormat::Version) 62 | { 63 | static impl::utils::enumTableT table 64 | { 65 | {SerialisationFormat::Version::SDK1, "SDK 1"} 66 | }; 67 | return table; 68 | } 69 | 70 | } 71 | 72 | #endif 73 | -------------------------------------------------------------------------------- /include/impl/utils/HexToBytes.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * Helper class for converting hex strings and characters to a byte 6 | * representation. 7 | */ 8 | 9 | #ifndef NCHAIN_SDK_STRING_TO_BYTES_H_ 10 | #define NCHAIN_SDK_STRING_TO_BYTES_H_ 11 | 12 | #include 13 | #include 14 | 15 | namespace nakasendo { namespace impl { namespace utils 16 | { 17 | 18 | /// Class for converting hex strings and characters to a byte 19 | /// representation and back again. 20 | class HexToBytes 21 | { 22 | public: 23 | 24 | /** 25 | * Convert a hex string to a big endian byte stream. 26 | * @param str A string to convert from hex to bytes. 27 | * @return A vector of bytes. 28 | */ 29 | static std::vector bigEndian(const std::string& str); 30 | 31 | /** 32 | * Convert a hex string to a little endian byte stream. 33 | * @param str A string to convert from hex to bytes. 34 | * @return A vector of bytes. 35 | */ 36 | static std::vector littleEndian(const std::string& str); 37 | 38 | /** 39 | * Convert a single hex character. 40 | * @param c A hex character to convert. 41 | * @return The byte value of the character. 42 | */ 43 | static inline uint8_t toByte(char c); 44 | 45 | /** 46 | * Convert a big endian byte stream to a hex string. 47 | * @param bytes A vector of bytes to convert. 48 | * @return A hex coded string. 49 | */ 50 | static std::string bigEndian(const std::vector& bytes); 51 | 52 | /** 53 | * Convert a little endian byte stream to a hex string. 54 | * @param bytes A vector of bytes to convert. 55 | * @return A hex coded string. 56 | */ 57 | static std::string littleEndian(const std::vector& bytes); 58 | 59 | /** 60 | * Convert a nibble to a char. 61 | * @param nibble A nibble to convert. 62 | * @return A hex character. 63 | */ 64 | static inline char toChar(uint8_t nibble); 65 | 66 | }; 67 | 68 | }}} 69 | #endif 70 | -------------------------------------------------------------------------------- /include/interface/MetaDataCollection.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * Interface to a collection of metadata. Provides some utility methods on 6 | * top of what map gives us and enforces thread safety. 7 | */ 8 | 9 | 10 | #ifndef _NCHAIN_SDK_META_DATA_COLLECTION_H_ 11 | #define _NCHAIN_SDK_META_DATA_COLLECTION_H_ 12 | 13 | #include "MetaData.h" 14 | #include "JSONSerialisable.h" 15 | 16 | #include 17 | #include 18 | 19 | namespace nakasendo 20 | { 21 | 22 | /// Forward declaration of MetaDataCollection pointer type 23 | class MetaDataCollection; 24 | /// Shared pointer type 25 | using MetaDataCollectionSPtr = std::shared_ptr; 26 | /// Shared pointer to a const collection 27 | using MetaDataCollectionConstSPtr = std::shared_ptr; 28 | 29 | /// Interface to a collection of metadata. 30 | class MetaDataCollection : public JSONSerialisable 31 | { 32 | public: 33 | 34 | /// Our underlying storage type. 35 | using MetaMap = std::unordered_map; 36 | 37 | /** 38 | * Check if the given key exists in the collection. 39 | * @param key The key to look for. 40 | * @return True if an entry for the given key was found. 41 | */ 42 | virtual bool keyExists(const MetaDataKey& key) const = 0; 43 | 44 | /** 45 | * Lookup the metadata value for some key. Throws if not found. 46 | * @param key The metadata key to lookup. 47 | * @return The metadata value for the given key. 48 | */ 49 | virtual const MetaDataValue& getMetaValue(const MetaDataKey& key) const = 0; 50 | 51 | /** 52 | * Set the value of a piece of metadata. 53 | * @param meta Some metadata to set. 54 | */ 55 | virtual void setMetaData(const MetaData& meta) = 0; 56 | 57 | /** 58 | * Get a copy of all our metadata. 59 | * @return A copy of all our metadata. 60 | */ 61 | virtual MetaMap getAllMetaData() const = 0; 62 | }; 63 | 64 | } // end of namespace nakasendo 65 | 66 | #endif // _NCHAIN_SDK_META_DATA_COLLECTION_H_ 67 | -------------------------------------------------------------------------------- /include/secp256k1/src/field_10x26.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_FIELD_REPR_H 8 | #define SECP256K1_FIELD_REPR_H 9 | 10 | #include 11 | 12 | typedef struct { 13 | /* X = sum(i=0..9, elem[i]*2^26) mod n */ 14 | uint32_t n[10]; 15 | #ifdef VERIFY 16 | int magnitude; 17 | int normalized; 18 | #endif 19 | } secp256k1_fe; 20 | 21 | /* Unpacks a constant into a overlapping multi-limbed FE element. */ 22 | #define SECP256K1_FE_CONST_INNER(d7, d6, d5, d4, d3, d2, d1, d0) { \ 23 | (d0) & 0x3FFFFFFUL, \ 24 | (((uint32_t)d0) >> 26) | (((uint32_t)(d1) & 0xFFFFFUL) << 6), \ 25 | (((uint32_t)d1) >> 20) | (((uint32_t)(d2) & 0x3FFFUL) << 12), \ 26 | (((uint32_t)d2) >> 14) | (((uint32_t)(d3) & 0xFFUL) << 18), \ 27 | (((uint32_t)d3) >> 8) | (((uint32_t)(d4) & 0x3UL) << 24), \ 28 | (((uint32_t)d4) >> 2) & 0x3FFFFFFUL, \ 29 | (((uint32_t)d4) >> 28) | (((uint32_t)(d5) & 0x3FFFFFUL) << 4), \ 30 | (((uint32_t)d5) >> 22) | (((uint32_t)(d6) & 0xFFFFUL) << 10), \ 31 | (((uint32_t)d6) >> 16) | (((uint32_t)(d7) & 0x3FFUL) << 16), \ 32 | (((uint32_t)d7) >> 10) \ 33 | } 34 | 35 | #ifdef VERIFY 36 | #define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0)), 1, 1} 37 | #else 38 | #define SECP256K1_FE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {SECP256K1_FE_CONST_INNER((d7), (d6), (d5), (d4), (d3), (d2), (d1), (d0))} 39 | #endif 40 | 41 | typedef struct { 42 | uint32_t n[8]; 43 | } secp256k1_fe_storage; 44 | 45 | #define SECP256K1_FE_STORAGE_CONST(d7, d6, d5, d4, d3, d2, d1, d0) {{ (d0), (d1), (d2), (d3), (d4), (d5), (d6), (d7) }} 46 | #define SECP256K1_FE_STORAGE_CONST_GET(d) d.n[7], d.n[6], d.n[5], d.n[4],d.n[3], d.n[2], d.n[1], d.n[0] 47 | 48 | #endif /* SECP256K1_FIELD_REPR_H */ 49 | -------------------------------------------------------------------------------- /include/secp256k1/src/modules/ecdh/main_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_MODULE_ECDH_MAIN_H 8 | #define SECP256K1_MODULE_ECDH_MAIN_H 9 | 10 | #include "include/secp256k1_ecdh.h" 11 | #include "ecmult_const_impl.h" 12 | 13 | int secp256k1_ecdh(const secp256k1_context* ctx, unsigned char *result, const secp256k1_pubkey *point, const unsigned char *scalar) { 14 | int ret = 0; 15 | int overflow = 0; 16 | secp256k1_gej res; 17 | secp256k1_ge pt; 18 | secp256k1_scalar s; 19 | VERIFY_CHECK(ctx != NULL); 20 | ARG_CHECK(result != NULL); 21 | ARG_CHECK(point != NULL); 22 | ARG_CHECK(scalar != NULL); 23 | 24 | secp256k1_pubkey_load(ctx, &pt, point); 25 | secp256k1_scalar_set_b32(&s, scalar, &overflow); 26 | if (overflow || secp256k1_scalar_is_zero(&s)) { 27 | ret = 0; 28 | } else { 29 | unsigned char x[32]; 30 | unsigned char y[1]; 31 | secp256k1_sha256 sha; 32 | 33 | secp256k1_ecmult_const(&res, &pt, &s); 34 | secp256k1_ge_set_gej(&pt, &res); 35 | /* Compute a hash of the point in compressed form 36 | * Note we cannot use secp256k1_eckey_pubkey_serialize here since it does not 37 | * expect its output to be secret and has a timing sidechannel. */ 38 | secp256k1_fe_normalize(&pt.x); 39 | secp256k1_fe_normalize(&pt.y); 40 | secp256k1_fe_get_b32(x, &pt.x); 41 | y[0] = 0x02 | secp256k1_fe_is_odd(&pt.y); 42 | 43 | secp256k1_sha256_initialize(&sha); 44 | secp256k1_sha256_write(&sha, y, sizeof(y)); 45 | secp256k1_sha256_write(&sha, x, sizeof(x)); 46 | secp256k1_sha256_finalize(&sha, result); 47 | ret = 1; 48 | } 49 | 50 | secp256k1_scalar_clear(&s); 51 | return ret; 52 | } 53 | 54 | #endif /* SECP256K1_MODULE_ECDH_MAIN_H */ 55 | -------------------------------------------------------------------------------- /include/native/BCHPublicKeyAddress.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /** 5 | * Implementation of a blockchain address for BCH public key addresses. 6 | */ 7 | #ifndef _NCHAIN_SDK_BLOCK_CHAIN_ADDRESS_BCH_PUBLIC_KEY_H_ 8 | #define _NCHAIN_SDK_BLOCK_CHAIN_ADDRESS_BCH_PUBLIC_KEY_H_ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace nakasendo 15 | { 16 | namespace native 17 | { 18 | class BCHPublicKeyAddress : public BlockChainAddress 19 | { 20 | /// Public key hash size. 21 | static constexpr size_t ECSECP256K1_PUBLIC_KEY_HASH_SIZE_IN_BYTES = 20; 22 | /// Version prefix. 23 | static constexpr size_t ECSECP256K1_ADDRESS_VERSION_PREFIX_SIZE_IN_BYTES = 1; 24 | 25 | public: 26 | /// Create a blockchain address based on a hash of the public key. 27 | BCHPublicKeyAddress(const impl::MetaDataDefinitions::NetworkType& networkType, const impl::utils::uint160& hash160); 28 | /// Copy constructor 29 | BCHPublicKeyAddress(const BCHPublicKeyAddress&) = default; 30 | /// Move constructor. 31 | BCHPublicKeyAddress(BCHPublicKeyAddress&&) = default; 32 | /// Default destructor. 33 | virtual ~BCHPublicKeyAddress() = default; 34 | 35 | private: 36 | /// Get version prefix for the network. 37 | uint8_t getVersionPrefix() const; 38 | 39 | /// Network type 40 | const impl::MetaDataDefinitions::NetworkType m_networkType; 41 | /// A hash of the public key. 42 | const impl::utils::uint160 m_pubKeyHash160; 43 | 44 | public: 45 | /** 46 | * Get a ECSECP256K1 blockchain address. 47 | * @return A string containing blockchain address. 48 | */ 49 | virtual std::string getAddress() const override; 50 | }; 51 | } // end of namespace native 52 | } // end of namespace nakasendo 53 | 54 | #endif // _NCHAIN_SDK_BLOCK_CHAIN_ADDRESS_BCH_PUBLIC_KEY_H_ 55 | -------------------------------------------------------------------------------- /include/impl/memory/APageLocker.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef ALOCKEDPAGEMANAGER_H 5 | #define ALOCKEDPAGEMANAGER_H 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | 12 | namespace nakasendo { namespace impl { namespace memory { 13 | 14 | class APageLocker 15 | { 16 | public: 17 | virtual ~APageLocker() {} 18 | /** Allocate and lock memory pages. 19 | * If len is not a multiple of the system page size, it is rounded up. 20 | * Returns 0 in case of allocation failure. 21 | * 22 | * If locking the memory pages could not be accomplished it will still 23 | * return the memory, however the lockingSuccess flag will be false. 24 | * lockingSuccess is undefined if the allocation fails. 25 | */ 26 | virtual utils::Error lockPage(void* ptrInPage) = 0; 27 | 28 | /** Unlock and free memory pages. 29 | * Clear the memory before unlocking. 30 | */ 31 | virtual utils::Error freePage(void* ptrPage) = 0; 32 | 33 | /** Get the total limit on the amount of memory that may be locked by this 34 | * process, in bytes. Return size_t max if there is no limit or the limit 35 | * is unknown. Return 0 if no memory can be locked at all. 36 | */ 37 | virtual size_t getLimit() const = 0; 38 | virtual utils::Error setLimit(size_t expectedLimit) = 0; 39 | 40 | /** Get the page size in bytes 41 | */ 42 | size_t pageSize()const { return mPageSize; } 43 | 44 | /** 45 | * Get the start absolute address of the page 46 | */ 47 | uintptr_t pageStart(const void* ptr) const{ 48 | const uintptr_t baseAddr = reinterpret_cast(ptr); 49 | return baseAddr & mPageMask; 50 | } 51 | 52 | /** 53 | * Get the end absolute address of the page 54 | */ 55 | uintptr_t pageEnd(const void* ptr, const size_t len) const{ 56 | const uintptr_t baseAddr = reinterpret_cast(ptr); 57 | return (baseAddr + len - 1) & mPageMask; 58 | } 59 | 60 | protected: 61 | size_t mPageMask = 0; 62 | size_t mPageSize = 0; 63 | }; 64 | 65 | } } } 66 | #endif // ALOCKEDPAGEMANAGER_H 67 | -------------------------------------------------------------------------------- /include/secp256k1/src/ecmult_gen.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECMULT_GEN_H 8 | #define SECP256K1_ECMULT_GEN_H 9 | 10 | #include "scalar.h" 11 | #include "group.h" 12 | 13 | typedef struct { 14 | /* For accelerating the computation of a*G: 15 | * To harden against timing attacks, use the following mechanism: 16 | * * Break up the multiplicand into groups of 4 bits, called n_0, n_1, n_2, ..., n_63. 17 | * * Compute sum(n_i * 16^i * G + U_i, i=0..63), where: 18 | * * U_i = U * 2^i (for i=0..62) 19 | * * U_i = U * (1-2^63) (for i=63) 20 | * where U is a point with no known corresponding scalar. Note that sum(U_i, i=0..63) = 0. 21 | * For each i, and each of the 16 possible values of n_i, (n_i * 16^i * G + U_i) is 22 | * precomputed (call it prec(i, n_i)). The formula now becomes sum(prec(i, n_i), i=0..63). 23 | * None of the resulting prec group elements have a known scalar, and neither do any of 24 | * the intermediate sums while computing a*G. 25 | */ 26 | secp256k1_ge_storage (*prec)[64][16]; /* prec[j][i] = 16^j * i * G + U_i */ 27 | secp256k1_scalar blind; 28 | secp256k1_gej initial; 29 | } secp256k1_ecmult_gen_context; 30 | 31 | static void secp256k1_ecmult_gen_context_init(secp256k1_ecmult_gen_context* ctx); 32 | static void secp256k1_ecmult_gen_context_build(secp256k1_ecmult_gen_context* ctx, const secp256k1_callback* cb); 33 | static void secp256k1_ecmult_gen_context_clone(secp256k1_ecmult_gen_context *dst, 34 | const secp256k1_ecmult_gen_context* src, const secp256k1_callback* cb); 35 | static void secp256k1_ecmult_gen_context_clear(secp256k1_ecmult_gen_context* ctx); 36 | static int secp256k1_ecmult_gen_context_is_built(const secp256k1_ecmult_gen_context* ctx); 37 | 38 | /** Multiply with the generator: R = a*G */ 39 | static void secp256k1_ecmult_gen(const secp256k1_ecmult_gen_context* ctx, secp256k1_gej *r, const secp256k1_scalar *a); 40 | 41 | static void secp256k1_ecmult_gen_blind(secp256k1_ecmult_gen_context *ctx, const unsigned char *seed32); 42 | 43 | #endif /* SECP256K1_ECMULT_GEN_H */ 44 | -------------------------------------------------------------------------------- /include/native/KeyFragmentECSecp256k1.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /** 5 | * Implementation of a key fragment for ECSecp256k1. 6 | */ 7 | #ifndef _NCHAIN_SDK_KEY_FRAGMENT_ECSECP256K1_H_ 8 | #define _NCHAIN_SDK_KEY_FRAGMENT_ECSECP256K1_H_ 9 | 10 | #include 11 | 12 | namespace nakasendo 13 | { 14 | namespace native 15 | { 16 | class KeyFragmentECSecp256k1 : public KeyFragment 17 | { 18 | /// Secret's name (with a given prefix) needs to be unique. 19 | static const std::string PREFIX; 20 | static const std::string SEPARATOR; 21 | 22 | public: 23 | 24 | /// Create key's fragment. 25 | KeyFragmentECSecp256k1(); 26 | KeyFragmentECSecp256k1(Secret&& secret, 27 | const int nFragmenIdx, 28 | const std::string& sPubKey, 29 | const MetaDataCollectionConstSPtr& metaData); 30 | /// Copy constructor 31 | KeyFragmentECSecp256k1(const KeyFragmentECSecp256k1&) = delete; 32 | /// Move constructor. 33 | KeyFragmentECSecp256k1(KeyFragmentECSecp256k1&&) = delete; 34 | /// Default destructor. 35 | virtual ~KeyFragmentECSecp256k1() = default; 36 | 37 | private: 38 | std::string getPubKeyFromSecretName() const; 39 | 40 | /// Flag to indicate we have registered with the JSON serialiser factory. 41 | /// Initialising this static actually triggers the registration. 42 | static bool KeyFragmentECSecp256k1JSONRegistered; 43 | 44 | public: 45 | 46 | /** 47 | * Get public key as string. 48 | * @return Public key as hex string. 49 | */ 50 | virtual std::string getPubKeyAsHexString() const override; 51 | 52 | 53 | // JSONSerialisable interface 54 | 55 | /** 56 | * Get unique ID for this object type. 57 | * @return A unique string identifer for objects of this type. 58 | */ 59 | const std::string jsonObjectType() const override; 60 | 61 | }; 62 | 63 | //using KeyFragmentECSecp256k1Ptr = std::shared_ptr; 64 | } // end of namespace native 65 | } // end of namespace nakasendo 66 | 67 | #endif // _NCHAIN_SDK_KEY_FRAGMENT_ECSECP256K1_H_ 68 | -------------------------------------------------------------------------------- /include/native/KeyConverter.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * A utility class for converting keys to eliptic curve points. 6 | */ 7 | 8 | #ifndef _NCHAIN_SDK_KEY_CONVERTER_H_ 9 | #define _NCHAIN_SDK_KEY_CONVERTER_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | namespace nakasendo 16 | { 17 | class Key; 18 | class PubKey; 19 | 20 | namespace impl 21 | { 22 | /// Class to help in converting keys to ECP points. 23 | class KeyConverter 24 | { 25 | public: 26 | 27 | /** 28 | * Default constructor. 29 | */ 30 | KeyConverter() = default; 31 | 32 | /** 33 | * Get a CryptoPP public key for one of our public keys. 34 | * @param pubKey One of our public keys. 35 | * @return A CryptoPP Elliptic Curve Discrete Log (DL) public key. 36 | */ 37 | CryptoPP::DL_PublicKey_EC ecpPubKey(const PubKey& pubKey); 38 | 39 | /** 40 | * Get raw scalar for the given byte array. 41 | * @param data Pointer to the start of the data to convert. 42 | * @param size Number of bytes to convert. 43 | * @return Scalar value for the converted bytes. 44 | */ 45 | static CryptoPP::Integer ecpScalar(const uint8_t* data, size_t size); 46 | 47 | /** 48 | * Get raw scalar for the given private key. 49 | * @param key A private key. 50 | * @return Scalar value of the private key. 51 | */ 52 | static CryptoPP::Integer ecpScalar(const Key& key); 53 | 54 | /** 55 | * Initialise a CryptoPP eliptic curve private key from one of our 56 | * private keys. 57 | * @param key Our private key. 58 | * @param out The CryptoPP eliptic curve private key to initialise. 59 | */ 60 | void ecpPrvKeyInit(const Key& key, CryptoPP::DL_PrivateKey_EC& out); 61 | 62 | /** 63 | * Get a CryptoPP ECPPoint for the given public key. 64 | * @param pubKey A public key. 65 | * @return An ECPPoint. 66 | */ 67 | static CryptoPP::ECPPoint ecpPoint(const PubKey& pubKey); 68 | 69 | private: 70 | 71 | /// A random number generator 72 | CryptoPP::AutoSeededRandomPool mRng{}; 73 | 74 | }; 75 | } 76 | } 77 | 78 | #endif // _NCHAIN_SDK_KEY_CONVERTER_H_ 79 | -------------------------------------------------------------------------------- /include/interface/SecretBackingStore.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * Interface definition for all secret persistence backends. 6 | * 7 | * See JSONSecretBackingStore for a simple file based example implementation 8 | * of this interface. A more sophisticated implementation could 9 | * persist (for example) to a database or an OS keyring. 10 | */ 11 | 12 | #ifndef _NCHAIN_SDK_SECRET_BACKING_STORE_H_ 13 | #define _NCHAIN_SDK_SECRET_BACKING_STORE_H_ 14 | 15 | #include "Secret.h" 16 | #include "Types.h" 17 | 18 | #include 19 | 20 | namespace nakasendo 21 | { 22 | 23 | /// Forward declaration of SecretBackingStore pointer type 24 | class SecretBackingStore; 25 | /// Unique pointer type 26 | using SecretBackingStorePtr = std::unique_ptr; 27 | /// Shared pointer type 28 | using SecretBackingStoreSPtr = std::shared_ptr; 29 | 30 | /// Interface definition for all secret persistence backends. 31 | class SecretBackingStore 32 | { 33 | public: 34 | 35 | /// Destructor 36 | virtual ~SecretBackingStore() = default; 37 | 38 | /** 39 | * Save a new secret. 40 | * @param secret The new secret to persist. 41 | */ 42 | virtual void saveSecret(const SecretSPtr& secret) = 0; 43 | 44 | /** 45 | * Save a list of new secrets. This will be more efficient than repeatedly 46 | * calling saveSecret() for each individual secret. 47 | * @param secrets The new secrets to persist. 48 | */ 49 | virtual void saveSecrets(const std::vector& secrets) = 0; 50 | 51 | /** 52 | * Update a changed secret. 53 | * @param name The name of the changed secret. Note that this parameter is 54 | * required because it might be the name itself of the secret that has changed. 55 | * @param secret New details of the changed secret. 56 | */ 57 | virtual void updateSecret(const std::string& name, const SecretSPtr& secret) = 0; 58 | 59 | /** 60 | * Remove a secret. 61 | * @param name The name of the secret to remove. 62 | */ 63 | virtual void removeSecret(const std::string& name) = 0; 64 | 65 | /** 66 | * Load all stored secrets. 67 | */ 68 | virtual void loadAll() = 0; 69 | 70 | /** 71 | * Remove everything currently in the backing store and replace it with 72 | * whatever is currently held by the secret store. 73 | * @param secrets The required new contents of the backing store. 74 | */ 75 | virtual void replaceAll(const std::vector& secrets) = 0; 76 | 77 | }; 78 | 79 | } // end of namespace nakasendo 80 | 81 | #endif // _NCHAIN_SDK_SECRET_BACKING_STORE_H_ 82 | -------------------------------------------------------------------------------- /include/impl/memory/Array.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef ARRAY_H 5 | #define ARRAY_H 6 | 7 | #include 8 | #include 9 | 10 | namespace nakasendo{ namespace impl{ namespace memory{ 11 | 12 | template 13 | using Array = TArray; 14 | 15 | /** 16 | * @brief makeSecureUnique Unique pointer that owns and manages memory block allocated by #mAlloc.byteAlloc 17 | * @param size number of elements of type T 18 | * @return unique_ptr of type T to #Array of #size elements 19 | * @throw any exception from #Array 20 | */ 21 | template 22 | using ArrayUniquePtr = std::unique_ptr>; 23 | template< class T> 24 | ArrayUniquePtr makeSecureUnique( size_t size ){ 25 | return std::unique_ptr>(new Array(size)); 26 | } 27 | 28 | /** 29 | * @brief makeSecureUnique Unique pointer that owns and manages memory block allocated by #mAlloc.byteAlloc placement version 30 | * @param size number of elements of type T 31 | * @param allocMem pointer to previoulsy allocate memeory block 32 | * @return unique_ptr of type T to #Array of #size elements 33 | * @throw any exception from #Array 34 | */ 35 | template 36 | using ArrayUniquePtr = std::unique_ptr>; 37 | template< class T> 38 | ArrayUniquePtr makeSecureUnique( size_t size, T* allocMem ){ 39 | return std::unique_ptr>(new Array(size, allocMem)); 40 | } 41 | 42 | /** 43 | * @brief makeSecureShared Shared pointer that owns and manages memory block allocated by #mAlloc.byteAlloc 44 | * @param size number of elements of type T 45 | * @return shared_ptr of type T to #Array of #size elements 46 | * @throw any exception from #Array 47 | */ 48 | template 49 | using ArraySharedPtr = std::shared_ptr>; 50 | template< class T> 51 | ArraySharedPtr makeSecureShared( size_t size ){ 52 | return std::shared_ptr>(new Array(size)); 53 | } 54 | 55 | /** 56 | * @brief makeSecureShared Shared pointer that owns and manages memory block allocated by #mAlloc.byteAlloc placement version 57 | * @param size number of elements of type T 58 | * @param allocMem pointer to previoulsy allocate memeory block 59 | * @return shared_ptr of type T to #Array of #size elements 60 | * @throw any exception from #Array 61 | */ 62 | template 63 | using ArraySharedPtr = std::shared_ptr>; 64 | template< class T> 65 | ArraySharedPtr makeSecureShared( size_t size, T* allocMem ){ 66 | return std::shared_ptr>(new Array(size, allocMem)); 67 | } 68 | 69 | /** 70 | * Alias for weak_ptr of #Array 71 | */ 72 | template 73 | using ArrayWeakPtr = std::weak_ptr>; 74 | } } } 75 | #endif // ARRAY_H 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nakasendo Sandbox 2 | ** Powered by nChain's Nakasendo libraries ** 3 | 4 | This repository provides a sample Dockerfile which can be used to build a CentOS based image with the Nakasendo SDK installed along with its dependencies. I have published a built image on [DockerHub](https://hub.docker.com/r/dymurray/nakasendo/) which you can pull and immediately use. 5 | 6 | WARNING: By using this software to build applications with the nChain Nakasendo SDK you are agreeing that any applications built using this software will only be deployed on the Bitcoin Cash (BCH) blockchain. I am not responsible for any uses of this software that does not agree to these terms. Please read nChain's [Open Bitcoin Cash License](https://nchain.com/app/uploads/2018/04/nChain-Open-BCH-Licence.pdf) before using this tool. 7 | 8 | Due to the beta-nature of the SDK release, I will oblige to any takedown requests by nChain of this repository. I created this for educational purposes only. 9 | 10 | ## Prerequisites 11 | * docker 12 | 13 | ## Usage 14 | Currently, all building and execution should be done from within the container. The linking is done dynamically so unless your host has the libraries preinstalled then you cannot execute the binary outside of the container. Regardless, I recommend you mount your source directly into the container like so: 15 | ``` 16 | docker run -it -v $PWD:/home/nakasendo/:Z docker.io/dymurray/nakasendo 17 | ``` 18 | 19 | Note: the `:Z` argument to the volume mount is required since selinux is enabled within the container. 20 | 21 | ## Example 22 | I included in this repo an example test application (ripped from nChain example) which demonstrates Key Derivation from a private/pub key pair. 23 | ``` 24 | $ docker run -it -v $PWD/examples/c++/testapp:/home/nakasendo/testapp:Z docker.io/dymurray/nakasendo 25 | ``` 26 | Now from within the container we can build and run the compiled binary: 27 | ``` 28 | sh-4.2$ cd testapp/ 29 | sh-4.2$ make 30 | sh-4.2$ ./testapp 31 | Signature verified ok 32 | ``` 33 | 34 | You can start building your own examples using the documents in the `guides` folder. DISCLAIMER: I did not write any of these files. These are documents taken from the Nakasendo SDK. If I am granted permission I will post the full release docs but I do not want to step on any toes for now. 35 | 36 | ## Future Plans 37 | * Allow for static linking so that binary can be executed on Linux host outside of container 38 | * Include Bitcoin c++ libraries in container 39 | * Include Java dependencies 40 | * Reusable scripts that perform key cryptopraphic functions provided by Nakasendo 41 | * Shrink container size... 2 gigs is NOT ideal!! 42 | 43 | # THANK YOU! 44 | Huge thank you to nChain for allowing me to play with these libraries early. So much exciting potential moving forward and I would love to foster a community of developers sharing their new found use cases with these libraries. Any contributions are welcome! 45 | -------------------------------------------------------------------------------- /include/impl/memory/SecureArray.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef SECUREARRAY_H 5 | #define SECUREARRAY_H 6 | 7 | #include 8 | #include 9 | 10 | namespace nakasendo{ namespace impl{ namespace memory{ 11 | 12 | template 13 | using SecureArray = TArray; 14 | 15 | /** 16 | * @brief makeSecureUnique Unique pointer that owns and manages memory block allocated by #mAlloc.byteAlloc 17 | * @param size number of elements of type T 18 | * @return unique_ptr of type T to #SecureArray of #size elements 19 | * @throw any exception from #SecureArray 20 | */ 21 | template 22 | using SecureArrayUniquePtr = std::unique_ptr>; 23 | template< class T> 24 | SecureArrayUniquePtr makeSecureUnique( size_t size ){ 25 | return std::unique_ptr>(new SecureArray(size)); 26 | } 27 | 28 | /** 29 | * @brief makeSecureUnique Unique pointer that owns and manages memory block allocated by #mAlloc.byteAlloc placement version 30 | * @param size number of elements of type T 31 | * @param allocMem pointer to previoulsy allocate memeory block 32 | * @return unique_ptr of type T to #SecureArray of #size elements 33 | * @throw any exception from #SecureArray 34 | */ 35 | template 36 | using SecureArrayUniquePtr = std::unique_ptr>; 37 | template< class T> 38 | SecureArrayUniquePtr makeSecureUnique( size_t size, T* allocMem ){ 39 | return std::unique_ptr>(new SecureArray(size, allocMem)); 40 | } 41 | 42 | /** 43 | * @brief makeSecureShared Shared pointer that owns and manages memory block allocated by #mAlloc.byteAlloc 44 | * @param size number of elements of type T 45 | * @return shared_ptr of type T to #SecureArray of #size elements 46 | * @throw any exception from #SecureArray 47 | */ 48 | template 49 | using SecureArraySharedPtr = std::shared_ptr>; 50 | template< class T> 51 | SecureArraySharedPtr makeSecureShared( size_t size ){ 52 | return std::shared_ptr>(new SecureArray(size)); 53 | } 54 | 55 | /** 56 | * @brief makeSecureShared Shared pointer that owns and manages memory block allocated by #mAlloc.byteAlloc placement version 57 | * @param size number of elements of type T 58 | * @param allocMem pointer to previoulsy allocate memeory block 59 | * @return shared_ptr of type T to #SecureArray of #size elements 60 | * @throw any exception from #SecureArray 61 | */ 62 | template 63 | using SecureArraySharedPtr = std::shared_ptr>; 64 | template< class T> 65 | SecureArraySharedPtr makeSecureShared( size_t size, T* allocMem ){ 66 | return std::shared_ptr>(new SecureArray(size, allocMem)); 67 | } 68 | 69 | /** 70 | * Alias for weak_ptr of #SecureArray 71 | */ 72 | template 73 | using SecureArrayWeakPtr = std::weak_ptr>; 74 | } } } 75 | #endif // SECUREARRAY_H 76 | -------------------------------------------------------------------------------- /include/impl/Base58DataT.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * Handle the encoding and decoding of Base58 and Base58Check data. 6 | */ 7 | 8 | #include 9 | 10 | namespace nakasendo { namespace impl 11 | { 12 | 13 | namespace 14 | { 15 | const char* Base58Alphabet { "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" }; 16 | } 17 | 18 | // Encode our raw data as a Base58 string. 19 | // Functionality lifted from Bitcoin ABC. 20 | template 21 | auto Base58Data::encode(const typename std::enable_if::value, V>::type& data) 22 | -> typename std::enable_if::value || std::is_same::value, S>::type 23 | { 24 | const uint8_t* pbegin { data.data() }; 25 | const uint8_t* pend { pbegin + data.size() }; 26 | 27 | // Skip & count leading zeroes. 28 | int zeroes {0}; 29 | int length {0}; 30 | while(pbegin != pend && *pbegin == 0) 31 | { 32 | ++pbegin; 33 | ++zeroes; 34 | } 35 | 36 | // Allocate enough space in big-endian base58 representation. 37 | // log(256) / log(58), rounded up. 38 | int size { static_cast((pend - pbegin) * 138 / 100 + 1) }; 39 | std::vector b58(size); 40 | // Process the bytes. 41 | while(pbegin != pend) 42 | { 43 | int carry { *pbegin }; 44 | int i {0}; 45 | // Apply "b58 = b58 * 256 + ch". 46 | for(std::vector::reverse_iterator it = b58.rbegin(); 47 | (carry != 0 || i < length) && (it != b58.rend()); it++, i++) 48 | { 49 | carry += 256 * (*it); 50 | *it = carry % 58; 51 | carry /= 58; 52 | } 53 | 54 | length = i; 55 | ++pbegin; 56 | } 57 | 58 | // Skip leading zeroes in base58 result. 59 | std::vector::iterator it { b58.begin() + (size - length) }; 60 | while(it != b58.end() && *it == 0) 61 | { 62 | ++it; 63 | } 64 | 65 | // Translate the result into a string. 66 | S str; 67 | str.reserve(zeroes + (b58.end() - it)); 68 | str.assign(zeroes, '1'); 69 | while(it != b58.end()) 70 | { 71 | str += Base58Alphabet[*(it++)]; 72 | } 73 | 74 | return str; 75 | } 76 | 77 | // Encode our raw data and version bytes in Base58Checked format. 78 | template 79 | auto Base58Data::checkEncode(const typename std::enable_if::value, V>::type& data) 80 | -> typename std::enable_if::value || std::is_same::value, S>::type 81 | { 82 | // Add 4-byte hash check to the end 83 | V allData { data }; 84 | utils::uint256 hash { utils::Hash256(data.begin(), data.end()) }; 85 | allData.insert(allData.end(), (uint8_t*)&hash, (uint8_t*)&hash + 4); 86 | return encode(allData); 87 | } 88 | 89 | } // end of namespace impl 90 | } // end of namespace nakasendo 91 | -------------------------------------------------------------------------------- /include/impl/memory/KeyExport.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef KEYEXPORT_H 5 | #define KEYEXPORT_H 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | namespace nakasendo { namespace impl { namespace memory { 17 | 18 | /** 19 | * @brief The KeyExport class 20 | * @details This class is a delivery container for a Key entity 21 | * It consists of secure memory block with Key content, it size, 22 | * metadata structure and an error message. Class data is readonly 23 | * it can be populated by KeyStorage class only 24 | */ 25 | template 26 | class KeyExport{ 27 | friend class KeyStorage; 28 | public: 29 | KeyExport() = default; 30 | KeyExport(const KeyExport& ) = delete; 31 | KeyExport& operator==(const KeyExport& ) = delete; 32 | 33 | 34 | KeyExport(KeyExport&& other): 35 | mMeta(std::move(other.mMeta)), 36 | mpData(std::move(other.mpData)), 37 | mDataSize(other.mDataSize), 38 | mStatusMsg(std::move(other.mStatusMsg)) 39 | { other.mDataSize = 0; } 40 | 41 | 42 | KeyExport& operator==( KeyExport&& other) { 43 | if( this == &other ) 44 | return *this; 45 | 46 | mMeta = std::move(other.mMeta); 47 | mpData = std::move(other.mpData); 48 | mDataSize = other.mDataSize; other.mDataSize = 0; 49 | mStatusMsg = std::move(other.mStatusMsg); 50 | 51 | return *this; 52 | } 53 | 54 | 55 | ~KeyExport(){} 56 | 57 | /** 58 | * @brief name Return key name. Name is element of 59 | * meta data structure 60 | * @return Key name 61 | */ 62 | const std::string& name() const { 63 | return mMeta.name(); 64 | } 65 | 66 | /** 67 | * @brief size Size of secure memory block 68 | * @return Mem block size 69 | */ 70 | size_t size() const { 71 | return mDataSize; 72 | } 73 | 74 | /** 75 | * @brief data Pointer to allocated memory block 76 | * @return Pointer to secure mem block 77 | */ 78 | const T* data()const { 79 | return mpData.data(); 80 | } 81 | 82 | /** 83 | * @brief error Error message that could be populated 84 | * by KeyStorage class 85 | * @return Error message 86 | */ 87 | const utils::Status& status() const { 88 | return *mStatusMsg; 89 | } 90 | 91 | private: 92 | KeyMeta mMeta; // + SOME META data 93 | SecureArray mpData; /**< Secure data block */ 94 | size_t mDataSize = 0; /**< Secure data block size */ 95 | 96 | const utils::Status* mStatusMsg; /**< Error message */ 97 | }; 98 | 99 | } } } 100 | #endif // KEYEXPORT_H 101 | -------------------------------------------------------------------------------- /include/secp256k1/src/num.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_NUM_H 8 | #define SECP256K1_NUM_H 9 | 10 | #ifndef USE_NUM_NONE 11 | 12 | #if defined HAVE_CONFIG_H 13 | #include "libsecp256k1-config.h" 14 | #endif 15 | 16 | #if defined(USE_NUM_GMP) 17 | #include "num_gmp.h" 18 | #else 19 | #error "Please select num implementation" 20 | #endif 21 | 22 | /** Copy a number. */ 23 | static void secp256k1_num_copy(secp256k1_num *r, const secp256k1_num *a); 24 | 25 | /** Convert a number's absolute value to a binary big-endian string. 26 | * There must be enough place. */ 27 | static void secp256k1_num_get_bin(unsigned char *r, unsigned int rlen, const secp256k1_num *a); 28 | 29 | /** Set a number to the value of a binary big-endian string. */ 30 | static void secp256k1_num_set_bin(secp256k1_num *r, const unsigned char *a, unsigned int alen); 31 | 32 | /** Compute a modular inverse. The input must be less than the modulus. */ 33 | static void secp256k1_num_mod_inverse(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *m); 34 | 35 | /** Compute the jacobi symbol (a|b). b must be positive and odd. */ 36 | static int secp256k1_num_jacobi(const secp256k1_num *a, const secp256k1_num *b); 37 | 38 | /** Compare the absolute value of two numbers. */ 39 | static int secp256k1_num_cmp(const secp256k1_num *a, const secp256k1_num *b); 40 | 41 | /** Test whether two number are equal (including sign). */ 42 | static int secp256k1_num_eq(const secp256k1_num *a, const secp256k1_num *b); 43 | 44 | /** Add two (signed) numbers. */ 45 | static void secp256k1_num_add(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); 46 | 47 | /** Subtract two (signed) numbers. */ 48 | static void secp256k1_num_sub(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); 49 | 50 | /** Multiply two (signed) numbers. */ 51 | static void secp256k1_num_mul(secp256k1_num *r, const secp256k1_num *a, const secp256k1_num *b); 52 | 53 | /** Replace a number by its remainder modulo m. M's sign is ignored. The result is a number between 0 and m-1, 54 | even if r was negative. */ 55 | static void secp256k1_num_mod(secp256k1_num *r, const secp256k1_num *m); 56 | 57 | /** Right-shift the passed number by bits bits. */ 58 | static void secp256k1_num_shift(secp256k1_num *r, int bits); 59 | 60 | /** Check whether a number is zero. */ 61 | static int secp256k1_num_is_zero(const secp256k1_num *a); 62 | 63 | /** Check whether a number is one. */ 64 | static int secp256k1_num_is_one(const secp256k1_num *a); 65 | 66 | /** Check whether a number is strictly negative. */ 67 | static int secp256k1_num_is_neg(const secp256k1_num *a); 68 | 69 | /** Change a number's sign. */ 70 | static void secp256k1_num_negate(secp256k1_num *r); 71 | 72 | #endif 73 | 74 | #endif /* SECP256K1_NUM_H */ 75 | -------------------------------------------------------------------------------- /include/interface/PubKey.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /** 5 | * Encapsulate a logical public key used within the SDK 6 | */ 7 | 8 | #ifndef _NCHAIN_SDK_PUB_KEY_H_ 9 | #define _NCHAIN_SDK_PUB_KEY_H_ 10 | 11 | #include 12 | #include "BlockChainAddress.h" 13 | 14 | namespace nakasendo 15 | { 16 | /// Forward declaration of pointer type 17 | class PubKey; 18 | /// Unique pointer type 19 | using PubKeyPtr = std::unique_ptr; 20 | /// Shared pointer type 21 | using PubKeySPtr = std::shared_ptr; 22 | 23 | /** 24 | * This class encapsulates a logical public key used within the SDK. 25 | */ 26 | class PubKey 27 | { 28 | public: 29 | /// Public key can be compressed or uncompressed. 30 | enum class Type { COMPRESSED, UNCOMPRESSED }; 31 | /// Defualt destructor 32 | virtual ~PubKey() = default; 33 | 34 | public: 35 | /** 36 | * Check if the public key is compressed. 37 | */ 38 | virtual bool isCompressed() const = 0; 39 | 40 | /** 41 | * Decompress the public key if it's compressed. 42 | */ 43 | virtual void decompress() = 0; 44 | 45 | /** 46 | * Compress the public key if it's uncompressed. 47 | */ 48 | virtual void compress() = 0; 49 | 50 | /** 51 | * Get a vector of public key. 52 | * @return A vector containing raw public key. 53 | */ 54 | virtual std::vector getContent() const = 0; 55 | 56 | /** 57 | * Get a public key as a hex string. 58 | * @return A hexadecimal string representing of public key. 59 | */ 60 | virtual std::string getContentAsHexString() const = 0; 61 | 62 | /** 63 | * Derive a blockchain address from the public key. 64 | * @return A pointer to the blockchain address derived from the public key. 65 | */ 66 | virtual BlockChainAddressPtr getBlockChainAddress() const = 0; 67 | 68 | /** 69 | * Verify a signature of a message. 70 | * @param message The message the signature should be for. 71 | * @param signature The signature. 72 | * @return True if we can verify the signature. 73 | */ 74 | virtual bool verify(const std::vector& message, 75 | const std::vector& signature) const = 0; 76 | 77 | /** 78 | * Encrypt the given message so it may only be decrypted by our 79 | * corresponding private key. 80 | * @param message The message to encrypt. 81 | * @return An encrypted message. 82 | */ 83 | virtual std::vector encrypt(const impl::memory::SecureByteVec& message) const = 0; 84 | 85 | /** 86 | * Deterministically derives a new key from this key using the given 87 | * message. 88 | * @param message The message to be used in deterministically deriving 89 | * the new key. 90 | * @return A derived new key. 91 | */ 92 | virtual PubKeyPtr derive(const std::vector& message) const = 0; 93 | 94 | }; 95 | 96 | } // end of namespace nakasendo 97 | 98 | #endif // _NCHAIN_SDK_PUB_KEY_H_ 99 | -------------------------------------------------------------------------------- /include/impl/MetaDataDefinitions.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * Some well known and useful MetaData definitions. 6 | */ 7 | 8 | #ifndef _NCHAIN_SDK_META_DATA_DEFINITIONS_H_ 9 | #define _NCHAIN_SDK_META_DATA_DEFINITIONS_H_ 10 | 11 | #include "utils/EnumCast.h" 12 | 13 | #include 14 | 15 | namespace nakasendo { namespace impl 16 | { 17 | 18 | /// Useful internal metadata types. 19 | /// 20 | /// The metadata definitions consist of a list of metadata key types 21 | /// and for each key, a list of expected values. If you add a new key 22 | /// to the KeyType enum, then you should also create a new enumeration 23 | /// listing the expected values for that new key type. 24 | /// 25 | /// NOTE: Don't forget to update the enum_table_t for KeyType after 26 | /// modifying KeyType! 27 | struct MetaDataDefinitions 28 | { 29 | 30 | /// Metadata key types 31 | enum class KeyType 32 | { 33 | UNKNOWN, 34 | NETWORK_TYPE, 35 | PUBLIC_KEY, 36 | COMPRESSION_TYPE 37 | }; 38 | 39 | /// Metadata value types for key = NETWORK_TYPE 40 | enum class NetworkType 41 | { 42 | UNKNOWN, 43 | MAIN_NET, 44 | TEST_NET, 45 | REGTEST 46 | }; 47 | 48 | /// Metadata value types for key = COMPRESSION_TYPE 49 | enum class CompressionType 50 | { 51 | UNKNOWN, 52 | COMPRESSED, 53 | UNCOMPRESSED 54 | }; 55 | }; 56 | 57 | /// Enable enum_cast for KeyType 58 | inline const utils::enumTableT& 59 | enumTable(MetaDataDefinitions::KeyType) 60 | { 61 | static utils::enumTableT table 62 | { 63 | {MetaDataDefinitions::KeyType::UNKNOWN, "Unknown"}, 64 | {MetaDataDefinitions::KeyType::NETWORK_TYPE, "NetworkType"}, 65 | {MetaDataDefinitions::KeyType::PUBLIC_KEY, "PublicKey"}, 66 | {MetaDataDefinitions::KeyType::COMPRESSION_TYPE, "CompressionType"} 67 | }; 68 | return table; 69 | } 70 | 71 | /// Enable enum_cast for NetworkType 72 | inline const utils::enumTableT& 73 | enumTable(MetaDataDefinitions::NetworkType) 74 | { 75 | static utils::enumTableT table 76 | { 77 | {MetaDataDefinitions::NetworkType::UNKNOWN, "Unknown"}, 78 | {MetaDataDefinitions::NetworkType::MAIN_NET, "MainNet"}, 79 | {MetaDataDefinitions::NetworkType::TEST_NET, "TestNet"}, 80 | {MetaDataDefinitions::NetworkType::REGTEST, "RegTest"} 81 | }; 82 | return table; 83 | } 84 | 85 | /// Enable enum_cast for CompressionType 86 | inline const utils::enumTableT& 87 | enumTable(MetaDataDefinitions::CompressionType) 88 | { 89 | static utils::enumTableT table 90 | { 91 | {MetaDataDefinitions::CompressionType::UNKNOWN, "Unknown"}, 92 | {MetaDataDefinitions::CompressionType::COMPRESSED, "Compressed"}, 93 | {MetaDataDefinitions::CompressionType::UNCOMPRESSED, "Uncompressed"}, 94 | }; 95 | return table; 96 | } 97 | 98 | }} 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /include/secp256k1/src/util.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_UTIL_H 8 | #define SECP256K1_UTIL_H 9 | 10 | #if defined HAVE_CONFIG_H 11 | #include "libsecp256k1-config.h" 12 | #endif 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | typedef struct { 19 | void (*fn)(const char *text, void* data); 20 | const void* data; 21 | } secp256k1_callback; 22 | 23 | static SECP256K1_INLINE void secp256k1_callback_call(const secp256k1_callback * const cb, const char * const text) { 24 | cb->fn(text, (void*)cb->data); 25 | } 26 | 27 | #ifdef DETERMINISTIC 28 | #define TEST_FAILURE(msg) do { \ 29 | fprintf(stderr, "%s\n", msg); \ 30 | abort(); \ 31 | } while(0); 32 | #else 33 | #define TEST_FAILURE(msg) do { \ 34 | fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, msg); \ 35 | abort(); \ 36 | } while(0) 37 | #endif 38 | 39 | #ifdef HAVE_BUILTIN_EXPECT 40 | #define EXPECT(x,c) __builtin_expect((x),(c)) 41 | #else 42 | #define EXPECT(x,c) (x) 43 | #endif 44 | 45 | #ifdef DETERMINISTIC 46 | #define CHECK(cond) do { \ 47 | if (EXPECT(!(cond), 0)) { \ 48 | TEST_FAILURE("test condition failed"); \ 49 | } \ 50 | } while(0) 51 | #else 52 | #define CHECK(cond) do { \ 53 | if (EXPECT(!(cond), 0)) { \ 54 | TEST_FAILURE("test condition failed: " #cond); \ 55 | } \ 56 | } while(0) 57 | #endif 58 | 59 | /* Like assert(), but when VERIFY is defined, and side-effect safe. */ 60 | #if defined(COVERAGE) 61 | #define VERIFY_CHECK(check) 62 | #define VERIFY_SETUP(stmt) 63 | #elif defined(VERIFY) 64 | #define VERIFY_CHECK CHECK 65 | #define VERIFY_SETUP(stmt) do { stmt; } while(0) 66 | #else 67 | #define VERIFY_CHECK(cond) do { (void)(cond); } while(0) 68 | #define VERIFY_SETUP(stmt) 69 | #endif 70 | 71 | static SECP256K1_INLINE void *checked_malloc(const secp256k1_callback* cb, size_t size) { 72 | void *ret = malloc(size); 73 | if (ret == NULL) { 74 | secp256k1_callback_call(cb, "Out of memory"); 75 | } 76 | return ret; 77 | } 78 | 79 | /* Macro for restrict, when available and not in a VERIFY build. */ 80 | #if defined(SECP256K1_BUILD) && defined(VERIFY) 81 | # define SECP256K1_RESTRICT 82 | #else 83 | # if (!defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L) ) 84 | # if SECP256K1_GNUC_PREREQ(3,0) 85 | # define SECP256K1_RESTRICT __restrict__ 86 | # elif (defined(_MSC_VER) && _MSC_VER >= 1400) 87 | # define SECP256K1_RESTRICT __restrict 88 | # else 89 | # define SECP256K1_RESTRICT 90 | # endif 91 | # else 92 | # define SECP256K1_RESTRICT restrict 93 | # endif 94 | #endif 95 | 96 | #if defined(_WIN32) 97 | # define I64FORMAT "I64d" 98 | # define I64uFORMAT "I64u" 99 | #else 100 | # define I64FORMAT "lld" 101 | # define I64uFORMAT "llu" 102 | #endif 103 | 104 | #if defined(HAVE___INT128) 105 | # if defined(__GNUC__) 106 | # define SECP256K1_GNUC_EXT __extension__ 107 | # else 108 | # define SECP256K1_GNUC_EXT 109 | # endif 110 | SECP256K1_GNUC_EXT typedef unsigned __int128 uint128_t; 111 | #endif 112 | 113 | #endif /* SECP256K1_UTIL_H */ 114 | -------------------------------------------------------------------------------- /include/impl/MetaDataCollectionImpl.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * Implementation of a collection of metadata. Provides some utility methods on 6 | * top of what map gives us and enforces thread safety. 7 | */ 8 | 9 | #ifndef _NCHAIN_SDK_META_DATA_COLLECTION_IMPL_H_ 10 | #define _NCHAIN_SDK_META_DATA_COLLECTION_IMPL_H_ 11 | 12 | #include "utils/EnumCast.h" 13 | 14 | #include 15 | #include 16 | 17 | namespace nakasendo { namespace impl 18 | { 19 | 20 | /// Implements a MetaDataCollection. 21 | class MetaDataCollectionImpl : public MetaDataCollection 22 | { 23 | public: 24 | 25 | /// Default constructor 26 | MetaDataCollectionImpl() = default; 27 | /// Copy constructor 28 | MetaDataCollectionImpl(const MetaDataCollectionImpl& that); 29 | /// Move constructor 30 | MetaDataCollectionImpl(MetaDataCollectionImpl&& that); 31 | 32 | /// Assignment 33 | MetaDataCollectionImpl& operator=(const MetaDataCollectionImpl& that); 34 | /// Move assignment 35 | MetaDataCollectionImpl& operator=(MetaDataCollectionImpl&& that); 36 | 37 | /** 38 | * Check if the given key exists in the collection. 39 | * @param key The key to look for. 40 | * @return True if an entry for the given key was found. 41 | */ 42 | bool keyExists(const MetaDataKey& key) const override; 43 | 44 | /** 45 | * Lookup the metadata value for some key. Throws if not found. 46 | * @param key The metadata key to lookup. 47 | * @return The metadata value for the given key. 48 | */ 49 | const MetaDataValue& getMetaValue(const MetaDataKey& key) const override; 50 | 51 | /** 52 | * Set the value of a piece of metadata. 53 | * @param meta The metadata to set. 54 | */ 55 | void setMetaData(const MetaData& meta) override; 56 | 57 | /** 58 | * Get a copy of all our metadata. 59 | * @return A copy of all our metadata. 60 | */ 61 | MetaMap getAllMetaData() const override; 62 | 63 | /** 64 | * Copy some item of metadata. 65 | * @param src The MetaDataCollection to copy from. 66 | * @param key The key for the item to copy. 67 | */ 68 | template 69 | void copyMetaData(MetaDataCollectionConstSPtr& src, MetaType key) 70 | { 71 | const std::string& keyName { utils::enum_cast(key) }; 72 | setMetaData( { keyName, src->getMetaValue(keyName) } ); 73 | } 74 | 75 | 76 | // JSONSerialisable interface 77 | 78 | /// Get a unique identifer for this JSONSerialisable type. 79 | const std::string jsonObjectType() const override; 80 | 81 | /// Construct a boost::property_tree representation of ourselves. 82 | boost::property_tree::ptree toJson(const SerialisationFormat& fmt) const override; 83 | 84 | /// Set ourselves from the given boost::property_tree. 85 | void fromJson(const boost::property_tree::ptree& root, 86 | const SerialisationFormat& fmt) override; 87 | 88 | private: 89 | 90 | /// Mutex for thread safety 91 | mutable std::mutex mMtx {}; 92 | 93 | /// A map of metadata keys to values 94 | MetaMap mMetaData {}; 95 | 96 | }; 97 | 98 | /// Pointer type 99 | using MetaDataCollectionImplPtr = std::shared_ptr; 100 | 101 | }} 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /include/impl/JSONSecretBackingStore.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * An implementation of a secret backing store that serialises 6 | * secrets to a flat JSON file. 7 | */ 8 | 9 | #ifndef _NCHAIN_SDK_JSON_SECRET_BACKING_STORE_H_ 10 | #define _NCHAIN_SDK_JSON_SECRET_BACKING_STORE_H_ 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | namespace nakasendo { namespace impl { 18 | 19 | /// Forward declaration of JSONSecretBackingStore pointer type 20 | class JSONSecretBackingStore; 21 | /// Unique pointer type 22 | using JSONSecretBackingStorePtr = std::unique_ptr; 23 | /// Shared pointer type 24 | using JSONSecretBackingStoreSPtr = std::shared_ptr; 25 | 26 | /// A flat JSON file based secret DB. 27 | class JSONSecretBackingStore : public SecretBackingStore 28 | { 29 | public: 30 | 31 | /// Initialisation modes for the backing store file. 32 | enum class InitialisationMode 33 | { 34 | INIT_NONE, // Do not initialise the file (we assume it already exists). 35 | INIT_CREATE // Create an empty file. 36 | }; 37 | 38 | /** 39 | * Constructor. 40 | * @param fileName Fully qualified filename of file to persist to. 41 | * @param init How to initialise the backing file. 42 | */ 43 | JSONSecretBackingStore(const std::string& fileName, 44 | InitialisationMode init = InitialisationMode::INIT_NONE); 45 | 46 | /** 47 | * Save a new secret. 48 | * @param secret The new secret to persist. 49 | */ 50 | void saveSecret(const SecretSPtr& secret) override; 51 | 52 | /** 53 | * Save a list of new secrets. This will be more efficient than repeatedly 54 | * calling saveSecret() for each individual secret. 55 | * @param secrets The new secrets to persist. 56 | */ 57 | void saveSecrets(const std::vector& secrets) override; 58 | 59 | /** 60 | * Update a changed secret. 61 | * @param name The name of the changed secret. Note that this parameter is 62 | * required because it might be the name itself of the secret that has changed. 63 | * @param secret New details of the changed secret. 64 | */ 65 | void updateSecret(const std::string& name, const SecretSPtr& secret) override; 66 | 67 | /** 68 | * Remove a secret. 69 | * @param name The name of the secret to remove. 70 | */ 71 | void removeSecret(const std::string& name) override; 72 | 73 | /** 74 | * Load all stored secrets. 75 | */ 76 | void loadAll() override; 77 | 78 | /** 79 | * Remove everything currently in the backing store and replace it with 80 | * whatever is currently held by the secret store. 81 | * @param secrets The required new contents of the backing store. 82 | */ 83 | void replaceAll(const std::vector& secrets) override; 84 | 85 | private: 86 | 87 | /// Rewrite our file from our map 88 | void writeToFile(); 89 | 90 | /// A mutex for thread safety. 91 | mutable std::mutex mMtx {}; 92 | 93 | /// Filename to use for saving to. 94 | std::string mFileName {}; 95 | 96 | /// Maintain a map of persisted secrets 97 | std::unordered_map mSecrets {}; 98 | 99 | }; 100 | 101 | }} 102 | 103 | #endif 104 | -------------------------------------------------------------------------------- /include/impl/ContextAction.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef CONTEXTACTION_H 5 | #define CONTEXTACTION_H 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | namespace{ 15 | template 16 | struct callImpl 17 | { 18 | static void call(F f, Tuple && t){ 19 | callImpl::call(f, std::forward(t)); 20 | } 21 | }; 22 | 23 | template 24 | struct callImpl 25 | { 26 | static void call(F f, Tuple && t){ 27 | f(std::get(std::forward(t))...); 28 | } 29 | }; 30 | 31 | // User call 32 | template 33 | void call(F f, Tuple && t) 34 | { 35 | typedef typename std::decay::type ttype; 36 | callImpl::value, std::tuple_size::value>::call(f, std::forward(t)); 37 | } 38 | } 39 | 40 | 41 | namespace nakasendo { 42 | namespace impl { 43 | 44 | class AContextAction{ 45 | public: 46 | virtual ~AContextAction() = default; 47 | virtual bool runAction(const std::string& name) = 0; 48 | }; 49 | 50 | template 51 | class ContextAction : public AContextAction 52 | { 53 | public: 54 | ContextAction(){} 55 | 56 | void addAction(const std::string& name, Functor actionFunc, FunctorArgs&&... args){ 57 | std::lock_guard locker(mMutex); 58 | mActions.emplace(name, FunctorArgsPack( actionFunc, args... )); 59 | } 60 | 61 | bool removeAction(const std::string& name){ 62 | std::lock_guard locker(mMutex); 63 | 64 | auto found = mActions.find(name); 65 | if( found != mActions.end() ){ 66 | mActions.erase(found); 67 | return true; 68 | } 69 | 70 | return false; 71 | } 72 | 73 | bool runAction(const std::string& name) override{ 74 | std::lock_guard locker(mMutex); 75 | 76 | auto found = mActions.find(name); 77 | if( found != mActions.end() ){ 78 | FunctorArgsPack& currAction = found->second; 79 | call(currAction.mFunctor, currAction.mArgs); 80 | return true; 81 | } 82 | return false; 83 | } 84 | 85 | private: 86 | struct FunctorArgsPack{ 87 | FunctorArgsPack(Functor functor, FunctorArgs&&... args ): 88 | mFunctor(functor), 89 | mArgs(std::forward_as_tuple(args...)) 90 | {} 91 | 92 | Functor mFunctor; 93 | std::tuple mArgs; 94 | }; 95 | 96 | std::mutex mMutex; 97 | std::map mActions; 98 | 99 | }; 100 | } 101 | } 102 | 103 | 104 | 105 | #endif // CONTEXTACTION_H 106 | -------------------------------------------------------------------------------- /include/impl/utils/EnumCast.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * A general purpose mechanism for casting between enums and strings. 6 | * 7 | * Given an enumeration, we also provide a function enumTable() that returns 8 | * an enumTableT specifying a mapping between the enumeration and the 9 | * castable string values. With that in place we can perform casting with 10 | * enum_cast(string) or enum_cast(Enum). 11 | * 12 | * Eg: 13 | * 14 | * enum class MyTypes { UNKNOWN, Type1, Type2 }; 15 | * 16 | * const enumTableT& enumTable(MyTypes, std::string) 17 | * { 18 | * static enumTableT table 19 | * { 20 | * {MyTypes::UNKNOWN, "Unknown"}, {MyTypes::Type1, "Type 1"}, {MyTypes::Type2, "Type 2"} 21 | * }; 22 | * return table; 23 | * } 24 | * 25 | * std::string str { enum_cast(MyTypes::Type1) }; 26 | * MyTypes mytype { enum_cast(str) }; 27 | */ 28 | 29 | #ifndef _NCHAIN_SDK_ENUM_CAST_H_ 30 | #define _NCHAIN_SDK_ENUM_CAST_H_ 31 | 32 | #include 33 | #include 34 | 35 | namespace nakasendo { namespace impl { namespace utils 36 | { 37 | 38 | /// The type returned by all enum_table() functions. 39 | template 40 | class enumTableT 41 | { 42 | public: 43 | 44 | /// Constructor 45 | enumTableT(std::initializer_list> table) 46 | : mLookupTable{table}, mDefaultValue{*table.begin()} 47 | { 48 | // Populate reverse lookup table 49 | for(const typename LookupTable::value_type& item : mLookupTable) 50 | { 51 | mReverseLookupTable[item.second] = item.first; 52 | } 53 | } 54 | 55 | /// Cast from enum to string 56 | template 57 | const std::string& castToString(const CastType& from) const 58 | { 59 | typename LookupTable::const_iterator it { mLookupTable.find(from) }; 60 | if(it != mLookupTable.end()) 61 | { 62 | return it->second; 63 | } 64 | return mDefaultValue.second; 65 | } 66 | 67 | /// Cast from string to enum 68 | template 69 | const From& castToEnum(const CastType& to) const 70 | { 71 | typename ReverseLookupTable::const_iterator it { mReverseLookupTable.find(to) }; 72 | if(it != mReverseLookupTable.end()) 73 | { 74 | return it->second; 75 | } 76 | return mDefaultValue.first; 77 | } 78 | 79 | private: 80 | 81 | using LookupTable = std::unordered_map; 82 | using ReverseLookupTable = std::unordered_map; 83 | 84 | LookupTable mLookupTable {}; 85 | ReverseLookupTable mReverseLookupTable {}; 86 | typename LookupTable::value_type mDefaultValue {}; 87 | 88 | }; 89 | 90 | /// Cast to string 91 | template 92 | std::string enum_cast(const FromType& value) 93 | { 94 | return enumTable(FromType{}).castToString(value); 95 | } 96 | 97 | /// Cast from string 98 | template 99 | ToType enum_cast(const std::string& value) 100 | { 101 | return enumTable(ToType{}).castToEnum(value); 102 | } 103 | 104 | /// Cast from convertable to string 105 | template 106 | ToType enum_cast(const char* value) 107 | { 108 | return enumTable(ToType{}).castToEnum(value); 109 | } 110 | 111 | 112 | }}} 113 | 114 | #endif 115 | -------------------------------------------------------------------------------- /include/impl/memory/SecureByteAlloc.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef SECUREBYTEALLOC_H 5 | #define SECUREBYTEALLOC_H 6 | 7 | #include 8 | #include 9 | 10 | namespace nakasendo{ namespace impl{ namespace memory{ 11 | 12 | /** 13 | * @brief byteAlloc Allocates requested number of bytes as a conventional memory 14 | * @param n number of bytes to allocate 15 | * @return non-null pointer to suitably aligned memory of size at least n 16 | * @throw any exception that could be thrown by operator new 17 | */ 18 | extern void* byteAlloc(size_t n); 19 | 20 | /** 21 | * @brief byteFree Deallocates storage previously allocated by a matching #byteAlloc(size_t n) 22 | * @param ptr pointer to a memory block to deallocate or a null pointer 23 | */ 24 | extern void byteFree(void* ptr) noexcept; 25 | 26 | /** 27 | * @brief byteAlloc Allocates requested number of bytes from preacllocated conventional memory block 28 | * @param n number of bytes to allocate 29 | * @param stage pointer to a memory area to allocate bytes at 30 | * @return non-null pointer to suitably aligned memory of size at least n 31 | * @throw any exception that could be thrown by operator new 32 | */ 33 | extern void *byteAlloc(size_t n, void* stage); 34 | 35 | /** 36 | * @brief byteFree Deallocates storage previously allocated by a matching #byteAlloc(size_t n, void* ptr) 37 | * @param ptr pointer to a memory block to deallocate or a null pointer 38 | * @param stage pointer to a memory area where bytes are allocated 39 | */ 40 | extern void byteFree(void* volatile ptr, void* stage) noexcept; 41 | 42 | /** 43 | * @brief secureByteAlloc Allocates memory block and register it with #PageLockerManager 44 | * as non swappable in order to avoid memory block being placed in a swap file 45 | * @param n Required Memory block size in bytes 46 | * @return Pointer to allocated memory block 47 | * @throw bad_alloc() if memory allocation fails or secure_bad_alloc() if locking memory block fails 48 | */ 49 | extern void *secureByteAlloc(size_t n); 50 | 51 | /** 52 | * @brief secureByteAlloc Placement allocator .Allocates memory block and register it with #PageLockerManager 53 | * as non swappable in order to avoid memory block being placed in a swap file 54 | * @param n Required Memory block size in bytes 55 | * @param stage Required Pointer to previously allocated memory block. If size of memory block pointed by #ptr is 56 | * less then #n then behavior undefined 57 | * @return Pointer to allocated memory block 58 | * @throw bad_alloc() if ptr is null or secure_bad_alloc() if locking memory block fails 59 | */ 60 | extern void *secureByteAlloc(size_t n, void* stage); 61 | 62 | /** 63 | * @brief secureByteFree Releases memory block previously allocated by #secureByteAlloc. 64 | * The memory content is wiped before the release 65 | * @param ptr Pointer to a memory block 66 | * @param n Block size 67 | */ 68 | extern void secureByteFree( void* volatile ptr) noexcept; 69 | 70 | /** 71 | * @brief secureByteFree Releases memory block previously allocated by placement #secureByteAlloc. 72 | * The memory content is wiped before the release 73 | * @param ptr Pointer to a memory block 74 | * @param stage Pointer to a preallocated memory block 75 | * @param n Block size 76 | */ 77 | extern void secureByteFree(void* volatile ptr, void* stage) noexcept; 78 | 79 | /** 80 | * @brief toUnsecure Converts memory allocated by #secureByteAlloc() to a conventional memory which 81 | * can be freed by a corresponding #byteFree 82 | * @param ptr Pointer to a memory block 83 | */ 84 | extern void convertToUnsecure(void* ptr) noexcept; 85 | 86 | /** 87 | * @brief secureCheckSize 88 | * @param ptr 89 | * @return 90 | */ 91 | extern size_t secureCheckSize(void* ptr) noexcept; 92 | 93 | } } } 94 | #endif // SECUREUNIQUEPTR_H 95 | -------------------------------------------------------------------------------- /include/secp256k1/src/eckey_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_ECKEY_IMPL_H 8 | #define SECP256K1_ECKEY_IMPL_H 9 | 10 | #include "eckey.h" 11 | 12 | #include "scalar.h" 13 | #include "field.h" 14 | #include "group.h" 15 | #include "ecmult_gen.h" 16 | 17 | static int secp256k1_eckey_pubkey_parse(secp256k1_ge *elem, const unsigned char *pub, size_t size) { 18 | if (size == 33 && (pub[0] == SECP256K1_TAG_PUBKEY_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_ODD)) { 19 | secp256k1_fe x; 20 | return secp256k1_fe_set_b32(&x, pub+1) && secp256k1_ge_set_xo_var(elem, &x, pub[0] == SECP256K1_TAG_PUBKEY_ODD); 21 | } else if (size == 65 && (pub[0] == 0x04 || pub[0] == 0x06 || pub[0] == 0x07)) { 22 | secp256k1_fe x, y; 23 | if (!secp256k1_fe_set_b32(&x, pub+1) || !secp256k1_fe_set_b32(&y, pub+33)) { 24 | return 0; 25 | } 26 | secp256k1_ge_set_xy(elem, &x, &y); 27 | if ((pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_EVEN || pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD) && 28 | secp256k1_fe_is_odd(&y) != (pub[0] == SECP256K1_TAG_PUBKEY_HYBRID_ODD)) { 29 | return 0; 30 | } 31 | return secp256k1_ge_is_valid_var(elem); 32 | } else { 33 | return 0; 34 | } 35 | } 36 | 37 | static int secp256k1_eckey_pubkey_serialize(secp256k1_ge *elem, unsigned char *pub, size_t *size, int compressed) { 38 | if (secp256k1_ge_is_infinity(elem)) { 39 | return 0; 40 | } 41 | secp256k1_fe_normalize_var(&elem->x); 42 | secp256k1_fe_normalize_var(&elem->y); 43 | secp256k1_fe_get_b32(&pub[1], &elem->x); 44 | if (compressed) { 45 | *size = 33; 46 | pub[0] = secp256k1_fe_is_odd(&elem->y) ? SECP256K1_TAG_PUBKEY_ODD : SECP256K1_TAG_PUBKEY_EVEN; 47 | } else { 48 | *size = 65; 49 | pub[0] = SECP256K1_TAG_PUBKEY_UNCOMPRESSED; 50 | secp256k1_fe_get_b32(&pub[33], &elem->y); 51 | } 52 | return 1; 53 | } 54 | 55 | static int secp256k1_eckey_privkey_tweak_add(secp256k1_scalar *key, const secp256k1_scalar *tweak) { 56 | secp256k1_scalar_add(key, key, tweak); 57 | if (secp256k1_scalar_is_zero(key)) { 58 | return 0; 59 | } 60 | return 1; 61 | } 62 | 63 | static int secp256k1_eckey_pubkey_tweak_add(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { 64 | secp256k1_gej pt; 65 | secp256k1_scalar one; 66 | secp256k1_gej_set_ge(&pt, key); 67 | secp256k1_scalar_set_int(&one, 1); 68 | secp256k1_ecmult(ctx, &pt, &pt, &one, tweak); 69 | 70 | if (secp256k1_gej_is_infinity(&pt)) { 71 | return 0; 72 | } 73 | secp256k1_ge_set_gej(key, &pt); 74 | return 1; 75 | } 76 | 77 | static int secp256k1_eckey_privkey_tweak_mul(secp256k1_scalar *key, const secp256k1_scalar *tweak) { 78 | if (secp256k1_scalar_is_zero(tweak)) { 79 | return 0; 80 | } 81 | 82 | secp256k1_scalar_mul(key, key, tweak); 83 | return 1; 84 | } 85 | 86 | static int secp256k1_eckey_pubkey_tweak_mul(const secp256k1_ecmult_context *ctx, secp256k1_ge *key, const secp256k1_scalar *tweak) { 87 | secp256k1_scalar zero; 88 | secp256k1_gej pt; 89 | if (secp256k1_scalar_is_zero(tweak)) { 90 | return 0; 91 | } 92 | 93 | secp256k1_scalar_set_int(&zero, 0); 94 | secp256k1_gej_set_ge(&pt, key); 95 | secp256k1_ecmult(ctx, &pt, &pt, tweak, &zero); 96 | secp256k1_ge_set_gej(key, &pt); 97 | return 1; 98 | } 99 | 100 | #endif /* SECP256K1_ECKEY_IMPL_H */ 101 | -------------------------------------------------------------------------------- /include/secp256k1/contrib/lax_der_privatekey_parsing.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014, 2015 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | /**** 8 | * Please do not link this file directly. It is not part of the libsecp256k1 9 | * project and does not promise any stability in its API, functionality or 10 | * presence. Projects which use this code should instead copy this header 11 | * and its accompanying .c file directly into their codebase. 12 | ****/ 13 | 14 | /* This file contains code snippets that parse DER private keys with 15 | * various errors and violations. This is not a part of the library 16 | * itself, because the allowed violations are chosen arbitrarily and 17 | * do not follow or establish any standard. 18 | * 19 | * It also contains code to serialize private keys in a compatible 20 | * manner. 21 | * 22 | * These functions are meant for compatibility with applications 23 | * that require BER encoded keys. When working with secp256k1-specific 24 | * code, the simple 32-byte private keys normally used by the 25 | * library are sufficient. 26 | */ 27 | 28 | #ifndef SECP256K1_CONTRIB_BER_PRIVATEKEY_H 29 | #define SECP256K1_CONTRIB_BER_PRIVATEKEY_H 30 | 31 | #include 32 | 33 | #ifdef __cplusplus 34 | extern "C" { 35 | #endif 36 | 37 | /** Export a private key in DER format. 38 | * 39 | * Returns: 1 if the private key was valid. 40 | * Args: ctx: pointer to a context object, initialized for signing (cannot 41 | * be NULL) 42 | * Out: privkey: pointer to an array for storing the private key in BER. 43 | * Should have space for 279 bytes, and cannot be NULL. 44 | * privkeylen: Pointer to an int where the length of the private key in 45 | * privkey will be stored. 46 | * In: seckey: pointer to a 32-byte secret key to export. 47 | * compressed: 1 if the key should be exported in 48 | * compressed format, 0 otherwise 49 | * 50 | * This function is purely meant for compatibility with applications that 51 | * require BER encoded keys. When working with secp256k1-specific code, the 52 | * simple 32-byte private keys are sufficient. 53 | * 54 | * Note that this function does not guarantee correct DER output. It is 55 | * guaranteed to be parsable by secp256k1_ec_privkey_import_der 56 | */ 57 | SECP256K1_WARN_UNUSED_RESULT int ec_privkey_export_der( 58 | const secp256k1_context* ctx, 59 | unsigned char *privkey, 60 | size_t *privkeylen, 61 | const unsigned char *seckey, 62 | int compressed 63 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); 64 | 65 | /** Import a private key in DER format. 66 | * Returns: 1 if a private key was extracted. 67 | * Args: ctx: pointer to a context object (cannot be NULL). 68 | * Out: seckey: pointer to a 32-byte array for storing the private key. 69 | * (cannot be NULL). 70 | * In: privkey: pointer to a private key in DER format (cannot be NULL). 71 | * privkeylen: length of the DER private key pointed to be privkey. 72 | * 73 | * This function will accept more than just strict DER, and even allow some BER 74 | * violations. The public key stored inside the DER-encoded private key is not 75 | * verified for correctness, nor are the curve parameters. Use this function 76 | * only if you know in advance it is supposed to contain a secp256k1 private 77 | * key. 78 | */ 79 | SECP256K1_WARN_UNUSED_RESULT int ec_privkey_import_der( 80 | const secp256k1_context* ctx, 81 | unsigned char *seckey, 82 | const unsigned char *privkey, 83 | size_t privkeylen 84 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 85 | 86 | #ifdef __cplusplus 87 | } 88 | #endif 89 | 90 | #endif /* SECP256K1_CONTRIB_BER_PRIVATEKEY_H */ 91 | -------------------------------------------------------------------------------- /include/secp256k1/contrib/lax_der_parsing.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | /**** 8 | * Please do not link this file directly. It is not part of the libsecp256k1 9 | * project and does not promise any stability in its API, functionality or 10 | * presence. Projects which use this code should instead copy this header 11 | * and its accompanying .c file directly into their codebase. 12 | ****/ 13 | 14 | /* This file defines a function that parses DER with various errors and 15 | * violations. This is not a part of the library itself, because the allowed 16 | * violations are chosen arbitrarily and do not follow or establish any 17 | * standard. 18 | * 19 | * In many places it matters that different implementations do not only accept 20 | * the same set of valid signatures, but also reject the same set of signatures. 21 | * The only means to accomplish that is by strictly obeying a standard, and not 22 | * accepting anything else. 23 | * 24 | * Nonetheless, sometimes there is a need for compatibility with systems that 25 | * use signatures which do not strictly obey DER. The snippet below shows how 26 | * certain violations are easily supported. You may need to adapt it. 27 | * 28 | * Do not use this for new systems. Use well-defined DER or compact signatures 29 | * instead if you have the choice (see secp256k1_ecdsa_signature_parse_der and 30 | * secp256k1_ecdsa_signature_parse_compact). 31 | * 32 | * The supported violations are: 33 | * - All numbers are parsed as nonnegative integers, even though X.609-0207 34 | * section 8.3.3 specifies that integers are always encoded as two's 35 | * complement. 36 | * - Integers can have length 0, even though section 8.3.1 says they can't. 37 | * - Integers with overly long padding are accepted, violation section 38 | * 8.3.2. 39 | * - 127-byte long length descriptors are accepted, even though section 40 | * 8.1.3.5.c says that they are not. 41 | * - Trailing garbage data inside or after the signature is ignored. 42 | * - The length descriptor of the sequence is ignored. 43 | * 44 | * Compared to for example OpenSSL, many violations are NOT supported: 45 | * - Using overly long tag descriptors for the sequence or integers inside, 46 | * violating section 8.1.2.2. 47 | * - Encoding primitive integers as constructed values, violating section 48 | * 8.3.1. 49 | */ 50 | 51 | #ifndef SECP256K1_CONTRIB_LAX_DER_PARSING_H 52 | #define SECP256K1_CONTRIB_LAX_DER_PARSING_H 53 | 54 | #include 55 | 56 | #ifdef __cplusplus 57 | extern "C" { 58 | #endif 59 | 60 | /** Parse a signature in "lax DER" format 61 | * 62 | * Returns: 1 when the signature could be parsed, 0 otherwise. 63 | * Args: ctx: a secp256k1 context object 64 | * Out: sig: a pointer to a signature object 65 | * In: input: a pointer to the signature to be parsed 66 | * inputlen: the length of the array pointed to be input 67 | * 68 | * This function will accept any valid DER encoded signature, even if the 69 | * encoded numbers are out of range. In addition, it will accept signatures 70 | * which violate the DER spec in various ways. Its purpose is to allow 71 | * validation of the Bitcoin blockchain, which includes non-DER signatures 72 | * from before the network rules were updated to enforce DER. Note that 73 | * the set of supported violations is a strict subset of what OpenSSL will 74 | * accept. 75 | * 76 | * After the call, sig will always be initialized. If parsing failed or the 77 | * encoded numbers are out of range, signature validation with it is 78 | * guaranteed to fail for every message and public key. 79 | */ 80 | int ecdsa_signature_parse_der_lax( 81 | const secp256k1_context* ctx, 82 | secp256k1_ecdsa_signature* sig, 83 | const unsigned char *input, 84 | size_t inputlen 85 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 86 | 87 | #ifdef __cplusplus 88 | } 89 | #endif 90 | 91 | #endif /* SECP256K1_CONTRIB_LAX_DER_PARSING_H */ 92 | -------------------------------------------------------------------------------- /include/native/contrib/lax_der_privatekey_parsing.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014, 2015 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | /**** 8 | * Please do not link this file directly. It is not part of the libsecp256k1 9 | * project and does not promise any stability in its API, functionality or 10 | * presence. Projects which use this code should instead copy this header 11 | * and its accompanying .c file directly into their codebase. 12 | ****/ 13 | 14 | /* This file contains code snippets that parse DER private keys with 15 | * various errors and violations. This is not a part of the library 16 | * itself, because the allowed violations are chosen arbitrarily and 17 | * do not follow or establish any standard. 18 | * 19 | * It also contains code to serialize private keys in a compatible 20 | * manner. 21 | * 22 | * These functions are meant for compatibility with applications 23 | * that require BER encoded keys. When working with secp256k1-specific 24 | * code, the simple 32-byte private keys normally used by the 25 | * library are sufficient. 26 | */ 27 | 28 | #ifndef SECP256K1_CONTRIB_BER_PRIVATEKEY_H 29 | #define SECP256K1_CONTRIB_BER_PRIVATEKEY_H 30 | 31 | #include 32 | 33 | namespace nakasendo { namespace native { namespace contrib { 34 | 35 | #ifdef __cplusplus 36 | extern "C" { 37 | #endif 38 | 39 | /** Export a private key in DER format. 40 | * 41 | * Returns: 1 if the private key was valid. 42 | * Args: ctx: pointer to a context object, initialized for signing (cannot 43 | * be NULL) 44 | * Out: privkey: pointer to an array for storing the private key in BER. 45 | * Should have space for 279 bytes, and cannot be NULL. 46 | * privkeylen: Pointer to an int where the length of the private key in 47 | * privkey will be stored. 48 | * In: seckey: pointer to a 32-byte secret key to export. 49 | * compressed: 1 if the key should be exported in 50 | * compressed format, 0 otherwise 51 | * 52 | * This function is purely meant for compatibility with applications that 53 | * require BER encoded keys. When working with secp256k1-specific code, the 54 | * simple 32-byte private keys are sufficient. 55 | * 56 | * Note that this function does not guarantee correct DER output. It is 57 | * guaranteed to be parsable by secp256k1_ec_privkey_import_der 58 | */ 59 | SECP256K1_WARN_UNUSED_RESULT int ec_privkey_export_der( 60 | const secp256k1_context* ctx, 61 | unsigned char *privkey, 62 | size_t *privkeylen, 63 | const unsigned char *seckey, 64 | int compressed 65 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); 66 | 67 | /** Import a private key in DER format. 68 | * Returns: 1 if a private key was extracted. 69 | * Args: ctx: pointer to a context object (cannot be NULL). 70 | * Out: seckey: pointer to a 32-byte array for storing the private key. 71 | * (cannot be NULL). 72 | * In: privkey: pointer to a private key in DER format (cannot be NULL). 73 | * privkeylen: length of the DER private key pointed to be privkey. 74 | * 75 | * This function will accept more than just strict DER, and even allow some BER 76 | * violations. The public key stored inside the DER-encoded private key is not 77 | * verified for correctness, nor are the curve parameters. Use this function 78 | * only if you know in advance it is supposed to contain a secp256k1 private 79 | * key. 80 | */ 81 | SECP256K1_WARN_UNUSED_RESULT int ec_privkey_import_der( 82 | const secp256k1_context* ctx, 83 | unsigned char *seckey, 84 | const unsigned char *privkey, 85 | size_t privkeylen 86 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 87 | 88 | #ifdef __cplusplus 89 | } 90 | #endif 91 | 92 | } /// end of namespace contrib 93 | } /// end of namespace native 94 | } /// end of namespace nakasendo 95 | 96 | #endif /* SECP256K1_CONTRIB_BER_PRIVATEKEY_H */ 97 | -------------------------------------------------------------------------------- /include/secp256k1/src/scalar_low_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_REPR_IMPL_H 8 | #define SECP256K1_SCALAR_REPR_IMPL_H 9 | 10 | #include "scalar.h" 11 | 12 | #include 13 | 14 | SECP256K1_INLINE static int secp256k1_scalar_is_even(const secp256k1_scalar *a) { 15 | return !(*a & 1); 16 | } 17 | 18 | SECP256K1_INLINE static void secp256k1_scalar_clear(secp256k1_scalar *r) { *r = 0; } 19 | SECP256K1_INLINE static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v) { *r = v; } 20 | 21 | SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { 22 | if (offset < 32) 23 | return ((*a >> offset) & ((((uint32_t)1) << count) - 1)); 24 | else 25 | return 0; 26 | } 27 | 28 | SECP256K1_INLINE static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count) { 29 | return secp256k1_scalar_get_bits(a, offset, count); 30 | } 31 | 32 | SECP256K1_INLINE static int secp256k1_scalar_check_overflow(const secp256k1_scalar *a) { return *a >= EXHAUSTIVE_TEST_ORDER; } 33 | 34 | static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { 35 | *r = (*a + *b) % EXHAUSTIVE_TEST_ORDER; 36 | return *r < *b; 37 | } 38 | 39 | static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag) { 40 | if (flag && bit < 32) 41 | *r += (1 << bit); 42 | #ifdef VERIFY 43 | VERIFY_CHECK(secp256k1_scalar_check_overflow(r) == 0); 44 | #endif 45 | } 46 | 47 | static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *b32, int *overflow) { 48 | const int base = 0x100 % EXHAUSTIVE_TEST_ORDER; 49 | int i; 50 | *r = 0; 51 | for (i = 0; i < 32; i++) { 52 | *r = ((*r * base) + b32[i]) % EXHAUSTIVE_TEST_ORDER; 53 | } 54 | /* just deny overflow, it basically always happens */ 55 | if (overflow) *overflow = 0; 56 | } 57 | 58 | static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a) { 59 | memset(bin, 0, 32); 60 | bin[28] = *a >> 24; bin[29] = *a >> 16; bin[30] = *a >> 8; bin[31] = *a; 61 | } 62 | 63 | SECP256K1_INLINE static int secp256k1_scalar_is_zero(const secp256k1_scalar *a) { 64 | return *a == 0; 65 | } 66 | 67 | static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a) { 68 | if (*a == 0) { 69 | *r = 0; 70 | } else { 71 | *r = EXHAUSTIVE_TEST_ORDER - *a; 72 | } 73 | } 74 | 75 | SECP256K1_INLINE static int secp256k1_scalar_is_one(const secp256k1_scalar *a) { 76 | return *a == 1; 77 | } 78 | 79 | static int secp256k1_scalar_is_high(const secp256k1_scalar *a) { 80 | return *a > EXHAUSTIVE_TEST_ORDER / 2; 81 | } 82 | 83 | static int secp256k1_scalar_cond_negate(secp256k1_scalar *r, int flag) { 84 | if (flag) secp256k1_scalar_negate(r, r); 85 | return flag ? -1 : 1; 86 | } 87 | 88 | static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b) { 89 | *r = (*a * *b) % EXHAUSTIVE_TEST_ORDER; 90 | } 91 | 92 | static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n) { 93 | int ret; 94 | VERIFY_CHECK(n > 0); 95 | VERIFY_CHECK(n < 16); 96 | ret = *r & ((1 << n) - 1); 97 | *r >>= n; 98 | return ret; 99 | } 100 | 101 | static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a) { 102 | *r = (*a * *a) % EXHAUSTIVE_TEST_ORDER; 103 | } 104 | 105 | static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a) { 106 | *r1 = *a; 107 | *r2 = 0; 108 | } 109 | 110 | SECP256K1_INLINE static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b) { 111 | return *a == *b; 112 | } 113 | 114 | #endif /* SECP256K1_SCALAR_REPR_IMPL_H */ 115 | -------------------------------------------------------------------------------- /include/secp256k1/src/java/org_bitcoin_NativeSecp256k1.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | #include "include/secp256k1.h" 4 | /* Header for class org_bitcoin_NativeSecp256k1 */ 5 | 6 | #ifndef _Included_org_bitcoin_NativeSecp256k1 7 | #define _Included_org_bitcoin_NativeSecp256k1 8 | #ifdef __cplusplus 9 | extern "C" { 10 | #endif 11 | /* 12 | * Class: org_bitcoin_NativeSecp256k1 13 | * Method: secp256k1_ctx_clone 14 | * Signature: (J)J 15 | */ 16 | SECP256K1_API jlong JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ctx_1clone 17 | (JNIEnv *, jclass, jlong); 18 | 19 | /* 20 | * Class: org_bitcoin_NativeSecp256k1 21 | * Method: secp256k1_context_randomize 22 | * Signature: (Ljava/nio/ByteBuffer;J)I 23 | */ 24 | SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1context_1randomize 25 | (JNIEnv *, jclass, jobject, jlong); 26 | 27 | /* 28 | * Class: org_bitcoin_NativeSecp256k1 29 | * Method: secp256k1_privkey_tweak_add 30 | * Signature: (Ljava/nio/ByteBuffer;J)[[B 31 | */ 32 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1add 33 | (JNIEnv *, jclass, jobject, jlong); 34 | 35 | /* 36 | * Class: org_bitcoin_NativeSecp256k1 37 | * Method: secp256k1_privkey_tweak_mul 38 | * Signature: (Ljava/nio/ByteBuffer;J)[[B 39 | */ 40 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1privkey_1tweak_1mul 41 | (JNIEnv *, jclass, jobject, jlong); 42 | 43 | /* 44 | * Class: org_bitcoin_NativeSecp256k1 45 | * Method: secp256k1_pubkey_tweak_add 46 | * Signature: (Ljava/nio/ByteBuffer;JI)[[B 47 | */ 48 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1add 49 | (JNIEnv *, jclass, jobject, jlong, jint); 50 | 51 | /* 52 | * Class: org_bitcoin_NativeSecp256k1 53 | * Method: secp256k1_pubkey_tweak_mul 54 | * Signature: (Ljava/nio/ByteBuffer;JI)[[B 55 | */ 56 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1pubkey_1tweak_1mul 57 | (JNIEnv *, jclass, jobject, jlong, jint); 58 | 59 | /* 60 | * Class: org_bitcoin_NativeSecp256k1 61 | * Method: secp256k1_destroy_context 62 | * Signature: (J)V 63 | */ 64 | SECP256K1_API void JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1destroy_1context 65 | (JNIEnv *, jclass, jlong); 66 | 67 | /* 68 | * Class: org_bitcoin_NativeSecp256k1 69 | * Method: secp256k1_ecdsa_verify 70 | * Signature: (Ljava/nio/ByteBuffer;JII)I 71 | */ 72 | SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1verify 73 | (JNIEnv *, jclass, jobject, jlong, jint, jint); 74 | 75 | /* 76 | * Class: org_bitcoin_NativeSecp256k1 77 | * Method: secp256k1_ecdsa_sign 78 | * Signature: (Ljava/nio/ByteBuffer;J)[[B 79 | */ 80 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdsa_1sign 81 | (JNIEnv *, jclass, jobject, jlong); 82 | 83 | /* 84 | * Class: org_bitcoin_NativeSecp256k1 85 | * Method: secp256k1_ec_seckey_verify 86 | * Signature: (Ljava/nio/ByteBuffer;J)I 87 | */ 88 | SECP256K1_API jint JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1seckey_1verify 89 | (JNIEnv *, jclass, jobject, jlong); 90 | 91 | /* 92 | * Class: org_bitcoin_NativeSecp256k1 93 | * Method: secp256k1_ec_pubkey_create 94 | * Signature: (Ljava/nio/ByteBuffer;J)[[B 95 | */ 96 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1create 97 | (JNIEnv *, jclass, jobject, jlong); 98 | 99 | /* 100 | * Class: org_bitcoin_NativeSecp256k1 101 | * Method: secp256k1_ec_pubkey_parse 102 | * Signature: (Ljava/nio/ByteBuffer;JI)[[B 103 | */ 104 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ec_1pubkey_1parse 105 | (JNIEnv *, jclass, jobject, jlong, jint); 106 | 107 | /* 108 | * Class: org_bitcoin_NativeSecp256k1 109 | * Method: secp256k1_ecdh 110 | * Signature: (Ljava/nio/ByteBuffer;JI)[[B 111 | */ 112 | SECP256K1_API jobjectArray JNICALL Java_org_bitcoin_NativeSecp256k1_secp256k1_1ecdh 113 | (JNIEnv* env, jclass classObject, jobject byteBufferObject, jlong ctx_l, jint publen); 114 | 115 | 116 | #ifdef __cplusplus 117 | } 118 | #endif 119 | #endif 120 | -------------------------------------------------------------------------------- /include/secp256k1/src/modules/ecdh/tests_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2015 Andrew Poelstra * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_MODULE_ECDH_TESTS_H 8 | #define SECP256K1_MODULE_ECDH_TESTS_H 9 | 10 | void test_ecdh_api(void) { 11 | /* Setup context that just counts errors */ 12 | secp256k1_context *tctx = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); 13 | secp256k1_pubkey point; 14 | unsigned char res[32]; 15 | unsigned char s_one[32] = { 0 }; 16 | int32_t ecount = 0; 17 | s_one[31] = 1; 18 | 19 | secp256k1_context_set_error_callback(tctx, counting_illegal_callback_fn, &ecount); 20 | secp256k1_context_set_illegal_callback(tctx, counting_illegal_callback_fn, &ecount); 21 | CHECK(secp256k1_ec_pubkey_create(tctx, &point, s_one) == 1); 22 | 23 | /* Check all NULLs are detected */ 24 | CHECK(secp256k1_ecdh(tctx, res, &point, s_one) == 1); 25 | CHECK(ecount == 0); 26 | CHECK(secp256k1_ecdh(tctx, NULL, &point, s_one) == 0); 27 | CHECK(ecount == 1); 28 | CHECK(secp256k1_ecdh(tctx, res, NULL, s_one) == 0); 29 | CHECK(ecount == 2); 30 | CHECK(secp256k1_ecdh(tctx, res, &point, NULL) == 0); 31 | CHECK(ecount == 3); 32 | CHECK(secp256k1_ecdh(tctx, res, &point, s_one) == 1); 33 | CHECK(ecount == 3); 34 | 35 | /* Cleanup */ 36 | secp256k1_context_destroy(tctx); 37 | } 38 | 39 | void test_ecdh_generator_basepoint(void) { 40 | unsigned char s_one[32] = { 0 }; 41 | secp256k1_pubkey point[2]; 42 | int i; 43 | 44 | s_one[31] = 1; 45 | /* Check against pubkey creation when the basepoint is the generator */ 46 | for (i = 0; i < 100; ++i) { 47 | secp256k1_sha256 sha; 48 | unsigned char s_b32[32]; 49 | unsigned char output_ecdh[32]; 50 | unsigned char output_ser[32]; 51 | unsigned char point_ser[33]; 52 | size_t point_ser_len = sizeof(point_ser); 53 | secp256k1_scalar s; 54 | 55 | random_scalar_order(&s); 56 | secp256k1_scalar_get_b32(s_b32, &s); 57 | 58 | /* compute using ECDH function */ 59 | CHECK(secp256k1_ec_pubkey_create(ctx, &point[0], s_one) == 1); 60 | CHECK(secp256k1_ecdh(ctx, output_ecdh, &point[0], s_b32) == 1); 61 | /* compute "explicitly" */ 62 | CHECK(secp256k1_ec_pubkey_create(ctx, &point[1], s_b32) == 1); 63 | CHECK(secp256k1_ec_pubkey_serialize(ctx, point_ser, &point_ser_len, &point[1], SECP256K1_EC_COMPRESSED) == 1); 64 | CHECK(point_ser_len == sizeof(point_ser)); 65 | secp256k1_sha256_initialize(&sha); 66 | secp256k1_sha256_write(&sha, point_ser, point_ser_len); 67 | secp256k1_sha256_finalize(&sha, output_ser); 68 | /* compare */ 69 | CHECK(memcmp(output_ecdh, output_ser, sizeof(output_ser)) == 0); 70 | } 71 | } 72 | 73 | void test_bad_scalar(void) { 74 | unsigned char s_zero[32] = { 0 }; 75 | unsigned char s_overflow[32] = { 76 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 77 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 78 | 0xba, 0xae, 0xdc, 0xe6, 0xaf, 0x48, 0xa0, 0x3b, 79 | 0xbf, 0xd2, 0x5e, 0x8c, 0xd0, 0x36, 0x41, 0x41 80 | }; 81 | unsigned char s_rand[32] = { 0 }; 82 | unsigned char output[32]; 83 | secp256k1_scalar rand; 84 | secp256k1_pubkey point; 85 | 86 | /* Create random point */ 87 | random_scalar_order(&rand); 88 | secp256k1_scalar_get_b32(s_rand, &rand); 89 | CHECK(secp256k1_ec_pubkey_create(ctx, &point, s_rand) == 1); 90 | 91 | /* Try to multiply it by bad values */ 92 | CHECK(secp256k1_ecdh(ctx, output, &point, s_zero) == 0); 93 | CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow) == 0); 94 | /* ...and a good one */ 95 | s_overflow[31] -= 1; 96 | CHECK(secp256k1_ecdh(ctx, output, &point, s_overflow) == 1); 97 | } 98 | 99 | void run_ecdh_tests(void) { 100 | test_ecdh_api(); 101 | test_ecdh_generator_basepoint(); 102 | test_bad_scalar(); 103 | } 104 | 105 | #endif /* SECP256K1_MODULE_ECDH_TESTS_H */ 106 | -------------------------------------------------------------------------------- /include/secp256k1/src/testrand_impl.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013-2015 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_TESTRAND_IMPL_H 8 | #define SECP256K1_TESTRAND_IMPL_H 9 | 10 | #include 11 | #include 12 | 13 | #include "testrand.h" 14 | #include "hash.h" 15 | 16 | static secp256k1_rfc6979_hmac_sha256 secp256k1_test_rng; 17 | static uint32_t secp256k1_test_rng_precomputed[8]; 18 | static int secp256k1_test_rng_precomputed_used = 8; 19 | static uint64_t secp256k1_test_rng_integer; 20 | static int secp256k1_test_rng_integer_bits_left = 0; 21 | 22 | SECP256K1_INLINE static void secp256k1_rand_seed(const unsigned char *seed16) { 23 | secp256k1_rfc6979_hmac_sha256_initialize(&secp256k1_test_rng, seed16, 16); 24 | } 25 | 26 | SECP256K1_INLINE static uint32_t secp256k1_rand32(void) { 27 | if (secp256k1_test_rng_precomputed_used == 8) { 28 | secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, (unsigned char*)(&secp256k1_test_rng_precomputed[0]), sizeof(secp256k1_test_rng_precomputed)); 29 | secp256k1_test_rng_precomputed_used = 0; 30 | } 31 | return secp256k1_test_rng_precomputed[secp256k1_test_rng_precomputed_used++]; 32 | } 33 | 34 | static uint32_t secp256k1_rand_bits(int bits) { 35 | uint32_t ret; 36 | if (secp256k1_test_rng_integer_bits_left < bits) { 37 | secp256k1_test_rng_integer |= (((uint64_t)secp256k1_rand32()) << secp256k1_test_rng_integer_bits_left); 38 | secp256k1_test_rng_integer_bits_left += 32; 39 | } 40 | ret = secp256k1_test_rng_integer; 41 | secp256k1_test_rng_integer >>= bits; 42 | secp256k1_test_rng_integer_bits_left -= bits; 43 | ret &= ((~((uint32_t)0)) >> (32 - bits)); 44 | return ret; 45 | } 46 | 47 | static uint32_t secp256k1_rand_int(uint32_t range) { 48 | /* We want a uniform integer between 0 and range-1, inclusive. 49 | * B is the smallest number such that range <= 2**B. 50 | * two mechanisms implemented here: 51 | * - generate B bits numbers until one below range is found, and return it 52 | * - find the largest multiple M of range that is <= 2**(B+A), generate B+A 53 | * bits numbers until one below M is found, and return it modulo range 54 | * The second mechanism consumes A more bits of entropy in every iteration, 55 | * but may need fewer iterations due to M being closer to 2**(B+A) then 56 | * range is to 2**B. The array below (indexed by B) contains a 0 when the 57 | * first mechanism is to be used, and the number A otherwise. 58 | */ 59 | static const int addbits[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 1, 0}; 60 | uint32_t trange, mult; 61 | int bits = 0; 62 | if (range <= 1) { 63 | return 0; 64 | } 65 | trange = range - 1; 66 | while (trange > 0) { 67 | trange >>= 1; 68 | bits++; 69 | } 70 | if (addbits[bits]) { 71 | bits = bits + addbits[bits]; 72 | mult = ((~((uint32_t)0)) >> (32 - bits)) / range; 73 | trange = range * mult; 74 | } else { 75 | trange = range; 76 | mult = 1; 77 | } 78 | while(1) { 79 | uint32_t x = secp256k1_rand_bits(bits); 80 | if (x < trange) { 81 | return (mult == 1) ? x : (x % range); 82 | } 83 | } 84 | } 85 | 86 | static void secp256k1_rand256(unsigned char *b32) { 87 | secp256k1_rfc6979_hmac_sha256_generate(&secp256k1_test_rng, b32, 32); 88 | } 89 | 90 | static void secp256k1_rand_bytes_test(unsigned char *bytes, size_t len) { 91 | size_t bits = 0; 92 | memset(bytes, 0, len); 93 | while (bits < len * 8) { 94 | int now; 95 | uint32_t val; 96 | now = 1 + (secp256k1_rand_bits(6) * secp256k1_rand_bits(5) + 16) / 31; 97 | val = secp256k1_rand_bits(1); 98 | while (now > 0 && bits < len * 8) { 99 | bytes[bits / 8] |= val << (bits % 8); 100 | now--; 101 | bits++; 102 | } 103 | } 104 | } 105 | 106 | static void secp256k1_rand256_test(unsigned char *b32) { 107 | secp256k1_rand_bytes_test(b32, 32); 108 | } 109 | 110 | #endif /* SECP256K1_TESTRAND_IMPL_H */ 111 | -------------------------------------------------------------------------------- /include/interface/SecretStore.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * An in-memory registry for storing secrets. Implemented as a singleton. 6 | * 7 | * The store should have a master password set for encryption/decryption 8 | * and be hooked up with a pluggable backend for persisting secrets before 9 | * being used. 10 | */ 11 | 12 | #ifndef _NCHAIN_SDK_SECRET_STORE_H_ 13 | #define _NCHAIN_SDK_SECRET_STORE_H_ 14 | 15 | #include "SecretBackingStore.h" 16 | #include "Secret.h" 17 | 18 | namespace nakasendo 19 | { 20 | 21 | /// An in-memory store of secrets. Implemented as a singleton. 22 | class SecretStore 23 | { 24 | public: 25 | 26 | /// A collection of secrets. 27 | using SecretSet = std::vector; 28 | 29 | /// Non copy-constructable. 30 | SecretStore(const SecretStore&) = delete; 31 | /// Non move-constructable. 32 | SecretStore(SecretStore&&) = delete; 33 | 34 | /// Default destructor 35 | virtual ~SecretStore() = default; 36 | 37 | /** 38 | * Accessor for the singleton instance. 39 | * @return A reference to the SecretStore. 40 | */ 41 | static SecretStore& get(); 42 | 43 | /** 44 | * Set the master password used for encrypting/decrypting all stored secrets. 45 | * @param passwd The master password to use for encrypting/decrypting. 46 | */ 47 | virtual void setMasterPassword(const impl::memory::SecureByteVec& passwd) = 0; 48 | 49 | /** 50 | * Set the persistent backing store. The store will use this to save/load 51 | * the secrets going forward. 52 | * @param db The persistence DB to use. 53 | */ 54 | virtual void setSecretBackingStore(const SecretBackingStoreSPtr& db) = 0; 55 | 56 | /** 57 | * Add a new secret to the store. 58 | * @param secret The new secret to add. 59 | */ 60 | virtual void addSecret(const SecretSPtr& secret) = 0; 61 | 62 | /** 63 | * Add a list of new secrets to the store. 64 | * @param secrets The new secrets to add. 65 | */ 66 | virtual void addSecrets(const SecretSet& secrets) = 0; 67 | 68 | /** 69 | * Replace an existing secret in the store. 70 | * @param name The name of the secret currently in the store to replace. 71 | * @param secret The new secret to replace the old one with. 72 | */ 73 | virtual void replaceSecret(const std::string& name, const SecretSPtr& secret) = 0; 74 | 75 | /** 76 | * Remove the named secret from the store. 77 | * @param name The name of the secret to erase. 78 | */ 79 | virtual void removeSecret(const std::string& name) = 0; 80 | 81 | /** 82 | * Fetch secret by name. 83 | * @param name The name of the secret to lookup. 84 | * @return A pointer to the requested secret if found, nullptr otherwise. 85 | */ 86 | virtual SecretSPtr getSecret(const std::string& name) const = 0; 87 | 88 | /** 89 | * Fetch all secrets. 90 | * @return A list of all secrets in the store. 91 | */ 92 | virtual SecretSet getAllSecrets() const = 0; 93 | 94 | /** 95 | * Lookup secrets according to metadata. 96 | * @param key Metadata key to lookup. 97 | * @param value Metadata value to lookup. 98 | * @return A list of secrets that have metadata key=value. 99 | */ 100 | virtual SecretSet getAllSecretsWhere(const std::string& key, 101 | const std::string& value) const = 0; 102 | 103 | /** 104 | * Fetch all secrets names. 105 | * @return A list of all stored secret names. 106 | */ 107 | virtual std::vector getAllSecretNames() const = 0; 108 | 109 | /** 110 | * Add a newly loaded (restored from backing store) secret. Should only 111 | * be called from a SecretBackingStore implementation class. 112 | * @param secret A newly loaded secret to be added to the store. 113 | */ 114 | virtual void loadSecret(const SecretSPtr& secret) = 0; 115 | 116 | /** 117 | * Notification that the named secret has changed and the perisitence 118 | * backend should be informed. Note: it is not expected that users of the 119 | * SDK should need to call this method, it should happen automatically if 120 | * a secret is modified. 121 | * @param name The name of the modified secret in the store. 122 | */ 123 | virtual void secretUpdated(const std::string& name) = 0; 124 | 125 | protected: 126 | 127 | /// Constructor 128 | SecretStore() = default; 129 | 130 | }; 131 | 132 | } 133 | 134 | #endif 135 | -------------------------------------------------------------------------------- /include/impl/Base58Data.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * Handle the encoding and decoding of Base58 and Base58Check data. 6 | */ 7 | 8 | #ifndef _NCHAIN_SDK_BASE_58_DATA_H_ 9 | #define _NCHAIN_SDK_BASE_58_DATA_H_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "MetaDataDefinitions.h" 17 | 18 | #include 19 | #include 20 | 21 | namespace nakasendo 22 | { 23 | class Key; 24 | } 25 | 26 | namespace nakasendo { namespace impl 27 | { 28 | 29 | /// A class to wrap Base58/Base58Check encoding and decoding. 30 | class Base58Data 31 | { 32 | public: 33 | 34 | /// Well known version prefixes. 35 | /// 36 | /// NOTE! If you change these here, don't forget to also update 37 | /// the static map VersionPrefixMap. 38 | enum class VersionPrefix 39 | { 40 | PUBLIC_KEY_ADDRESS, 41 | SCRIPT_ADDRESS, 42 | PRIVATE_KEY, 43 | 44 | TESTNET_PUBLIC_KEY_ADDRESS, 45 | TESTNET_SCRIPT_ADDRESS, 46 | TESTNET_PRIVATE_KEY, 47 | 48 | REGTEST_PUBLIC_KEY_ADDRESS, 49 | REGTEST_SCRIPT_ADDRESS, 50 | REGTEST_PRIVATE_KEY, 51 | }; 52 | 53 | 54 | /** 55 | * Encode the given raw data in Base58 format. 56 | * @param data The data to encode. 57 | * @return A Base58 encoded representation of the raw data. 58 | */ 59 | template 60 | static auto encode(const typename std::enable_if::value, V>::type& data) 61 | -> typename std::enable_if::value || std::is_same::value, S>::type; 62 | 63 | /** 64 | * Decode encoded string from Base58 format. 65 | * @param encoded Base58 encoded string to decode. 66 | * @return Raw decoded data. 67 | */ 68 | static memory::SecureByteVec decode(const memory::SecureString& encoded); 69 | 70 | /** 71 | * Encode the given raw data in Base58Check format. 72 | * @param data The data to encode. 73 | * @return A Base58Check encoded representation of the raw data. 74 | */ 75 | template 76 | static auto checkEncode(const typename std::enable_if::value, V>::type& data) 77 | -> typename std::enable_if::value || std::is_same::value, S>::type; 78 | 79 | /** 80 | * Encode the given private key in Base58Check format. Used for 81 | * creating wallet import format (WIF) strings. 82 | * @param key A private key. 83 | * @return A Base58Check encoded WIF representation of the key. 84 | */ 85 | static memory::SecureString checkEncode(const Key& key); 86 | 87 | /** 88 | * Decode encoded string from Base58Check format. 89 | * @param encoded Base58Check encoded string to decode. 90 | * @return Raw decoded data. 91 | */ 92 | static memory::SecureByteVec checkDecode(const memory::SecureString& encoded); 93 | 94 | 95 | /** 96 | * Utility method to get the appropriate version byte(s) for the requested 97 | * well know version prefix type. 98 | * @param ver A well know version prefix from the VersionPrefix enumeration. 99 | * @return The version bytes for the requested type. 100 | */ 101 | static const std::vector& getVersionBytesFor(VersionPrefix ver); 102 | 103 | /** 104 | * Utility method to get the well known version prefix type for some 105 | * Base58Check encoded data. Throws if it can't identify the data. 106 | * @parm data Base58Check encoded data with version prefix bytes at the start. 107 | * @return The VersionPrefix for the data. 108 | */ 109 | static VersionPrefix getVersionOf(const memory::SecureByteVec& data); 110 | 111 | /** 112 | * Utility method to get the network type corresponding to a version prefix. 113 | * @param ver A VersionPrefix enumeration. 114 | * @return A NetworkType enumeration for the given version prefix. 115 | */ 116 | static MetaDataDefinitions::NetworkType getNetworkFor(VersionPrefix ver); 117 | 118 | private: 119 | 120 | /// Static map of VersionPrefixes to version bytes and NetworkType 121 | using VersionPrefixMap = std::map, MetaDataDefinitions::NetworkType>>; 122 | static const VersionPrefixMap mVersionPrefixMap; 123 | 124 | }; 125 | 126 | }} 127 | 128 | #include "Base58DataT.h" 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /include/interface/Key.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * Encapsulate a logical private key used within the SDK. 6 | */ 7 | 8 | #ifndef _NCHAIN_SDK_KEY_H_ 9 | #define _NCHAIN_SDK_KEY_H_ 10 | 11 | #include "ContextObject.h" 12 | #include "MetaDataCollection.h" 13 | #include "Types.h" 14 | #include "PubKey.h" 15 | #include "KeyFragment.h" 16 | #include "Secret.h" 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | namespace nakasendo 24 | { 25 | /// Forward declaration of Key pointer type 26 | class Key; 27 | /// Unique pointer type 28 | using KeyPtr = std::unique_ptr; 29 | /// Shared pointer type 30 | using KeySPtr = std::shared_ptr; 31 | 32 | /** 33 | * This class encapsulates a logical key used within the SDK. 34 | */ 35 | class Key : public Secret 36 | { 37 | public: 38 | 39 | /// Default constructor. 40 | Key() = default; 41 | 42 | /// Construct from an existing Secret. 43 | Key(const Secret& secret) : Secret{secret} {} 44 | 45 | /// Move construct from an existing Secret. 46 | Key(Secret&& secret) : Secret{std::move(secret)} {} 47 | 48 | /// Default destructor 49 | virtual ~Key() = default; 50 | 51 | /** 52 | * Derive public key from private key. 53 | * @return A pointer to a new public key. 54 | */ 55 | virtual PubKeyPtr getPubKey() const = 0; 56 | 57 | /** 58 | * Derive public key of the requested type from private key. 59 | * @param pkType Generate a COMPRESSED or UNCOMPRESSED public key. 60 | * @return A pointer to a new public key. 61 | */ 62 | virtual PubKeyPtr getPubKey(PubKey::Type pkType) const = 0; 63 | 64 | /** 65 | * Splits the Key into the requested number of fragments. 66 | * @param nSplitSharesN The absolute number of parts that the generated 67 | * key should be split into. 68 | * @param nRecoverySharesM The minimum number of parts that need to be brought 69 | * together in order to recovery the Key. 70 | * @return vector of created KeyFragment instances. If the split fails, 71 | * throws an exception. 72 | */ 73 | virtual std::vector split(const int nSplitSharesN=3, const int nRecoverySharesM=2) const = 0; 74 | 75 | /** 76 | * Export ourselves in wallet import format (WIF). 77 | * @return A WIF encoded string. 78 | */ 79 | virtual impl::memory::SecureString exportAsWIF() const = 0; 80 | 81 | /** 82 | * Import ourselves from wallet import format (WIF). 83 | * @param wif A WIF encoded string. 84 | */ 85 | virtual void importFromWIF(const impl::memory::SecureString& wif) = 0; 86 | 87 | /** 88 | * Sign a message with this key. 89 | * @param message the message to sign as a byte array. 90 | * @return The signed message. 91 | */ 92 | virtual std::vector sign(const std::vector& message) const = 0; 93 | 94 | /** 95 | * Decrypt a message previously encrypted by our public key. 96 | * @param message An encrypted message. 97 | * @return The decrypted message. 98 | */ 99 | virtual impl::memory::SecureByteVec decrypt(const std::vector& message) const = 0; 100 | 101 | /** 102 | * Deterministically derives a new key from this key using the given 103 | * message. 104 | * @param message The message to be used in deterministically deriving 105 | * the new key. 106 | * @return A derived new key. 107 | */ 108 | virtual KeyPtr derive(const std::vector& message) const = 0; 109 | 110 | /** 111 | * Produce a shared secret by using the other party's public key with 112 | * a given message and this private key. The result will be identical 113 | * to one produced by the other party, i.e. calculating with their 114 | * private key, our public key, and the same message. 115 | * @param pubKey The other party's public key. 116 | * @param message The shared message. 117 | * @param secretName The name to give the derived shared secret. If not 118 | * specified, the SDK will pick a random name. 119 | * @return A shared secret. 120 | */ 121 | virtual SecretPtr sharedSecret(const PubKeyPtr& pubKey, 122 | const std::vector& message, 123 | const std::string& secretName = {}) const = 0; 124 | 125 | }; 126 | 127 | } 128 | 129 | #endif // _NCHAIN_SDK_KEY_H_ 130 | 131 | -------------------------------------------------------------------------------- /include/secp256k1/include/secp256k1_recovery.h: -------------------------------------------------------------------------------- 1 | #ifndef SECP256K1_RECOVERY_H 2 | #define SECP256K1_RECOVERY_H 3 | 4 | #include "secp256k1.h" 5 | 6 | #ifdef __cplusplus 7 | extern "C" { 8 | #endif 9 | 10 | /** Opaque data structured that holds a parsed ECDSA signature, 11 | * supporting pubkey recovery. 12 | * 13 | * The exact representation of data inside is implementation defined and not 14 | * guaranteed to be portable between different platforms or versions. It is 15 | * however guaranteed to be 65 bytes in size, and can be safely copied/moved. 16 | * If you need to convert to a format suitable for storage or transmission, use 17 | * the secp256k1_ecdsa_signature_serialize_* and 18 | * secp256k1_ecdsa_signature_parse_* functions. 19 | * 20 | * Furthermore, it is guaranteed that identical signatures (including their 21 | * recoverability) will have identical representation, so they can be 22 | * memcmp'ed. 23 | */ 24 | typedef struct { 25 | unsigned char data[65]; 26 | } secp256k1_ecdsa_recoverable_signature; 27 | 28 | /** Parse a compact ECDSA signature (64 bytes + recovery id). 29 | * 30 | * Returns: 1 when the signature could be parsed, 0 otherwise 31 | * Args: ctx: a secp256k1 context object 32 | * Out: sig: a pointer to a signature object 33 | * In: input64: a pointer to a 64-byte compact signature 34 | * recid: the recovery id (0, 1, 2 or 3) 35 | */ 36 | SECP256K1_API int secp256k1_ecdsa_recoverable_signature_parse_compact( 37 | const secp256k1_context* ctx, 38 | secp256k1_ecdsa_recoverable_signature* sig, 39 | const unsigned char *input64, 40 | int recid 41 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 42 | 43 | /** Convert a recoverable signature into a normal signature. 44 | * 45 | * Returns: 1 46 | * Out: sig: a pointer to a normal signature (cannot be NULL). 47 | * In: sigin: a pointer to a recoverable signature (cannot be NULL). 48 | */ 49 | SECP256K1_API int secp256k1_ecdsa_recoverable_signature_convert( 50 | const secp256k1_context* ctx, 51 | secp256k1_ecdsa_signature* sig, 52 | const secp256k1_ecdsa_recoverable_signature* sigin 53 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3); 54 | 55 | /** Serialize an ECDSA signature in compact format (64 bytes + recovery id). 56 | * 57 | * Returns: 1 58 | * Args: ctx: a secp256k1 context object 59 | * Out: output64: a pointer to a 64-byte array of the compact signature (cannot be NULL) 60 | * recid: a pointer to an integer to hold the recovery id (can be NULL). 61 | * In: sig: a pointer to an initialized signature object (cannot be NULL) 62 | */ 63 | SECP256K1_API int secp256k1_ecdsa_recoverable_signature_serialize_compact( 64 | const secp256k1_context* ctx, 65 | unsigned char *output64, 66 | int *recid, 67 | const secp256k1_ecdsa_recoverable_signature* sig 68 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); 69 | 70 | /** Create a recoverable ECDSA signature. 71 | * 72 | * Returns: 1: signature created 73 | * 0: the nonce generation function failed, or the private key was invalid. 74 | * Args: ctx: pointer to a context object, initialized for signing (cannot be NULL) 75 | * Out: sig: pointer to an array where the signature will be placed (cannot be NULL) 76 | * In: msg32: the 32-byte message hash being signed (cannot be NULL) 77 | * seckey: pointer to a 32-byte secret key (cannot be NULL) 78 | * noncefp:pointer to a nonce generation function. If NULL, secp256k1_nonce_function_default is used 79 | * ndata: pointer to arbitrary data used by the nonce generation function (can be NULL) 80 | */ 81 | SECP256K1_API int secp256k1_ecdsa_sign_recoverable( 82 | const secp256k1_context* ctx, 83 | secp256k1_ecdsa_recoverable_signature *sig, 84 | const unsigned char *msg32, 85 | const unsigned char *seckey, 86 | secp256k1_nonce_function noncefp, 87 | const void *ndata 88 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); 89 | 90 | /** Recover an ECDSA public key from a signature. 91 | * 92 | * Returns: 1: public key successfully recovered (which guarantees a correct signature). 93 | * 0: otherwise. 94 | * Args: ctx: pointer to a context object, initialized for verification (cannot be NULL) 95 | * Out: pubkey: pointer to the recovered public key (cannot be NULL) 96 | * In: sig: pointer to initialized signature that supports pubkey recovery (cannot be NULL) 97 | * msg32: the 32-byte message hash assumed to be signed (cannot be NULL) 98 | */ 99 | SECP256K1_API SECP256K1_WARN_UNUSED_RESULT int secp256k1_ecdsa_recover( 100 | const secp256k1_context* ctx, 101 | secp256k1_pubkey *pubkey, 102 | const secp256k1_ecdsa_recoverable_signature *sig, 103 | const unsigned char *msg32 104 | ) SECP256K1_ARG_NONNULL(1) SECP256K1_ARG_NONNULL(2) SECP256K1_ARG_NONNULL(3) SECP256K1_ARG_NONNULL(4); 105 | 106 | #ifdef __cplusplus 107 | } 108 | #endif 109 | 110 | #endif /* SECP256K1_RECOVERY_H */ 111 | -------------------------------------------------------------------------------- /include/secp256k1/src/scalar.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_SCALAR_H 8 | #define SECP256K1_SCALAR_H 9 | 10 | #include "num.h" 11 | 12 | #if defined HAVE_CONFIG_H 13 | #include "libsecp256k1-config.h" 14 | #endif 15 | 16 | #if defined(EXHAUSTIVE_TEST_ORDER) 17 | #include "scalar_low.h" 18 | #elif defined(USE_SCALAR_4X64) 19 | #include "scalar_4x64.h" 20 | #elif defined(USE_SCALAR_8X32) 21 | #include "scalar_8x32.h" 22 | #else 23 | #error "Please select scalar implementation" 24 | #endif 25 | 26 | /** Clear a scalar to prevent the leak of sensitive data. */ 27 | static void secp256k1_scalar_clear(secp256k1_scalar *r); 28 | 29 | /** Access bits from a scalar. All requested bits must belong to the same 32-bit limb. */ 30 | static unsigned int secp256k1_scalar_get_bits(const secp256k1_scalar *a, unsigned int offset, unsigned int count); 31 | 32 | /** Access bits from a scalar. Not constant time. */ 33 | static unsigned int secp256k1_scalar_get_bits_var(const secp256k1_scalar *a, unsigned int offset, unsigned int count); 34 | 35 | /** Set a scalar from a big endian byte array. */ 36 | static void secp256k1_scalar_set_b32(secp256k1_scalar *r, const unsigned char *bin, int *overflow); 37 | 38 | /** Set a scalar to an unsigned integer. */ 39 | static void secp256k1_scalar_set_int(secp256k1_scalar *r, unsigned int v); 40 | 41 | /** Convert a scalar to a byte array. */ 42 | static void secp256k1_scalar_get_b32(unsigned char *bin, const secp256k1_scalar* a); 43 | 44 | /** Add two scalars together (modulo the group order). Returns whether it overflowed. */ 45 | static int secp256k1_scalar_add(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); 46 | 47 | /** Conditionally add a power of two to a scalar. The result is not allowed to overflow. */ 48 | static void secp256k1_scalar_cadd_bit(secp256k1_scalar *r, unsigned int bit, int flag); 49 | 50 | /** Multiply two scalars (modulo the group order). */ 51 | static void secp256k1_scalar_mul(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b); 52 | 53 | /** Shift a scalar right by some amount strictly between 0 and 16, returning 54 | * the low bits that were shifted off */ 55 | static int secp256k1_scalar_shr_int(secp256k1_scalar *r, int n); 56 | 57 | /** Compute the square of a scalar (modulo the group order). */ 58 | static void secp256k1_scalar_sqr(secp256k1_scalar *r, const secp256k1_scalar *a); 59 | 60 | /** Compute the inverse of a scalar (modulo the group order). */ 61 | static void secp256k1_scalar_inverse(secp256k1_scalar *r, const secp256k1_scalar *a); 62 | 63 | /** Compute the inverse of a scalar (modulo the group order), without constant-time guarantee. */ 64 | static void secp256k1_scalar_inverse_var(secp256k1_scalar *r, const secp256k1_scalar *a); 65 | 66 | /** Compute the complement of a scalar (modulo the group order). */ 67 | static void secp256k1_scalar_negate(secp256k1_scalar *r, const secp256k1_scalar *a); 68 | 69 | /** Check whether a scalar equals zero. */ 70 | static int secp256k1_scalar_is_zero(const secp256k1_scalar *a); 71 | 72 | /** Check whether a scalar equals one. */ 73 | static int secp256k1_scalar_is_one(const secp256k1_scalar *a); 74 | 75 | /** Check whether a scalar, considered as an nonnegative integer, is even. */ 76 | static int secp256k1_scalar_is_even(const secp256k1_scalar *a); 77 | 78 | /** Check whether a scalar is higher than the group order divided by 2. */ 79 | static int secp256k1_scalar_is_high(const secp256k1_scalar *a); 80 | 81 | /** Conditionally negate a number, in constant time. 82 | * Returns -1 if the number was negated, 1 otherwise */ 83 | static int secp256k1_scalar_cond_negate(secp256k1_scalar *a, int flag); 84 | 85 | #ifndef USE_NUM_NONE 86 | /** Convert a scalar to a number. */ 87 | static void secp256k1_scalar_get_num(secp256k1_num *r, const secp256k1_scalar *a); 88 | 89 | /** Get the order of the group as a number. */ 90 | static void secp256k1_scalar_order_get_num(secp256k1_num *r); 91 | #endif 92 | 93 | /** Compare two scalars. */ 94 | static int secp256k1_scalar_eq(const secp256k1_scalar *a, const secp256k1_scalar *b); 95 | 96 | #ifdef USE_ENDOMORPHISM 97 | /** Find r1 and r2 such that r1+r2*2^128 = a. */ 98 | static void secp256k1_scalar_split_128(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a); 99 | /** Find r1 and r2 such that r1+r2*lambda = a, and r1 and r2 are maximum 128 bits long (see secp256k1_gej_mul_lambda). */ 100 | static void secp256k1_scalar_split_lambda(secp256k1_scalar *r1, secp256k1_scalar *r2, const secp256k1_scalar *a); 101 | #endif 102 | 103 | /** Multiply a and b (without taking the modulus!), divide by 2**shift, and round to the nearest integer. Shift must be at least 256. */ 104 | static void secp256k1_scalar_mul_shift_var(secp256k1_scalar *r, const secp256k1_scalar *a, const secp256k1_scalar *b, unsigned int shift); 105 | 106 | #endif /* SECP256K1_SCALAR_H */ 107 | -------------------------------------------------------------------------------- /include/impl/memory/KeyStorage.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef SECUREARENA_H 5 | #define SECUREARENA_H 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | 18 | namespace nakasendo { namespace impl { namespace memory { 19 | 20 | /** 21 | * @brief The KeyStorage class. This class provides a secure storage service 22 | * It employes two different approaches on Windows and Linux. 23 | * On Windows this class itulises the system provided API for securing the data in user space memory. 24 | * On linux this class utilises services provided by kernel keyring service. This serive is used to store 25 | * binary blocks of user data in the kernel area. 26 | */ 27 | class KeyStorage 28 | { 29 | /** 30 | * @brief mStatusBase Unique #Status message code base 31 | */ 32 | static constexpr uint32_t mStatusBase = utils::Hash::fnv1a32("KeyStorage"); 33 | public: 34 | /* Key storage Status */ 35 | static constexpr utils::Status ERR_MAX_SIZE { mStatusBase, "Payload is too big" }; 36 | static constexpr utils::Status ERR_ZERO_SIZE{ mStatusBase + 1, "Payload has zero size" }; 37 | static constexpr utils::Status ERR_PADDING { mStatusBase + 2, "Wrong padding" }; 38 | static constexpr utils::Status ERR_MEMORY { mStatusBase + 3, "Could not allocate secure memory block" }; 39 | static constexpr utils::Status ERR_INIT { mStatusBase + 4, "Already initialised" }; 40 | static constexpr utils::Status ERR_NON_INIT { mStatusBase + 5, "Not initialised" }; 41 | static constexpr utils::Status ERR_DECRYPT { mStatusBase + 6, "Decryption failed" }; 42 | static constexpr utils::Status ERR_ENCRYPT { mStatusBase + 7, "Encryption failed" }; 43 | public: 44 | 45 | /** 46 | * @brief The Limits struct Provides information about system limits on number of keys and bytes. 47 | */ 48 | struct Limits{ 49 | std::string toStr()const { 50 | return "Keys: " + std::to_string(numOfKeys) + 51 | "; Bytes: " + std::to_string(numOfBytes); 52 | } 53 | 54 | size_t numOfKeys = 0; 55 | size_t numOfBytes = 0; 56 | }; 57 | 58 | /** 59 | * @brief KeyStorage Default constructor 60 | */ 61 | KeyStorage(){} 62 | 63 | /** 64 | * @brief KeyStorage Deleted copy constructor 65 | */ 66 | KeyStorage(const KeyStorage&) = delete; 67 | 68 | /** 69 | * @brief KeyStorage Move constructor 70 | */ 71 | KeyStorage(KeyStorage&&); 72 | 73 | 74 | /** 75 | * @brief KeyStorage Deleted copy assignment operator 76 | */ 77 | KeyStorage& operator=(const KeyStorage&) = delete; 78 | 79 | /** 80 | * @brief operator = move assignment operator 81 | * @return KeyStorage instance 82 | */ 83 | KeyStorage& operator=(KeyStorage&&); 84 | 85 | /** 86 | Destructor 87 | */ 88 | ~KeyStorage(); 89 | 90 | /** 91 | * @brief limits Queries system wide information about allocated keys and bytes used. 92 | * @param max If true then requests max limits for user, otherwise reports number of 93 | * keys and bytes already used 94 | * @return Limits structure 95 | */ 96 | static Limits limits(bool max = true); 97 | 98 | /** 99 | * @brief write writes payload and its name into secured storage 100 | * @param name payload name 101 | * @param clearData payload in a plain data 102 | * @param size payload size 103 | * @return True if successful 104 | */ 105 | const utils::Status& write(const KeyMeta& meta, SecureArray &&clearText); 106 | 107 | /** 108 | * @brief read Returns key data decrypted in key export format 109 | * @return smart pointer to key structure 110 | */ 111 | KeyExport read() const; 112 | 113 | /** 114 | * @brief remove Delete payload from secure storeage and release resources 115 | * @return True if successful 116 | */ 117 | utils::Status remove(); 118 | 119 | uintptr_t id()const; 120 | size_t size() const; 121 | 122 | std::string debug() const; 123 | 124 | private: 125 | /** 126 | * @brief getError Returns human readable description of the last error. 127 | * @return String description 128 | */ 129 | std::string getError() const; 130 | 131 | bool validateSize(size_t size) const; 132 | 133 | /* Storage protocol details */ 134 | static constexpr uint8_t PADDING_LENGTH = sizeof(uint8_t); 135 | static constexpr uint8_t SALT_LENGTH = sizeof(uintptr_t); 136 | static constexpr uint8_t META_LENGTH = sizeof(size_t); 137 | static constexpr uint8_t PAYLOAD_LENGTH = sizeof(size_t); 138 | static constexpr uint8_t HEADER_LENGTH = PADDING_LENGTH + SALT_LENGTH + META_LENGTH + PAYLOAD_LENGTH; 139 | 140 | static constexpr short maxSize = std::numeric_limits::max(); 141 | 142 | uintptr_t mStage = 0; /**< on Linux: serial number of the secure storage, Windows: pointer to secure memory area */ 143 | size_t mStageSize = 0; /**< size of unecrypted data */ 144 | bool mActive = false; /**< Treu if class instance is not initialised */ 145 | }; 146 | 147 | } } } 148 | #endif // SECUREARENA_H 149 | -------------------------------------------------------------------------------- /include/interface/RandomRangeGenerator.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | #ifndef _NCHAIN_SDK_SEEDER_H_ 5 | #define _NCHAIN_SDK_SEEDER_H_ 6 | 7 | #include 8 | 9 | #include 10 | 11 | namespace nakasendo { 12 | 13 | /** 14 | * A definition of supported sources of randomness. A user can provide it's own implementation of random source class to 15 | * instantiate KeyECSecp256k1 object (such a class should expose void generate(Iterator start, Iterator end) method and 16 | * a constructor with a seed if it is desired). 17 | */ 18 | 19 | template::value>::type, 22 | typename... Params> 23 | class RandomRangeGenerator 24 | { 25 | using IRandomType = RandomType; 26 | public: 27 | /// Provided seeds must be at least this many bytes 28 | static constexpr uint8_t MINIMUM_SEED_SIZE = SEED_SIZE; /* in bytes */ 29 | 30 | /// Default constructor 31 | RandomRangeGenerator() = default; 32 | 33 | RandomRangeGenerator(const RandomRangeGenerator&) = default; 34 | RandomRangeGenerator& operator=(const RandomRangeGenerator&) = default; 35 | 36 | RandomRangeGenerator(RandomRangeGenerator&& other): 37 | mSeeder(std::move(other.mSeeder)) 38 | {} 39 | 40 | RandomRangeGenerator& operator=(RandomRangeGenerator&& other){ 41 | if( this == &other ) 42 | return *this; 43 | 44 | mSeeder = std::move(other.mSeeder); 45 | 46 | return *this; 47 | } 48 | 49 | /** 50 | * @brief RandomRangeGenerator Initialize RNG generator with a user's seed (deterministic initialization of the seeder). 51 | * @param seedBegin iterator pointing at the start of seed sequence 52 | * @param seedEnd iterator pointing at the end of seed sequence 53 | */ 54 | template 55 | RandomRangeGenerator(const Range& seed, Params&&... params) /* seeded constructor */ 56 | { 57 | auto seedSrc = initSeed(std::begin(seed), std::end(seed)); 58 | cSeed( seedSrc.first, seedSrc.second, std::forward(params)... ); 59 | } 60 | 61 | template 62 | RandomRangeGenerator(const Iter begin, const Iter end, Params... params) /* seeded constructor */ 63 | { 64 | auto seedSrc = initSeed(begin, end); 65 | cSeed( seedSrc.first, seedSrc.second, std::forward(params)... ); 66 | } 67 | 68 | template 69 | size_t generate(Iter begin, Iter end, Params&&... params){ 70 | if( begin == end) 71 | return 0; 72 | 73 | auto result = convert(begin, end); 74 | auto size = std::distance(begin, end); 75 | 76 | cGenerate(result.first, result.second, std::forward(params)...); 77 | return size - size % sizeof(IRandomType); 78 | } 79 | 80 | /** 81 | * @brief generate a pseudo-random sequence of bytes. 82 | * @param first iterator pointing at the start of the sequence where generated data should be stored 83 | * @param last iterator pointing at the start of the sequence where generated data should be stored 84 | * @return number of generated bytes divisible by sizeof(RandomType) 85 | */ 86 | template 87 | size_t generate(Range& range, Params&&... params){ 88 | return generate(std::begin(range), std::end(range), std::forward(params)... ); 89 | } 90 | 91 | private: 92 | /* Generator dependent operations */ 93 | void cSeed(IRandomType* first, IRandomType* last, Params&&...); 94 | void cGenerate(IRandomType* first, IRandomType* last, Params&&...); 95 | /********************************/ 96 | 97 | template 98 | auto initSeed(const Iter& begin, const Iter& end) 99 | { 100 | checkSeedSize(begin, end); 101 | auto seedSrc = convert(begin, end); 102 | return seedSrc; 103 | } 104 | 105 | void asserts()const{ 106 | static_assert(std::is_integral::value, "Random data type is not integral"); 107 | static_assert(SEED_SIZE >= 32, "Seed size is too small"); 108 | } 109 | 110 | template 111 | size_t checkSeedSize(const Iter& begin, const Iter& end) const{ 112 | // Check the source seed is large enough 113 | size_t result = std::distance(begin, end) * sizeof( typename Iter::value_type ); /* in bytes */ 114 | if( result < MINIMUM_SEED_SIZE ){ 115 | throw std::runtime_error("Seed size needs to be at least " + std::to_string(MINIMUM_SEED_SIZE)); 116 | } 117 | return result / sizeof( RandomType ); /* in random numbers */ 118 | } 119 | 120 | template 121 | std::pair convert(const ConversionFrom& begin, const ConversionFrom& end) const{ 122 | std::pair result; 123 | decltype(&*begin) pBegin = &*begin; 124 | decltype(&*end) pEnd = pBegin + std::distance(begin, end); 125 | 126 | result.first = (ConversionTo*)pBegin; 127 | result.second = result.first + ( pEnd - pBegin) / sizeof( ConversionTo ); 128 | return result; 129 | } 130 | 131 | Generator mSeeder; 132 | }; 133 | 134 | using RandutilsSeed = RandomRangeGenerator; 135 | using RandutilsSeedSTL = RandomRangeGenerator; 136 | 137 | } 138 | #endif // _NCHAIN_SDK_SEEDER_H_ 139 | -------------------------------------------------------------------------------- /include/impl/SecretStoreImpl.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /* 5 | * The implementation for a secret store. 6 | */ 7 | 8 | #ifndef _NCHAIN_SDK_SECRET_STORE_IMPL_H_ 9 | #define _NCHAIN_SDK_SECRET_STORE_IMPL_H_ 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | namespace nakasendo { namespace impl 18 | { 19 | 20 | /// The implementation for a secret store. 21 | class SecretStoreImpl final : public SecretStore 22 | { 23 | /// For unit testing. 24 | friend class SecretStoreTester; 25 | 26 | public: 27 | /// Default constructor. 28 | SecretStoreImpl() = default; 29 | 30 | /// Forbid copying and assignment. 31 | SecretStoreImpl(const SecretStoreImpl&) = delete; 32 | SecretStoreImpl(SecretStoreImpl&&) = delete; 33 | SecretStoreImpl& operator=(const SecretStoreImpl&) = delete; 34 | SecretStoreImpl& operator=(SecretStoreImpl&&) = delete; 35 | 36 | /** 37 | * Set the master password used for encrypting/decrypting all stored secrets. 38 | * @param passwd The master password to use. 39 | */ 40 | void setMasterPassword(const impl::memory::SecureByteVec& passwd) override; 41 | 42 | /** 43 | * Set the persistent backing store. The store will use this to save/load 44 | * the secrets going forward. 45 | * @param db The persistence DB to use. 46 | */ 47 | void setSecretBackingStore(const SecretBackingStoreSPtr& db) override; 48 | 49 | /** 50 | * Add a new secret to the store. 51 | * @param secret The new secret to add. 52 | */ 53 | void addSecret(const SecretSPtr& secret) override; 54 | 55 | /** 56 | * Add a list of new secrets to the store. 57 | * @param secrets The new secrets to add. 58 | */ 59 | void addSecrets(const SecretSet& secrets) override; 60 | 61 | /** 62 | * Replace an existing secret in the store. 63 | * @param name The name of the secret currently in the store to replace. 64 | * @param secret The new secret to replace the old one with. 65 | */ 66 | void replaceSecret(const std::string& name, const SecretSPtr& secret) override; 67 | 68 | /** 69 | * Remove the named secret from the store. 70 | * @param name The name of the secret to erase. 71 | */ 72 | void removeSecret(const std::string& name) override; 73 | 74 | /** 75 | * Fetch secret by name. 76 | * @param name The name of the secret to lookup. 77 | * @return A pointer to the requested secret if found, nullptr otherwise. 78 | */ 79 | SecretSPtr getSecret(const std::string& name) const override; 80 | 81 | /** 82 | * Fetch all secrets. 83 | * @return A list of all secrets in the store. 84 | */ 85 | SecretSet getAllSecrets() const override; 86 | 87 | /** 88 | * Lookup secrets according to metadata. 89 | * @param key Metadata key to lookup. 90 | * @param value Metadata value to lookup. 91 | * @return A list of secrets that have metadata key=value. 92 | */ 93 | SecretSet getAllSecretsWhere(const std::string& key, 94 | const std::string& value) const override; 95 | 96 | /** 97 | * Fetch all secrets names. 98 | * @return A list of all stored secret names. 99 | */ 100 | std::vector getAllSecretNames() const override; 101 | 102 | /** 103 | * Add a newly loaded (restored from backing store) secret. Should only 104 | * be called from a SecretBackingStore implementation class. 105 | * @param secret A newly loaded secret to be added to the store. 106 | */ 107 | virtual void loadSecret(const SecretSPtr& secret) override; 108 | 109 | /** 110 | * Notification that the named secret has changed and the perisitence 111 | * backend should be informed. 112 | * @param name The name of the modified secret in the store. 113 | */ 114 | void secretUpdated(const std::string& name) override; 115 | 116 | private: 117 | 118 | /// Check we have a backing store and return it 119 | SecretBackingStoreSPtr getBackingStore(); 120 | 121 | /// A mutex for thread safety. 122 | mutable std::mutex mMtx {}; 123 | 124 | /// A pointer to the backing store in use. 125 | SecretBackingStoreSPtr mBackingStore {}; 126 | 127 | /// Map of secret names to Secrets 128 | using SecretMap = std::unordered_map; 129 | SecretMap mSecretMap {}; 130 | 131 | /// The master password to use when encrypting/descrypting. 132 | impl::memory::SecureByteVec mMasterPasswd {}; 133 | 134 | /// Flag to indicate we're currently performing a reload 135 | std::atomic mReloading {false}; 136 | }; 137 | 138 | 139 | /// A helper class for unit testing only. 140 | class SecretStoreTester 141 | { 142 | public: 143 | /// Constructor 144 | SecretStoreTester(SecretStoreImpl& store) : mStore{store} {} 145 | 146 | /// Clear out the secret store 147 | void clear() 148 | { 149 | std::lock_guard lck { mStore.mMtx }; 150 | mStore.mSecretMap.clear(); 151 | } 152 | 153 | /// Reload the secret store 154 | void reload() 155 | { 156 | mStore.setSecretBackingStore(mStore.mBackingStore); 157 | } 158 | 159 | /// Get size of secret store 160 | size_t storeSize() const 161 | { 162 | std::lock_guard lck { mStore.mMtx }; 163 | return mStore.mSecretMap.size(); 164 | } 165 | 166 | /// Reset the backing store 167 | void resetBackingStore() 168 | { 169 | std::lock_guard lck { mStore.mMtx }; 170 | mStore.mBackingStore = nullptr; 171 | } 172 | 173 | private: 174 | /// Reference to the store. 175 | SecretStoreImpl& mStore; 176 | }; 177 | 178 | 179 | }} 180 | 181 | #endif 182 | -------------------------------------------------------------------------------- /include/native/PubKeyECSecp256k1.h: -------------------------------------------------------------------------------- 1 | // Powered by nChain's Nakasendo libraries. 2 | // See LICENSE.txt in project root for licensing information. 3 | 4 | /** 5 | * Implementation of a public key for ECSecp256k1. 6 | */ 7 | 8 | #ifndef _NCHAIN_SDK_PUB_KEY_ECSECP256K1_H_ 9 | #define _NCHAIN_SDK_PUB_KEY_ECSECP256K1_H_ 10 | 11 | #include "EccontextSecp256k1.h" 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | namespace nakasendo 23 | { 24 | namespace native 25 | { 26 | /// Implementation of serialized public key (including compressed and uncompressed version). 27 | class PubKeyECSecp256k1 : public PubKey, 28 | public EccontextSecp256k1 29 | { 30 | /// Size of X & Y components of public keys 31 | static constexpr size_t PUB_KEY_XY_COMPONENT_SIZE { 32 }; 32 | /// Uncompressed public key size: Prefix(1byte) + Coordinates(64bytes = x(32bytes) + y(32bytes)) 33 | static constexpr size_t UNCOMPRESSED_PUB_KEY_SIZE { 1 + (PUB_KEY_XY_COMPONENT_SIZE * 2) }; 34 | /// Compressed public key size: Prefix(1byte) + Coordinates(32bytes = x(32bytes)) 35 | static constexpr size_t COMPRESSED_PUB_KEY_SIZE { 1 + PUB_KEY_XY_COMPONENT_SIZE }; 36 | /// A prefix for compressed key (0x02 - y is even, 0x03 - y is odd) 37 | static constexpr std::array COMPRESSED_PUB_KEY_PREFIX {0x02, 0x03}; 38 | /// A prefix for uncompressed key (0x04 - pubkey is uncompressed, 0x06 - pubkey is hybrid even, 0x07 - pubkey is hybrid odd) 39 | static constexpr std::array UNCOMPRESSED_PUB_KEY_PREFIX {0x04, 0x06, 0x07}; 40 | 41 | public: 42 | /// Create a public key from a given secret key (a valid public key in terms of secp256k1 specification). 43 | PubKeyECSecp256k1(const impl::MetaDataDefinitions::NetworkType& networkType, 44 | PubKey::Type pkType, 45 | const impl::memory::SecureByteVec& secKey); 46 | 47 | /// Create public key and set it from the given raw bytes. 48 | PubKeyECSecp256k1(const std::vector& bytes, 49 | const impl::MetaDataDefinitions::NetworkType networkType = 50 | impl::MetaDataDefinitions::NetworkType::MAIN_NET); 51 | 52 | private: 53 | /// Make public key. 54 | void makePublicKey(PubKey::Type pkType, const impl::memory::SecureByteVec& secKey); 55 | /// Source coding 56 | void sourceCoding(PubKey::Type pkType); 57 | /// Check if the public key is valid. 58 | bool isValid() const; 59 | /// Serialize secp public key 60 | std::vector serializeSecpPubKey(PubKey::Type pkType, const secp256k1_pubkey& secpPubKey) const; 61 | /// Get hash of the key. 62 | impl::utils::uint160 getHash160() const; 63 | 64 | /// Network type. 65 | const impl::MetaDataDefinitions::NetworkType m_networkType; 66 | /// Serialized public key. 67 | std::vector m_vSerializedPubKey {}; 68 | /// A mutex for thread safety modifications. 69 | mutable std::mutex m_mtx {}; 70 | 71 | public: 72 | /// Public key interface. 73 | 74 | /** 75 | * Check if the public key is compressed. 76 | */ 77 | virtual bool isCompressed() const override; 78 | 79 | /** 80 | * Decompress the public key if it's compressed. 81 | */ 82 | virtual void decompress() override; 83 | 84 | /** 85 | * Compress the public key if it's uncompressed. 86 | */ 87 | virtual void compress() override; 88 | 89 | /** 90 | * Get a vector of public key. 91 | * @return A vector containing raw public key. 92 | */ 93 | virtual std::vector getContent() const override; 94 | 95 | /** 96 | * Get a public key as a hex string. 97 | * @return A hexadecimal string representing of public key. 98 | */ 99 | virtual std::string getContentAsHexString() const override; 100 | 101 | /** 102 | * Derive a blockchain address from the public key. 103 | * @return A pointer to the blockchain address derived from the public key. 104 | */ 105 | virtual BlockChainAddressPtr getBlockChainAddress() const override; 106 | 107 | /** 108 | * Verify a signature of a message. 109 | * @param message The message the signature should be for. 110 | * @param signature The signature. 111 | * @return True if we can verify the signature. 112 | */ 113 | virtual bool verify(const std::vector& message, 114 | const std::vector& signature) const override; 115 | 116 | /** 117 | * Encrypt the given message so it may only be decrypted by our 118 | * corresponding private key. 119 | * @param message The message to encrypt. 120 | * @return An encrypted message. 121 | */ 122 | std::vector encrypt(const impl::memory::SecureByteVec& message) const override; 123 | 124 | /** 125 | * Deterministically derives a new key from this key using the given 126 | * message. 127 | * @param message The message to be used in deterministically deriving 128 | * the new key. 129 | * @return A derived new key. 130 | */ 131 | virtual PubKeyPtr derive(const std::vector& message) const override; 132 | 133 | }; 134 | 135 | } // end of namespace native 136 | } // end of namespace nakasendo 137 | 138 | #endif // _NCHAIN_SDK_PUB_KEY_ECSECP256K1_H_ 139 | -------------------------------------------------------------------------------- /include/secp256k1/src/field.h: -------------------------------------------------------------------------------- 1 | /********************************************************************** 2 | * Copyright (c) 2013, 2014 Pieter Wuille * 3 | * Distributed under the MIT software license, see the accompanying * 4 | * file COPYING or http://www.opensource.org/licenses/mit-license.php.* 5 | **********************************************************************/ 6 | 7 | #ifndef SECP256K1_FIELD_H 8 | #define SECP256K1_FIELD_H 9 | 10 | /** Field element module. 11 | * 12 | * Field elements can be represented in several ways, but code accessing 13 | * it (and implementations) need to take certain properties into account: 14 | * - Each field element can be normalized or not. 15 | * - Each field element has a magnitude, which represents how far away 16 | * its representation is away from normalization. Normalized elements 17 | * always have a magnitude of 1, but a magnitude of 1 doesn't imply 18 | * normality. 19 | */ 20 | 21 | #if defined HAVE_CONFIG_H 22 | #include "libsecp256k1-config.h" 23 | #endif 24 | 25 | #if defined(USE_FIELD_10X26) 26 | #include "field_10x26.h" 27 | #elif defined(USE_FIELD_5X52) 28 | #include "field_5x52.h" 29 | #else 30 | #error "Please select field implementation" 31 | #endif 32 | 33 | #include "util.h" 34 | 35 | /** Normalize a field element. */ 36 | static void secp256k1_fe_normalize(secp256k1_fe *r); 37 | 38 | /** Weakly normalize a field element: reduce it magnitude to 1, but don't fully normalize. */ 39 | static void secp256k1_fe_normalize_weak(secp256k1_fe *r); 40 | 41 | /** Normalize a field element, without constant-time guarantee. */ 42 | static void secp256k1_fe_normalize_var(secp256k1_fe *r); 43 | 44 | /** Verify whether a field element represents zero i.e. would normalize to a zero value. The field 45 | * implementation may optionally normalize the input, but this should not be relied upon. */ 46 | static int secp256k1_fe_normalizes_to_zero(secp256k1_fe *r); 47 | 48 | /** Verify whether a field element represents zero i.e. would normalize to a zero value. The field 49 | * implementation may optionally normalize the input, but this should not be relied upon. */ 50 | static int secp256k1_fe_normalizes_to_zero_var(secp256k1_fe *r); 51 | 52 | /** Set a field element equal to a small integer. Resulting field element is normalized. */ 53 | static void secp256k1_fe_set_int(secp256k1_fe *r, int a); 54 | 55 | /** Sets a field element equal to zero, initializing all fields. */ 56 | static void secp256k1_fe_clear(secp256k1_fe *a); 57 | 58 | /** Verify whether a field element is zero. Requires the input to be normalized. */ 59 | static int secp256k1_fe_is_zero(const secp256k1_fe *a); 60 | 61 | /** Check the "oddness" of a field element. Requires the input to be normalized. */ 62 | static int secp256k1_fe_is_odd(const secp256k1_fe *a); 63 | 64 | /** Compare two field elements. Requires magnitude-1 inputs. */ 65 | static int secp256k1_fe_equal(const secp256k1_fe *a, const secp256k1_fe *b); 66 | 67 | /** Same as secp256k1_fe_equal, but may be variable time. */ 68 | static int secp256k1_fe_equal_var(const secp256k1_fe *a, const secp256k1_fe *b); 69 | 70 | /** Compare two field elements. Requires both inputs to be normalized */ 71 | static int secp256k1_fe_cmp_var(const secp256k1_fe *a, const secp256k1_fe *b); 72 | 73 | /** Set a field element equal to 32-byte big endian value. If successful, the resulting field element is normalized. */ 74 | static int secp256k1_fe_set_b32(secp256k1_fe *r, const unsigned char *a); 75 | 76 | /** Convert a field element to a 32-byte big endian value. Requires the input to be normalized */ 77 | static void secp256k1_fe_get_b32(unsigned char *r, const secp256k1_fe *a); 78 | 79 | /** Set a field element equal to the additive inverse of another. Takes a maximum magnitude of the input 80 | * as an argument. The magnitude of the output is one higher. */ 81 | static void secp256k1_fe_negate(secp256k1_fe *r, const secp256k1_fe *a, int m); 82 | 83 | /** Multiplies the passed field element with a small integer constant. Multiplies the magnitude by that 84 | * small integer. */ 85 | static void secp256k1_fe_mul_int(secp256k1_fe *r, int a); 86 | 87 | /** Adds a field element to another. The result has the sum of the inputs' magnitudes as magnitude. */ 88 | static void secp256k1_fe_add(secp256k1_fe *r, const secp256k1_fe *a); 89 | 90 | /** Sets a field element to be the product of two others. Requires the inputs' magnitudes to be at most 8. 91 | * The output magnitude is 1 (but not guaranteed to be normalized). */ 92 | static void secp256k1_fe_mul(secp256k1_fe *r, const secp256k1_fe *a, const secp256k1_fe * SECP256K1_RESTRICT b); 93 | 94 | /** Sets a field element to be the square of another. Requires the input's magnitude to be at most 8. 95 | * The output magnitude is 1 (but not guaranteed to be normalized). */ 96 | static void secp256k1_fe_sqr(secp256k1_fe *r, const secp256k1_fe *a); 97 | 98 | /** If a has a square root, it is computed in r and 1 is returned. If a does not 99 | * have a square root, the root of its negation is computed and 0 is returned. 100 | * The input's magnitude can be at most 8. The output magnitude is 1 (but not 101 | * guaranteed to be normalized). The result in r will always be a square 102 | * itself. */ 103 | static int secp256k1_fe_sqrt(secp256k1_fe *r, const secp256k1_fe *a); 104 | 105 | /** Checks whether a field element is a quadratic residue. */ 106 | static int secp256k1_fe_is_quad_var(const secp256k1_fe *a); 107 | 108 | /** Sets a field element to be the (modular) inverse of another. Requires the input's magnitude to be 109 | * at most 8. The output magnitude is 1 (but not guaranteed to be normalized). */ 110 | static void secp256k1_fe_inv(secp256k1_fe *r, const secp256k1_fe *a); 111 | 112 | /** Potentially faster version of secp256k1_fe_inv, without constant-time guarantee. */ 113 | static void secp256k1_fe_inv_var(secp256k1_fe *r, const secp256k1_fe *a); 114 | 115 | /** Calculate the (modular) inverses of a batch of field elements. Requires the inputs' magnitudes to be 116 | * at most 8. The output magnitudes are 1 (but not guaranteed to be normalized). The inputs and 117 | * outputs must not overlap in memory. */ 118 | static void secp256k1_fe_inv_all_var(secp256k1_fe *r, const secp256k1_fe *a, size_t len); 119 | 120 | /** Convert a field element to the storage type. */ 121 | static void secp256k1_fe_to_storage(secp256k1_fe_storage *r, const secp256k1_fe *a); 122 | 123 | /** Convert a field element back from the storage type. */ 124 | static void secp256k1_fe_from_storage(secp256k1_fe *r, const secp256k1_fe_storage *a); 125 | 126 | /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ 127 | static void secp256k1_fe_storage_cmov(secp256k1_fe_storage *r, const secp256k1_fe_storage *a, int flag); 128 | 129 | /** If flag is true, set *r equal to *a; otherwise leave it. Constant-time. */ 130 | static void secp256k1_fe_cmov(secp256k1_fe *r, const secp256k1_fe *a, int flag); 131 | 132 | #endif /* SECP256K1_FIELD_H */ 133 | --------------------------------------------------------------------------------