From: Rusty Russell Date: Mon, 5 Dec 2016 05:48:20 +0000 (+1030) Subject: shachain: allow overriding of number of bits, add cmdline tool. X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=4bb69fe6d568f84bd682cf6f86bae168313deb91;hp=d07f742c5925b97ed558eb07aae285616f5df823;ds=sidebyside shachain: allow overriding of number of bits, add cmdline tool. lightning uses 48 bits, so this provides a quick utility for our test vectors, and provides a nice example. Signed-off-by: Rusty Russell --- diff --git a/ccan/crypto/shachain/shachain.c b/ccan/crypto/shachain/shachain.c index c6bd37e8..2c9cb3d5 100644 --- a/ccan/crypto/shachain/shachain.c +++ b/ccan/crypto/shachain/shachain.c @@ -5,8 +5,6 @@ #include #include -#define INDEX_BITS ((sizeof(shachain_index_t)) * CHAR_BIT) - static void change_bit(unsigned char *arr, size_t index) { arr[index / CHAR_BIT] ^= (1 << (index % CHAR_BIT)); @@ -15,11 +13,11 @@ static void change_bit(unsigned char *arr, size_t index) static unsigned int count_trailing_zeroes(shachain_index_t index) { #if HAVE_BUILTIN_CTZLL - return index ? (unsigned int)__builtin_ctzll(index) : INDEX_BITS; + return index ? (unsigned int)__builtin_ctzll(index) : SHACHAIN_BITS; #else unsigned int i; - for (i = 0; i < INDEX_BITS; i++) { + for (i = 0; i < SHACHAIN_BITS; i++) { if (index & (1ULL << i)) break; } @@ -81,7 +79,8 @@ bool shachain_add_hash(struct shachain *chain, /* You have to insert them in order! */ assert(index == chain->min_index - 1 || - (index == (shachain_index_t)(-1ULL) && chain->num_valid == 0)); + (index == (shachain_index_t)(UINT64_MAX >> (64 - SHACHAIN_BITS)) + && chain->num_valid == 0)); pos = count_trailing_zeroes(index); diff --git a/ccan/crypto/shachain/shachain.h b/ccan/crypto/shachain/shachain.h index ba4ba11c..90f2380e 100644 --- a/ccan/crypto/shachain/shachain.h +++ b/ccan/crypto/shachain/shachain.h @@ -11,6 +11,10 @@ #define shachain_index_t uint64_t #endif +#ifndef SHACHAIN_BITS +#define SHACHAIN_BITS (sizeof(shachain_index_t) * 8) +#endif + /** * shachain_from_seed - Generate an unpredictable SHA from a seed value. * @seed: (secret) seed value to use @@ -56,7 +60,7 @@ struct shachain { struct { shachain_index_t index; struct sha256 hash; - } known[sizeof(shachain_index_t) * 8 + 1]; + } known[SHACHAIN_BITS + 1]; }; /** diff --git a/ccan/crypto/shachain/tools/.gitignore b/ccan/crypto/shachain/tools/.gitignore new file mode 100644 index 00000000..883658e3 --- /dev/null +++ b/ccan/crypto/shachain/tools/.gitignore @@ -0,0 +1 @@ +shachain48 diff --git a/ccan/crypto/shachain/tools/Makefile b/ccan/crypto/shachain/tools/Makefile new file mode 100644 index 00000000..a1b0177c --- /dev/null +++ b/ccan/crypto/shachain/tools/Makefile @@ -0,0 +1,39 @@ +#! /usr/bin/make + +CCANDIR=../../../.. +CFLAGS=-Wall -Werror -O3 -I$(CCANDIR) -DSHACHAIN_BITS=48 +#CFLAGS=-Wall -Werror -g3 -I$(CCANDIR) -DSHACHAIN_BITS=48 + +# 48 bit index for shachain. This is what lightning uses. +CCAN_OBJS:=ccan-str.o ccan-err.o ccan-hex.o ccan-shachain.o ccan-sha256.o ccan-rbuf.o + +all: shachain48 + +shachain48: shachain48.o $(CCAN_OBJS) + +shachain48.o: $(CCANDIR)/ccan/crypto/shachain/shachain.h \ + $(CCANDIR)/ccan/str/hex/hex.h \ + $(CCANDIR)/ccan/str/str.h \ + $(CCANDIR)/ccan/err/err.h \ + $(CCANDIR)/ccan/rbuf/rbuf.h + +shachain48.o $(CCAN_OBJS): $(CCANDIR)/config.h + +$(CCANDIR)/config.h: + $(MAKE) -C $(CCANDIR) config.h + +clean: + rm -f shachain *.o + +ccan-err.o: $(CCANDIR)/ccan/err/err.c + $(CC) $(CFLAGS) -c -o $@ $< +ccan-hex.o: $(CCANDIR)/ccan/str/hex/hex.c + $(CC) $(CFLAGS) -c -o $@ $< +ccan-str.o: $(CCANDIR)/ccan/str/str.c + $(CC) $(CFLAGS) -c -o $@ $< +ccan-shachain.o: $(CCANDIR)/ccan/crypto/shachain/shachain.c + $(CC) $(CFLAGS) -c -o $@ $< +ccan-sha256.o: $(CCANDIR)/ccan/crypto/sha256/sha256.c + $(CC) $(CFLAGS) -c -o $@ $< +ccan-rbuf.o: $(CCANDIR)/ccan/rbuf/rbuf.c + $(CC) $(CFLAGS) -c -o $@ $< diff --git a/ccan/crypto/shachain/tools/shachain48.c b/ccan/crypto/shachain/tools/shachain48.c new file mode 100644 index 00000000..5cc91090 --- /dev/null +++ b/ccan/crypto/shachain/tools/shachain48.c @@ -0,0 +1,58 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) +{ + if (argc == 2 && streq(argv[1], "--store")) { + struct shachain s; + struct rbuf rbuf; + size_t size = rbuf_good_size(STDIN_FILENO); + char *p; + + shachain_init(&s); + rbuf_init(&rbuf, STDIN_FILENO, malloc(size), size); + + while ((p = rbuf_read_str(&rbuf, '\n', realloc)) != NULL) { + struct sha256 hash; + unsigned long long idx; + + if (strstarts(p, "0x")) + p += 2; + if (!hex_decode(p, 64, &hash, sizeof(hash))) + errx(2, "%.*s is not 64 chars of hex", 64, p); + p += 64; + p += strspn(p, " \t"); + idx = strtoull(p, NULL, 0); + if (shachain_add_hash(&s, idx, &hash)) + printf("OK\n"); + else + printf("ERROR\n"); + } + } else if (argc == 3) { + struct sha256 seed, hash; + const char *p; + unsigned long long idx; + char hex[65]; + + if (strstarts(argv[1], "0x")) + p = argv[1] + 2; + else + p = argv[1]; + idx = strtoull(argv[2], NULL, 0); + + if (!hex_decode(p, 64, &seed, sizeof(seed))) + errx(2, "%s is not 64 chars of hex", p); + + shachain_from_seed(&seed, idx, &hash); + hex_encode(&hash, sizeof(hash), hex, sizeof(hex)); + printf("0x%s\n", hex); + } else + errx(1, "Usage: shachain --store OR shachain "); + return 0; +}