Skip to content

Commit a69d714

Browse files
committed
Add support for optimised SHA256 on 64 bit x86 (Taken from core)
As this requires testing for support at runtime, users must call wally_init(0) on startup to (potentially) enable it.
1 parent 4fda14b commit a69d714

File tree

7 files changed

+1046
-15
lines changed

7 files changed

+1046
-15
lines changed

include/wally_core.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ extern "C" {
2828
#define WALLY_EINVAL -2 /** Invalid argument */
2929
#define WALLY_ENOMEM -3 /** malloc() failed */
3030

31+
/**
32+
* Initialize wally.
33+
*
34+
* As wally is not currently threadsafe, this function should be called once
35+
* before threads are created by the application.
36+
*
37+
* :param flags: Flags controlling what to initialize. Currently must be zero.
38+
*/
39+
WALLY_CORE_API int wally_init(uint32_t flags);
40+
3141
/**
3242
* Free any internally allocated memory.
3343
*
@@ -74,6 +84,10 @@ WALLY_CORE_API int wally_free_string(
7484
* The caller should call this function before using any functions that rely on
7585
* libsecp256k1 (i.e. Anything using public/private keys).
7686
*
87+
* As wally is not currently threadsafe, this function should either be
88+
* called before threads are created or access to wally functions wrapped
89+
* in an application level mutex.
90+
*
7791
* :param bytes: Entropy to use.
7892
* :param bytes_len: Size of ``bytes`` in bytes. Must be ``WALLY_SECP_RANDOMISE_LEN``.
7993
*/

src/ccan/ccan/crypto/sha256/sha256.c

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,25 +13,17 @@
1313
#include <assert.h>
1414
#include <string.h>
1515

16+
#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
1617
static void invalidate_sha256(struct sha256_ctx *ctx)
1718
{
18-
#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
1919
ctx->c.md_len = 0;
20-
#else
21-
ctx->bytes = (size_t)-1;
22-
#endif
2320
}
2421

2522
static void check_sha256(struct sha256_ctx *ctx UNUSED)
2623
{
27-
#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
2824
assert(ctx->c.md_len != 0);
29-
#else
30-
assert(ctx->bytes != (size_t)-1);
31-
#endif
3225
}
3326

34-
#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
3527
void sha256_init(struct sha256_ctx *ctx)
3628
{
3729
SHA256_Init(&ctx->c);
@@ -49,6 +41,16 @@ void sha256_done(struct sha256_ctx *ctx, struct sha256 *res)
4941
invalidate_sha256(ctx);
5042
}
5143
#else
44+
static void invalidate_sha256(struct sha256_ctx *ctx)
45+
{
46+
ctx->bytes = (size_t)-1;
47+
}
48+
49+
static void check_sha256(struct sha256_ctx *ctx UNUSED)
50+
{
51+
assert(ctx->bytes != (size_t)-1);
52+
}
53+
5254
static uint32_t Ch(uint32_t x, uint32_t y, uint32_t z)
5355
{
5456
return z ^ (x & (y ^ z));
@@ -83,8 +85,8 @@ static void Round(uint32_t a, uint32_t b, uint32_t c, uint32_t *d, uint32_t e, u
8385
*h = t1 + t2;
8486
}
8587

86-
/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
87-
static void Transform(uint32_t *s, const uint32_t *chunk, size_t blocks)
88+
/** Perform a number of SHA-256 transformations, processing 64-byte chunks. */
89+
static void TransformDefault(uint32_t *s, const uint32_t *chunk, size_t blocks)
8890
{
8991
while (blocks--) {
9092
uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7];
@@ -170,6 +172,25 @@ static void Transform(uint32_t *s, const uint32_t *chunk, size_t blocks)
170172
}
171173
}
172174

175+
#if defined(__x86_64__) || defined(__amd64__)
176+
#include <cpuid.h>
177+
178+
#include "sha256_sse4.c"
179+
180+
static int use_optimized_transform = 0;
181+
#endif
182+
183+
static inline void Transform(uint32_t *s, const uint32_t *chunk, size_t blocks)
184+
{
185+
#if defined(__x86_64__) || defined(__amd64__)
186+
if (use_optimized_transform) {
187+
TransformSSE4(s, chunk, blocks);
188+
return;
189+
}
190+
#endif
191+
TransformDefault(s, chunk, blocks);
192+
}
193+
173194
static void add(struct sha256_ctx *ctx, const void *p, size_t len)
174195
{
175196
const unsigned char *data = p;
@@ -209,6 +230,16 @@ static void add(struct sha256_ctx *ctx, const void *p, size_t len)
209230
}
210231
}
211232

233+
void sha256_optimize(void)
234+
{
235+
#if defined(__x86_64__) || defined(__amd64__)
236+
uint32_t eax, ebx, ecx, edx;
237+
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) && (ecx >> 19) & 1) {
238+
use_optimized_transform = 1;
239+
}
240+
#endif
241+
}
242+
212243
void sha256_init(struct sha256_ctx *ctx)
213244
{
214245
struct sha256_ctx init = SHA256_INIT;

src/ccan/ccan/crypto/sha256/sha256.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ struct sha256 {
2626
} u;
2727
};
2828

29+
/**
30+
* sha256_optimize - check for and enable optimised functionality if possible.
31+
*/
32+
void sha256_optimize(void);
33+
2934
/**
3035
* sha256 - return sha256 of an object.
3136
* @sha256: the sha256 to fill in

0 commit comments

Comments
 (0)