commit 94e6f571e969a5fc40ee9fb3808615ee191b851c
Author: William Casarin <jb55@jb55.com>
Date: Fri, 24 May 2019 13:26:33 -0700
initial commit
Diffstat:
A | .dir-locals.el | | | 7 | +++++++ |
A | .gitignore | | | 3 | +++ |
A | Makefile | | | 31 | +++++++++++++++++++++++++++++++ |
A | base58.c | | | 301 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | base58.h | | | 31 | +++++++++++++++++++++++++++++++ |
A | bip32.c | | | 762 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | bip32.h | | | 252 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | check.c | | | 11 | +++++++++++ |
A | clightning-dumpkeys.c | | | 160 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | compiler.c | | | 12 | ++++++++++++ |
A | compiler.h | | | 55 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | ec.c | | | 30 | ++++++++++++++++++++++++++++++ |
A | ec.h | | | 34 | ++++++++++++++++++++++++++++++++++ |
A | endian.h | | | 360 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | hash.c | | | 28 | ++++++++++++++++++++++++++++ |
A | hash.h | | | 13 | +++++++++++++ |
A | hkdf.c | | | 98 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | hkdf.h | | | 22 | ++++++++++++++++++++++ |
A | hmac.c | | | 248 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | hmac.h | | | 116 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | ripemd160.c | | | 404 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | ripemd160.h | | | 148 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | sha256.c | | | 321 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | sha256.h | | | 158 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | sha512.c | | | 261 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | sha512.h | | | 138 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | short_types.h | | | 21 | +++++++++++++++++++++ |
27 files changed, 4025 insertions(+), 0 deletions(-)
diff --git a/.dir-locals.el b/.dir-locals.el
@@ -0,0 +1,7 @@
+((c-mode . ((c-file-style . "linux")
+ (indent-tabs-mode . t)
+ (show-trailing-whitespace . t)
+ (c-basic-offset . 8)
+ (tab-width . 8)
+ ))
+ )
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,3 @@
+*.o
+/clightning-dumpkeys
+/check
diff --git a/Makefile b/Makefile
@@ -0,0 +1,31 @@
+
+BIN = clightning-dumpkeys
+PREFIX ?= /usr/local
+
+LDFLAGS = -lsecp256k1
+CFLAGS = $(DEFS) -Og -g -I src -Wall -Werror -Wextra -std=c99
+
+OBJS = sha256.o
+OBJS += sha512.o
+OBJS += ripemd160.o
+OBJS += hmac.o
+OBJS += hkdf.o
+OBJS += bip32.o
+OBJS += compiler.o
+OBJS += ec.o
+OBJS += hash.o
+OBJS += base58.o
+
+SRCS=$(OBJS:.o=.c)
+
+all: $(BIN)
+
+$(BIN): clightning-dumpkeys.o $(OBJS)
+ $(CC) $(LDFLAGS) $(CFLAGS) $^ -o $@
+
+clean:
+ rm -f $(OBJS) clightning-dumpkeys.o check.o $(BIN) check
+
+check: check.o $(OBJS)
+ $(CC) $(LDFLAGS) $^ -o $@
+ ./check
diff --git a/base58.c b/base58.c
@@ -0,0 +1,301 @@
+
+#include "base58.h"
+#include "sha256.h"
+#include "endian.h"
+#include "short_types.h"
+#include "compiler.h"
+
+#include <strings.h>
+
+/* Temporary stack buffer sizes */
+#define BIGNUM_WORDS 128u
+#define BIGNUM_BYTES (BIGNUM_WORDS * sizeof(uint32_t))
+#define BASE58_ALL_DEFINED_FLAGS (BASE58_FLAG_CHECKSUM)
+
+static const unsigned char base58_to_byte[256] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* .1234567 */
+ 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 89...... */
+
+ 0x00, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, /* .ABCDEFG */
+ 0x11, 0x00, 0x12, 0x13, 0x14, 0x15, 0x16, 0x00, /* H.JKLMN. */
+ 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, /* PQRSTUVW */
+ 0x1F, 0x20, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, /* XYZ..... */
+
+ 0x00, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, /* .abcdefg */
+ 0x29, 0x2A, 0x2B, 0x2C, 0x00, 0x2D, 0x2E, 0x2F, /* hijk.mno */
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* pqrstuvx */
+ 0x38, 0x39, 0x3A, 0x00, 0x00, 0x00, 0x00, 0x00, /* xyz..... */
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+};
+
+static const char byte_to_base58[58] = {
+ '1', '2', '3', '4', '5', '6', '7', '8',
+ '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q',
+ 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y',
+ 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
+ 'h', 'i', 'j', 'k', 'm', 'n', 'o', 'p',
+ 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'y','z'
+};
+
+/* Returns non-zero on error. If 0 is returned then:
+ * *len <= input value - OK, bytes_out contains data.
+ * *len > input value - Failed and bytes_out untouched.
+ */
+static int base58_decode(const char *base58, size_t base58_len,
+ unsigned char *bytes_out, size_t *len)
+{
+ uint32_t bn_buf[BIGNUM_WORDS];
+ uint32_t *bn = bn_buf, *top_word, *bn_p;
+ size_t bn_words = 0, ones, cp_len, i;
+ unsigned char *cp;
+ int ret = WALLY_EINVAL;
+
+ if (!base58 || !base58_len)
+ return WALLY_EINVAL; /* Empty string can't be decoded or represented */
+
+ /* Process leading '1's */
+ for (ones = 0; ones < base58_len && base58[ones] == '1'; ++ones)
+ ; /* no-op*/
+
+ if (!(base58_len -= ones)) {
+ if (bytes_out && ones <= *len)
+ memset(bytes_out, 0, ones);
+ *len = ones;
+ return WALLY_OK; /* String of all '1's */
+ }
+ base58 += ones; /* Skip over leading '1's */
+
+ /* Take 6 bits to store each 58 bit number, rounded up to the next byte,
+ * then round that up to a uint32_t word boundary. */
+ bn_words = ((base58_len * 6 + 7) / 8 + 3) / 4;
+
+ /* Allocate our bignum buffer if it won't fit on the stack */
+ if (bn_words > BIGNUM_WORDS)
+ if (!(bn = malloc(bn_words * sizeof(*bn)))) {
+ ret = WALLY_ENOMEM;
+ goto cleanup;
+ }
+
+ /* Iterate through the characters adding them to our bignum. We keep
+ * track of the current top word to avoid iterating over words that
+ * we know are zero. */
+ top_word = bn + bn_words - 1;
+ *top_word = 0;
+
+ for (i = 0; i < base58_len; ++i) {
+ unsigned char byte = base58_to_byte[((unsigned char *)base58)[i]];
+ if (!byte--)
+ goto cleanup; /* Invalid char */
+
+ for (bn_p = bn + bn_words - 1; bn_p >= top_word; --bn_p) {
+ uint64_t mult = *bn_p * 58ull + byte;
+ *bn_p = mult & 0xffffffff;
+ byte = (mult >> 32) & 0xff;
+ if (byte && bn_p == top_word) {
+ *--top_word = byte; /* Increase bignum size */
+ break;
+ }
+ }
+ }
+
+ /* We have our bignum stored from top_word to bn + bn_words - 1. Convert
+ * its words to big-endian so we can simply memcpy it to bytes_out. */
+ for (bn_p = top_word; bn_p < bn + bn_words; ++bn_p)
+ *bn_p = cpu_to_be32(*bn_p); /* No-op on big-endian machines */
+
+ for (cp = (unsigned char *)top_word; !*cp; ++cp)
+ ; /* Skip leading zero bytes in our bignum */
+
+ /* Copy the result if it fits, cleanup and return */
+ cp_len = (unsigned char *)(bn + bn_words) - cp;
+
+ if (bytes_out && ones + cp_len <= *len) {
+ memset(bytes_out, 0, ones);
+ memcpy(bytes_out + ones, cp, cp_len);
+ }
+
+ *len = ones + cp_len;
+ ret = WALLY_OK;
+
+cleanup:
+ wally_clear(bn, bn_words * sizeof(*bn));
+ if (bn != bn_buf)
+ free(bn);
+ return ret;
+}
+
+uint32_t base58_get_checksum(const unsigned char *bytes, size_t bytes_len)
+{
+ struct sha256 sha;
+ uint32_t checksum;
+
+ sha256d(bytes, bytes_len, (unsigned char *)&sha, sizeof(sha));
+ checksum = sha.u.u32[0];
+ wally_clear(&sha, sizeof(sha));
+ return checksum;
+}
+
+
+int wally_base58_from_bytes(const unsigned char *bytes, size_t bytes_len,
+ uint32_t flags, char **output)
+{
+ uint32_t checksum, *cs_p = NULL;
+ unsigned char bn_buf[BIGNUM_BYTES];
+ unsigned char *bn = bn_buf, *top_byte, *bn_p;
+ size_t bn_bytes = 0, zeros, i, orig_len = bytes_len;
+ int ret = WALLY_EINVAL;
+
+ if (output)
+ *output = NULL;
+
+ if (!bytes || !bytes_len || (flags & ~BASE58_ALL_DEFINED_FLAGS) || !output)
+ goto cleanup; /* Invalid argument */
+
+ if (flags & BASE58_FLAG_CHECKSUM) {
+ checksum = base58_get_checksum(bytes, bytes_len);
+ cs_p = &checksum;
+ bytes_len += 4;
+ }
+
+#define b(n) (n < orig_len ? bytes[n] : ((unsigned char *)cs_p)[n - orig_len])
+
+ /* Process leading zeros */
+ for (zeros = 0; zeros < bytes_len && !b(zeros); ++zeros)
+ ; /* no-op*/
+
+ if (zeros == bytes_len) {
+ if (!(*output = malloc(zeros + 1))) {
+ ret = WALLY_ENOMEM;
+ goto cleanup;
+ }
+
+ memset(*output, '1', zeros);
+ (*output)[zeros] = '\0';
+ return WALLY_OK; /* All 0's */
+ }
+
+ bn_bytes = (bytes_len - zeros) * 138 / 100 + 1; /* log(256)/log(58) rounded up */
+
+ /* Allocate our bignum buffer if it won't fit on the stack */
+ if (bn_bytes > BIGNUM_BYTES)
+ if (!(bn = malloc(bn_bytes))) {
+ ret = WALLY_ENOMEM;
+ goto cleanup;
+ }
+
+ top_byte = bn + bn_bytes - 1;
+ *top_byte = 0;
+
+ for (i = zeros; i < bytes_len; ++i) {
+ uint32_t carry = b(i);
+ for (bn_p = bn + bn_bytes - 1; bn_p >= top_byte; --bn_p) {
+ carry = *bn_p * 256 + carry;
+ *bn_p = carry % 58;
+ carry = carry / 58;
+ if (carry && bn_p == top_byte)
+ *--top_byte = 0; /* Increase bignum size */
+ }
+ }
+
+ while (!*top_byte && top_byte < bn + bn_bytes - 1)
+ ++top_byte; /* Skip leading zero bytes in our bignum */
+
+ /* Copy the result */
+ bn_bytes = bn + bn_bytes - top_byte;
+
+ if (!(*output = malloc(zeros + bn_bytes + 1))) {
+ ret = WALLY_ENOMEM;
+ goto cleanup;
+ }
+
+ memset(*output, '1', zeros);
+ for (i = 0; i < bn_bytes; ++i)
+ (*output)[zeros + i] = byte_to_base58[top_byte[i]];
+ (*output)[zeros + bn_bytes] = '\0';
+
+ ret = WALLY_OK;
+
+cleanup:
+ wally_clear(bn, bn_bytes);
+ if (bn != bn_buf)
+ free(bn);
+ return ret;
+#undef b
+}
+
+
+int wally_base58_get_length(const char *str_in, size_t *written)
+{
+ return base58_decode(str_in, strlen(str_in), NULL, written);
+}
+
+int wally_base58_to_bytes(const char *str_in, uint32_t flags,
+ unsigned char *bytes_out, size_t len,
+ size_t *written)
+{
+ size_t offset;
+ uint32_t checksum;
+ int ret;
+
+ if (written)
+ *written = 0;
+
+ if (!str_in || flags & ~BASE58_ALL_DEFINED_FLAGS ||
+ !bytes_out || !len || !written)
+ return WALLY_EINVAL;
+
+ if (flags & BASE58_FLAG_CHECKSUM && len <= BASE58_CHECKSUM_LEN)
+ return WALLY_EINVAL; /* No room for checksum */
+
+ *written = len;
+ ret = base58_decode(str_in, strlen(str_in), bytes_out, written);
+ if (!ret && *written > len)
+ return WALLY_OK; /* not enough space, return required amount */
+
+ if (!ret && (flags & BASE58_FLAG_CHECKSUM)) {
+ if (*written <= BASE58_CHECKSUM_LEN) {
+ wally_clear(bytes_out, len);
+ return WALLY_EINVAL; /* Input not long enough to contain a checksum */
+ }
+
+ offset = *written - BASE58_CHECKSUM_LEN;
+ checksum = base58_get_checksum(bytes_out, offset);
+
+ if (memcmp(bytes_out + offset, &checksum, sizeof(checksum))) {
+ wally_clear(bytes_out, len);
+ return WALLY_EINVAL; /* Checksum mismatch */
+ }
+
+ wally_clear(bytes_out + offset, BASE58_CHECKSUM_LEN);
+ *written -= BASE58_CHECKSUM_LEN;
+ }
+ return ret;
+}
diff --git a/base58.h b/base58.h
@@ -0,0 +1,31 @@
+
+#ifndef LIBWALLY_BASE58_H
+#define LIBWALLY_BASE58_H
+
+#include <stdint.h>
+#include <stdlib.h>
+
+/**
+ * Calculate the base58 checksum of a block of binary data.
+ *
+ * @bytes: Binary data to calculate the checksum for.
+ * @len: The length of @bytes in bytes.
+ */
+uint32_t base58_get_checksum(
+ const unsigned char *bytes,
+ size_t len);
+
+int wally_base58_from_bytes(const unsigned char *bytes, size_t bytes_len,
+ uint32_t flags, char **output);
+
+int wally_base58_to_bytes(
+ const char *str_in,
+ uint32_t flags,
+ unsigned char *bytes_out,
+ size_t len,
+ size_t *written);
+
+#define BASE58_FLAG_CHECKSUM 0x1
+#define BASE58_CHECKSUM_LEN 4
+
+#endif /* LIBWALLY_BASE58_H */
diff --git a/bip32.c b/bip32.c
@@ -0,0 +1,762 @@
+
+#include "hmac.h"
+#include "ripemd160.h"
+#include "sha512.h"
+#include "endian.h"
+#include "compiler.h"
+#include "bip32.h"
+#include "ec.h"
+#include "hash.h"
+#include "base58.h"
+#include "short_types.h"
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <string.h>
+#include <stdio.h>
+
+#define EC_PRIVATE_KEY_LEN 32
+#define BIP32_ALL_DEFINED_FLAGS (BIP32_FLAG_KEY_PRIVATE | BIP32_FLAG_KEY_PUBLIC | BIP32_FLAG_SKIP_HASH)
+
+static const unsigned char SEED[] = {
+ 'B', 'i', 't', 'c', 'o', 'i', 'n', ' ', 's', 'e', 'e', 'd'
+};
+
+/* LCOV_EXCL_START */
+/* Check assumptions we expect to hold true */
+void assert_bip32_assumptions(void)
+{
+#define key_off(member) offsetof(struct ext_key, member)
+#define key_size(member) sizeof(((struct ext_key *)0)->member)
+
+ /* Our ripend buffers must be uint32_t aligned and the correct size */
+ BUILD_ASSERT(key_off(parent160) % sizeof(uint32_t) == 0);
+ BUILD_ASSERT(key_off(hash160) % sizeof(uint32_t) == 0);
+ BUILD_ASSERT(key_size(parent160) == sizeof(struct ripemd160));
+ BUILD_ASSERT(key_size(hash160) == sizeof(struct ripemd160));
+ BUILD_ASSERT(key_size(priv_key) == EC_PRIVATE_KEY_LEN + 1);
+
+ /* Our keys following the parity byte must be uint64_t aligned */
+ BUILD_ASSERT((key_off(priv_key) + 1) % sizeof(uint64_t) == 0);
+ BUILD_ASSERT((key_off(pub_key) + 1) % sizeof(uint64_t) == 0);
+
+ /* child_num must be contigous after priv_key */
+ BUILD_ASSERT((key_off(priv_key) + key_size(priv_key)) == key_off(child_num));
+
+ /* We use priv_key[0] to determine if this extended key is public or
+ * private, If priv_key[0] is BIP32_FLAG_KEY_PRIVATE then this key is private
+ * with a computed public key present. If set to BIP32_FLAG_KEY_PUBLIC then
+ * this is a public key with no private key (A BIP32 'neutered' key).
+ *
+ * For this to work BIP32_FLAG_KEY_PRIVATE must be zero so the whole 33 byte
+ * private key is valid when serialized, and BIP32_FLAG_KEY_PUBLIC cannot be
+ * 2 or 3 as they are valid parity bytes for public keys.
+ */
+ BUILD_ASSERT(BIP32_FLAG_KEY_PRIVATE == 0);
+ BUILD_ASSERT(BIP32_FLAG_KEY_PUBLIC != BIP32_FLAG_KEY_PRIVATE &&
+ BIP32_FLAG_KEY_PUBLIC != 2u &&
+ BIP32_FLAG_KEY_PUBLIC != 3u);
+}
+/* LCOV_EXCL_STOP */
+
+static bool mem_is_zero(const void *mem, size_t len)
+{
+ size_t i;
+ for (i = 0; i < len; ++i)
+ if (((const unsigned char *)mem)[i])
+ return false;
+ return true;
+}
+
+static bool child_is_hardened(uint32_t child_num)
+{
+ return child_num >= BIP32_INITIAL_HARDENED_CHILD;
+}
+
+static bool version_is_valid(uint32_t ver, uint32_t flags)
+{
+ if (ver == BIP32_VER_MAIN_PRIVATE || ver == BIP32_VER_TEST_PRIVATE)
+ return true;
+
+ return flags == BIP32_FLAG_KEY_PUBLIC &&
+ (ver == BIP32_VER_MAIN_PUBLIC || ver == BIP32_VER_TEST_PUBLIC);
+}
+
+static bool version_is_mainnet(uint32_t ver)
+{
+ return ver == BIP32_VER_MAIN_PRIVATE || ver == BIP32_VER_MAIN_PUBLIC;
+}
+
+static bool key_is_private(const struct ext_key *hdkey)
+{
+ return hdkey->priv_key[0] == BIP32_FLAG_KEY_PRIVATE;
+}
+
+static void key_strip_private_key(struct ext_key *key_out)
+{
+ key_out->priv_key[0] = BIP32_FLAG_KEY_PUBLIC;
+ memclear(key_out->priv_key + 1, sizeof(key_out->priv_key) - 1);
+}
+
+/* Compute a public key from a private key */
+static int key_compute_pub_key(const secp256k1_context *ctx,
+ struct ext_key *key_out)
+{
+ return wally_ec_public_key_from_private_key(ctx,
+ key_out->priv_key + 1,
+ EC_PRIVATE_KEY_LEN,
+ key_out->pub_key,
+ sizeof(key_out->pub_key));
+}
+
+static void key_compute_hash160(struct ext_key *key_out)
+{
+ wally_hash160(key_out->pub_key, sizeof(key_out->pub_key),
+ key_out->hash160, sizeof(key_out->hash160));
+}
+
+int bip32_key_free(const struct ext_key *hdkey)
+{
+ if (!hdkey)
+ return WALLY_EINVAL;
+ memclear((void *)hdkey, sizeof(*hdkey));
+ free((void *)hdkey);
+ return WALLY_OK;
+}
+
+static bool is_valid_seed_len(size_t len) {
+ return len == BIP32_ENTROPY_LEN_512 || len == BIP32_ENTROPY_LEN_256 ||
+ len == BIP32_ENTROPY_LEN_128;
+}
+
+int bip32_key_from_seed(
+ const secp256k1_context *ctx,
+ const unsigned char *bytes, size_t bytes_len,
+ uint32_t version, uint32_t flags,
+ struct ext_key *key_out)
+{
+ struct hmac_sha512 hmac;
+
+ if (!bytes || !is_valid_seed_len(bytes_len) ||
+ !version_is_valid(version, BIP32_FLAG_KEY_PRIVATE) ||
+ (flags & ~BIP32_FLAG_SKIP_HASH) || !key_out)
+ {
+ return WALLY_EINVAL;
+ }
+
+ memclear(key_out, sizeof(*key_out));
+ key_out->version = version;
+
+ /* Generate private key and chain code */
+ hmac_sha512(&hmac, SEED, sizeof(SEED), bytes, bytes_len);
+
+ /* Check that the generated private key is valid */
+ if (!secp256k1_ec_seckey_verify(ctx, hmac.sha.u.u8)) {
+ memclear(&hmac, sizeof(hmac));
+ return WALLY_ERROR; /* Invalid private key */
+ }
+
+ /* Copy the private key and set its prefix */
+ key_out->priv_key[0] = BIP32_FLAG_KEY_PRIVATE;
+ memcpy(key_out->priv_key + 1, hmac.sha.u.u8, sizeof(hmac) / 2);
+ if (key_compute_pub_key(ctx, key_out) != WALLY_OK) {
+ memclear(&hmac, sizeof(hmac));
+ memclear(key_out, sizeof(*key_out));
+ printf("\n");
+ return WALLY_EINVAL;
+ }
+
+ /* Copy the chain code */
+ memcpy(key_out->chain_code, hmac.sha.u.u8 + sizeof(hmac.sha) / 2,
+ sizeof(hmac.sha) / 2);
+
+ key_out->depth = 0; /* Master key, depth 0 */
+ key_out->child_num = 0;
+ if (!(flags & BIP32_FLAG_SKIP_HASH))
+ key_compute_hash160(key_out);
+ memclear(&hmac, sizeof(hmac));
+ return WALLY_OK;
+}
+
+#define ALLOC_KEY() \
+ if (!output) \
+ return WALLY_EINVAL; \
+ *output = malloc(sizeof(struct ext_key)); \
+ if (!*output) \
+ return WALLY_ENOMEM; \
+ memclear((void *)*output, sizeof(struct ext_key))
+
+int bip32_key_from_seed_alloc(const secp256k1_context *ctx,
+ const unsigned char *bytes, size_t bytes_len,
+ uint32_t version, uint32_t flags,
+ struct ext_key **output)
+{
+ int ret;
+
+ ALLOC_KEY();
+ ret = bip32_key_from_seed(ctx, bytes, bytes_len, version, flags, *output);
+ if (ret != WALLY_OK) {
+ free((void *)*output);
+ *output = NULL;
+ }
+ return ret;
+}
+
+static unsigned char *copy_out(unsigned char *dest,
+ const void *src, size_t len)
+{
+ memcpy(dest, src, len);
+ return dest + len;
+}
+
+static bool key_is_valid(const struct ext_key *hdkey)
+{
+ bool is_private = key_is_private(hdkey);
+ bool is_master = !hdkey->depth;
+ int8_t ver_flags = is_private ? BIP32_FLAG_KEY_PRIVATE : BIP32_FLAG_KEY_PUBLIC;
+
+ if (!version_is_valid(hdkey->version, ver_flags)) {
+ return false;
+ }
+
+ if (mem_is_zero(hdkey->chain_code, sizeof(hdkey->chain_code)) ||
+ (hdkey->pub_key[0] != 0x2 && hdkey->pub_key[0] != 0x3) ||
+ mem_is_zero(hdkey->pub_key + 1, sizeof(hdkey->pub_key) - 1))
+ return false;
+
+ if (hdkey->priv_key[0] != BIP32_FLAG_KEY_PUBLIC &&
+ hdkey->priv_key[0] != BIP32_FLAG_KEY_PRIVATE)
+ return false;
+
+ if (is_private &&
+ mem_is_zero(hdkey->priv_key + 1, sizeof(hdkey->priv_key) - 1))
+ return false;
+
+ if (is_master &&
+ !mem_is_zero(hdkey->parent160, sizeof(hdkey->parent160)))
+ return false;
+
+ return true;
+}
+
+int bip32_key_serialize(const struct ext_key *hdkey, uint32_t flags,
+ unsigned char *bytes_out, size_t len)
+{
+ const bool serialize_private = !(flags & BIP32_FLAG_KEY_PUBLIC);
+ unsigned char *out = bytes_out;
+ uint32_t tmp32;
+ beint32_t tmp32_be;
+
+ if (flags & ~BIP32_FLAG_KEY_PUBLIC)
+ return WALLY_EINVAL; /* Only this flag makes sense here */
+
+ /* Validate our arguments and then the input key */
+ if (!hdkey ||
+ (serialize_private && !key_is_private(hdkey)) ||
+ !key_is_valid(hdkey) ||
+ !bytes_out || len != BIP32_SERIALIZED_LEN)
+ return WALLY_EINVAL;
+
+
+ tmp32 = hdkey->version;
+ if (!serialize_private) {
+ /* Change version if serializing the public part of a private key */
+ if (tmp32 == BIP32_VER_MAIN_PRIVATE)
+ tmp32 = BIP32_VER_MAIN_PUBLIC;
+ else if (tmp32 == BIP32_VER_TEST_PRIVATE)
+ tmp32 = BIP32_VER_TEST_PUBLIC;
+ }
+ tmp32_be = cpu_to_be32(tmp32);
+ out = copy_out(out, &tmp32_be, sizeof(tmp32_be));
+
+ *out++ = hdkey->depth;
+
+ /* Save the first 32 bits of the parent key (aka fingerprint) only */
+ out = copy_out(out, hdkey->parent160, sizeof(uint32_t));
+
+
+ tmp32_be = cpu_to_be32(hdkey->child_num);
+ out = copy_out(out, &tmp32_be, sizeof(tmp32_be));
+
+ out = copy_out(out, hdkey->chain_code, sizeof(hdkey->chain_code));
+
+ if (serialize_private)
+ copy_out(out, hdkey->priv_key, sizeof(hdkey->priv_key));
+ else
+ copy_out(out, hdkey->pub_key, sizeof(hdkey->pub_key));
+
+ return WALLY_OK;
+}
+
+static const unsigned char *copy_in(void *dest,
+ const unsigned char *src, size_t len)
+{
+ memcpy(dest, src, len);
+ return src + len;
+}
+
+/* Wipe a key and return failure for the caller to propigate */
+static int wipe_key_fail(struct ext_key *key_out)
+{
+ memclear(key_out, sizeof(*key_out));
+ return WALLY_EINVAL;
+}
+
+int bip32_key_unserialize(const secp256k1_context *ctx,
+ const unsigned char *bytes, size_t bytes_len,
+ struct ext_key *key_out)
+{
+ if (!bytes || bytes_len != BIP32_SERIALIZED_LEN || !key_out)
+ return WALLY_EINVAL;
+
+ memclear(key_out, sizeof(*key_out));
+
+ bytes = copy_in(&key_out->version, bytes, sizeof(key_out->version));
+ key_out->version = be32_to_cpu(key_out->version);
+ if (!version_is_valid(key_out->version, BIP32_FLAG_KEY_PUBLIC))
+ return wipe_key_fail(key_out);
+
+ bytes = copy_in(&key_out->depth, bytes, sizeof(key_out->depth));
+
+ /* We only have a partial fingerprint available. Copy it, but the
+ * user will need to call bip32_key_set_parent() (FIXME: Implement)
+ * later if they want it to be fully populated.
+ */
+ bytes = copy_in(key_out->parent160, bytes, sizeof(uint32_t));
+ bytes = copy_in(&key_out->child_num, bytes, sizeof(key_out->child_num));
+ key_out->child_num = be32_to_cpu(key_out->child_num);
+ bytes = copy_in(key_out->chain_code, bytes, sizeof(key_out->chain_code));
+
+ if (bytes[0] == BIP32_FLAG_KEY_PRIVATE) {
+ if (key_out->version == BIP32_VER_MAIN_PUBLIC ||
+ key_out->version == BIP32_VER_TEST_PUBLIC)
+ return wipe_key_fail(key_out); /* Private key data in public key */
+
+ copy_in(key_out->priv_key, bytes, sizeof(key_out->priv_key));
+ if (key_compute_pub_key(ctx, key_out) != WALLY_OK)
+ return wipe_key_fail(key_out);
+ } else {
+ if (key_out->version == BIP32_VER_MAIN_PRIVATE ||
+ key_out->version == BIP32_VER_TEST_PRIVATE)
+ return wipe_key_fail(key_out); /* Public key data in private key */
+
+ copy_in(key_out->pub_key, bytes, sizeof(key_out->pub_key));
+ key_strip_private_key(key_out);
+ }
+
+ key_compute_hash160(key_out);
+ return WALLY_OK;
+}
+
+int bip32_key_unserialize_alloc(
+ const secp256k1_context *ctx,
+ const unsigned char *bytes,
+ size_t bytes_len, struct ext_key **output)
+{
+ int ret;
+
+ ALLOC_KEY();
+ ret = bip32_key_unserialize(ctx, bytes, bytes_len, *output);
+ if (ret) {
+ free(*output);
+ *output = 0;
+ }
+ return ret;
+}
+
+/* BIP32: Child Key Derivations
+ *
+ * The spec doesn't have a simple table of derivations, its:
+ *
+ * Parent Child Hardened Status Path In Spec
+ * private private no OK m/n Y
+ * private private yes OK m/nH Y
+ * private public no OK - N
+ * private public yes OK - N
+ * public private no FAIL (N/A) (N/A)
+ * public private yes FAIL (N/A) (N/A)
+ * public public no OK M/n N
+ * public public yes FAIL M/nH (N/A)
+ *
+ * The spec path nomenclature only expresses derivations where the parent
+ * and desired child type match. For private->public the derivation is
+ * described in terms of private-private and public->public, but there are
+ * no test vectors or paths describing these values to validate against.
+ * Further, there are no public-public vectors in the BIP32 spec either.
+ */
+int bip32_key_from_parent(const secp256k1_context *ctx,
+ const struct ext_key *hdkey,
+ uint32_t child_num, uint32_t flags,
+ struct ext_key *key_out)
+{
+ struct hmac_sha512 hmac;
+ const bool we_are_private = hdkey && key_is_private(hdkey);
+ const bool derive_private = !(flags & BIP32_FLAG_KEY_PUBLIC);
+ const bool hardened = child_is_hardened(child_num);
+
+ if (flags & ~BIP32_ALL_DEFINED_FLAGS)
+ return WALLY_EINVAL; /* These flags are not defined yet */
+
+ if (!hdkey || !key_out)
+ return WALLY_EINVAL;
+
+ if (!we_are_private && (derive_private || hardened))
+ return wipe_key_fail(key_out); /* Unsupported derivation */
+
+ if (hdkey->depth == 0xff)
+ return wipe_key_fail(key_out); /* Maximum depth reached */
+
+ /*
+ * Private parent -> private child:
+ * CKDpriv((kpar, cpar), i) -> (ki, ci)
+ *
+ * Private parent -> public child:
+ * N(CKDpriv((kpar, cpar), i) -> (ki, ci))
+ * As we always calculate the public key, we can derive a public
+ * child by deriving a private one and stripping its private key.
+ *
+ * Public parent -> non hardened public child
+ * CKDpub((Kpar, cpar), i) -> (Ki, ci)
+ */
+
+ /* NB: We use the key_outs' priv_key+child_num to hold 'Data' here */
+ if (hardened) {
+ /* Hardened: Data = 0x00 || ser256(kpar) || ser32(i)) */
+ memcpy(key_out->priv_key, hdkey->priv_key, sizeof(hdkey->priv_key));
+ } else {
+ /* Non Hardened Private: Data = serP(point(kpar)) || ser32(i)
+ * Non Hardened Public : Data = serP(kpar) || ser32(i)
+ * point(kpar) when par is private is the public key.
+ */
+ memcpy(key_out->priv_key, hdkey->pub_key, sizeof(hdkey->pub_key));
+ }
+
+ /* This is the '|| ser32(i)' part of the above */
+ key_out->child_num = cpu_to_be32(child_num);
+
+ /* I = HMAC-SHA512(Key = cpar, Data) */
+ hmac_sha512(&hmac, hdkey->chain_code, sizeof(hdkey->chain_code),
+ key_out->priv_key,
+ sizeof(key_out->priv_key) + sizeof(key_out->child_num));
+
+ /* Split I into two 32-byte sequences, IL and IR
+ * The returned chain code ci is IR (i.e. the 2nd half of our hmac sha512)
+ */
+ memcpy(key_out->chain_code, hmac.sha.u.u8 + sizeof(hmac.sha) / 2,
+ sizeof(key_out->chain_code));
+
+ if (we_are_private) {
+ /* The returned child key ki is parse256(IL) + kpar (mod n)
+ * In case parse256(IL) ≥ n or ki = 0, the resulting key is invalid
+ * (NOTE: privkey_tweak_add checks both conditions)
+ */
+ memcpy(key_out->priv_key, hdkey->priv_key, sizeof(hdkey->priv_key));
+ if (!secp256k1_ec_privkey_tweak_add(ctx, key_out->priv_key + 1,
+ hmac.sha.u.u8)) {
+ memclear(&hmac.sha, sizeof(hmac.sha));
+ return wipe_key_fail(key_out); /* Out of bounds FIXME: Iterate to the next? */
+ }
+
+ if (key_compute_pub_key(ctx, key_out) != WALLY_OK) {
+ memclear(&hmac.sha, sizeof(hmac.sha));
+ return wipe_key_fail(key_out);
+ }
+ } else {
+ /* The returned child key ki is point(parse256(IL) + kpar)
+ * In case parse256(IL) ≥ n or Ki is the point at infinity, the
+ * resulting key is invalid (NOTE: pubkey_tweak_add checks both
+ * conditions)
+ */
+ secp256k1_pubkey pub_key;
+ size_t len = sizeof(key_out->pub_key);
+
+ /* FIXME: Out of bounds on pubkey_tweak_add */
+ if (!secp256k1_ec_pubkey_parse(ctx, &pub_key, hdkey->pub_key,
+ sizeof(hdkey->pub_key)) ||
+
+ !secp256k1_ec_privkey_tweak_add(ctx, pub_key.data,
+ hmac.sha.u.u8) ||
+
+ !secp256k1_ec_pubkey_serialize(ctx, key_out->pub_key,
+ &len, &pub_key,
+ SECP256K1_EC_COMPRESSED) ||
+ len != sizeof(key_out->pub_key)) {
+ memclear(&hmac.sha, sizeof(hmac.sha));
+ return wipe_key_fail(key_out);
+ }
+ }
+
+ if (derive_private) {
+ if (version_is_mainnet(hdkey->version))
+ key_out->version = BIP32_VER_MAIN_PRIVATE;
+ else
+ key_out->version = BIP32_VER_TEST_PRIVATE;
+
+ } else {
+ if (version_is_mainnet(hdkey->version))
+ key_out->version = BIP32_VER_MAIN_PUBLIC;
+ else
+ key_out->version = BIP32_VER_TEST_PUBLIC;
+
+ key_strip_private_key(key_out);
+ }
+
+ key_out->depth = hdkey->depth + 1;
+ key_out->child_num = child_num;
+ if (flags & BIP32_FLAG_SKIP_HASH) {
+ memclear_2(&key_out->parent160, sizeof(key_out->parent160),
+ &key_out->hash160, sizeof(key_out->hash160));
+ }
+ else {
+ memcpy(key_out->parent160, hdkey->hash160, sizeof(hdkey->hash160));
+ key_compute_hash160(key_out);
+ }
+ memclear(&hmac.sha, sizeof(hmac.sha));
+ return WALLY_OK;
+}
+
+int bip32_key_from_parent_alloc(
+ const secp256k1_context *ctx,
+ const struct ext_key *hdkey,
+ uint32_t child_num, uint32_t flags,
+ struct ext_key **output)
+{
+ int ret;
+
+ ALLOC_KEY();
+ ret = bip32_key_from_parent(ctx, hdkey, child_num, flags, *output);
+ if (ret) {
+ free(*output);
+ *output = 0;
+ }
+ return ret;
+}
+
+int bip32_key_from_parent_path(
+ const secp256k1_context *ctx,
+ const struct ext_key *hdkey,
+ const uint32_t *child_path, size_t child_path_len,
+ uint32_t flags, struct ext_key *key_out)
+{
+ /* Optimization: We can skip hash calculations for internal nodes */
+ uint32_t derivation_flags = flags | BIP32_FLAG_SKIP_HASH;
+ struct ext_key tmp[2];
+ size_t i, tmp_idx = 0;
+ int ret = WALLY_OK;
+
+ if (flags & ~BIP32_ALL_DEFINED_FLAGS)
+ return WALLY_EINVAL; /* These flags are not defined yet */
+
+ if (!hdkey || !child_path || !child_path_len || !key_out)
+ return WALLY_EINVAL;
+
+ for (i = 0; i < child_path_len; ++i) {
+ struct ext_key *derived = &tmp[tmp_idx];
+
+ if (i + 2 >= child_path_len)
+ derivation_flags = flags; /* Use callers flags for the final derivations */
+
+ ret = bip32_key_from_parent(ctx, hdkey, child_path[i],
+ derivation_flags, derived);
+
+ if (ret != WALLY_OK)
+ break;
+
+ hdkey = derived; /* Derived becomes next parent */
+ tmp_idx = !tmp_idx; /* Use free slot in tmp for next derived */
+ }
+
+ if (ret == WALLY_OK)
+ memcpy(key_out, hdkey, sizeof(*key_out));
+
+ memclear(tmp, sizeof(tmp));
+ return ret;
+}
+
+int bip32_key_from_parent_path_alloc(
+ const secp256k1_context *ctx,
+ const struct ext_key *hdkey,
+ const uint32_t *child_path, size_t child_path_len,
+ uint32_t flags,
+ struct ext_key **output)
+{
+ int ret;
+
+ ALLOC_KEY();
+ ret = bip32_key_from_parent_path(ctx, hdkey, child_path,
+ child_path_len, flags, *output);
+ if (ret) {
+ free(*output);
+ *output = 0;
+ }
+ return ret;
+}
+
+int bip32_key_init_alloc(
+ const secp256k1_context *ctx,
+ uint32_t version, uint32_t depth, uint32_t child_num,
+ const unsigned char *chain_code, size_t chain_code_len,
+ const unsigned char *pub_key, size_t pub_key_len,
+ const unsigned char *priv_key, size_t priv_key_len,
+ const unsigned char *hash160, size_t hash160_len,
+ const unsigned char *parent160, size_t parent160_len,
+ struct ext_key **output)
+{
+ struct ext_key *key_out;
+
+ if (!output)
+ return WALLY_EINVAL;
+ *output = NULL;
+
+ switch (version) {
+ case BIP32_VER_MAIN_PRIVATE:
+ case BIP32_VER_TEST_PRIVATE:
+ if (!priv_key || priv_key_len != key_size(priv_key) - 1)
+ return WALLY_EINVAL;
+ break;
+ case BIP32_VER_MAIN_PUBLIC:
+ case BIP32_VER_TEST_PUBLIC:
+ if (!pub_key || pub_key_len != key_size(pub_key))
+ return WALLY_EINVAL;
+ break;
+ }
+
+ if (!chain_code || chain_code_len != key_size(chain_code))
+ return WALLY_EINVAL;
+
+ if ((priv_key && priv_key_len != key_size(priv_key) - 1) || (!priv_key && priv_key_len) ||
+ (pub_key && pub_key_len != key_size(pub_key)) || (!pub_key && pub_key_len) ||
+ (hash160 && hash160_len != key_size(hash160)) || (!hash160 && hash160_len) ||
+ (parent160 && parent160_len != key_size(parent160)))
+ return WALLY_EINVAL;
+
+ ALLOC_KEY();
+
+ key_out = *output;
+ key_out->version = version;
+ key_out->depth = depth;
+ key_out->child_num = child_num;
+
+ memcpy(key_out->chain_code, chain_code, key_size(chain_code));
+ if (priv_key && version != BIP32_VER_MAIN_PUBLIC && version != BIP32_VER_TEST_PUBLIC)
+ memcpy(key_out->priv_key + 1, priv_key, key_size(priv_key) - 1);
+ else
+ key_out->priv_key[0] = BIP32_FLAG_KEY_PUBLIC;
+ if (pub_key)
+ memcpy(key_out->pub_key, pub_key, key_size(pub_key));
+ else if (version == BIP32_VER_MAIN_PRIVATE || version == BIP32_VER_TEST_PRIVATE) {
+ /* Compute the public key if not given */
+ int ret = key_compute_pub_key(ctx, key_out);
+ if (ret != WALLY_OK) {
+ memclear(key_out, sizeof(*key_out));
+ free(key_out);
+ *output = 0;
+ return ret;
+ }
+ }
+ if (hash160)
+ memcpy(key_out->hash160, hash160, key_size(hash160));
+ else
+ key_compute_hash160(key_out);
+ if (parent160)
+ memcpy(key_out->parent160, parent160, key_size(parent160));
+
+ return WALLY_OK;
+}
+
+int bip32_key_to_base58(const struct ext_key *hdkey,
+ uint32_t flags,
+ char **output)
+{
+ int ret;
+ unsigned char bytes[BIP32_SERIALIZED_LEN];
+
+ if ((ret = bip32_key_serialize(hdkey, flags, bytes, sizeof(bytes))))
+ return ret;
+
+ ret = wally_base58_from_bytes(bytes, BIP32_SERIALIZED_LEN,
+ BASE58_FLAG_CHECKSUM, output);
+
+ memclear(bytes, sizeof(bytes));
+ return ret;
+}
+
+int bip32_key_from_base58(
+ const secp256k1_context *ctx,
+ const char *base58,
+ struct ext_key *output)
+{
+ int ret;
+ unsigned char bytes[BIP32_SERIALIZED_LEN + BASE58_CHECKSUM_LEN];
+ size_t written;
+
+ if ((ret = wally_base58_to_bytes(base58, BASE58_FLAG_CHECKSUM, bytes, sizeof(bytes), &written)))
+ return ret;
+
+ if (written != BIP32_SERIALIZED_LEN)
+ ret = WALLY_EINVAL;
+ else
+ ret = bip32_key_unserialize(ctx, bytes,
+ BIP32_SERIALIZED_LEN, output);
+
+ memclear(bytes, sizeof(bytes));
+ return ret;
+}
+
+int bip32_key_from_base58_alloc(
+ const secp256k1_context *ctx,
+ const char *base58, struct ext_key **output)
+{
+ int ret;
+
+ ALLOC_KEY();
+ ret = bip32_key_from_base58(ctx, base58, *output);
+ if (ret) {
+ free(*output);
+ *output = 0;
+ }
+ return ret;
+}
+
+#if defined (SWIG_JAVA_BUILD) || defined (SWIG_PYTHON_BUILD) || defined (SWIG_JAVASCRIPT_BUILD)
+
+/* Getters for ext_key values */
+
+static int getb_impl(const struct ext_key *hdkey,
+ const unsigned char *src, size_t src_len,
+ unsigned char *bytes_out, size_t len)
+{
+ if (!hdkey || !bytes_out || len != src_len)
+ return WALLY_EINVAL;
+ memcpy(bytes_out, src, len);
+ return WALLY_OK;
+}
+
+#define GET_B(name) \
+ int bip32_key_get_ ## name(const struct ext_key *hdkey, unsigned char *bytes_out, size_t len) { \
+ return getb_impl(hdkey, hdkey->name, sizeof(hdkey->name), bytes_out, len); \
+ }
+
+GET_B(chain_code)
+GET_B(parent160)
+GET_B(hash160)
+GET_B(pub_key)
+
+int bip32_key_get_priv_key(const struct ext_key *hdkey, unsigned char *bytes_out, size_t len) {
+ return getb_impl(hdkey, hdkey->priv_key + 1, sizeof(hdkey->priv_key) - 1, bytes_out, len);
+}
+
+
+#define GET_I(name) \
+ int bip32_key_get_ ## name(const struct ext_key *hdkey, size_t *written) { \
+ if (written) *written = 0; \
+ if (!hdkey || !written) return WALLY_EINVAL; \
+ *written = hdkey->name; \
+ return WALLY_OK; \
+ }
+
+GET_I(depth)
+GET_I(child_num)
+GET_I(version)
+
+#endif /* SWIG_JAVA_BUILD/SWIG_PYTHON_BUILD */
diff --git a/bip32.h b/bip32.h
@@ -0,0 +1,252 @@
+
+#ifndef LIBWALLY_CORE_BIP32_H
+#define LIBWALLY_CORE_BIP32_H
+
+#include <stdint.h>
+#include "secp256k1.h"
+
+/** The required lengths of entropy for `bip32_key_from_seed` */
+#define BIP32_ENTROPY_LEN_128 16
+#define BIP32_ENTROPY_LEN_256 32
+#define BIP32_ENTROPY_LEN_512 64
+
+/** Length of an ext_key serialized using BIP32 format */
+#define BIP32_SERIALIZED_LEN 78
+
+/** Child number of the first hardened child */
+#define BIP32_INITIAL_HARDENED_CHILD 0x80000000
+
+/** Indicate that we want to derive a private key in `bip32_key_from_parent` */
+#define BIP32_FLAG_KEY_PRIVATE 0x0
+/** Indicate that we want to derive a public key in `bip32_key_from_parent` */
+#define BIP32_FLAG_KEY_PUBLIC 0x1
+/** Indicate that we want to skip hash calculation when deriving a key in `bip32_key_from_parent` */
+#define BIP32_FLAG_SKIP_HASH 0x2
+
+/** Version codes for extended keys */
+#define BIP32_VER_MAIN_PUBLIC 0x0488B21E
+#define BIP32_VER_MAIN_PRIVATE 0x0488ADE4
+#define BIP32_VER_TEST_PUBLIC 0x043587CF
+#define BIP32_VER_TEST_PRIVATE 0x04358394
+
+/** An extended key */
+struct ext_key {
+ /** The chain code for this key */
+ unsigned char chain_code[32];
+ /** The Hash160 of this keys parent */
+ unsigned char parent160[20];
+ /** The depth of this key */
+ uint8_t depth;
+ unsigned char pad1[10];
+ /** The private key with prefix byte 0 */
+ unsigned char priv_key[33];
+ /** The child number of the parent key that this key represents */
+ uint32_t child_num;
+ /** The Hash160 of this key */
+ unsigned char hash160[20];
+ /** The version code for this key indicating main/testnet and private/public */
+ uint32_t version;
+ unsigned char pad2[3];
+ /** The public key with prefix byte 0x2 or 0x3 */
+ unsigned char pub_key[33];
+};
+
+/**
+ * Free a key allocated by `bip32_key_from_seed_alloc`
+ * or `bip32_key_unserialize_alloc`.
+ *
+ * :param hdkey: Key to free.
+ */
+int bip32_key_free(const struct ext_key *hdkey);
+
+/**
+ */
+
+int bip32_key_init_alloc(
+ const secp256k1_context *ctx,
+ uint32_t version, uint32_t depth, uint32_t child_num,
+ const unsigned char *chain_code, size_t chain_code_len,
+ const unsigned char *pub_key, size_t pub_key_len,
+ const unsigned char *priv_key, size_t priv_key_len,
+ const unsigned char *hash160, size_t hash160_len,
+ const unsigned char *parent160, size_t parent160_len,
+ struct ext_key **output
+ );
+
+
+/**
+ * Create a new master extended key from entropy.
+ *
+ * This creates a new master key, i.e. the root of a new HD tree.
+ * The entropy passed in may produce an invalid key. If this happens,
+ * WALLY_ERROR will be returned and the caller should retry with
+ * new entropy.
+ *
+ * :param bytes: Entropy to use.
+ * :param bytes_len: Size of ``bytes`` in bytes. Must be one of ``BIP32_ENTROPY_LEN_128``,
+ *| ``BIP32_ENTROPY_LEN_256`` or ``BIP32_ENTROPY_LEN_512``.
+ * :param version: Either ``BIP32_VER_MAIN_PRIVATE`` or ``BIP32_VER_TEST_PRIVATE``,
+ *| indicating mainnet or testnet/regtest respectively.
+ * :param flags: Either ``BIP32_FLAG_SKIP_HASH`` to skip hash160 calculation, or 0.
+ * :param output: Destination for the resulting master extended key.
+ */
+int bip32_key_from_seed(
+ const secp256k1_context *ctx,
+ const unsigned char *bytes,
+ size_t bytes_len,
+ uint32_t version,
+ uint32_t flags,
+ struct ext_key *output);
+
+/**
+ * As per `bip32_key_from_seed`, but allocates the key.
+ *
+ * .. note:: The returned key should be freed with `bip32_key_free`.
+ */
+int bip32_key_from_seed_alloc(
+ const secp256k1_context *ctx,
+ const unsigned char *bytes,
+ size_t bytes_len,
+ uint32_t version,
+ uint32_t flags,
+ struct ext_key **output);
+
+/**
+ * Serialize an extended key to memory using BIP32 format.
+ *
+ * :param hdkey: The extended key to serialize.
+ * :param flags: BIP32_FLAG_KEY_ Flags indicating which key to serialize. You can not
+ *| serialize a private extended key from a public extended key.
+ * :param bytes_out: Destination for the serialized key.
+ * :param len: Size of ``bytes_out`` in bytes. Must be ``BIP32_SERIALIZED_LEN``.
+ */
+int bip32_key_serialize(
+ const struct ext_key *hdkey,
+ uint32_t flags,
+ unsigned char *bytes_out,
+ size_t len);
+
+
+/**
+ * Un-serialize an extended key from memory.
+ *
+ * :param bytes: Storage holding the serialized key.
+ * :param bytes_len: Size of ``bytes`` in bytes. Must be ``BIP32_SERIALIZED_LEN``.
+ * :param output: Destination for the resulting extended key.
+ */
+int bip32_key_unserialize(
+ const secp256k1_context *ctx,
+ const unsigned char *bytes,
+ size_t bytes_len,
+ struct ext_key *output);
+
+/**
+ * As per `bip32_key_unserialize`, but allocates the key.
+ *
+ * .. note:: The returned key should be freed with `bip32_key_free`.
+ */
+int bip32_key_unserialize_alloc(
+ const secp256k1_context *ctx,
+ const unsigned char *bytes,
+ size_t bytes_len,
+ struct ext_key **output);
+
+/**
+ * Create a new child extended key from a parent extended key.
+ *
+ * :param hdkey: The parent extended key.
+ * :param child_num: The child number to create. Numbers greater
+ *| than or equal to ``BIP32_INITIAL_HARDENED_CHILD`` represent
+ *| hardened keys that cannot be created from public parent
+ *| extended keys.
+ * :param flags: BIP32_FLAG_KEY_ Flags indicating the type of derivation wanted.
+ *| You can not derive a private child extended key from a public
+ *| parent extended key.
+ * :param output: Destination for the resulting child extended key.
+ */
+int bip32_key_from_parent(
+ const secp256k1_context *ctx,
+ const struct ext_key *hdkey,
+ uint32_t child_num,
+ uint32_t flags,
+ struct ext_key *output);
+
+/**
+ * As per `bip32_key_from_parent`, but allocates the key.
+ *
+ * .. note:: The returned key should be freed with `bip32_key_free`.
+ */
+int bip32_key_from_parent_alloc(
+ const secp256k1_context *ctx,
+ const struct ext_key *hdkey,
+ uint32_t child_num,
+ uint32_t flags,
+ struct ext_key **output);
+
+/**
+ * Create a new child extended key from a parent extended key and a path.
+ *
+ * :param hdkey: The parent extended key.
+ * :param child_path: The path of child numbers to create.
+ * :param child_path_len: The number of child numbers in ``child_path``.
+ * :param flags: BIP32_KEY_ Flags indicating the type of derivation wanted.
+ * :param output: Destination for the resulting child extended key.
+ */
+int bip32_key_from_parent_path(
+ const secp256k1_context *ctx,
+ const struct ext_key *hdkey,
+ const uint32_t *child_path,
+ size_t child_path_len,
+ uint32_t flags,
+ struct ext_key *output);
+
+/**
+ * As per `bip32_key_from_parent_path`, but allocates the key.
+ *
+ * .. note:: The returned key should be freed with `bip32_key_free`.
+ */
+int bip32_key_from_parent_path_alloc(
+ const secp256k1_context *ctx,
+ const struct ext_key *hdkey,
+ const uint32_t *child_path,
+ size_t child_path_len,
+ uint32_t flags,
+ struct ext_key **output);
+
+/**
+ * Convert an extended key to base58.
+ *
+ * :param hdkey: The extended key.
+ * :param flags: BIP32_FLAG_KEY_ Flags indicating which key to serialize. You can not
+ *| serialize a private extended key from a public extended key.
+ * :param output: Destination for the resulting key in bas58.
+ */
+int bip32_key_to_base58(
+ const struct ext_key *hdkey,
+ uint32_t flags,
+ char **output);
+
+/**
+ * Convert a base58 encoded extended key to an extended key.
+ *
+ * :param wif: The extended key in base58.
+ * :param output: Destination for the resulting extended key.
+ */
+
+int bip32_key_from_base58(
+ const secp256k1_context *ctx,
+ const char *base58,
+ struct ext_key *output);
+
+/**
+ * As per `bip32_key_from_base58`, but allocates the key.
+ *
+ * .. note:: The returned key should be freed with `bip32_key_free`.
+ */
+int bip32_key_from_base58_alloc(
+ const secp256k1_context *ctx,
+ const char *base58, struct ext_key **output);
+
+void assert_bip32_assumptions(void);
+
+#endif /* LIBWALLY_CORE_BIP32_H */
diff --git a/check.c b/check.c
@@ -0,0 +1,11 @@
+
+#include "bip32.h"
+#include <stdio.h>
+
+int main()
+{
+ printf("asserting bip32 assumptions\n");
+ assert_bip32_assumptions();
+ printf("ok!\n");
+ return 0;
+}
diff --git a/clightning-dumpkeys.c b/clightning-dumpkeys.c
@@ -0,0 +1,160 @@
+
+#include "short_types.h"
+#include "hkdf.h"
+#include "compiler.h"
+#include "secp256k1.h"
+#include "bip32.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <assert.h>
+
+#define BIP32_ENTROPY_LEN_256 32
+
+
+#define fatal(fmt, ...) do { fprintf(stderr, fmt "\n", __VA_ARGS__); exit(1); } while (0)
+#define fatal1(...) do { fprintf(stderr, __VA_ARGS__); exit(1); } while (0)
+
+/* General 256-bit secret, which must be private. Used in various places. */
+struct secret {
+ u8 data[32];
+};
+
+static struct {
+ struct secret hsm_secret;
+ struct ext_key bip32;
+} secretstuff;
+
+struct bip32_key_version {
+ u32 bip32_pubkey_version;
+ u32 bip32_privkey_version;
+};
+
+
+
+/* Version codes for BIP32 extended keys in libwally-core.
+ * It's not suitable to add this struct into client struct,
+ * so set it static.*/
+static struct bip32_key_version bip32_key_version;
+
+bool read_all(int fd, void *data, size_t size)
+{
+ while (size) {
+ ssize_t done;
+
+ done = read(fd, data, size);
+ if (done < 0 && errno == EINTR)
+ continue;
+ if (done <= 0)
+ return false;
+ data = (char *)data + done;
+ size -= done;
+ }
+
+ return true;
+}
+
+
+
+static void populate_secretstuff(void)
+{
+ u8 bip32_seed[BIP32_ENTROPY_LEN_256];
+ u32 salt = 0;
+ struct ext_key master_extkey, child_extkey;
+ const u32 flags = SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN;
+ secp256k1_context *ctx = secp256k1_context_create(flags);
+
+ bip32_key_version = (struct bip32_key_version) {
+ .bip32_pubkey_version = BIP32_VER_MAIN_PUBLIC,
+ .bip32_privkey_version = BIP32_VER_MAIN_PRIVATE
+ };
+
+ assert(bip32_key_version.bip32_pubkey_version == BIP32_VER_MAIN_PUBLIC
+ || bip32_key_version.bip32_pubkey_version == BIP32_VER_TEST_PUBLIC);
+
+ assert(bip32_key_version.bip32_privkey_version == BIP32_VER_MAIN_PRIVATE
+ || bip32_key_version.bip32_privkey_version == BIP32_VER_TEST_PRIVATE);
+
+ /* Fill in the BIP32 tree for bitcoin addresses. */
+ /* In libwally-core, the version BIP32_VER_TEST_PRIVATE is for testnet/regtest,
+ * and BIP32_VER_MAIN_PRIVATE is for mainnet. For litecoin, we also set it like
+ * bitcoin else.*/
+ do {
+ hkdf_sha256(bip32_seed, sizeof(bip32_seed),
+ &salt, sizeof(salt),
+ &secretstuff.hsm_secret,
+ sizeof(secretstuff.hsm_secret),
+ "bip32 seed", strlen("bip32 seed"));
+ salt++;
+ } while (bip32_key_from_seed(ctx, bip32_seed, sizeof(bip32_seed),
+ bip32_key_version.bip32_privkey_version,
+ 0, &master_extkey) != WALLY_OK);
+
+ /* BIP 32:
+ *
+ * The default wallet layout
+ *
+ * An HDW is organized as several 'accounts'. Accounts are numbered,
+ * the default account ("") being number 0. Clients are not required
+ * to support more than one account - if not, they only use the
+ * default account.
+ *
+ * Each account is composed of two keypair chains: an internal and an
+ * external one. The external keychain is used to generate new public
+ * addresses, while the internal keychain is used for all other
+ * operations (change addresses, generation addresses, ..., anything
+ * that doesn't need to be communicated). Clients that do not support
+ * separate keychains for these should use the external one for
+ * everything.
+ *
+ * - m/iH/0/k corresponds to the k'th keypair of the external chain of
+ * account number i of the HDW derived from master m.
+ */
+ /* Hence child 0, then child 0 again to get extkey to derive from. */
+ if (bip32_key_from_parent(ctx, &master_extkey, 0,
+ BIP32_FLAG_KEY_PRIVATE,
+ &child_extkey) != WALLY_OK)
+ /*~ status_failed() is a helper which exits and sends lightningd
+ * a message about what happened. For hsmd, that's fatal to
+ * lightningd. */
+ fatal1("Can't derive child bip32 key");
+
+ if (bip32_key_from_parent(ctx, &child_extkey, 0,
+ BIP32_FLAG_KEY_PRIVATE,
+ &secretstuff.bip32) != WALLY_OK)
+ fatal1("Can't derive private bip32 key");
+}
+
+static void load_hsm(const char *secretfile)
+{
+ int fd = open(secretfile ? secretfile : "hsm_secret", O_RDONLY);
+ if (fd < 0)
+ fatal("opening: %s", strerror(errno));
+ if (!read_all(fd, &secretstuff.hsm_secret, sizeof(secretstuff.hsm_secret)))
+ fatal("reading: %s", strerror(errno));
+ close(fd);
+
+ populate_secretstuff();
+}
+
+void usage()
+{
+ fprintf(stderr, "usage: clightning-dumpkeys <hsmd_secretfile>\n");
+ exit(42);
+}
+
+int main(int argc, char *argv[])
+{
+ if (argc != 2)
+ usage();
+
+ const char *secretfile = argv[1];
+
+ assert_bip32_assumptions();
+ load_hsm(secretfile);
+
+ return 0;
+}
diff --git a/compiler.c b/compiler.c
@@ -0,0 +1,12 @@
+
+#include <stdlib.h>
+#include "compiler.h"
+
+bool alignment_ok(const void *p, size_t n)
+{
+#if HAVE_UNALIGNED_ACCESS
+ return true;
+#else
+ return ((size_t)p % n == 0);
+#endif
+}
diff --git a/compiler.h b/compiler.h
@@ -0,0 +1,55 @@
+
+#ifndef COMPILER_H
+#define COMPILER_H
+
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+bool alignment_ok(const void *p, size_t n);
+
+#define UNUSED __attribute__((__unused__))
+
+/**
+ * BUILD_ASSERT - assert a build-time dependency.
+ * @cond: the compile-time condition which must be true.
+ *
+ * Your compile will fail if the condition isn't true, or can't be evaluated
+ * by the compiler. This can only be used within a function.
+ *
+ * Example:
+ * #include <stddef.h>
+ * ...
+ * static char *foo_to_char(struct foo *foo)
+ * {
+ * // This code needs string to be at start of foo.
+ * BUILD_ASSERT(offsetof(struct foo, string) == 0);
+ * return (char *)foo;
+ * }
+ */
+#define BUILD_ASSERT(cond) \
+ do { (void) sizeof(char [1 - 2*!(cond)]); } while(0)
+
+/**
+ * BUILD_ASSERT_OR_ZERO - assert a build-time dependency, as an expression.
+ * @cond: the compile-time condition which must be true.
+ *
+ * Your compile will fail if the condition isn't true, or can't be evaluated
+ * by the compiler. This can be used in an expression: its value is "0".
+ *
+ * Example:
+ * #define foo_to_char(foo) \
+ * ((char *)(foo) \
+ * + BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0))
+ */
+#define BUILD_ASSERT_OR_ZERO(cond) \
+ (sizeof(char [1 - 2*!(cond)]) - 1)
+
+#define memclear(mem, size) memset(mem, 0, size)
+#define memclear_2(m1, s1, m2, s2) { memclear(m1, s1); memclear(m2, s2); }
+#define memclear_3(m1, s1, m2, s2, m3, s3) { memclear(m1, s1); memclear(m2, s2); memclear(m3, s3); }
+#define wally_clear memclear
+#define wally_clear_2 memclear_2
+#define wally_clear_3 memclear_3
+
+#endif /* COMPILER_H */
diff --git a/ec.c b/ec.c
@@ -0,0 +1,30 @@
+/* from wally_core */
+
+#include "ec.h"
+#include <stdbool.h>
+#include "short_types.h"
+#include "compiler.h"
+
+int wally_ec_public_key_from_private_key(
+ const secp256k1_context *ctx,
+ const unsigned char *priv_key, size_t priv_key_len,
+ unsigned char *bytes_out, size_t len)
+{
+ secp256k1_pubkey pub;
+ size_t len_in_out = EC_PUBLIC_KEY_LEN;
+ bool ok;
+
+ if (!ctx)
+ return WALLY_ENOMEM;
+
+ ok = priv_key && priv_key_len == EC_PRIVATE_KEY_LEN &&
+ bytes_out && len == EC_PUBLIC_KEY_LEN &&
+ secp256k1_ec_pubkey_create(ctx, &pub, priv_key) &&
+ secp256k1_ec_pubkey_serialize(ctx, bytes_out, &len_in_out, &pub, SECP256K1_EC_COMPRESSED) &&
+ len_in_out == EC_PUBLIC_KEY_LEN;
+
+ if (!ok && bytes_out)
+ memclear(bytes_out, len);
+ memclear(&pub, sizeof(pub));
+ return ok ? WALLY_OK : WALLY_EINVAL;
+}
diff --git a/ec.h b/ec.h
@@ -0,0 +1,34 @@
+
+#ifndef EC_H
+#define EC_H
+
+#include <stdlib.h>
+#include "secp256k1.h"
+
+/** The length of a private key used for EC signing */
+#define EC_PRIVATE_KEY_LEN 32
+/** The length of a public key used for EC signing */
+#define EC_PUBLIC_KEY_LEN 33
+/** The length of an uncompressed public key */
+#define EC_PUBLIC_KEY_UNCOMPRESSED_LEN 65
+/** The length of a message hash to EC sign */
+#define EC_MESSAGE_HASH_LEN 32
+/** The length of a compact signature produced by EC signing */
+#define EC_SIGNATURE_LEN 64
+/** The maximum encoded length of a DER encoded signature */
+#define EC_SIGNATURE_DER_MAX_LEN 72
+/** The maximum encoded length of a DER encoded signature created with EC_FLAG_GRIND_R */
+#define EC_SIGNATURE_DER_MAX_LOW_R_LEN 71
+
+/** Indicates that a signature using ECDSA/secp256k1 is required */
+#define EC_FLAG_ECDSA 0x1
+/** Indicates that a signature using EC-Schnorr-SHA256 is required */
+#define EC_FLAG_SCHNORR 0x2
+/** Indicates that the signature nonce should be incremented until the signature is low-R */
+#define EC_FLAG_GRIND_R 0x4
+
+int wally_ec_public_key_from_private_key(
+ const secp256k1_context *ctx, const unsigned char *priv_key,
+ size_t priv_key_len, unsigned char *bytes_out, size_t len);
+
+#endif /* EC_H */
diff --git a/endian.h b/endian.h
@@ -0,0 +1,360 @@
+/* CC0 (Public domain) */
+#ifndef CCAN_ENDIAN_H
+#define CCAN_ENDIAN_H
+#include <stdint.h>
+
+/**
+ * BSWAP_16 - reverse bytes in a constant uint16_t value.
+ * @val: constant value whose bytes to swap.
+ *
+ * Designed to be usable in constant-requiring initializers.
+ *
+ * Example:
+ * struct mystruct {
+ * char buf[BSWAP_16(0x1234)];
+ * };
+ */
+#define BSWAP_16(val) \
+ ((((uint16_t)(val) & 0x00ff) << 8) \
+ | (((uint16_t)(val) & 0xff00) >> 8))
+
+/**
+ * BSWAP_32 - reverse bytes in a constant uint32_t value.
+ * @val: constant value whose bytes to swap.
+ *
+ * Designed to be usable in constant-requiring initializers.
+ *
+ * Example:
+ * struct mystruct {
+ * char buf[BSWAP_32(0xff000000)];
+ * };
+ */
+#define BSWAP_32(val) \
+ ((((uint32_t)(val) & 0x000000ff) << 24) \
+ | (((uint32_t)(val) & 0x0000ff00) << 8) \
+ | (((uint32_t)(val) & 0x00ff0000) >> 8) \
+ | (((uint32_t)(val) & 0xff000000) >> 24))
+
+/**
+ * BSWAP_64 - reverse bytes in a constant uint64_t value.
+ * @val: constantvalue whose bytes to swap.
+ *
+ * Designed to be usable in constant-requiring initializers.
+ *
+ * Example:
+ * struct mystruct {
+ * char buf[BSWAP_64(0xff00000000000000ULL)];
+ * };
+ */
+#define BSWAP_64(val) \
+ ((((uint64_t)(val) & 0x00000000000000ffULL) << 56) \
+ | (((uint64_t)(val) & 0x000000000000ff00ULL) << 40) \
+ | (((uint64_t)(val) & 0x0000000000ff0000ULL) << 24) \
+ | (((uint64_t)(val) & 0x00000000ff000000ULL) << 8) \
+ | (((uint64_t)(val) & 0x000000ff00000000ULL) >> 8) \
+ | (((uint64_t)(val) & 0x0000ff0000000000ULL) >> 24) \
+ | (((uint64_t)(val) & 0x00ff000000000000ULL) >> 40) \
+ | (((uint64_t)(val) & 0xff00000000000000ULL) >> 56))
+
+#if HAVE_BYTESWAP_H
+#include <byteswap.h>
+#else
+/**
+ * bswap_16 - reverse bytes in a uint16_t value.
+ * @val: value whose bytes to swap.
+ *
+ * Example:
+ * // Output contains "1024 is 4 as two bytes reversed"
+ * printf("1024 is %u as two bytes reversed\n", bswap_16(1024));
+ */
+static inline uint16_t bswap_16(uint16_t val)
+{
+ return BSWAP_16(val);
+}
+
+/**
+ * bswap_32 - reverse bytes in a uint32_t value.
+ * @val: value whose bytes to swap.
+ *
+ * Example:
+ * // Output contains "1024 is 262144 as four bytes reversed"
+ * printf("1024 is %u as four bytes reversed\n", bswap_32(1024));
+ */
+static inline uint32_t bswap_32(uint32_t val)
+{
+ return BSWAP_32(val);
+}
+#endif /* !HAVE_BYTESWAP_H */
+
+#if !HAVE_BSWAP_64
+/**
+ * bswap_64 - reverse bytes in a uint64_t value.
+ * @val: value whose bytes to swap.
+ *
+ * Example:
+ * // Output contains "1024 is 1125899906842624 as eight bytes reversed"
+ * printf("1024 is %llu as eight bytes reversed\n",
+ * (unsigned long long)bswap_64(1024));
+ */
+static inline uint64_t bswap_64(uint64_t val)
+{
+ return BSWAP_64(val);
+}
+#endif
+
+/* Needed for Glibc like endiness check */
+#define __LITTLE_ENDIAN 1234
+#define __BIG_ENDIAN 4321
+
+/* Sanity check the defines. We don't handle weird endianness. */
+#if HAVE_LITTLE_ENDIAN && HAVE_BIG_ENDIAN
+#error "Can't compile for both big and little endian."
+#elif HAVE_LITTLE_ENDIAN
+#ifndef __BYTE_ORDER
+#define __BYTE_ORDER __LITTLE_ENDIAN
+#elif __BYTE_ORDER != __LITTLE_ENDIAN
+#error "__BYTE_ORDER already defined, but not equal to __LITTLE_ENDIAN"
+#endif
+#elif HAVE_BIG_ENDIAN
+#ifndef __BYTE_ORDER
+#define __BYTE_ORDER __BIG_ENDIAN
+#elif __BYTE_ORDER != __BIG_ENDIAN
+#error "__BYTE_ORDER already defined, but not equal to __BIG_ENDIAN"
+#endif
+#endif
+
+
+#ifdef __CHECKER__
+/* sparse needs forcing to remove bitwise attribute from ccan/short_types */
+#define ENDIAN_CAST __attribute__((force))
+#define ENDIAN_TYPE __attribute__((bitwise))
+#else
+#define ENDIAN_CAST
+#define ENDIAN_TYPE
+#endif
+
+typedef uint64_t ENDIAN_TYPE leint64_t;
+typedef uint64_t ENDIAN_TYPE beint64_t;
+typedef uint32_t ENDIAN_TYPE leint32_t;
+typedef uint32_t ENDIAN_TYPE beint32_t;
+typedef uint16_t ENDIAN_TYPE leint16_t;
+typedef uint16_t ENDIAN_TYPE beint16_t;
+
+#if HAVE_LITTLE_ENDIAN
+/**
+ * CPU_TO_LE64 - convert a constant uint64_t value to little-endian
+ * @native: constant to convert
+ */
+#define CPU_TO_LE64(native) ((ENDIAN_CAST leint64_t)(native))
+
+/**
+ * CPU_TO_LE32 - convert a constant uint32_t value to little-endian
+ * @native: constant to convert
+ */
+#define CPU_TO_LE32(native) ((ENDIAN_CAST leint32_t)(native))
+
+/**
+ * CPU_TO_LE16 - convert a constant uint16_t value to little-endian
+ * @native: constant to convert
+ */
+#define CPU_TO_LE16(native) ((ENDIAN_CAST leint16_t)(native))
+
+/**
+ * LE64_TO_CPU - convert a little-endian uint64_t constant
+ * @le_val: little-endian constant to convert
+ */
+#define LE64_TO_CPU(le_val) ((ENDIAN_CAST uint64_t)(le_val))
+
+/**
+ * LE32_TO_CPU - convert a little-endian uint32_t constant
+ * @le_val: little-endian constant to convert
+ */
+#define LE32_TO_CPU(le_val) ((ENDIAN_CAST uint32_t)(le_val))
+
+/**
+ * LE16_TO_CPU - convert a little-endian uint16_t constant
+ * @le_val: little-endian constant to convert
+ */
+#define LE16_TO_CPU(le_val) ((ENDIAN_CAST uint16_t)(le_val))
+
+#else /* ... HAVE_BIG_ENDIAN */
+#define CPU_TO_LE64(native) ((ENDIAN_CAST leint64_t)BSWAP_64(native))
+#define CPU_TO_LE32(native) ((ENDIAN_CAST leint32_t)BSWAP_32(native))
+#define CPU_TO_LE16(native) ((ENDIAN_CAST leint16_t)BSWAP_16(native))
+#define LE64_TO_CPU(le_val) BSWAP_64((ENDIAN_CAST uint64_t)le_val)
+#define LE32_TO_CPU(le_val) BSWAP_32((ENDIAN_CAST uint32_t)le_val)
+#define LE16_TO_CPU(le_val) BSWAP_16((ENDIAN_CAST uint16_t)le_val)
+#endif /* HAVE_BIG_ENDIAN */
+
+#if HAVE_BIG_ENDIAN
+/**
+ * CPU_TO_BE64 - convert a constant uint64_t value to big-endian
+ * @native: constant to convert
+ */
+#define CPU_TO_BE64(native) ((ENDIAN_CAST beint64_t)(native))
+
+/**
+ * CPU_TO_BE32 - convert a constant uint32_t value to big-endian
+ * @native: constant to convert
+ */
+#define CPU_TO_BE32(native) ((ENDIAN_CAST beint32_t)(native))
+
+/**
+ * CPU_TO_BE16 - convert a constant uint16_t value to big-endian
+ * @native: constant to convert
+ */
+#define CPU_TO_BE16(native) ((ENDIAN_CAST beint16_t)(native))
+
+/**
+ * BE64_TO_CPU - convert a big-endian uint64_t constant
+ * @le_val: big-endian constant to convert
+ */
+#define BE64_TO_CPU(le_val) ((ENDIAN_CAST uint64_t)(le_val))
+
+/**
+ * BE32_TO_CPU - convert a big-endian uint32_t constant
+ * @le_val: big-endian constant to convert
+ */
+#define BE32_TO_CPU(le_val) ((ENDIAN_CAST uint32_t)(le_val))
+
+/**
+ * BE16_TO_CPU - convert a big-endian uint16_t constant
+ * @le_val: big-endian constant to convert
+ */
+#define BE16_TO_CPU(le_val) ((ENDIAN_CAST uint16_t)(le_val))
+
+#else /* ... HAVE_LITTLE_ENDIAN */
+#define CPU_TO_BE64(native) ((ENDIAN_CAST beint64_t)BSWAP_64(native))
+#define CPU_TO_BE32(native) ((ENDIAN_CAST beint32_t)BSWAP_32(native))
+#define CPU_TO_BE16(native) ((ENDIAN_CAST beint16_t)BSWAP_16(native))
+#define BE64_TO_CPU(le_val) BSWAP_64((ENDIAN_CAST uint64_t)le_val)
+#define BE32_TO_CPU(le_val) BSWAP_32((ENDIAN_CAST uint32_t)le_val)
+#define BE16_TO_CPU(le_val) BSWAP_16((ENDIAN_CAST uint16_t)le_val)
+#endif /* HAVE_LITTE_ENDIAN */
+
+
+/**
+ * cpu_to_le64 - convert a uint64_t value to little-endian
+ * @native: value to convert
+ */
+static inline leint64_t cpu_to_le64(uint64_t native)
+{
+ return CPU_TO_LE64(native);
+}
+
+/**
+ * cpu_to_le32 - convert a uint32_t value to little-endian
+ * @native: value to convert
+ */
+static inline leint32_t cpu_to_le32(uint32_t native)
+{
+ return CPU_TO_LE32(native);
+}
+
+/**
+ * cpu_to_le16 - convert a uint16_t value to little-endian
+ * @native: value to convert
+ */
+static inline leint16_t cpu_to_le16(uint16_t native)
+{
+ return CPU_TO_LE16(native);
+}
+
+/**
+ * le64_to_cpu - convert a little-endian uint64_t value
+ * @le_val: little-endian value to convert
+ */
+static inline uint64_t le64_to_cpu(leint64_t le_val)
+{
+ return LE64_TO_CPU(le_val);
+}
+
+/**
+ * le32_to_cpu - convert a little-endian uint32_t value
+ * @le_val: little-endian value to convert
+ */
+static inline uint32_t le32_to_cpu(leint32_t le_val)
+{
+ return LE32_TO_CPU(le_val);
+}
+
+/**
+ * le16_to_cpu - convert a little-endian uint16_t value
+ * @le_val: little-endian value to convert
+ */
+static inline uint16_t le16_to_cpu(leint16_t le_val)
+{
+ return LE16_TO_CPU(le_val);
+}
+
+/**
+ * cpu_to_be64 - convert a uint64_t value to big endian.
+ * @native: value to convert
+ */
+static inline beint64_t cpu_to_be64(uint64_t native)
+{
+ return CPU_TO_BE64(native);
+}
+
+/**
+ * cpu_to_be32 - convert a uint32_t value to big endian.
+ * @native: value to convert
+ */
+static inline beint32_t cpu_to_be32(uint32_t native)
+{
+ return CPU_TO_BE32(native);
+}
+
+/**
+ * cpu_to_be16 - convert a uint16_t value to big endian.
+ * @native: value to convert
+ */
+static inline beint16_t cpu_to_be16(uint16_t native)
+{
+ return CPU_TO_BE16(native);
+}
+
+/**
+ * be64_to_cpu - convert a big-endian uint64_t value
+ * @be_val: big-endian value to convert
+ */
+static inline uint64_t be64_to_cpu(beint64_t be_val)
+{
+ return BE64_TO_CPU(be_val);
+}
+
+/**
+ * be32_to_cpu - convert a big-endian uint32_t value
+ * @be_val: big-endian value to convert
+ */
+static inline uint32_t be32_to_cpu(beint32_t be_val)
+{
+ return BE32_TO_CPU(be_val);
+}
+
+/**
+ * be16_to_cpu - convert a big-endian uint16_t value
+ * @be_val: big-endian value to convert
+ */
+static inline uint16_t be16_to_cpu(beint16_t be_val)
+{
+ return BE16_TO_CPU(be_val);
+}
+
+/* Whichever they include first, they get these definitions. */
+#ifdef CCAN_SHORT_TYPES_H
+/**
+ * be64/be32/be16 - 64/32/16 bit big-endian representation.
+ */
+typedef beint64_t be64;
+typedef beint32_t be32;
+typedef beint16_t be16;
+
+/**
+ * le64/le32/le16 - 64/32/16 bit little-endian representation.
+ */
+typedef leint64_t le64;
+typedef leint32_t le32;
+typedef leint16_t le16;
+#endif
+#endif /* CCAN_ENDIAN_H */
diff --git a/hash.c b/hash.c
@@ -0,0 +1,28 @@
+
+#include "ripemd160.h"
+#include "sha256.h"
+#include "compiler.h"
+#include "hash.h"
+
+int wally_hash160(const unsigned char *bytes, size_t bytes_len,
+ unsigned char *bytes_out, size_t len)
+{
+ struct sha256 sha;
+ struct ripemd160 ripemd;
+ bool aligned = alignment_ok(bytes_out, sizeof(ripemd.u.u32));
+
+ if (!bytes || !bytes_out || len != HASH160_LEN)
+ return 0;
+
+ BUILD_ASSERT(sizeof(ripemd) == HASH160_LEN);
+
+ sha256(&sha, bytes, bytes_len);
+ ripemd160(aligned ? (struct ripemd160 *)bytes_out : &ripemd, &sha, sizeof(sha));
+ if (!aligned) {
+ memcpy(bytes_out, &ripemd, sizeof(ripemd));
+ memclear(&ripemd, sizeof(ripemd));
+ }
+ memclear(&sha, sizeof(sha));
+ return 1;
+}
+
diff --git a/hash.h b/hash.h
@@ -0,0 +1,13 @@
+
+#ifndef HASH_H
+#define HASH_H
+
+#include <stdlib.h>
+
+/** Output length for `wally_hash160` */
+#define HASH160_LEN 20
+
+int wally_hash160(const unsigned char *bytes, size_t bytes_len,
+ unsigned char *bytes_out, size_t len);
+
+#endif /* HASH_H */
diff --git a/hkdf.c b/hkdf.c
@@ -0,0 +1,98 @@
+
+/* MIT (BSD) license - see LICENSE file for details */
+#include "hmac.h"
+#include "sha256.h"
+#include <assert.h>
+#include <string.h>
+
+void hkdf_sha256(void *okm, size_t okm_size,
+ const void *s, size_t ssize,
+ const void *k, size_t ksize,
+ const void *info, size_t isize)
+{
+ struct hmac_sha256 prk, t;
+ struct hmac_sha256_ctx ctx;
+ unsigned char c;
+
+ assert(okm_size < 255 * sizeof(t));
+
+ /* RFC 5869:
+ *
+ * 2.2. Step 1: Extract
+ *
+ * HKDF-Extract(salt, IKM) -> PRK
+ *
+ * Options:
+ * Hash a hash function; HashLen denotes the length of the
+ * hash function output in octets
+ *
+ * Inputs:
+ * salt optional salt value (a non-secret random value);
+ * if not provided, it is set to a string of HashLen zeros.
+ * IKM input keying material
+ *
+ * Output:
+ * PRK a pseudorandom key (of HashLen octets)
+ *
+ * The output PRK is calculated as follows:
+ *
+ * PRK = HMAC-Hash(salt, IKM)
+ */
+ hmac_sha256(&prk, s, ssize, k, ksize);
+
+ /*
+ * 2.3. Step 2: Expand
+ *
+ * HKDF-Expand(PRK, info, L) -> OKM
+ *
+ * Options:
+ * Hash a hash function; HashLen denotes the length of the
+ * hash function output in octets
+ *
+ * Inputs:
+ * PRK a pseudorandom key of at least HashLen octets
+ * (usually, the output from the extract step)
+ * info optional context and application specific information
+ * (can be a zero-length string)
+ * L length of output keying material in octets
+ * (<= 255*HashLen)
+ *
+ * Output:
+ * OKM output keying material (of L octets)
+ *
+ * The output OKM is calculated as follows:
+ *
+ * N = ceil(L/HashLen)
+ * T = T(1) | T(2) | T(3) | ... | T(N)
+ * OKM = first L octets of T
+ *
+ * where:
+ * T(0) = empty string (zero length)
+ * T(1) = HMAC-Hash(PRK, T(0) | info | 0x01)
+ * T(2) = HMAC-Hash(PRK, T(1) | info | 0x02)
+ * T(3) = HMAC-Hash(PRK, T(2) | info | 0x03)
+ * ...
+ *
+ * (where the constant concatenated to the end of each T(n) is a
+ * single octet.)
+ */
+ c = 1;
+ hmac_sha256_init(&ctx, &prk, sizeof(prk));
+ hmac_sha256_update(&ctx, info, isize);
+ hmac_sha256_update(&ctx, &c, 1);
+ hmac_sha256_done(&ctx, &t);
+
+ while (okm_size > sizeof(t)) {
+ memcpy(okm, &t, sizeof(t));
+ okm = (char *)okm + sizeof(t);
+ okm_size -= sizeof(t);
+
+ c++;
+ hmac_sha256_init(&ctx, &prk, sizeof(prk));
+ hmac_sha256_update(&ctx, &t, sizeof(t));
+ hmac_sha256_update(&ctx, info, isize);
+ hmac_sha256_update(&ctx, &c, 1);
+ hmac_sha256_done(&ctx, &t);
+ }
+ memcpy(okm, &t, okm_size);
+}
diff --git a/hkdf.h b/hkdf.h
@@ -0,0 +1,22 @@
+
+#ifndef CCAN_CRYPTO_HKDF_SHA256_H
+#define CCAN_CRYPTO_HKDF_SHA256_H
+/* BSD-MIT - see LICENSE file for details */
+#include <stdlib.h>
+
+/**
+ * hkdf_sha256 - generate a derived key
+ * @okm: where to output the key
+ * @okm_size: the number of bytes pointed to by @okm (must be less than 255*32)
+ * @s: salt
+ * @ssize: the number of bytes pointed to by @s
+ * @k: pointer to input key
+ * @ksize: the number of bytes pointed to by @k
+ * @info: pointer to info
+ * @isize: the number of bytes pointed to by @info
+ */
+void hkdf_sha256(void *okm, size_t okm_size,
+ const void *s, size_t ssize,
+ const void *k, size_t ksize,
+ const void *info, size_t isize);
+#endif /* CCAN_CRYPTO_HKDF_SHA256_H */
diff --git a/hmac.c b/hmac.c
@@ -0,0 +1,248 @@
+
+#include <string.h>
+#include "hmac.h"
+
+#define IPAD 0x3636363636363636ULL
+#define OPAD 0x5C5C5C5C5C5C5C5CULL
+
+#define BLOCK_U64S (HMAC_SHA256_BLOCKSIZE / sizeof(uint64_t))
+
+static inline void xor_block(uint64_t block[BLOCK_U64S], uint64_t pad)
+{
+ size_t i;
+
+ for (i = 0; i < BLOCK_U64S; i++)
+ block[i] ^= pad;
+}
+
+void hmac_sha256_init(struct hmac_sha256_ctx *ctx,
+ const void *k, size_t ksize)
+{
+ struct sha256 hashed_key;
+ /* We use k_opad as k_ipad temporarily. */
+ uint64_t *k_ipad = ctx->k_opad;
+
+ /* (keys longer than B bytes are first hashed using H) */
+ if (ksize > HMAC_SHA256_BLOCKSIZE) {
+ sha256(&hashed_key, k, ksize);
+ k = &hashed_key;
+ ksize = sizeof(hashed_key);
+ }
+
+ /* From RFC2104:
+ *
+ * (1) append zeros to the end of K to create a B byte string
+ * (e.g., if K is of length 20 bytes and B=64, then K will be
+ * appended with 44 zero bytes 0x00)
+ */
+ memcpy(k_ipad, k, ksize);
+ memset((char *)k_ipad + ksize, 0, HMAC_SHA256_BLOCKSIZE - ksize);
+
+ /*
+ * (2) XOR (bitwise exclusive-OR) the B byte string computed
+ * in step (1) with ipad
+ */
+ xor_block(k_ipad, IPAD);
+
+ /*
+ * We start (4) here, appending text later:
+ *
+ * (3) append the stream of data 'text' to the B byte string resulting
+ * from step (2)
+ * (4) apply H to the stream generated in step (3)
+ */
+ sha256_init(&ctx->sha);
+ sha256_update(&ctx->sha, k_ipad, HMAC_SHA256_BLOCKSIZE);
+
+ /*
+ * (5) XOR (bitwise exclusive-OR) the B byte string computed in
+ * step (1) with opad
+ */
+ xor_block(ctx->k_opad, IPAD^OPAD);
+}
+
+
+void hmac_sha512_init(struct hmac_sha512_ctx *ctx,
+ const void *k, size_t ksize)
+{
+ struct sha512 hashed_key;
+ /* We use k_opad as k_ipad temporarily. */
+ uint64_t *k_ipad = ctx->k_opad;
+
+ /* (keys longer than B bytes are first hashed using H) */
+ if (ksize > HMAC_SHA512_BLOCKSIZE) {
+ sha512(&hashed_key, k, ksize);
+ k = &hashed_key;
+ ksize = sizeof(hashed_key);
+ }
+
+ /* From RFC2104:
+ *
+ * (1) append zeros to the end of K to create a B byte string
+ * (e.g., if K is of length 20 bytes and B=64, then K will be
+ * appended with 44 zero bytes 0x00)
+ */
+ memcpy(k_ipad, k, ksize);
+ memset((char *)k_ipad + ksize, 0, HMAC_SHA512_BLOCKSIZE - ksize);
+
+ /*
+ * (2) XOR (bitwise exclusive-OR) the B byte string computed
+ * in step (1) with ipad
+ */
+ xor_block(k_ipad, IPAD);
+
+ /*
+ * We start (4) here, appending text later:
+ *
+ * (3) append the stream of data 'text' to the B byte string resulting
+ * from step (2)
+ * (4) apply H to the stream generated in step (3)
+ */
+ sha512_init(&ctx->sha);
+ sha512_update(&ctx->sha, k_ipad, HMAC_SHA512_BLOCKSIZE);
+
+ /*
+ * (5) XOR (bitwise exclusive-OR) the B byte string computed in
+ * step (1) with opad
+ */
+ xor_block(ctx->k_opad, IPAD^OPAD);
+}
+
+
+void hmac_sha256_update(struct hmac_sha256_ctx *ctx, const void *p, size_t size)
+{
+ /* This is the appending-text part of this:
+ *
+ * (3) append the stream of data 'text' to the B byte string resulting
+ * from step (2)
+ * (4) apply H to the stream generated in step (3)
+ */
+ sha256_update(&ctx->sha, p, size);
+}
+
+
+void hmac_sha512_update(struct hmac_sha512_ctx *ctx, const void *p, size_t size)
+{
+ sha512_update(&ctx->sha, p, size);
+}
+
+
+void hmac_sha256_done(struct hmac_sha256_ctx *ctx,
+ struct hmac_sha256 *hmac)
+{
+ /* (4) apply H to the stream generated in step (3) */
+ sha256_done(&ctx->sha, &hmac->sha);
+
+ /*
+ * (6) append the H result from step (4) to the B byte string
+ * resulting from step (5)
+ * (7) apply H to the stream generated in step (6) and output
+ * the result
+ */
+ sha256_init(&ctx->sha);
+ sha256_update(&ctx->sha, ctx->k_opad, sizeof(ctx->k_opad));
+ sha256_update(&ctx->sha, &hmac->sha, sizeof(hmac->sha));
+ sha256_done(&ctx->sha, &hmac->sha);
+}
+
+
+void hmac_sha512_done(struct hmac_sha512_ctx *ctx,
+ struct hmac_sha512 *hmac)
+{
+ /* (4) apply H to the stream generated in step (3) */
+ sha512_done(&ctx->sha, &hmac->sha);
+
+ /*
+ * (6) append the H result from step (4) to the B byte string
+ * resulting from step (5)
+ * (7) apply H to the stream generated in step (6) and output
+ * the result
+ */
+ sha512_init(&ctx->sha);
+ sha512_update(&ctx->sha, ctx->k_opad, sizeof(ctx->k_opad));
+ sha512_update(&ctx->sha, &hmac->sha, sizeof(hmac->sha));
+ sha512_done(&ctx->sha, &hmac->sha);
+}
+
+#if 1
+void hmac_sha256(struct hmac_sha256 *hmac,
+ const void *k, size_t ksize,
+ const void *d, size_t dsize)
+{
+ struct hmac_sha256_ctx ctx;
+
+ hmac_sha256_init(&ctx, k, ksize);
+ hmac_sha256_update(&ctx, d, dsize);
+ hmac_sha256_done(&ctx, hmac);
+}
+
+
+void hmac_sha512(struct hmac_sha512 *hmac,
+ const void *k, size_t ksize,
+ const void *d, size_t dsize)
+{
+ struct hmac_sha512_ctx ctx;
+
+ hmac_sha512_init(&ctx, k, ksize);
+ hmac_sha512_update(&ctx, d, dsize);
+ hmac_sha512_done(&ctx, hmac);
+}
+
+
+#else
+/* Direct mapping from MD5 example in RFC2104 */
+void hmac_sha256(struct hmac_sha256 *hmac,
+ const void *key, size_t key_len,
+ const void *text, size_t text_len)
+{
+ struct sha256_ctx context;
+ unsigned char k_ipad[65]; /* inner padding -
+ * key XORd with ipad
+ */
+ unsigned char k_opad[65]; /* outer padding -
+ * key XORd with opad
+ *//* start out by storing key in pads */
+ unsigned char tk[32];
+ int i;
+
+ /* if key is longer than 64 bytes reset it to key=MD5(key) */
+ if (key_len > 64) {
+
+ struct sha256_ctx tctx;
+
+ sha256_init(&tctx);
+ sha256_update(&tctx, key, key_len);
+ sha256_done(&tctx, tk);
+
+ key = tk;
+ key_len = 32;
+ }
+ bzero( k_ipad, sizeof k_ipad);
+ bzero( k_opad, sizeof k_opad);
+ bcopy( key, k_ipad, key_len);
+ bcopy( key, k_opad, key_len);
+
+ /* XOR key with ipad and opad values */
+ for (i=0; i<64; i++) {
+ k_ipad[i] ^= 0x36;
+ k_opad[i] ^= 0x5c;
+ }
+ /*
+ * perform inner MD5
+ */
+ sha256_init(&context); /* init context for 1st
+ * pass */
+ sha256_update(&context, k_ipad, 64); /* start with inner pad */
+ sha256_update(&context, text, text_len); /* then text of datagram */
+ sha256_done(&context, &hmac->sha); /* finish up 1st pass */
+ /*
+ * perform outer MD5
+ */
+ sha256_init(&context); /* init context for 2nd
+ * pass */
+ sha256_update(&context, k_opad, 64); /* start with outer pad */
+ sha256_update(&context, &hmac->sha, 32); /* then results of 1st
+ * hash */
+ sha256_done(&context, &hmac->sha); /* finish up 2nd pass */
+}
+#endif
diff --git a/hmac.h b/hmac.h
@@ -0,0 +1,116 @@
+
+#ifndef CCAN_CRYPTO_HMAC_SHA256_H
+#define CCAN_CRYPTO_HMAC_SHA256_H
+/* BSD-MIT */
+#include <stdint.h>
+#include <stdlib.h>
+#include "sha256.h"
+#include "sha512.h"
+
+/* Number of bytes per block. */
+#define HMAC_SHA256_BLOCKSIZE 64
+#define HMAC_SHA512_BLOCKSIZE 128
+
+/**
+ * struct hmac_sha256 - structure representing a completed HMAC.
+ */
+struct hmac_sha256 {
+ struct sha256 sha;
+};
+
+
+struct hmac_sha512 {
+ struct sha512 sha;
+};
+
+/**
+ * hmac_sha256 - return hmac of an object with a key.
+ * @hmac: the hmac to fill in
+ * @k: pointer to the key,
+ * @ksize: the number of bytes pointed to by @k
+ * @d: pointer to memory,
+ * @dsize: the number of bytes pointed to by @d
+ */
+void hmac_sha256(struct hmac_sha256 *hmac,
+ const void *k, size_t ksize,
+ const void *d, size_t dsize);
+
+void hmac_sha512(struct hmac_sha512 *hmac,
+ const void *k, size_t ksize,
+ const void *d, size_t dsize);
+
+/**
+ * struct hmac_sha256_ctx - structure to store running context for hmac_sha256
+ */
+struct hmac_sha256_ctx {
+ struct sha256_ctx sha;
+ uint64_t k_opad[HMAC_SHA256_BLOCKSIZE / sizeof(uint64_t)];
+};
+
+
+struct hmac_sha512_ctx {
+ struct sha512_ctx sha;
+ uint64_t k_opad[HMAC_SHA512_BLOCKSIZE / sizeof(uint64_t)];
+};
+
+/**
+ * hmac_sha256_init - initialize an HMAC_SHA256 context.
+ * @ctx: the hmac_sha256_ctx to initialize
+ * @k: pointer to the key,
+ * @ksize: the number of bytes pointed to by @k
+ *
+ * This must be called before hmac_sha256_update or hmac_sha256_done.
+ *
+ * If it was already initialized, this forgets anything which was
+ * hashed before.
+ *
+ * Example:
+ * static void hmac_all(const char *key,
+ * const char **arr, struct hmac_sha256 *hash)
+ * {
+ * size_t i;
+ * struct hmac_sha256_ctx ctx;
+ *
+ * hmac_sha256_init(&ctx, key, strlen(key));
+ * for (i = 0; arr[i]; i++)
+ * hmac_sha256_update(&ctx, arr[i], strlen(arr[i]));
+ * hmac_sha256_done(&ctx, hash);
+ * }
+ */
+void hmac_sha256_init(struct hmac_sha256_ctx *ctx,
+ const void *k, size_t ksize);
+
+void hmac_sha512_init(struct hmac_sha512_ctx *ctx,
+ const void *k, size_t ksize);
+
+
+/**
+ * hmac_sha256_update - include some memory in the hash.
+ * @ctx: the hmac_sha256_ctx to use
+ * @p: pointer to memory,
+ * @size: the number of bytes pointed to by @p
+ *
+ * You can call this multiple times to hash more data, before calling
+ * hmac_sha256_done().
+ */
+void hmac_sha256_update(struct hmac_sha256_ctx *ctx,
+ const void *p, size_t size);
+
+void hmac_sha512_update(struct hmac_sha512_ctx *ctx,
+ const void *p, size_t size);
+
+/**
+ * hmac_sha256_done - finish HMAC_SHA256 and return the hash
+ * @ctx: the hmac_sha256_ctx to complete
+ * @res: the hash to return.
+ *
+ * Note that @ctx is *destroyed* by this, and must be reinitialized.
+ * To avoid that, pass a copy instead.
+ */
+void hmac_sha256_done(struct hmac_sha256_ctx *hmac_sha256,
+ struct hmac_sha256 *res);
+
+void hmac_sha512_done(struct hmac_sha512_ctx *hmac_sha256,
+ struct hmac_sha512 *res);
+
+#endif /* CCAN_CRYPTO_HMAC_SHA256_H */
diff --git a/ripemd160.c b/ripemd160.c
@@ -0,0 +1,404 @@
+/* MIT (BSD) license - see LICENSE file for details */
+/* RIPEMD core code translated from the Bitcoin project's C++:
+ *
+ * src/crypto/ripemd160.cpp commit f914f1a746d7f91951c1da262a4a749dd3ebfa71
+ * Copyright (c) 2014 The Bitcoin Core developers
+ * Distributed under the MIT software license, see the accompanying
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.
+ */
+#include "ripemd160.h"
+#include "endian.h"
+#include "compiler.h"
+#include <stdbool.h>
+#include <assert.h>
+#include <string.h>
+
+static void invalidate_ripemd160(struct ripemd160_ctx *ctx)
+{
+#ifdef CCAN_CRYPTO_RIPEMD160_USE_OPENSSL
+ ctx->c.num = -1U;
+#else
+ ctx->bytes = -1ULL;
+#endif
+}
+
+static void check_ripemd160(struct ripemd160_ctx *ctx)
+{
+#ifdef CCAN_CRYPTO_RIPEMD160_USE_OPENSSL
+ assert(ctx->c.num != -1U);
+#else
+ assert(ctx->bytes != -1ULL);
+#endif
+}
+
+#ifdef CCAN_CRYPTO_RIPEMD160_USE_OPENSSL
+void ripemd160_init(struct ripemd160_ctx *ctx)
+{
+ RIPEMD160_Init(&ctx->c);
+}
+
+void ripemd160_update(struct ripemd160_ctx *ctx, const void *p, size_t size)
+{
+ check_ripemd160(ctx);
+ RIPEMD160_Update(&ctx->c, p, size);
+}
+
+void ripemd160_done(struct ripemd160_ctx *ctx, struct ripemd160 *res)
+{
+ RIPEMD160_Final(res->u.u8, &ctx->c);
+ invalidate_ripemd160(ctx);
+}
+#else
+inline static uint32_t f1(uint32_t x, uint32_t y, uint32_t z) { return x ^ y ^ z; }
+inline static uint32_t f2(uint32_t x, uint32_t y, uint32_t z) { return (x & y) | (~x & z); }
+inline static uint32_t f3(uint32_t x, uint32_t y, uint32_t z) { return (x | ~y) ^ z; }
+inline static uint32_t f4(uint32_t x, uint32_t y, uint32_t z) { return (x & z) | (y & ~z); }
+inline static uint32_t f5(uint32_t x, uint32_t y, uint32_t z) { return x ^ (y | ~z); }
+
+/** Initialize RIPEMD-160 state. */
+inline static void Initialize(uint32_t* s)
+{
+ s[0] = 0x67452301ul;
+ s[1] = 0xEFCDAB89ul;
+ s[2] = 0x98BADCFEul;
+ s[3] = 0x10325476ul;
+ s[4] = 0xC3D2E1F0ul;
+}
+
+inline static uint32_t rol(uint32_t x, int i) { return (x << i) | (x >> (32 - i)); }
+
+inline static void Round(uint32_t *a, uint32_t b UNUSED, uint32_t *c, uint32_t d UNUSED, uint32_t e, uint32_t f, uint32_t x, uint32_t k, int r)
+{
+ *a = rol(*a + f + x + k, r) + e;
+ *c = rol(*c, 10);
+}
+
+inline static void R11(uint32_t *a, uint32_t b, uint32_t *c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, *c, d), x, 0, r); }
+inline static void R21(uint32_t *a, uint32_t b, uint32_t *c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, *c, d), x, 0x5A827999ul, r); }
+inline static void R31(uint32_t *a, uint32_t b, uint32_t *c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, *c, d), x, 0x6ED9EBA1ul, r); }
+inline static void R41(uint32_t *a, uint32_t b, uint32_t *c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, *c, d), x, 0x8F1BBCDCul, r); }
+inline static void R51(uint32_t *a, uint32_t b, uint32_t *c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, *c, d), x, 0xA953FD4Eul, r); }
+
+inline static void R12(uint32_t *a, uint32_t b, uint32_t *c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f5(b, *c, d), x, 0x50A28BE6ul, r); }
+inline static void R22(uint32_t *a, uint32_t b, uint32_t *c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f4(b, *c, d), x, 0x5C4DD124ul, r); }
+inline static void R32(uint32_t *a, uint32_t b, uint32_t *c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f3(b, *c, d), x, 0x6D703EF3ul, r); }
+inline static void R42(uint32_t *a, uint32_t b, uint32_t *c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f2(b, *c, d), x, 0x7A6D76E9ul, r); }
+inline static void R52(uint32_t *a, uint32_t b, uint32_t *c, uint32_t d, uint32_t e, uint32_t x, int r) { Round(a, b, c, d, e, f1(b, *c, d), x, 0, r); }
+
+/** Perform a RIPEMD-160 transformation, processing a 64-byte chunk. */
+static void Transform(uint32_t *s, const uint32_t *chunk)
+{
+ uint32_t a1 = s[0], b1 = s[1], c1 = s[2], d1 = s[3], e1 = s[4];
+ uint32_t a2 = a1, b2 = b1, c2 = c1, d2 = d1, e2 = e1;
+ uint32_t w0 = le32_to_cpu(chunk[0]), w1 = le32_to_cpu(chunk[1]), w2 = le32_to_cpu(chunk[2]), w3 = le32_to_cpu(chunk[3]);
+ uint32_t w4 = le32_to_cpu(chunk[4]), w5 = le32_to_cpu(chunk[5]), w6 = le32_to_cpu(chunk[6]), w7 = le32_to_cpu(chunk[7]);
+ uint32_t w8 = le32_to_cpu(chunk[8]), w9 = le32_to_cpu(chunk[9]), w10 = le32_to_cpu(chunk[10]), w11 = le32_to_cpu(chunk[11]);
+ uint32_t w12 = le32_to_cpu(chunk[12]), w13 = le32_to_cpu(chunk[13]), w14 = le32_to_cpu(chunk[14]), w15 = le32_to_cpu(chunk[15]);
+ uint32_t t;
+
+ R11(&a1, b1, &c1, d1, e1, w0, 11);
+ R12(&a2, b2, &c2, d2, e2, w5, 8);
+ R11(&e1, a1, &b1, c1, d1, w1, 14);
+ R12(&e2, a2, &b2, c2, d2, w14, 9);
+ R11(&d1, e1, &a1, b1, c1, w2, 15);
+ R12(&d2, e2, &a2, b2, c2, w7, 9);
+ R11(&c1, d1, &e1, a1, b1, w3, 12);
+ R12(&c2, d2, &e2, a2, b2, w0, 11);
+ R11(&b1, c1, &d1, e1, a1, w4, 5);
+ R12(&b2, c2, &d2, e2, a2, w9, 13);
+ R11(&a1, b1, &c1, d1, e1, w5, 8);
+ R12(&a2, b2, &c2, d2, e2, w2, 15);
+ R11(&e1, a1, &b1, c1, d1, w6, 7);
+ R12(&e2, a2, &b2, c2, d2, w11, 15);
+ R11(&d1, e1, &a1, b1, c1, w7, 9);
+ R12(&d2, e2, &a2, b2, c2, w4, 5);
+ R11(&c1, d1, &e1, a1, b1, w8, 11);
+ R12(&c2, d2, &e2, a2, b2, w13, 7);
+ R11(&b1, c1, &d1, e1, a1, w9, 13);
+ R12(&b2, c2, &d2, e2, a2, w6, 7);
+ R11(&a1, b1, &c1, d1, e1, w10, 14);
+ R12(&a2, b2, &c2, d2, e2, w15, 8);
+ R11(&e1, a1, &b1, c1, d1, w11, 15);
+ R12(&e2, a2, &b2, c2, d2, w8, 11);
+ R11(&d1, e1, &a1, b1, c1, w12, 6);
+ R12(&d2, e2, &a2, b2, c2, w1, 14);
+ R11(&c1, d1, &e1, a1, b1, w13, 7);
+ R12(&c2, d2, &e2, a2, b2, w10, 14);
+ R11(&b1, c1, &d1, e1, a1, w14, 9);
+ R12(&b2, c2, &d2, e2, a2, w3, 12);
+ R11(&a1, b1, &c1, d1, e1, w15, 8);
+ R12(&a2, b2, &c2, d2, e2, w12, 6);
+
+ R21(&e1, a1, &b1, c1, d1, w7, 7);
+ R22(&e2, a2, &b2, c2, d2, w6, 9);
+ R21(&d1, e1, &a1, b1, c1, w4, 6);
+ R22(&d2, e2, &a2, b2, c2, w11, 13);
+ R21(&c1, d1, &e1, a1, b1, w13, 8);
+ R22(&c2, d2, &e2, a2, b2, w3, 15);
+ R21(&b1, c1, &d1, e1, a1, w1, 13);
+ R22(&b2, c2, &d2, e2, a2, w7, 7);
+ R21(&a1, b1, &c1, d1, e1, w10, 11);
+ R22(&a2, b2, &c2, d2, e2, w0, 12);
+ R21(&e1, a1, &b1, c1, d1, w6, 9);
+ R22(&e2, a2, &b2, c2, d2, w13, 8);
+ R21(&d1, e1, &a1, b1, c1, w15, 7);
+ R22(&d2, e2, &a2, b2, c2, w5, 9);
+ R21(&c1, d1, &e1, a1, b1, w3, 15);
+ R22(&c2, d2, &e2, a2, b2, w10, 11);
+ R21(&b1, c1, &d1, e1, a1, w12, 7);
+ R22(&b2, c2, &d2, e2, a2, w14, 7);
+ R21(&a1, b1, &c1, d1, e1, w0, 12);
+ R22(&a2, b2, &c2, d2, e2, w15, 7);
+ R21(&e1, a1, &b1, c1, d1, w9, 15);
+ R22(&e2, a2, &b2, c2, d2, w8, 12);
+ R21(&d1, e1, &a1, b1, c1, w5, 9);
+ R22(&d2, e2, &a2, b2, c2, w12, 7);
+ R21(&c1, d1, &e1, a1, b1, w2, 11);
+ R22(&c2, d2, &e2, a2, b2, w4, 6);
+ R21(&b1, c1, &d1, e1, a1, w14, 7);
+ R22(&b2, c2, &d2, e2, a2, w9, 15);
+ R21(&a1, b1, &c1, d1, e1, w11, 13);
+ R22(&a2, b2, &c2, d2, e2, w1, 13);
+ R21(&e1, a1, &b1, c1, d1, w8, 12);
+ R22(&e2, a2, &b2, c2, d2, w2, 11);
+
+ R31(&d1, e1, &a1, b1, c1, w3, 11);
+ R32(&d2, e2, &a2, b2, c2, w15, 9);
+ R31(&c1, d1, &e1, a1, b1, w10, 13);
+ R32(&c2, d2, &e2, a2, b2, w5, 7);
+ R31(&b1, c1, &d1, e1, a1, w14, 6);
+ R32(&b2, c2, &d2, e2, a2, w1, 15);
+ R31(&a1, b1, &c1, d1, e1, w4, 7);
+ R32(&a2, b2, &c2, d2, e2, w3, 11);
+ R31(&e1, a1, &b1, c1, d1, w9, 14);
+ R32(&e2, a2, &b2, c2, d2, w7, 8);
+ R31(&d1, e1, &a1, b1, c1, w15, 9);
+ R32(&d2, e2, &a2, b2, c2, w14, 6);
+ R31(&c1, d1, &e1, a1, b1, w8, 13);
+ R32(&c2, d2, &e2, a2, b2, w6, 6);
+ R31(&b1, c1, &d1, e1, a1, w1, 15);
+ R32(&b2, c2, &d2, e2, a2, w9, 14);
+ R31(&a1, b1, &c1, d1, e1, w2, 14);
+ R32(&a2, b2, &c2, d2, e2, w11, 12);
+ R31(&e1, a1, &b1, c1, d1, w7, 8);
+ R32(&e2, a2, &b2, c2, d2, w8, 13);
+ R31(&d1, e1, &a1, b1, c1, w0, 13);
+ R32(&d2, e2, &a2, b2, c2, w12, 5);
+ R31(&c1, d1, &e1, a1, b1, w6, 6);
+ R32(&c2, d2, &e2, a2, b2, w2, 14);
+ R31(&b1, c1, &d1, e1, a1, w13, 5);
+ R32(&b2, c2, &d2, e2, a2, w10, 13);
+ R31(&a1, b1, &c1, d1, e1, w11, 12);
+ R32(&a2, b2, &c2, d2, e2, w0, 13);
+ R31(&e1, a1, &b1, c1, d1, w5, 7);
+ R32(&e2, a2, &b2, c2, d2, w4, 7);
+ R31(&d1, e1, &a1, b1, c1, w12, 5);
+ R32(&d2, e2, &a2, b2, c2, w13, 5);
+
+ R41(&c1, d1, &e1, a1, b1, w1, 11);
+ R42(&c2, d2, &e2, a2, b2, w8, 15);
+ R41(&b1, c1, &d1, e1, a1, w9, 12);
+ R42(&b2, c2, &d2, e2, a2, w6, 5);
+ R41(&a1, b1, &c1, d1, e1, w11, 14);
+ R42(&a2, b2, &c2, d2, e2, w4, 8);
+ R41(&e1, a1, &b1, c1, d1, w10, 15);
+ R42(&e2, a2, &b2, c2, d2, w1, 11);
+ R41(&d1, e1, &a1, b1, c1, w0, 14);
+ R42(&d2, e2, &a2, b2, c2, w3, 14);
+ R41(&c1, d1, &e1, a1, b1, w8, 15);
+ R42(&c2, d2, &e2, a2, b2, w11, 14);
+ R41(&b1, c1, &d1, e1, a1, w12, 9);
+ R42(&b2, c2, &d2, e2, a2, w15, 6);
+ R41(&a1, b1, &c1, d1, e1, w4, 8);
+ R42(&a2, b2, &c2, d2, e2, w0, 14);
+ R41(&e1, a1, &b1, c1, d1, w13, 9);
+ R42(&e2, a2, &b2, c2, d2, w5, 6);
+ R41(&d1, e1, &a1, b1, c1, w3, 14);
+ R42(&d2, e2, &a2, b2, c2, w12, 9);
+ R41(&c1, d1, &e1, a1, b1, w7, 5);
+ R42(&c2, d2, &e2, a2, b2, w2, 12);
+ R41(&b1, c1, &d1, e1, a1, w15, 6);
+ R42(&b2, c2, &d2, e2, a2, w13, 9);
+ R41(&a1, b1, &c1, d1, e1, w14, 8);
+ R42(&a2, b2, &c2, d2, e2, w9, 12);
+ R41(&e1, a1, &b1, c1, d1, w5, 6);
+ R42(&e2, a2, &b2, c2, d2, w7, 5);
+ R41(&d1, e1, &a1, b1, c1, w6, 5);
+ R42(&d2, e2, &a2, b2, c2, w10, 15);
+ R41(&c1, d1, &e1, a1, b1, w2, 12);
+ R42(&c2, d2, &e2, a2, b2, w14, 8);
+
+ R51(&b1, c1, &d1, e1, a1, w4, 9);
+ R52(&b2, c2, &d2, e2, a2, w12, 8);
+ R51(&a1, b1, &c1, d1, e1, w0, 15);
+ R52(&a2, b2, &c2, d2, e2, w15, 5);
+ R51(&e1, a1, &b1, c1, d1, w5, 5);
+ R52(&e2, a2, &b2, c2, d2, w10, 12);
+ R51(&d1, e1, &a1, b1, c1, w9, 11);
+ R52(&d2, e2, &a2, b2, c2, w4, 9);
+ R51(&c1, d1, &e1, a1, b1, w7, 6);
+ R52(&c2, d2, &e2, a2, b2, w1, 12);
+ R51(&b1, c1, &d1, e1, a1, w12, 8);
+ R52(&b2, c2, &d2, e2, a2, w5, 5);
+ R51(&a1, b1, &c1, d1, e1, w2, 13);
+ R52(&a2, b2, &c2, d2, e2, w8, 14);
+ R51(&e1, a1, &b1, c1, d1, w10, 12);
+ R52(&e2, a2, &b2, c2, d2, w7, 6);
+ R51(&d1, e1, &a1, b1, c1, w14, 5);
+ R52(&d2, e2, &a2, b2, c2, w6, 8);
+ R51(&c1, d1, &e1, a1, b1, w1, 12);
+ R52(&c2, d2, &e2, a2, b2, w2, 13);
+ R51(&b1, c1, &d1, e1, a1, w3, 13);
+ R52(&b2, c2, &d2, e2, a2, w13, 6);
+ R51(&a1, b1, &c1, d1, e1, w8, 14);
+ R52(&a2, b2, &c2, d2, e2, w14, 5);
+ R51(&e1, a1, &b1, c1, d1, w11, 11);
+ R52(&e2, a2, &b2, c2, d2, w0, 15);
+ R51(&d1, e1, &a1, b1, c1, w6, 8);
+ R52(&d2, e2, &a2, b2, c2, w3, 13);
+ R51(&c1, d1, &e1, a1, b1, w15, 5);
+ R52(&c2, d2, &e2, a2, b2, w9, 11);
+ R51(&b1, c1, &d1, e1, a1, w13, 6);
+ R52(&b2, c2, &d2, e2, a2, w11, 11);
+
+ t = s[0];
+ s[0] = s[1] + c1 + d2;
+ s[1] = s[2] + d1 + e2;
+ s[2] = s[3] + e1 + a2;
+ s[3] = s[4] + a1 + b2;
+ s[4] = t + b1 + c2;
+}
+
+static void add(struct ripemd160_ctx *ctx, const void *p, size_t len)
+{
+ const unsigned char *data = p;
+ size_t bufsize = ctx->bytes % 64;
+
+ if (bufsize + len >= 64) {
+ /* Fill the buffer, and process it. */
+ memcpy(ctx->buf.u8 + bufsize, data, 64 - bufsize);
+ ctx->bytes += 64 - bufsize;
+ data += 64 - bufsize;
+ len -= 64 - bufsize;
+ Transform(ctx->s, ctx->buf.u32);
+ bufsize = 0;
+ }
+
+ while (len >= 64) {
+ /* Process full chunks directly from the source. */
+ if (alignment_ok(data, sizeof(uint32_t)))
+ Transform(ctx->s, (const uint32_t *)data);
+ else {
+ memcpy(ctx->buf.u8, data, sizeof(ctx->buf));
+ Transform(ctx->s, ctx->buf.u32);
+ }
+ ctx->bytes += 64;
+ data += 64;
+ len -= 64;
+ }
+
+ if (len) {
+ /* Fill the buffer with what remains. */
+ memcpy(ctx->buf.u8 + bufsize, data, len);
+ ctx->bytes += len;
+ }
+}
+
+void ripemd160_init(struct ripemd160_ctx *ctx)
+{
+ struct ripemd160_ctx init = RIPEMD160_INIT;
+ *ctx = init;
+}
+
+void ripemd160_update(struct ripemd160_ctx *ctx, const void *p, size_t size)
+{
+ check_ripemd160(ctx);
+ add(ctx, p, size);
+}
+
+void ripemd160_done(struct ripemd160_ctx *ctx, struct ripemd160 *res)
+{
+ static const unsigned char pad[64] = {0x80};
+ uint64_t sizedesc;
+ size_t i;
+
+ sizedesc = cpu_to_le64(ctx->bytes << 3);
+ /* Add '1' bit to terminate, then all 0 bits, up to next block - 8. */
+ add(ctx, pad, 1 + ((119 - (ctx->bytes % 64)) % 64));
+ /* Add number of bits of data (big endian) */
+ add(ctx, &sizedesc, 8);
+ for (i = 0; i < sizeof(ctx->s) / sizeof(ctx->s[0]); i++)
+ res->u.u32[i] = cpu_to_le32(ctx->s[i]);
+ invalidate_ripemd160(ctx);
+}
+#endif
+
+void ripemd160(struct ripemd160 *ripemd, const void *p, size_t size)
+{
+ struct ripemd160_ctx ctx;
+
+ ripemd160_init(&ctx);
+ ripemd160_update(&ctx, p, size);
+ ripemd160_done(&ctx, ripemd);
+ memset(&ctx, 0, sizeof(ctx));
+}
+
+void ripemd160_u8(struct ripemd160_ctx *ctx, uint8_t v)
+{
+ ripemd160_update(ctx, &v, sizeof(v));
+}
+
+void ripemd160_u16(struct ripemd160_ctx *ctx, uint16_t v)
+{
+ ripemd160_update(ctx, &v, sizeof(v));
+}
+
+void ripemd160_u32(struct ripemd160_ctx *ctx, uint32_t v)
+{
+ ripemd160_update(ctx, &v, sizeof(v));
+}
+
+void ripemd160_u64(struct ripemd160_ctx *ctx, uint64_t v)
+{
+ ripemd160_update(ctx, &v, sizeof(v));
+}
+
+/* Add as little-endian */
+void ripemd160_le16(struct ripemd160_ctx *ctx, uint16_t v)
+{
+ leint16_t lev = cpu_to_le16(v);
+ ripemd160_update(ctx, &lev, sizeof(lev));
+}
+
+void ripemd160_le32(struct ripemd160_ctx *ctx, uint32_t v)
+{
+ leint32_t lev = cpu_to_le32(v);
+ ripemd160_update(ctx, &lev, sizeof(lev));
+}
+
+void ripemd160_le64(struct ripemd160_ctx *ctx, uint64_t v)
+{
+ leint64_t lev = cpu_to_le64(v);
+ ripemd160_update(ctx, &lev, sizeof(lev));
+}
+
+/* Add as big-endian */
+void ripemd160_be16(struct ripemd160_ctx *ctx, uint16_t v)
+{
+ beint16_t bev = cpu_to_be16(v);
+ ripemd160_update(ctx, &bev, sizeof(bev));
+}
+
+void ripemd160_be32(struct ripemd160_ctx *ctx, uint32_t v)
+{
+ beint32_t bev = cpu_to_be32(v);
+ ripemd160_update(ctx, &bev, sizeof(bev));
+}
+
+void ripemd160_be64(struct ripemd160_ctx *ctx, uint64_t v)
+{
+ beint64_t bev = cpu_to_be64(v);
+ ripemd160_update(ctx, &bev, sizeof(bev));
+}
+
+
diff --git a/ripemd160.h b/ripemd160.h
@@ -0,0 +1,148 @@
+
+#ifndef CCAN_CRYPTO_RIPEMD160_H
+#define CCAN_CRYPTO_RIPEMD160_H
+/* BSD-MIT - see LICENSE file for details */
+#include <stdint.h>
+#include <stdlib.h>
+
+/* Uncomment this to use openssl's RIPEMD160 routines (and link with -lcrypto) */
+/*#define CCAN_CRYPTO_RIPEMD160_USE_OPENSSL 1*/
+
+#ifdef CCAN_CRYPTO_RIPEMD160_USE_OPENSSL
+#include <openssl/ripemd.h>
+#endif
+
+/**
+ * struct ripemd160 - structure representing a completed RIPEMD160.
+ * @u.u8: an unsigned char array.
+ * @u.u32: a 32-bit integer array.
+ *
+ * Other fields may be added to the union in future.
+ */
+struct ripemd160 {
+ union {
+ /* Array of chars */
+ unsigned char u8[20];
+ /* Array of uint32_t */
+ uint32_t u32[5];
+ } u;
+};
+
+/**
+ * ripemd160 - return ripemd160 of an object.
+ * @ripemd160: the ripemd160 to fill in
+ * @p: pointer to memory,
+ * @size: the number of bytes pointed to by @p
+ *
+ * The bytes pointed to by @p is RIPEMD160 hashed into @ripemd160. This is
+ * equivalent to ripemd160_init(), ripemd160_update() then ripemd160_done().
+ */
+void ripemd160(struct ripemd160 *ripemd, const void *p, size_t size);
+
+/**
+ * struct ripemd160_ctx - structure to store running context for ripemd160
+ */
+struct ripemd160_ctx {
+#ifdef CCAN_CRYPTO_RIPEMD160_USE_OPENSSL
+ RIPEMD160_CTX c;
+#else
+ uint32_t s[5];
+ uint64_t bytes;
+ union {
+ uint32_t u32[16];
+ unsigned char u8[64];
+ } buf;
+#endif
+};
+
+/**
+ * ripemd160_init - initialize an RIPEMD160 context.
+ * @ctx: the ripemd160_ctx to initialize
+ *
+ * This must be called before ripemd160_update or ripemd160_done, or
+ * alternately you can assign RIPEMD160_INIT.
+ *
+ * If it was already initialized, this forgets anything which was
+ * hashed before.
+ *
+ * Example:
+ * static void hash_all(const char **arr, struct ripemd160 *hash)
+ * {
+ * size_t i;
+ * struct ripemd160_ctx ctx;
+ *
+ * ripemd160_init(&ctx);
+ * for (i = 0; arr[i]; i++)
+ * ripemd160_update(&ctx, arr[i], strlen(arr[i]));
+ * ripemd160_done(&ctx, hash);
+ * }
+ */
+void ripemd160_init(struct ripemd160_ctx *ctx);
+
+/**
+ * RIPEMD160_INIT - initializer for an RIPEMD160 context.
+ *
+ * This can be used to staticly initialize an RIPEMD160 context (instead
+ * of ripemd160_init()).
+ *
+ * Example:
+ * static void hash_all(const char **arr, struct ripemd160 *hash)
+ * {
+ * size_t i;
+ * struct ripemd160_ctx ctx = RIPEMD160_INIT;
+ *
+ * for (i = 0; arr[i]; i++)
+ * ripemd160_update(&ctx, arr[i], strlen(arr[i]));
+ * ripemd160_done(&ctx, hash);
+ * }
+ */
+#ifdef CCAN_CRYPTO_RIPEMD160_USE_OPENSSL
+#define RIPEMD160_INIT \
+ { { 0x67452301ul, 0xEFCDAB89ul, 0x98BADCFEul, 0x10325476ul, \
+ 0xC3D2E1F0ul, \
+ 0x0, 0x0, \
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
+ 0 } }
+#else
+#define RIPEMD160_INIT \
+ { { 0x67452301ul, 0xEFCDAB89ul, 0x98BADCFEul, 0x10325476ul, \
+ 0xC3D2E1F0ul }, 0, {{ 0 }} }
+#endif
+
+/**
+ * ripemd160_update - include some memory in the hash.
+ * @ctx: the ripemd160_ctx to use
+ * @p: pointer to memory,
+ * @size: the number of bytes pointed to by @p
+ *
+ * You can call this multiple times to hash more data, before calling
+ * ripemd160_done().
+ */
+void ripemd160_update(struct ripemd160_ctx *ctx, const void *p, size_t size);
+
+/**
+ * ripemd160_done - finish RIPEMD160 and return the hash
+ * @ctx: the ripemd160_ctx to complete
+ * @res: the hash to return.
+ *
+ * Note that @ctx is *destroyed* by this, and must be reinitialized.
+ * To avoid that, pass a copy instead.
+ */
+void ripemd160_done(struct ripemd160_ctx *ripemd160, struct ripemd160 *res);
+
+/* Add various types to an RIPEMD160 hash */
+void ripemd160_u8(struct ripemd160_ctx *ctx, uint8_t v);
+void ripemd160_u16(struct ripemd160_ctx *ctx, uint16_t v);
+void ripemd160_u32(struct ripemd160_ctx *ctx, uint32_t v);
+void ripemd160_u64(struct ripemd160_ctx *ctx, uint64_t v);
+
+/* Add as little-endian */
+void ripemd160_le16(struct ripemd160_ctx *ctx, uint16_t v);
+void ripemd160_le32(struct ripemd160_ctx *ctx, uint32_t v);
+void ripemd160_le64(struct ripemd160_ctx *ctx, uint64_t v);
+
+/* Add as big-endian */
+void ripemd160_be16(struct ripemd160_ctx *ctx, uint16_t v);
+void ripemd160_be32(struct ripemd160_ctx *ctx, uint32_t v);
+void ripemd160_be64(struct ripemd160_ctx *ctx, uint64_t v);
+#endif /* CCAN_CRYPTO_RIPEMD160_H */
diff --git a/sha256.c b/sha256.c
@@ -0,0 +1,321 @@
+
+/* MIT (BSD) license - see LICENSE file for details */
+/* SHA256 core code translated from the Bitcoin project's C++:
+ *
+ * src/crypto/sha256.cpp commit 417532c8acb93c36c2b6fd052b7c11b6a2906aa2
+ * Copyright (c) 2014 The Bitcoin Core developers
+ * Distributed under the MIT software license, see the accompanying
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.
+ */
+#include "sha256.h"
+#include "endian.h"
+#include "compiler.h"
+#include <stdbool.h>
+#include <assert.h>
+#include <string.h>
+
+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)
+{
+#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);
+}
+
+void sha256_update(struct sha256_ctx *ctx, const void *p, size_t size)
+{
+ check_sha256(ctx);
+ SHA256_Update(&ctx->c, p, size);
+}
+
+void sha256_done(struct sha256_ctx *ctx, struct sha256 *res)
+{
+ SHA256_Final(res->u.u8, &ctx->c);
+ invalidate_sha256(ctx);
+}
+#else
+static uint32_t Ch(uint32_t x, uint32_t y, uint32_t z)
+{
+ return z ^ (x & (y ^ z));
+}
+static uint32_t Maj(uint32_t x, uint32_t y, uint32_t z)
+{
+ return (x & y) | (z & (x | y));
+}
+static uint32_t Sigma0(uint32_t x)
+{
+ return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10);
+}
+static uint32_t Sigma1(uint32_t x)
+{
+ return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7);
+}
+static uint32_t sigma0(uint32_t x)
+{
+ return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3);
+}
+static uint32_t sigma1(uint32_t x)
+{
+ return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10);
+}
+
+/** One round of SHA-256. */
+static void Round(uint32_t a, uint32_t b, uint32_t c, uint32_t *d, uint32_t e, uint32_t f, uint32_t g, uint32_t *h, uint32_t k, uint32_t w)
+{
+ uint32_t t1 = *h + Sigma1(e) + Ch(e, f, g) + k + w;
+ uint32_t t2 = Sigma0(a) + Maj(a, b, c);
+ *d += t1;
+ *h = t1 + t2;
+}
+
+/** Perform one SHA-256 transformation, processing a 64-byte chunk. */
+static void Transform(uint32_t *s, const uint32_t *chunk)
+{
+ 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];
+ uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
+
+ Round(a, b, c, &d, e, f, g, &h, 0x428a2f98, w0 = be32_to_cpu(chunk[0]));
+ Round(h, a, b, &c, d, e, f, &g, 0x71374491, w1 = be32_to_cpu(chunk[1]));
+ Round(g, h, a, &b, c, d, e, &f, 0xb5c0fbcf, w2 = be32_to_cpu(chunk[2]));
+ Round(f, g, h, &a, b, c, d, &e, 0xe9b5dba5, w3 = be32_to_cpu(chunk[3]));
+ Round(e, f, g, &h, a, b, c, &d, 0x3956c25b, w4 = be32_to_cpu(chunk[4]));
+ Round(d, e, f, &g, h, a, b, &c, 0x59f111f1, w5 = be32_to_cpu(chunk[5]));
+ Round(c, d, e, &f, g, h, a, &b, 0x923f82a4, w6 = be32_to_cpu(chunk[6]));
+ Round(b, c, d, &e, f, g, h, &a, 0xab1c5ed5, w7 = be32_to_cpu(chunk[7]));
+ Round(a, b, c, &d, e, f, g, &h, 0xd807aa98, w8 = be32_to_cpu(chunk[8]));
+ Round(h, a, b, &c, d, e, f, &g, 0x12835b01, w9 = be32_to_cpu(chunk[9]));
+ Round(g, h, a, &b, c, d, e, &f, 0x243185be, w10 = be32_to_cpu(chunk[10]));
+ Round(f, g, h, &a, b, c, d, &e, 0x550c7dc3, w11 = be32_to_cpu(chunk[11]));
+ Round(e, f, g, &h, a, b, c, &d, 0x72be5d74, w12 = be32_to_cpu(chunk[12]));
+ Round(d, e, f, &g, h, a, b, &c, 0x80deb1fe, w13 = be32_to_cpu(chunk[13]));
+ Round(c, d, e, &f, g, h, a, &b, 0x9bdc06a7, w14 = be32_to_cpu(chunk[14]));
+ Round(b, c, d, &e, f, g, h, &a, 0xc19bf174, w15 = be32_to_cpu(chunk[15]));
+
+ Round(a, b, c, &d, e, f, g, &h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, &c, d, e, f, &g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, &b, c, d, e, &f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, &a, b, c, d, &e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, &h, a, b, c, &d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, &g, h, a, b, &c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, &f, g, h, a, &b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, &e, f, g, h, &a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, &d, e, f, g, &h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, &c, d, e, f, &g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, &b, c, d, e, &f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, &a, b, c, d, &e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, &h, a, b, c, &d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, &g, h, a, b, &c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, &f, g, h, a, &b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, &e, f, g, h, &a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, &d, e, f, g, &h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, &c, d, e, f, &g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, &b, c, d, e, &f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, &a, b, c, d, &e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, &h, a, b, c, &d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, &g, h, a, b, &c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, &f, g, h, a, &b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, &e, f, g, h, &a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, &d, e, f, g, &h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, &c, d, e, f, &g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, &b, c, d, e, &f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, &a, b, c, d, &e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, &h, a, b, c, &d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, &g, h, a, b, &c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, &f, g, h, a, &b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, &e, f, g, h, &a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, &d, e, f, g, &h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, &c, d, e, f, &g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, &b, c, d, e, &f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, &a, b, c, d, &e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, &h, a, b, c, &d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, &g, h, a, b, &c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, &f, g, h, a, &b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, &e, f, g, h, &a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, &d, e, f, g, &h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, &c, d, e, f, &g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, &b, c, d, e, &f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, &a, b, c, d, &e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, &h, a, b, c, &d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, &g, h, a, b, &c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, &f, g, h, a, &b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, &e, f, g, h, &a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0));
+
+ s[0] += a;
+ s[1] += b;
+ s[2] += c;
+ s[3] += d;
+ s[4] += e;
+ s[5] += f;
+ s[6] += g;
+ s[7] += h;
+}
+
+
+static void add(struct sha256_ctx *ctx, const void *p, size_t len)
+{
+ const unsigned char *data = p;
+ size_t bufsize = ctx->bytes % 64;
+
+ if (bufsize + len >= 64) {
+ /* Fill the buffer, and process it. */
+ memcpy(ctx->buf.u8 + bufsize, data, 64 - bufsize);
+ ctx->bytes += 64 - bufsize;
+ data += 64 - bufsize;
+ len -= 64 - bufsize;
+ Transform(ctx->s, ctx->buf.u32);
+ bufsize = 0;
+ }
+
+ while (len >= 64) {
+ /* Process full chunks directly from the source. */
+ if (alignment_ok(data, sizeof(uint32_t)))
+ Transform(ctx->s, (const uint32_t *)data);
+ else {
+ memcpy(ctx->buf.u8, data, sizeof(ctx->buf));
+ Transform(ctx->s, ctx->buf.u32);
+ }
+ ctx->bytes += 64;
+ data += 64;
+ len -= 64;
+ }
+
+ if (len) {
+ /* Fill the buffer with what remains. */
+ memcpy(ctx->buf.u8 + bufsize, data, len);
+ ctx->bytes += len;
+ }
+}
+
+void sha256_init(struct sha256_ctx *ctx)
+{
+ struct sha256_ctx init = SHA256_INIT;
+ *ctx = init;
+}
+
+void sha256_update(struct sha256_ctx *ctx, const void *p, size_t size)
+{
+ check_sha256(ctx);
+ add(ctx, p, size);
+}
+
+void sha256_done(struct sha256_ctx *ctx, struct sha256 *res)
+{
+ static const unsigned char pad[64] = {0x80};
+ uint64_t sizedesc;
+ size_t i;
+
+ sizedesc = cpu_to_be64((uint64_t)ctx->bytes << 3);
+ /* Add '1' bit to terminate, then all 0 bits, up to next block - 8. */
+ add(ctx, pad, 1 + ((128 - 8 - (ctx->bytes % 64) - 1) % 64));
+ /* Add number of bits of data (big endian) */
+ add(ctx, &sizedesc, 8);
+ for (i = 0; i < sizeof(ctx->s) / sizeof(ctx->s[0]); i++)
+ res->u.u32[i] = cpu_to_be32(ctx->s[i]);
+ invalidate_sha256(ctx);
+}
+#endif
+
+void sha256(struct sha256 *sha, const void *p, size_t size)
+{
+ struct sha256_ctx ctx;
+
+ sha256_init(&ctx);
+ sha256_update(&ctx, p, size);
+ sha256_done(&ctx, sha);
+}
+
+void sha256_u8(struct sha256_ctx *ctx, uint8_t v)
+{
+ sha256_update(ctx, &v, sizeof(v));
+}
+
+void sha256_u16(struct sha256_ctx *ctx, uint16_t v)
+{
+ sha256_update(ctx, &v, sizeof(v));
+}
+
+void sha256_u32(struct sha256_ctx *ctx, uint32_t v)
+{
+ sha256_update(ctx, &v, sizeof(v));
+}
+
+void sha256_u64(struct sha256_ctx *ctx, uint64_t v)
+{
+ sha256_update(ctx, &v, sizeof(v));
+}
+
+/* Add as little-endian */
+void sha256_le16(struct sha256_ctx *ctx, uint16_t v)
+{
+ leint16_t lev = cpu_to_le16(v);
+ sha256_update(ctx, &lev, sizeof(lev));
+}
+
+void sha256_le32(struct sha256_ctx *ctx, uint32_t v)
+{
+ leint32_t lev = cpu_to_le32(v);
+ sha256_update(ctx, &lev, sizeof(lev));
+}
+
+void sha256_le64(struct sha256_ctx *ctx, uint64_t v)
+{
+ leint64_t lev = cpu_to_le64(v);
+ sha256_update(ctx, &lev, sizeof(lev));
+}
+
+/* Add as big-endian */
+void sha256_be16(struct sha256_ctx *ctx, uint16_t v)
+{
+ beint16_t bev = cpu_to_be16(v);
+ sha256_update(ctx, &bev, sizeof(bev));
+}
+
+void sha256_be32(struct sha256_ctx *ctx, uint32_t v)
+{
+ beint32_t bev = cpu_to_be32(v);
+ sha256_update(ctx, &bev, sizeof(bev));
+}
+
+void sha256_be64(struct sha256_ctx *ctx, uint64_t v)
+{
+ beint64_t bev = cpu_to_be64(v);
+ sha256_update(ctx, &bev, sizeof(bev));
+}
+
+
+int sha256d(const unsigned char *bytes, size_t bytes_len,
+ unsigned char *bytes_out, size_t len)
+{
+ struct sha256 sha_1, sha_2;
+ bool aligned = alignment_ok(bytes_out, sizeof(sha_1.u.u32));
+
+ if (!bytes || !bytes_out || len != SHA256_LEN)
+ return 0;
+
+ sha256(&sha_1, bytes, bytes_len);
+ sha256(aligned ? (struct sha256 *)bytes_out : &sha_2, &sha_1, sizeof(sha_1));
+ if (!aligned) {
+ memcpy(bytes_out, &sha_2, sizeof(sha_2));
+ wally_clear(&sha_2, sizeof(sha_2));
+ }
+ wally_clear(&sha_1, sizeof(sha_1));
+ return 1;
+}
diff --git a/sha256.h b/sha256.h
@@ -0,0 +1,158 @@
+
+#ifndef CCAN_CRYPTO_SHA256_H
+#define CCAN_CRYPTO_SHA256_H
+
+
+/** Output length for `wally_sha256` */
+#define SHA256_LEN 32
+
+
+/* BSD-MIT - see LICENSE file for details */
+/* #include "config.h" */
+#include <stdint.h>
+#include <stdlib.h>
+
+/* Uncomment this to use openssl's SHA256 routines (and link with -lcrypto) */
+/*#define CCAN_CRYPTO_SHA256_USE_OPENSSL 1*/
+
+#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
+#include <openssl/sha.h>
+#endif
+
+/**
+ * struct sha256 - structure representing a completed SHA256.
+ * @u.u8: an unsigned char array.
+ * @u.u32: a 32-bit integer array.
+ *
+ * Other fields may be added to the union in future.
+ */
+struct sha256 {
+ union {
+ uint32_t u32[8];
+ unsigned char u8[32];
+ } u;
+};
+
+/**
+ * sha256 - return sha256 of an object.
+ * @sha256: the sha256 to fill in
+ * @p: pointer to memory,
+ * @size: the number of bytes pointed to by @p
+ *
+ * The bytes pointed to by @p is SHA256 hashed into @sha256. This is
+ * equivalent to sha256_init(), sha256_update() then sha256_done().
+ */
+void sha256(struct sha256 *sha, const void *p, size_t size);
+
+/**
+ * struct sha256_ctx - structure to store running context for sha256
+ */
+struct sha256_ctx {
+#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
+ SHA256_CTX c;
+#else
+ uint32_t s[8];
+ union {
+ uint32_t u32[16];
+ unsigned char u8[64];
+ } buf;
+ size_t bytes;
+#endif
+};
+
+/**
+ * sha256_init - initialize an SHA256 context.
+ * @ctx: the sha256_ctx to initialize
+ *
+ * This must be called before sha256_update or sha256_done, or
+ * alternately you can assign SHA256_INIT.
+ *
+ * If it was already initialized, this forgets anything which was
+ * hashed before.
+ *
+ * Example:
+ * static void hash_all(const char **arr, struct sha256 *hash)
+ * {
+ * size_t i;
+ * struct sha256_ctx ctx;
+ *
+ * sha256_init(&ctx);
+ * for (i = 0; arr[i]; i++)
+ * sha256_update(&ctx, arr[i], strlen(arr[i]));
+ * sha256_done(&ctx, hash);
+ * }
+ */
+void sha256_init(struct sha256_ctx *ctx);
+
+/**
+ * SHA256_INIT - initializer for an SHA256 context.
+ *
+ * This can be used to statically initialize an SHA256 context (instead
+ * of sha256_init()).
+ *
+ * Example:
+ * static void hash_all(const char **arr, struct sha256 *hash)
+ * {
+ * size_t i;
+ * struct sha256_ctx ctx = SHA256_INIT;
+ *
+ * for (i = 0; arr[i]; i++)
+ * sha256_update(&ctx, arr[i], strlen(arr[i]));
+ * sha256_done(&ctx, hash);
+ * }
+ */
+#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL
+#define SHA256_INIT \
+ { { { 0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, \
+ 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul }, \
+ 0x0, 0x0, \
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
+ 0x0, 0x20 } }
+#else
+#define SHA256_INIT \
+ { { 0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, \
+ 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul }, \
+ { { 0 } }, 0 }
+#endif
+
+/**
+ * sha256_update - include some memory in the hash.
+ * @ctx: the sha256_ctx to use
+ * @p: pointer to memory,
+ * @size: the number of bytes pointed to by @p
+ *
+ * You can call this multiple times to hash more data, before calling
+ * sha256_done().
+ */
+void sha256_update(struct sha256_ctx *ctx, const void *p, size_t size);
+
+/**
+ * sha256_done - finish SHA256 and return the hash
+ * @ctx: the sha256_ctx to complete
+ * @res: the hash to return.
+ *
+ * Note that @ctx is *destroyed* by this, and must be reinitialized.
+ * To avoid that, pass a copy instead.
+ */
+void sha256_done(struct sha256_ctx *sha256, struct sha256 *res);
+
+/* Add various types to an SHA256 hash */
+void sha256_u8(struct sha256_ctx *ctx, uint8_t v);
+void sha256_u16(struct sha256_ctx *ctx, uint16_t v);
+void sha256_u32(struct sha256_ctx *ctx, uint32_t v);
+void sha256_u64(struct sha256_ctx *ctx, uint64_t v);
+
+/* Add as little-endian */
+void sha256_le16(struct sha256_ctx *ctx, uint16_t v);
+void sha256_le32(struct sha256_ctx *ctx, uint32_t v);
+void sha256_le64(struct sha256_ctx *ctx, uint64_t v);
+
+/* Add as big-endian */
+void sha256_be16(struct sha256_ctx *ctx, uint16_t v);
+void sha256_be32(struct sha256_ctx *ctx, uint32_t v);
+void sha256_be64(struct sha256_ctx *ctx, uint64_t v);
+
+int sha256d(const unsigned char *bytes, size_t bytes_len,
+ unsigned char *bytes_out, size_t len);
+
+#endif /* CCAN_CRYPTO_SHA256_H */
diff --git a/sha512.c b/sha512.c
@@ -0,0 +1,261 @@
+
+/* MIT (BSD) license - see LICENSE file for details */
+/* SHA512 core code translated from the Bitcoin project's C++:
+ *
+ * src/crypto/sha512.cpp commit f914f1a746d7f91951c1da262a4a749dd3ebfa71
+ * Copyright (c) 2014 The Bitcoin Core developers
+ * Distributed under the MIT software license, see the accompanying
+ * file COPYING or http://www.opensource.org/licenses/mit-license.php.
+ */
+#include "sha512.h"
+#include "endian.h"
+#include "compiler.h"
+#include <stdbool.h>
+#include <assert.h>
+#include <string.h>
+
+static void invalidate_sha512(struct sha512_ctx *ctx)
+{
+#ifdef CCAN_CRYPTO_SHA512_USE_OPENSSL
+ ctx->c.md_len = 0;
+#else
+ ctx->bytes = (size_t)-1;
+#endif
+}
+
+static void check_sha512(struct sha512_ctx *ctx)
+{
+#ifdef CCAN_CRYPTO_SHA512_USE_OPENSSL
+ assert(ctx->c.md_len != 0);
+#else
+ assert(ctx->bytes != (size_t)-1);
+#endif
+}
+
+#ifdef CCAN_CRYPTO_SHA512_USE_OPENSSL
+void sha512_init(struct sha512_ctx *ctx)
+{
+ SHA512_Init(&ctx->c);
+}
+
+void sha512_update(struct sha512_ctx *ctx, const void *p, size_t size)
+{
+ check_sha512(ctx);
+ SHA512_Update(&ctx->c, p, size);
+}
+
+void sha512_done(struct sha512_ctx *ctx, struct sha512 *res)
+{
+ SHA512_Final(res->u.u8, &ctx->c);
+ invalidate_sha512(ctx);
+}
+#else
+static uint64_t Ch(uint64_t x, uint64_t y, uint64_t z)
+{
+ return z ^ (x & (y ^ z));
+}
+static uint64_t Maj(uint64_t x, uint64_t y, uint64_t z)
+{
+ return (x & y) | (z & (x | y));
+}
+static uint64_t Sigma0(uint64_t x)
+{
+ return (x >> 28 | x << 36) ^ (x >> 34 | x << 30) ^ (x >> 39 | x << 25);
+}
+static uint64_t Sigma1(uint64_t x)
+{
+ return (x >> 14 | x << 50) ^ (x >> 18 | x << 46) ^ (x >> 41 | x << 23);
+}
+static uint64_t sigma0(uint64_t x)
+{
+ return (x >> 1 | x << 63) ^ (x >> 8 | x << 56) ^ (x >> 7);
+}
+static uint64_t sigma1(uint64_t x)
+{
+ return (x >> 19 | x << 45) ^ (x >> 61 | x << 3) ^ (x >> 6);
+}
+
+/** One round of SHA-512. */
+static void Round(uint64_t a, uint64_t b, uint64_t c, uint64_t *d, uint64_t e, uint64_t f, uint64_t g, uint64_t *h, uint64_t k, uint64_t w)
+{
+ uint64_t t1 = *h + Sigma1(e) + Ch(e, f, g) + k + w;
+ uint64_t t2 = Sigma0(a) + Maj(a, b, c);
+ *d += t1;
+ *h = t1 + t2;
+}
+
+/** Perform one SHA-512 transformation, processing a 128-byte chunk. */
+static void Transform(uint64_t *s, const uint64_t *chunk)
+{
+ uint64_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];
+ uint64_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15;
+
+ Round(a, b, c, &d, e, f, g, &h, 0x428a2f98d728ae22ull, w0 = be64_to_cpu(chunk[0]));
+ Round(h, a, b, &c, d, e, f, &g, 0x7137449123ef65cdull, w1 = be64_to_cpu(chunk[1]));
+ Round(g, h, a, &b, c, d, e, &f, 0xb5c0fbcfec4d3b2full, w2 = be64_to_cpu(chunk[2]));
+ Round(f, g, h, &a, b, c, d, &e, 0xe9b5dba58189dbbcull, w3 = be64_to_cpu(chunk[3]));
+ Round(e, f, g, &h, a, b, c, &d, 0x3956c25bf348b538ull, w4 = be64_to_cpu(chunk[4]));
+ Round(d, e, f, &g, h, a, b, &c, 0x59f111f1b605d019ull, w5 = be64_to_cpu(chunk[5]));
+ Round(c, d, e, &f, g, h, a, &b, 0x923f82a4af194f9bull, w6 = be64_to_cpu(chunk[6]));
+ Round(b, c, d, &e, f, g, h, &a, 0xab1c5ed5da6d8118ull, w7 = be64_to_cpu(chunk[7]));
+ Round(a, b, c, &d, e, f, g, &h, 0xd807aa98a3030242ull, w8 = be64_to_cpu(chunk[8]));
+ Round(h, a, b, &c, d, e, f, &g, 0x12835b0145706fbeull, w9 = be64_to_cpu(chunk[9]));
+ Round(g, h, a, &b, c, d, e, &f, 0x243185be4ee4b28cull, w10 = be64_to_cpu(chunk[10]));
+ Round(f, g, h, &a, b, c, d, &e, 0x550c7dc3d5ffb4e2ull, w11 = be64_to_cpu(chunk[11]));
+ Round(e, f, g, &h, a, b, c, &d, 0x72be5d74f27b896full, w12 = be64_to_cpu(chunk[12]));
+ Round(d, e, f, &g, h, a, b, &c, 0x80deb1fe3b1696b1ull, w13 = be64_to_cpu(chunk[13]));
+ Round(c, d, e, &f, g, h, a, &b, 0x9bdc06a725c71235ull, w14 = be64_to_cpu(chunk[14]));
+ Round(b, c, d, &e, f, g, h, &a, 0xc19bf174cf692694ull, w15 = be64_to_cpu(chunk[15]));
+
+ Round(a, b, c, &d, e, f, g, &h, 0xe49b69c19ef14ad2ull, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, &c, d, e, f, &g, 0xefbe4786384f25e3ull, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, &b, c, d, e, &f, 0x0fc19dc68b8cd5b5ull, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, &a, b, c, d, &e, 0x240ca1cc77ac9c65ull, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, &h, a, b, c, &d, 0x2de92c6f592b0275ull, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, &g, h, a, b, &c, 0x4a7484aa6ea6e483ull, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, &f, g, h, a, &b, 0x5cb0a9dcbd41fbd4ull, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, &e, f, g, h, &a, 0x76f988da831153b5ull, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, &d, e, f, g, &h, 0x983e5152ee66dfabull, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, &c, d, e, f, &g, 0xa831c66d2db43210ull, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, &b, c, d, e, &f, 0xb00327c898fb213full, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, &a, b, c, d, &e, 0xbf597fc7beef0ee4ull, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, &h, a, b, c, &d, 0xc6e00bf33da88fc2ull, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, &g, h, a, b, &c, 0xd5a79147930aa725ull, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, &f, g, h, a, &b, 0x06ca6351e003826full, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, &e, f, g, h, &a, 0x142929670a0e6e70ull, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, &d, e, f, g, &h, 0x27b70a8546d22ffcull, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, &c, d, e, f, &g, 0x2e1b21385c26c926ull, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, &b, c, d, e, &f, 0x4d2c6dfc5ac42aedull, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, &a, b, c, d, &e, 0x53380d139d95b3dfull, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, &h, a, b, c, &d, 0x650a73548baf63deull, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, &g, h, a, b, &c, 0x766a0abb3c77b2a8ull, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, &f, g, h, a, &b, 0x81c2c92e47edaee6ull, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, &e, f, g, h, &a, 0x92722c851482353bull, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, &d, e, f, g, &h, 0xa2bfe8a14cf10364ull, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, &c, d, e, f, &g, 0xa81a664bbc423001ull, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, &b, c, d, e, &f, 0xc24b8b70d0f89791ull, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, &a, b, c, d, &e, 0xc76c51a30654be30ull, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, &h, a, b, c, &d, 0xd192e819d6ef5218ull, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, &g, h, a, b, &c, 0xd69906245565a910ull, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, &f, g, h, a, &b, 0xf40e35855771202aull, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, &e, f, g, h, &a, 0x106aa07032bbd1b8ull, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, &d, e, f, g, &h, 0x19a4c116b8d2d0c8ull, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, &c, d, e, f, &g, 0x1e376c085141ab53ull, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, &b, c, d, e, &f, 0x2748774cdf8eeb99ull, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, &a, b, c, d, &e, 0x34b0bcb5e19b48a8ull, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, &h, a, b, c, &d, 0x391c0cb3c5c95a63ull, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, &g, h, a, b, &c, 0x4ed8aa4ae3418acbull, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, &f, g, h, a, &b, 0x5b9cca4f7763e373ull, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, &e, f, g, h, &a, 0x682e6ff3d6b2b8a3ull, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, &d, e, f, g, &h, 0x748f82ee5defb2fcull, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, &c, d, e, f, &g, 0x78a5636f43172f60ull, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, &b, c, d, e, &f, 0x84c87814a1f0ab72ull, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, &a, b, c, d, &e, 0x8cc702081a6439ecull, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, &h, a, b, c, &d, 0x90befffa23631e28ull, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, &g, h, a, b, &c, 0xa4506cebde82bde9ull, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, &f, g, h, a, &b, 0xbef9a3f7b2c67915ull, w14 += sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, &e, f, g, h, &a, 0xc67178f2e372532bull, w15 += sigma1(w13) + w8 + sigma0(w0));
+
+ Round(a, b, c, &d, e, f, g, &h, 0xca273eceea26619cull, w0 += sigma1(w14) + w9 + sigma0(w1));
+ Round(h, a, b, &c, d, e, f, &g, 0xd186b8c721c0c207ull, w1 += sigma1(w15) + w10 + sigma0(w2));
+ Round(g, h, a, &b, c, d, e, &f, 0xeada7dd6cde0eb1eull, w2 += sigma1(w0) + w11 + sigma0(w3));
+ Round(f, g, h, &a, b, c, d, &e, 0xf57d4f7fee6ed178ull, w3 += sigma1(w1) + w12 + sigma0(w4));
+ Round(e, f, g, &h, a, b, c, &d, 0x06f067aa72176fbaull, w4 += sigma1(w2) + w13 + sigma0(w5));
+ Round(d, e, f, &g, h, a, b, &c, 0x0a637dc5a2c898a6ull, w5 += sigma1(w3) + w14 + sigma0(w6));
+ Round(c, d, e, &f, g, h, a, &b, 0x113f9804bef90daeull, w6 += sigma1(w4) + w15 + sigma0(w7));
+ Round(b, c, d, &e, f, g, h, &a, 0x1b710b35131c471bull, w7 += sigma1(w5) + w0 + sigma0(w8));
+ Round(a, b, c, &d, e, f, g, &h, 0x28db77f523047d84ull, w8 += sigma1(w6) + w1 + sigma0(w9));
+ Round(h, a, b, &c, d, e, f, &g, 0x32caab7b40c72493ull, w9 += sigma1(w7) + w2 + sigma0(w10));
+ Round(g, h, a, &b, c, d, e, &f, 0x3c9ebe0a15c9bebcull, w10 += sigma1(w8) + w3 + sigma0(w11));
+ Round(f, g, h, &a, b, c, d, &e, 0x431d67c49c100d4cull, w11 += sigma1(w9) + w4 + sigma0(w12));
+ Round(e, f, g, &h, a, b, c, &d, 0x4cc5d4becb3e42b6ull, w12 += sigma1(w10) + w5 + sigma0(w13));
+ Round(d, e, f, &g, h, a, b, &c, 0x597f299cfc657e2aull, w13 += sigma1(w11) + w6 + sigma0(w14));
+ Round(c, d, e, &f, g, h, a, &b, 0x5fcb6fab3ad6faecull, w14 + sigma1(w12) + w7 + sigma0(w15));
+ Round(b, c, d, &e, f, g, h, &a, 0x6c44198c4a475817ull, w15 + sigma1(w13) + w8 + sigma0(w0));
+
+ s[0] += a;
+ s[1] += b;
+ s[2] += c;
+ s[3] += d;
+ s[4] += e;
+ s[5] += f;
+ s[6] += g;
+ s[7] += h;
+}
+
+static void add(struct sha512_ctx *ctx, const void *p, size_t len)
+{
+ const unsigned char *data = p;
+ size_t bufsize = ctx->bytes % 128;
+
+ if (bufsize + len >= 128) {
+ /* Fill the buffer, and process it. */
+ memcpy(ctx->buf.u8 + bufsize, data, 128 - bufsize);
+ ctx->bytes += 128 - bufsize;
+ data += 128 - bufsize;
+ len -= 128 - bufsize;
+ Transform(ctx->s, ctx->buf.u64);
+ bufsize = 0;
+ }
+
+ while (len >= 128) {
+ /* Process full chunks directly from the source. */
+ if (alignment_ok(data, sizeof(uint64_t)))
+ Transform(ctx->s, (const uint64_t *)data);
+ else {
+ memcpy(ctx->buf.u8, data, sizeof(ctx->buf));
+ Transform(ctx->s, ctx->buf.u64);
+ }
+ ctx->bytes += 128;
+ data += 128;
+ len -= 128;
+ }
+
+ if (len) {
+ /* Fill the buffer with what remains. */
+ memcpy(ctx->buf.u8 + bufsize, data, len);
+ ctx->bytes += len;
+ }
+}
+
+void sha512_init(struct sha512_ctx *ctx)
+{
+ struct sha512_ctx init = SHA512_INIT;
+ *ctx = init;
+}
+
+void sha512_update(struct sha512_ctx *ctx, const void *p, size_t size)
+{
+ check_sha512(ctx);
+ add(ctx, p, size);
+}
+
+void sha512_done(struct sha512_ctx *ctx, struct sha512 *res)
+{
+ static const unsigned char pad[128] = { 0x80 };
+ uint64_t sizedesc[2] = { 0, 0 };
+ size_t i;
+
+ sizedesc[1] = cpu_to_be64((uint64_t)ctx->bytes << 3);
+
+ /* Add '1' bit to terminate, then all 0 bits, up to next block - 16. */
+ add(ctx, pad, 1 + ((256 - 16 - (ctx->bytes % 128) - 1) % 128));
+ /* Add number of bits of data (big endian) */
+ add(ctx, sizedesc, sizeof(sizedesc));
+ for (i = 0; i < sizeof(ctx->s) / sizeof(ctx->s[0]); i++)
+ res->u.u64[i] = cpu_to_be64(ctx->s[i]);
+ invalidate_sha512(ctx);
+}
+#endif /* CCAN_CRYPTO_SHA512_USE_OPENSSL */
+
+void sha512(struct sha512 *sha, const void *p, size_t size)
+{
+ struct sha512_ctx ctx;
+
+ sha512_init(&ctx);
+ sha512_update(&ctx, p, size);
+ sha512_done(&ctx, sha);
+ memset(&ctx, 0, sizeof(ctx));
+}
diff --git a/sha512.h b/sha512.h
@@ -0,0 +1,138 @@
+
+#ifndef CCAN_CRYPTO_SHA512_H
+#define CCAN_CRYPTO_SHA512_H
+/* BSD-MIT - see LICENSE file for details */
+#include <stdint.h>
+#include <stdlib.h>
+
+/** Output length for `wally_sha512` */
+#define SHA512_LEN 64
+
+/* Uncomment this to use openssl's SHA512 routines (and link with -lcrypto) */
+/*#define CCAN_CRYPTO_SHA512_USE_OPENSSL 1*/
+
+#ifdef CCAN_CRYPTO_SHA512_USE_OPENSSL
+#include <openssl/sha.h>
+#endif
+
+/**
+ * struct sha512 - structure representing a completed SHA512.
+ * @u.u8: an unsigned char array.
+ * @u.u64: a 64-bit integer array.
+ *
+ * Other fields may be added to the union in future.
+ */
+struct sha512 {
+ union {
+ uint64_t u64[8];
+ unsigned char u8[64];
+ } u;
+};
+
+/**
+ * sha512 - return sha512 of an object.
+ * @sha512: the sha512 to fill in
+ * @p: pointer to memory,
+ * @size: the number of bytes pointed to by @p
+ *
+ * The bytes pointed to by @p is SHA512 hashed into @sha512. This is
+ * equivalent to sha512_init(), sha512_update() then sha512_done().
+ */
+void sha512(struct sha512 *sha, const void *p, size_t size);
+
+/**
+ * struct sha512_ctx - structure to store running context for sha512
+ */
+struct sha512_ctx {
+#ifdef CCAN_CRYPTO_SHA512_USE_OPENSSL
+ SHA512_CTX c;
+#else
+ uint64_t s[8];
+ union {
+ uint64_t u64[16];
+ unsigned char u8[128];
+ } buf;
+ size_t bytes;
+#endif
+};
+
+/**
+ * sha512_init - initialize an SHA512 context.
+ * @ctx: the sha512_ctx to initialize
+ *
+ * This must be called before sha512_update or sha512_done, or
+ * alternately you can assign SHA512_INIT.
+ *
+ * If it was already initialized, this forgets anything which was
+ * hashed before.
+ *
+ * Example:
+ * static void hash_all(const char **arr, struct sha512 *hash)
+ * {
+ * size_t i;
+ * struct sha512_ctx ctx;
+ *
+ * sha512_init(&ctx);
+ * for (i = 0; arr[i]; i++)
+ * sha512_update(&ctx, arr[i], strlen(arr[i]));
+ * sha512_done(&ctx, hash);
+ * }
+ */
+void sha512_init(struct sha512_ctx *ctx);
+
+/**
+ * SHA512_INIT - initializer for an SHA512 context.
+ *
+ * This can be used to statically initialize an SHA512 context (instead
+ * of sha512_init()).
+ *
+ * Example:
+ * static void hash_all(const char **arr, struct sha512 *hash)
+ * {
+ * size_t i;
+ * struct sha512_ctx ctx = SHA512_INIT;
+ *
+ * for (i = 0; arr[i]; i++)
+ * sha512_update(&ctx, arr[i], strlen(arr[i]));
+ * sha512_done(&ctx, hash);
+ * }
+ */
+#ifdef CCAN_CRYPTO_SHA512_USE_OPENSSL
+ { { { 0x6a09e667f3bcc908ull, 0xbb67ae8584caa73bull, \
+ 0x3c6ef372fe94f82bull, 0xa54ff53a5f1d36f1ull, \
+ 0x510e527fade682d1ull, 0x9b05688c2b3e6c1full, \
+ 0x1f83d9abfb41bd6bull, 0x5be0cd19137e2179ull }, \
+ 0, 0, \
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \
+ 0, 0x40 } }
+#else
+#define SHA512_INIT \
+ { { 0x6a09e667f3bcc908ull, 0xbb67ae8584caa73bull, \
+ 0x3c6ef372fe94f82bull, 0xa54ff53a5f1d36f1ull, \
+ 0x510e527fade682d1ull, 0x9b05688c2b3e6c1full, \
+ 0x1f83d9abfb41bd6bull, 0x5be0cd19137e2179ull }, \
+ { { 0 } }, 0 }
+#endif
+
+/**
+ * sha512_update - include some memory in the hash.
+ * @ctx: the sha512_ctx to use
+ * @p: pointer to memory,
+ * @size: the number of bytes pointed to by @p
+ *
+ * You can call this multiple times to hash more data, before calling
+ * sha512_done().
+ */
+void sha512_update(struct sha512_ctx *ctx, const void *p, size_t size);
+
+/**
+ * sha512_done - finish SHA512 and return the hash
+ * @ctx: the sha512_ctx to complete
+ * @res: the hash to return.
+ *
+ * Note that @ctx is *destroyed* by this, and must be reinitialized.
+ * To avoid that, pass a copy instead.
+ */
+void sha512_done(struct sha512_ctx *sha512, struct sha512 *res);
+
+#endif /* CCAN_CRYPTO_SHA512_H */
diff --git a/short_types.h b/short_types.h
@@ -0,0 +1,21 @@
+
+#ifndef DK_SHORT_TYPES_H
+#define DK_SHORT_TYPES_H
+
+#include <stdint.h>
+
+typedef uint64_t u64;
+typedef int64_t s64;
+typedef uint32_t u32;
+typedef int32_t s32;
+typedef uint16_t u16;
+typedef int16_t s16;
+typedef uint8_t u8;
+typedef int8_t s8;
+
+#define WALLY_OK 0 /** Success */
+#define WALLY_ERROR -1 /** General error */
+#define WALLY_EINVAL -2 /** Invalid argument */
+#define WALLY_ENOMEM -3 /** malloc() failed */
+
+#endif /* DK_SHORT_TYPES_H */