Skip to content

Commit 54caf2e

Browse files
Merge #799: Add fallback LE/BE for architectures with known endianness + SHA256 selftest
8bc6aef Add SHA256 selftest (Pieter Wuille) 5e5fb28 Use additional system macros to figure out endianness (Pieter Wuille) Pull request description: These are all the architecture macros I could find with known endianness. Use those as a fallback when __BYTE_ORDER__ isn't available. See #787 (comment) It also adds a SHA256 selftest, so that improperly overriding the endianness detection will be detected at runtime. ACKs for top commit: real-or-random: ACK 8bc6aef I read the diff, and tested that the self-test passes/fails with/without the correct endianness setting gmaxwell: ACK 8bc6aef looks good and I also ran the tests on MIPS-BE and verified that forcing it to LE makes the runtime test fail. Tree-SHA512: aca4cebcd0715dcf5b58f5763cb4283af238987f43bd83a650e38e127f348131692b2eed7ae5b2ae96046d9b971fc77c6ab44467689399fe470a605c3458ecc5
2 parents f49c989 + 8bc6aef commit 54caf2e

File tree

4 files changed

+54
-6
lines changed

4 files changed

+54
-6
lines changed

Makefile.am

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ noinst_HEADERS += src/assumptions.h
3838
noinst_HEADERS += src/util.h
3939
noinst_HEADERS += src/scratch.h
4040
noinst_HEADERS += src/scratch_impl.h
41+
noinst_HEADERS += src/selftest.h
4142
noinst_HEADERS += src/testrand.h
4243
noinst_HEADERS += src/testrand_impl.h
4344
noinst_HEADERS += src/hash.h

src/secp256k1.c

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "eckey_impl.h"
2121
#include "hash_impl.h"
2222
#include "scratch_impl.h"
23+
#include "selftest.h"
2324

2425
#if defined(VALGRIND)
2526
# include <valgrind/memcheck.h>
@@ -118,6 +119,9 @@ secp256k1_context* secp256k1_context_preallocated_create(void* prealloc, unsigne
118119
size_t prealloc_size;
119120
secp256k1_context* ret;
120121

122+
if (!secp256k1_selftest()) {
123+
secp256k1_callback_call(&default_error_callback, "self test failed");
124+
}
121125
VERIFY_CHECK(prealloc != NULL);
122126
prealloc_size = secp256k1_context_preallocated_size(flags);
123127
ret = (secp256k1_context*)manual_alloc(&prealloc, sizeof(secp256k1_context), base, prealloc_size);

src/selftest.h

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**********************************************************************
2+
* Copyright (c) 2020 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_SELFTEST_H
8+
#define SECP256K1_SELFTEST_H
9+
10+
#include "hash.h"
11+
12+
#include <string.h>
13+
14+
static int secp256k1_selftest_sha256(void) {
15+
static const char *input63 = "For this sample, this 63-byte string will be used as input data";
16+
static const unsigned char output32[32] = {
17+
0xf0, 0x8a, 0x78, 0xcb, 0xba, 0xee, 0x08, 0x2b, 0x05, 0x2a, 0xe0, 0x70, 0x8f, 0x32, 0xfa, 0x1e,
18+
0x50, 0xc5, 0xc4, 0x21, 0xaa, 0x77, 0x2b, 0xa5, 0xdb, 0xb4, 0x06, 0xa2, 0xea, 0x6b, 0xe3, 0x42,
19+
};
20+
unsigned char out[32];
21+
secp256k1_sha256 hasher;
22+
secp256k1_sha256_initialize(&hasher);
23+
secp256k1_sha256_write(&hasher, (const unsigned char*)input63, 63);
24+
secp256k1_sha256_finalize(&hasher, out);
25+
return memcmp(out, output32, 32) == 0;
26+
}
27+
28+
static int secp256k1_selftest(void) {
29+
return secp256k1_selftest_sha256();
30+
}
31+
32+
#endif /* SECP256K1_SELFTEST_H */

src/util.h

+17-6
Original file line numberDiff line numberDiff line change
@@ -176,16 +176,27 @@ static SECP256K1_INLINE void *manual_alloc(void** prealloc_ptr, size_t alloc_siz
176176
# define SECP256K1_GNUC_EXT
177177
#endif
178178

179-
#if defined(__BYTE_ORDER__)
180-
# if defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ && !defined(SECP256K1_LITTLE_ENDIAN)
179+
/* If SECP256K1_{LITTLE,BIG}_ENDIAN is not explicitly provided, infer from various other system macros. */
180+
#if !defined(SECP256K1_LITTLE_ENDIAN) && !defined(SECP256K1_BIG_ENDIAN)
181+
/* Inspired by https://github.com/rofl0r/endianness.h/blob/9853923246b065a3b52d2c43835f3819a62c7199/endianness.h#L52L73 */
182+
# if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) || \
183+
defined(_X86_) || defined(__x86_64__) || defined(__i386__) || \
184+
defined(__i486__) || defined(__i586__) || defined(__i686__) || \
185+
defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) || \
186+
defined(__ARMEL__) || defined(__AARCH64EL__) || \
187+
(defined(__LITTLE_ENDIAN__) && __LITTLE_ENDIAN__ == 1) || \
188+
(defined(_LITTLE_ENDIAN) && _LITTLE_ENDIAN == 1) || \
189+
defined(_M_IX86) || defined(_M_AMD64) || defined(_M_ARM) /* MSVC */
181190
# define SECP256K1_LITTLE_ENDIAN
182-
# elif defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ && !defined(SECP256K1_BIG_ENDIAN)
191+
# endif
192+
# if (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) || \
193+
defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) || \
194+
defined(__MICROBLAZEEB__) || defined(__ARMEB__) || defined(__AARCH64EB__) || \
195+
(defined(__BIG_ENDIAN__) && __BIG_ENDIAN__ == 1) || \
196+
(defined(_BIG_ENDIAN) && _BIG_ENDIAN == 1)
183197
# define SECP256K1_BIG_ENDIAN
184198
# endif
185199
#endif
186-
#if defined(_MSC_VER) && defined(_WIN32) && !defined(SECP256K1_LITTLE_ENDIAN)
187-
# define SECP256K1_LITTLE_ENDIAN
188-
#endif
189200
#if defined(SECP256K1_LITTLE_ENDIAN) == defined(SECP256K1_BIG_ENDIAN)
190201
# error Please make sure that either SECP256K1_LITTLE_ENDIAN or SECP256K1_BIG_ENDIAN is set, see src/util.h.
191202
#endif

0 commit comments

Comments
 (0)