From 5e5fb28b4a45d7e35e55b5f5feead2be07bccc28 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Fri, 14 Aug 2020 11:49:34 -0700 Subject: [PATCH 1/2] Use additional system macros to figure out endianness Also permit it being overridden by explicitly passing SECP256K1_{BIG,LITTLE}_ENDIAN --- src/util.h | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/src/util.h b/src/util.h index eb4db4faf53bf..e8d7015c5dfad 100644 --- a/src/util.h +++ b/src/util.h @@ -176,16 +176,27 @@ static SECP256K1_INLINE void *manual_alloc(void** prealloc_ptr, size_t alloc_siz # define SECP256K1_GNUC_EXT #endif -#if defined(__BYTE_ORDER__) -# if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && !defined(SECP256K1_LITTLE_ENDIAN) +/* If SECP256K1_{LITTLE,BIG}_ENDIAN is not explicitly provided, infer from various other system macros. */ +#if !defined(SECP256K1_LITTLE_ENDIAN) && !defined(SECP256K1_BIG_ENDIAN) +/* Inspired by https://github.com/rofl0r/endianness.h/blob/9853923246b065a3b52d2c43835f3819a62c7199/endianness.h#L52L73 */ +# if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \ + defined(_X86_) || defined(__x86_64__) || defined(__i386__) || \ + defined(__i486__) || defined(__i586__) || defined(__i686__) || \ + defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) || \ + defined(__ARMEL__) || defined(__AARCH64EL__) || \ + (defined(__LITTLE_ENDIAN__) && __LITTLE_ENDIAN__ == 1) || \ + (defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN == 1) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_ARM) /* MSVC */ # define SECP256K1_LITTLE_ENDIAN -# elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && !defined(SECP256K1_BIG_ENDIAN) +# endif +# if (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \ + defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) || \ + defined(__MICROBLAZEEB__) || defined(__ARMEB__) || defined(__AARCH64EB__) || \ + (defined(__BIG_ENDIAN__) && __BIG_ENDIAN__ == 1) || \ + (defined(_BIG_ENDIAN) && _BIG_ENDIAN == 1) # define SECP256K1_BIG_ENDIAN # endif #endif -#if defined(_MSC_VER) && defined(_WIN32) && !defined(SECP256K1_LITTLE_ENDIAN) -# define SECP256K1_LITTLE_ENDIAN -#endif #if defined(SECP256K1_LITTLE_ENDIAN) == defined(SECP256K1_BIG_ENDIAN) # error Please make sure that either SECP256K1_LITTLE_ENDIAN or SECP256K1_BIG_ENDIAN is set, see src/util.h. #endif From 8bc6aeffa9a191e677cb9e3a22fff130f16990f3 Mon Sep 17 00:00:00 2001 From: Pieter Wuille Date: Mon, 17 Aug 2020 13:48:22 -0700 Subject: [PATCH 2/2] Add SHA256 selftest --- Makefile.am | 1 + src/secp256k1.c | 4 ++++ src/selftest.h | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 src/selftest.h diff --git a/Makefile.am b/Makefile.am index a30a84cd599c7..1d9bc7a2c694e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -37,6 +37,7 @@ noinst_HEADERS += src/field_5x52_asm_impl.h noinst_HEADERS += src/util.h noinst_HEADERS += src/scratch.h noinst_HEADERS += src/scratch_impl.h +noinst_HEADERS += src/selftest.h noinst_HEADERS += src/testrand.h noinst_HEADERS += src/testrand_impl.h noinst_HEADERS += src/hash.h diff --git a/src/secp256k1.c b/src/secp256k1.c index 3e7926503825d..4b7e82d260785 100644 --- a/src/secp256k1.c +++ b/src/secp256k1.c @@ -19,6 +19,7 @@ #include "eckey_impl.h" #include "hash_impl.h" #include "scratch_impl.h" +#include "selftest.h" #if defined(VALGRIND) # include @@ -117,6 +118,9 @@ secp256k1_context* secp256k1_context_preallocated_create(void* prealloc, unsigne size_t prealloc_size; secp256k1_context* ret; + if (!secp256k1_selftest()) { + secp256k1_callback_call(&default_error_callback, "self test failed"); + } VERIFY_CHECK(prealloc != NULL); prealloc_size = secp256k1_context_preallocated_size(flags); ret = (secp256k1_context*)manual_alloc(&prealloc, sizeof(secp256k1_context), base, prealloc_size); diff --git a/src/selftest.h b/src/selftest.h new file mode 100644 index 0000000000000..885983aa20999 --- /dev/null +++ b/src/selftest.h @@ -0,0 +1,32 @@ +/********************************************************************** + * Copyright (c) 2020 Pieter Wuille * + * Distributed under the MIT software license, see the accompanying * + * file COPYING or http://www.opensource.org/licenses/mit-license.php.* + **********************************************************************/ + +#ifndef SECP256K1_SELFTEST_H +#define SECP256K1_SELFTEST_H + +#include "hash.h" + +#include + +static int secp256k1_selftest_sha256(void) { + static const char *input63 = "For this sample, this 63-byte string will be used as input data"; + static const unsigned char output32[32] = { + 0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e, + 0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42, + }; + unsigned char out[32]; + secp256k1_sha256 hasher; + secp256k1_sha256_initialize(&hasher); + secp256k1_sha256_write(&hasher, (const unsigned char*)input63, 63); + secp256k1_sha256_finalize(&hasher, out); + return memcmp(out, output32, 32) == 0; +} + +static int secp256k1_selftest(void) { + return secp256k1_selftest_sha256(); +} + +#endif /* SECP256K1_SELFTEST_H */