diff --git a/common/Makefile b/common/Makefile index 5290afe19..de27d5c8f 100644 --- a/common/Makefile +++ b/common/Makefile @@ -11,6 +11,7 @@ COMMON_SRC := \ common/derive_basepoints.c \ common/dev_disconnect.c \ common/funding_tx.c \ + common/hash_u5.c \ common/htlc_state.c \ common/htlc_tx.c \ common/htlc_wire.c \ @@ -54,7 +55,7 @@ common/gen_htlc_state_names.h: common/htlc_state.h ccan/ccan/cdump/tools/cdump-e check-makefile: check-common-makefile check-common-makefile: - @if [ x"`LC_ALL=C ls common/*.h | grep -v ^common/gen_`" != x"`echo $(COMMON_HEADERS_NOGEN) | tr ' ' '\n' | LC_ALL=C sort`" ]; then echo COMMON_HEADERS_NOGEN incorrect; exit 1; fi + if [ x"`LC_ALL=C ls common/*.h | grep -v ^common/gen_`" != x"`echo $(COMMON_HEADERS_NOGEN) | tr ' ' '\n' | LC_ALL=C sort`" ]; then echo COMMON_HEADERS_NOGEN incorrect; exit 1; fi check-source-bolt: $(COMMON_SRC:%=bolt-check/%) $(COMMON_HEADERS:%=bolt-check/%) check-whitespace: $(COMMON_SRC:%=check-whitespace/%) $(COMMON_HEADERS:%=check-whitespace/%) diff --git a/common/hash_u5.c b/common/hash_u5.c new file mode 100644 index 000000000..0d3eb91a6 --- /dev/null +++ b/common/hash_u5.c @@ -0,0 +1,47 @@ +#include +#include +#include + +void hash_u5_init(struct hash_u5 *hu5, const char *hrp) +{ + hu5->buf = 0; + hu5->num_bits = 0; + sha256_init(&hu5->hash); + sha256_update(&hu5->hash, hrp, strlen(hrp)); +} + +void hash_u5(struct hash_u5 *hu5, const u8 *u5, size_t len) +{ + size_t bits = len * 5; + + while (bits) { + size_t n = 5; + + if (bits < n) + n = bits; + + hu5->buf <<= n; + hu5->buf |= (*u5 >> (5-n)); + bits -= n; + hu5->num_bits += n; + + if (n == 5) + u5++; + + if (hu5->num_bits >= 32) { + be32 be32 = cpu_to_be32(hu5->buf >> (hu5->num_bits-32)); + sha256_update(&hu5->hash, &be32, sizeof(be32)); + hu5->num_bits -= 32; + } + } +} + +void hash_u5_done(struct hash_u5 *hu5, struct sha256 *res) +{ + if (hu5->num_bits) { + be32 be32 = cpu_to_be32(hu5->buf << (32 - hu5->num_bits)); + + sha256_update(&hu5->hash, &be32, (hu5->num_bits + 7) / 8); + } + sha256_done(&hu5->hash, res); +} diff --git a/common/hash_u5.h b/common/hash_u5.h new file mode 100644 index 000000000..65ded9a6d --- /dev/null +++ b/common/hash_u5.h @@ -0,0 +1,21 @@ +/* bech32 (thus bolt11) deal in 5-bit values */ +#ifndef LIGHTNING_COMMON_HASH_U5_H +#define LIGHTNING_COMMON_HASH_U5_H +#include "config.h" +#include +#include + +/* Type to annotate a 5 bit value. */ +typedef unsigned char u5; + +struct hash_u5 { + u64 buf; + unsigned int num_bits; + struct sha256_ctx hash; +}; + +void hash_u5_init(struct hash_u5 *hu5, const char *hrp); +void hash_u5(struct hash_u5 *hu5, const u5 *u5, size_t len); +void hash_u5_done(struct hash_u5 *hu5, struct sha256 *res); + +#endif /* LIGHTNING_COMMON_HASH_U5_H */