Skip to content

Commit

Permalink
Add support for optimised SHA256 on 64 bit x86 (Taken from core)
Browse files Browse the repository at this point in the history
As this requires testing for support at runtime, users must
call wally_init(0) on startup to (potentially) enable it.
  • Loading branch information
jgriffiths committed Apr 13, 2018
1 parent 4fda14b commit a69d714
Show file tree
Hide file tree
Showing 7 changed files with 1,046 additions and 15 deletions.
14 changes: 14 additions & 0 deletions include/wally_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ extern "C" {
#define WALLY_EINVAL -2 /** Invalid argument */
#define WALLY_ENOMEM -3 /** malloc() failed */

/**
* Initialize wally.
*
* As wally is not currently threadsafe, this function should be called once
* before threads are created by the application.
*
* :param flags: Flags controlling what to initialize. Currently must be zero.
*/
WALLY_CORE_API int wally_init(uint32_t flags);

/**
* Free any internally allocated memory.
*
Expand Down Expand Up @@ -74,6 +84,10 @@ WALLY_CORE_API int wally_free_string(
* The caller should call this function before using any functions that rely on
* libsecp256k1 (i.e. Anything using public/private keys).
*
* As wally is not currently threadsafe, this function should either be
* called before threads are created or access to wally functions wrapped
* in an application level mutex.
*
* :param bytes: Entropy to use.
* :param bytes_len: Size of ``bytes`` in bytes. Must be ``WALLY_SECP_RANDOMISE_LEN``.
*/
Expand Down
53 changes: 42 additions & 11 deletions src/ccan/ccan/crypto/sha256/sha256.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,17 @@
#include <assert.h>
#include <string.h>

#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
static void invalidate_sha256(struct sha256_ctx *ctx)
{
#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
ctx->c.md_len = 0;
#else
ctx->bytes = (size_t)-1;
#endif
}

static void check_sha256(struct sha256_ctx *ctx UNUSED)
{
#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
assert(ctx->c.md_len != 0);
#else
assert(ctx->bytes != (size_t)-1);
#endif
}

#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
void sha256_init(struct sha256_ctx *ctx)
{
SHA256_Init(&ctx->c);
Expand All @@ -49,6 +41,16 @@ void sha256_done(struct sha256_ctx *ctx, struct sha256 *res)
invalidate_sha256(ctx);
}
#else
static void invalidate_sha256(struct sha256_ctx *ctx)
{
ctx->bytes = (size_t)-1;
}

static void check_sha256(struct sha256_ctx *ctx UNUSED)
{
assert(ctx->bytes != (size_t)-1);
}

static uint32_t Ch(uint32_t x, uint32_t y, uint32_t z)
{
return z ^ (x & (y ^ z));
Expand Down Expand Up @@ -83,8 +85,8 @@ static void Round(uint32_t a, uint32_t b, uint32_t c, uint32_t *d, uint32_t e, u
*h = t1 + t2;
}

/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
static void Transform(uint32_t *s, const uint32_t *chunk, size_t blocks)
/** Perform a number of SHA-256 transformations, processing 64-byte chunks. */
static void TransformDefault(uint32_t *s, const uint32_t *chunk, size_t blocks)
{
while (blocks--) {
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];
Expand Down Expand Up @@ -170,6 +172,25 @@ static void Transform(uint32_t *s, const uint32_t *chunk, size_t blocks)
}
}

#if defined(__x86_64__) || defined(__amd64__)
#include <cpuid.h>

#include "sha256_sse4.c"

static int use_optimized_transform = 0;
#endif

static inline void Transform(uint32_t *s, const uint32_t *chunk, size_t blocks)
{
#if defined(__x86_64__) || defined(__amd64__)
if (use_optimized_transform) {
TransformSSE4(s, chunk, blocks);
return;
}
#endif
TransformDefault(s, chunk, blocks);
}

static void add(struct sha256_ctx *ctx, const void *p, size_t len)
{
const unsigned char *data = p;
Expand Down Expand Up @@ -209,6 +230,16 @@ static void add(struct sha256_ctx *ctx, const void *p, size_t len)
}
}

void sha256_optimize(void)
{
#if defined(__x86_64__) || defined(__amd64__)
uint32_t eax, ebx, ecx, edx;
if (__get_cpuid(1, &eax, &ebx, &ecx, &edx) && (ecx >> 19) & 1) {
use_optimized_transform = 1;
}
#endif
}

void sha256_init(struct sha256_ctx *ctx)
{
struct sha256_ctx init = SHA256_INIT;
Expand Down
5 changes: 5 additions & 0 deletions src/ccan/ccan/crypto/sha256/sha256.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ struct sha256 {
} u;
};

/**
* sha256_optimize - check for and enable optimised functionality if possible.
*/
void sha256_optimize(void);

/**
* sha256 - return sha256 of an object.
* @sha256: the sha256 to fill in
Expand Down
Loading

0 comments on commit a69d714

Please sign in to comment.