iAdd mini hash framework - dedup - deduplicating backup program Err bitreich.org 70 hgit clone git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/ URL:git://bitreich.org/dedup/ git://enlrupgkhuxnvlhsf6lc3fziv5h2hhfrinws65d7roiv6bfj7d652fid.onion/dedup/ bitreich.org 70 1Log /scm/dedup/log.gph bitreich.org 70 1Files /scm/dedup/files.gph bitreich.org 70 1Refs /scm/dedup/refs.gph bitreich.org 70 1Tags /scm/dedup/tag bitreich.org 70 1README /scm/dedup/file/README.gph bitreich.org 70 1LICENSE /scm/dedup/file/LICENSE.gph bitreich.org 70 i--- Err bitreich.org 70 1commit b0e37d93a013e29a6ee2918eabe2708aa7022921 /scm/dedup/commit/b0e37d93a013e29a6ee2918eabe2708aa7022921.gph bitreich.org 70 1parent e5fdb8553cc9adfcebf7d567a57334b1238e3cd3 /scm/dedup/commit/e5fdb8553cc9adfcebf7d567a57334b1238e3cd3.gph bitreich.org 70 hAuthor: sin URL:mailto:sin@2f30.org bitreich.org 70 iDate: Sun, 7 Apr 2019 10:14:29 +0100 Err bitreich.org 70 i Err bitreich.org 70 iAdd mini hash framework Err bitreich.org 70 i Err bitreich.org 70 iDiffstat: Err bitreich.org 70 i M Makefile | 3 +++ Err bitreich.org 70 i M dedup.1 | 15 ++++++++------- Err bitreich.org 70 i M dedup.c | 80 ++++++++++--------------------- Err bitreich.org 70 i M dedup.h | 22 +++++++++++----------- Err bitreich.org 70 i A hash.c | 119 +++++++++++++++++++++++++++++++ Err bitreich.org 70 i A hash.h | 18 ++++++++++++++++++ Err bitreich.org 70 i Err bitreich.org 70 i6 files changed, 184 insertions(+), 73 deletions(-) Err bitreich.org 70 i--- Err bitreich.org 70 1diff --git a/Makefile b/Makefile /scm/dedup/file/Makefile.gph bitreich.org 70 i@@ -10,6 +10,7 @@ HDR = \ Err bitreich.org 70 i blake2.h \ Err bitreich.org 70 i config.h \ Err bitreich.org 70 i dedup.h \ Err bitreich.org 70 i+ hash.h \ Err bitreich.org 70 i tree.h \ Err bitreich.org 70 i Err bitreich.org 70 i SRC = \ Err bitreich.org 70 i@@ -19,6 +20,7 @@ SRC = \ Err bitreich.org 70 i blake2bp-ref.c \ Err bitreich.org 70 i chunker.c \ Err bitreich.org 70 i compress.c \ Err bitreich.org 70 i+ hash.c \ Err bitreich.org 70 i icache.c \ Err bitreich.org 70 i pack.c \ Err bitreich.org 70 i types.c \ Err bitreich.org 70 i@@ -31,6 +33,7 @@ OBJ = \ Err bitreich.org 70 i blake2bp-ref.o \ Err bitreich.org 70 i chunker.o \ Err bitreich.org 70 i compress.o \ Err bitreich.org 70 i+ hash.o \ Err bitreich.org 70 i icache.o \ Err bitreich.org 70 i pack.o \ Err bitreich.org 70 i types.o \ Err bitreich.org 70 1diff --git a/dedup.1 b/dedup.1 /scm/dedup/file/dedup.1.gph bitreich.org 70 i@@ -1,4 +1,4 @@ Err bitreich.org 70 i-.Dd April 6, 2019 Err bitreich.org 70 i+.Dd April 7, 2019 Err bitreich.org 70 i .Dt DEDUP 1 Err bitreich.org 70 i .Os Err bitreich.org 70 i .Sh NAME Err bitreich.org 70 i@@ -6,7 +6,8 @@ Err bitreich.org 70 i .Nd data deduplication program Err bitreich.org 70 i .Sh SYNOPSIS Err bitreich.org 70 i .Nm dedup Err bitreich.org 70 i-.Op Fl PZcilv Err bitreich.org 70 i+.Op Fl Zcilv Err bitreich.org 70 i+.Op Fl H Ar hash Err bitreich.org 70 i .Op Fl e Ar id Err bitreich.org 70 i .Op Fl r Ar root Err bitreich.org 70 i .Op Fl m Ar message Err bitreich.org 70 i@@ -27,11 +28,11 @@ should be used and piped into Err bitreich.org 70 i .Nm . Err bitreich.org 70 i .Sh OPTIONS Err bitreich.org 70 i .Bl -tag -width "-m message" Err bitreich.org 70 i-.It Fl P Err bitreich.org 70 i-Use the blake2bp variant which is a parallel version of blake2b. Err bitreich.org 70 i-These two variants are incompatible as they produce different Err bitreich.org 70 i-hashes. This flag only has an effect when initializing the Err bitreich.org 70 i-repository. By default blake2b is used. Err bitreich.org 70 i+.It Fl H Ar hash Err bitreich.org 70 i+The cryptographic hash function used to identify Err bitreich.org 70 i+unique blocks in the store. The supported hash functions Err bitreich.org 70 i+are blake2b and blake2bp. This flag only has an effect when Err bitreich.org 70 i+initializing the repository. By default blake2b is used. Err bitreich.org 70 i .It Fl Z Err bitreich.org 70 i Disable compression support for this repository. Err bitreich.org 70 i This flag only has an effect when initializing the repository. Err bitreich.org 70 1diff --git a/dedup.c b/dedup.c /scm/dedup/file/dedup.c.gph bitreich.org 70 i@@ -13,6 +13,7 @@ Err bitreich.org 70 i #include "arg.h" Err bitreich.org 70 i #include "blake2.h" Err bitreich.org 70 i #include "dedup.h" Err bitreich.org 70 i+#include "hash.h" Err bitreich.org 70 i Err bitreich.org 70 i #define SNAPSF ".snapshots" Err bitreich.org 70 i #define STOREF ".store" Err bitreich.org 70 i@@ -33,7 +34,7 @@ static struct blk_hdr blk_hdr; Err bitreich.org 70 i static struct icache *icache; Err bitreich.org 70 i static int ifd; Err bitreich.org 70 i static int sfd; Err bitreich.org 70 i-static int blake2b_parallel; Err bitreich.org 70 i+static int hash_algo; Err bitreich.org 70 i Err bitreich.org 70 i int verbose; Err bitreich.org 70 i char *argv0; Err bitreich.org 70 i@@ -105,38 +106,17 @@ free_snap(struct snap *snap) Err bitreich.org 70 i static void Err bitreich.org 70 i hash_snap(struct snap *snap, uint8_t *md) Err bitreich.org 70 i { Err bitreich.org 70 i- switch (blake2b_parallel) { Err bitreich.org 70 i- case 0: { Err bitreich.org 70 i- blake2b_state ctx; Err bitreich.org 70 i- uint64_t i; Err bitreich.org 70 i- Err bitreich.org 70 i- blake2b_init(&ctx, MD_SIZE); Err bitreich.org 70 i- for (i = 0; i < snap->nr_blk_descs; i++) { Err bitreich.org 70 i- struct blk_desc *blk_desc; Err bitreich.org 70 i- Err bitreich.org 70 i- blk_desc = &snap->blk_desc[i]; Err bitreich.org 70 i- blake2b_update(&ctx, blk_desc->md, Err bitreich.org 70 i- sizeof(blk_desc->md)); Err bitreich.org 70 i- } Err bitreich.org 70 i- blake2b_final(&ctx, md, MD_SIZE); Err bitreich.org 70 i- break; Err bitreich.org 70 i- } Err bitreich.org 70 i- case 1: { Err bitreich.org 70 i- blake2bp_state ctx; Err bitreich.org 70 i- uint64_t i; Err bitreich.org 70 i+ struct hash_ctx ctx; Err bitreich.org 70 i+ uint64_t i; Err bitreich.org 70 i Err bitreich.org 70 i- blake2bp_init(&ctx, MD_SIZE); Err bitreich.org 70 i- for (i = 0; i < snap->nr_blk_descs; i++) { Err bitreich.org 70 i- struct blk_desc *blk_desc; Err bitreich.org 70 i+ hash_init(&ctx, hash_algo, MD_SIZE); Err bitreich.org 70 i+ for (i = 0; i < snap->nr_blk_descs; i++) { Err bitreich.org 70 i+ struct blk_desc *blk_desc; Err bitreich.org 70 i Err bitreich.org 70 i- blk_desc = &snap->blk_desc[i]; Err bitreich.org 70 i- blake2bp_update(&ctx, blk_desc->md, Err bitreich.org 70 i- sizeof(blk_desc->md)); Err bitreich.org 70 i- } Err bitreich.org 70 i- blake2bp_final(&ctx, md, MD_SIZE); Err bitreich.org 70 i- break; Err bitreich.org 70 i- } Err bitreich.org 70 i+ blk_desc = &snap->blk_desc[i]; Err bitreich.org 70 i+ hash_update(&ctx, blk_desc->md, sizeof(blk_desc->md)); Err bitreich.org 70 i } Err bitreich.org 70 i+ hash_final(&ctx, md, MD_SIZE); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static struct snap * Err bitreich.org 70 i@@ -202,24 +182,11 @@ free_buf(uint8_t *buf) Err bitreich.org 70 i static void Err bitreich.org 70 i hash_blk(uint8_t *buf, size_t size, uint8_t *md) Err bitreich.org 70 i { Err bitreich.org 70 i- switch (blake2b_parallel) { Err bitreich.org 70 i- case 0: { Err bitreich.org 70 i- blake2b_state ctx; Err bitreich.org 70 i- Err bitreich.org 70 i- blake2b_init(&ctx, MD_SIZE); Err bitreich.org 70 i- blake2b_update(&ctx, buf, size); Err bitreich.org 70 i- blake2b_final(&ctx, md, MD_SIZE); Err bitreich.org 70 i- break; Err bitreich.org 70 i- } Err bitreich.org 70 i- case 1: { Err bitreich.org 70 i- blake2bp_state ctx; Err bitreich.org 70 i+ struct hash_ctx ctx; Err bitreich.org 70 i Err bitreich.org 70 i- blake2bp_init(&ctx, MD_SIZE); Err bitreich.org 70 i- blake2bp_update(&ctx, buf, size); Err bitreich.org 70 i- blake2bp_final(&ctx, md, MD_SIZE); Err bitreich.org 70 i- break; Err bitreich.org 70 i- } Err bitreich.org 70 i- } Err bitreich.org 70 i+ hash_init(&ctx, hash_algo, MD_SIZE); Err bitreich.org 70 i+ hash_update(&ctx, buf, size); Err bitreich.org 70 i+ hash_final(&ctx, md, MD_SIZE); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i@@ -467,7 +434,7 @@ init_blk_hdr(void) Err bitreich.org 70 i { Err bitreich.org 70 i blk_hdr.flags = (VER_MAJ << VER_MAJ_SHIFT) | VER_MIN; Err bitreich.org 70 i blk_hdr.flags |= compr_enabled << COMPR_ENABLED_SHIFT; Err bitreich.org 70 i- blk_hdr.flags |= blake2b_parallel << BLAKE2BP_ENABLED_SHIFT; Err bitreich.org 70 i+ blk_hdr.flags |= hash_algo << HASH_ALGO_SHIFT; Err bitreich.org 70 i blk_hdr.size = BLK_HDR_SIZE; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -484,9 +451,9 @@ load_blk_hdr(void) Err bitreich.org 70 i v &= COMPR_ENABLED_MASK; Err bitreich.org 70 i compr_enabled = v; Err bitreich.org 70 i Err bitreich.org 70 i- v = blk_hdr.flags >> BLAKE2BP_ENABLED_SHIFT; Err bitreich.org 70 i- v &= BLAKE2BP_ENABLED_MASK; Err bitreich.org 70 i- blake2b_parallel = v; Err bitreich.org 70 i+ v = blk_hdr.flags >> HASH_ALGO_SHIFT; Err bitreich.org 70 i+ v &= HASH_ALGO_MASK; Err bitreich.org 70 i+ hash_algo = v; Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i static void Err bitreich.org 70 i@@ -573,7 +540,7 @@ term(void) Err bitreich.org 70 i static void Err bitreich.org 70 i usage(void) Err bitreich.org 70 i { Err bitreich.org 70 i- fprintf(stderr, "usage: %s [-PZcilv] [-e id] [-r root] [-m message] [file]\n", argv0); Err bitreich.org 70 i+ fprintf(stderr, "usage: %s [-Zcilv] [-H hash] [-e id] [-r root] [-m message] [file]\n", argv0); Err bitreich.org 70 i exit(1); Err bitreich.org 70 i } Err bitreich.org 70 i Err bitreich.org 70 i@@ -581,13 +548,16 @@ int Err bitreich.org 70 i main(int argc, char *argv[]) Err bitreich.org 70 i { Err bitreich.org 70 i uint8_t md[MD_SIZE]; Err bitreich.org 70 i- char *id = NULL, *root = NULL, *msg = NULL; Err bitreich.org 70 i+ char *id = NULL, *root = NULL, *msg = NULL, *algo = NULL; Err bitreich.org 70 i int iflag = 0, lflag = 0, cflag = 0; Err bitreich.org 70 i int fd = -1; Err bitreich.org 70 i Err bitreich.org 70 i ARGBEGIN { Err bitreich.org 70 i- case 'P': Err bitreich.org 70 i- blake2b_parallel = 1; Err bitreich.org 70 i+ case 'H': Err bitreich.org 70 i+ algo = EARGF(usage()); Err bitreich.org 70 i+ hash_algo = hash_name2type(algo); Err bitreich.org 70 i+ if (hash_algo < 0) Err bitreich.org 70 i+ errx(1, "unknown hash: %s", algo); Err bitreich.org 70 i break; Err bitreich.org 70 i case 'Z': Err bitreich.org 70 i compr_enabled = 0; Err bitreich.org 70 1diff --git a/dedup.h b/dedup.h /scm/dedup/file/dedup.h.gph bitreich.org 70 i@@ -25,11 +25,11 @@ Err bitreich.org 70 i #define COMPR_ENABLED_SHIFT 16 Err bitreich.org 70 i #define COMPR_ENABLED_MASK 0x1 Err bitreich.org 70 i Err bitreich.org 70 i-#define BLAKE2BP_ENABLED_SHIFT 17 Err bitreich.org 70 i-#define BLAKE2BP_ENABLED_MASK 0x1 Err bitreich.org 70 i+#define HASH_ALGO_SHIFT 17 Err bitreich.org 70 i+#define HASH_ALGO_MASK 0x7 /* max 8 hash algos */ Err bitreich.org 70 i Err bitreich.org 70 i-struct icache; Err bitreich.org 70 i struct chunker; Err bitreich.org 70 i+struct icache; Err bitreich.org 70 i Err bitreich.org 70 i struct stats { Err bitreich.org 70 i uint64_t orig_size; /* original store size */ Err bitreich.org 70 i@@ -73,14 +73,6 @@ extern int compr_enabled; Err bitreich.org 70 i /* dedup.c */ Err bitreich.org 70 i extern int verbose; Err bitreich.org 70 i Err bitreich.org 70 i-/* icache.c */ Err bitreich.org 70 i-struct icache *alloc_icache(void); Err bitreich.org 70 i-void free_icache(struct icache *icache); Err bitreich.org 70 i-void insert_icache(struct icache *icache, struct blk_desc *desc); Err bitreich.org 70 i-int lookup_icache(struct icache *icache, struct blk_desc *desc); Err bitreich.org 70 i-void icache_stats(struct icache *icache, unsigned long long *hits, Err bitreich.org 70 i- unsigned long long *misses); Err bitreich.org 70 i- Err bitreich.org 70 i /* chunker.c */ Err bitreich.org 70 i struct chunker *alloc_chunker(int fd, size_t min_size, size_t max_size, Err bitreich.org 70 i size_t mask, size_t win_size); Err bitreich.org 70 i@@ -94,6 +86,14 @@ size_t compr_size(size_t size); Err bitreich.org 70 i size_t compr(uint8_t *in, uint8_t *out, size_t insize, size_t outsize); Err bitreich.org 70 i size_t decompr(uint8_t *in, uint8_t *out, size_t insize, size_t outsize); Err bitreich.org 70 i Err bitreich.org 70 i+/* icache.c */ Err bitreich.org 70 i+struct icache *alloc_icache(void); Err bitreich.org 70 i+void free_icache(struct icache *icache); Err bitreich.org 70 i+void insert_icache(struct icache *icache, struct blk_desc *desc); Err bitreich.org 70 i+int lookup_icache(struct icache *icache, struct blk_desc *desc); Err bitreich.org 70 i+void icache_stats(struct icache *icache, unsigned long long *hits, Err bitreich.org 70 i+ unsigned long long *misses); Err bitreich.org 70 i+ Err bitreich.org 70 i /* pack.c */ Err bitreich.org 70 i int pack(unsigned char *dst, char *fmt, ...); Err bitreich.org 70 i Err bitreich.org 70 1diff --git a/hash.c b/hash.c /scm/dedup/file/hash.c.gph bitreich.org 70 i@@ -0,0 +1,119 @@ Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+#include Err bitreich.org 70 i+ Err bitreich.org 70 i+#include "blake2.h" Err bitreich.org 70 i+#include "hash.h" Err bitreich.org 70 i+ Err bitreich.org 70 i+static int blake2bi(struct hash_ctx *ctx, size_t n); Err bitreich.org 70 i+static int blake2bu(struct hash_ctx *ctx, const void *buf, size_t n); Err bitreich.org 70 i+static int blake2bf(struct hash_ctx *ctx, void *buf, size_t n); Err bitreich.org 70 i+ Err bitreich.org 70 i+static int blake2bpi(struct hash_ctx *ctx, size_t n); Err bitreich.org 70 i+static int blake2bpu(struct hash_ctx *ctx, const void *buf, size_t n); Err bitreich.org 70 i+static int blake2bpf(struct hash_ctx *ctx, void *buf, size_t n); Err bitreich.org 70 i+ Err bitreich.org 70 i+static struct hash_ops { Err bitreich.org 70 i+ int (*init)(struct hash_ctx *ctx, size_t n); Err bitreich.org 70 i+ int (*update)(struct hash_ctx *ctx, const void *buf, size_t n); Err bitreich.org 70 i+ int (*final)(struct hash_ctx *ctx, void *buf, size_t n); Err bitreich.org 70 i+} hashes[NR_ALGOS] = { Err bitreich.org 70 i+ { Err bitreich.org 70 i+ .init = blake2bi, Err bitreich.org 70 i+ .update = blake2bu, Err bitreich.org 70 i+ .final = blake2bf, Err bitreich.org 70 i+ }, Err bitreich.org 70 i+ { Err bitreich.org 70 i+ .init = blake2bpi, Err bitreich.org 70 i+ .update = blake2bpu, Err bitreich.org 70 i+ .final = blake2bpf, Err bitreich.org 70 i+ } Err bitreich.org 70 i+}; Err bitreich.org 70 i+ Err bitreich.org 70 i+static struct algomap { Err bitreich.org 70 i+ char *name; Err bitreich.org 70 i+ int type; Err bitreich.org 70 i+} algomap[] = { Err bitreich.org 70 i+ { Err bitreich.org 70 i+ .name = "blake2b", Err bitreich.org 70 i+ .type = BLAKE2B_ALGO, Err bitreich.org 70 i+ }, Err bitreich.org 70 i+ { Err bitreich.org 70 i+ .name = "blake2bp", Err bitreich.org 70 i+ .type = BLAKE2BP_ALGO, Err bitreich.org 70 i+ }, Err bitreich.org 70 i+ { Err bitreich.org 70 i+ .name = NULL, Err bitreich.org 70 i+ }, Err bitreich.org 70 i+}; Err bitreich.org 70 i+ Err bitreich.org 70 i+static int Err bitreich.org 70 i+blake2bi(struct hash_ctx *ctx, size_t n) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return blake2b_init(&ctx->u.blake2b_ctx, n); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static int Err bitreich.org 70 i+blake2bu(struct hash_ctx *ctx, const void *buf, size_t n) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return blake2b_update(&ctx->u.blake2b_ctx, buf, n); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static int Err bitreich.org 70 i+blake2bf(struct hash_ctx *ctx, void *buf, size_t n) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return blake2b_final(&ctx->u.blake2b_ctx, buf, n); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static int Err bitreich.org 70 i+blake2bpi(struct hash_ctx *ctx, size_t n) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return blake2bp_init(&ctx->u.blake2bp_ctx, n); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static int Err bitreich.org 70 i+blake2bpu(struct hash_ctx *ctx, const void *buf, size_t n) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return blake2bp_update(&ctx->u.blake2bp_ctx, buf, n); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+static int Err bitreich.org 70 i+blake2bpf(struct hash_ctx *ctx, void *buf, size_t n) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return blake2bp_final(&ctx->u.blake2bp_ctx, buf, n); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+hash_init(struct hash_ctx *ctx, int type, size_t n) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ if (type < 0 || type >= NR_ALGOS) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ Err bitreich.org 70 i+ ctx->ops = &hashes[type]; Err bitreich.org 70 i+ return (*ctx->ops->init)(ctx, n); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+hash_update(struct hash_ctx *ctx, const void *buf, size_t n) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return (*ctx->ops->update)(ctx, buf, n); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+hash_final(struct hash_ctx *ctx, void *buf, size_t n) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ return (*ctx->ops->final)(ctx, buf, n); Err bitreich.org 70 i+} Err bitreich.org 70 i+ Err bitreich.org 70 i+int Err bitreich.org 70 i+hash_name2type(char *name) Err bitreich.org 70 i+{ Err bitreich.org 70 i+ struct algomap *algo; Err bitreich.org 70 i+ Err bitreich.org 70 i+ for (algo = &algomap[0]; algo->name != NULL; algo++) Err bitreich.org 70 i+ if (strcmp(algo->name, name) == 0) Err bitreich.org 70 i+ break; Err bitreich.org 70 i+ if (algo->name == NULL) Err bitreich.org 70 i+ return -1; Err bitreich.org 70 i+ return algo->type; Err bitreich.org 70 i+} Err bitreich.org 70 1diff --git a/hash.h b/hash.h /scm/dedup/file/hash.h.gph bitreich.org 70 i@@ -0,0 +1,18 @@ Err bitreich.org 70 i+enum hash_algo { Err bitreich.org 70 i+ BLAKE2B_ALGO, Err bitreich.org 70 i+ BLAKE2BP_ALGO, Err bitreich.org 70 i+ NR_ALGOS, Err bitreich.org 70 i+}; Err bitreich.org 70 i+ Err bitreich.org 70 i+struct hash_ctx { Err bitreich.org 70 i+ union { Err bitreich.org 70 i+ blake2b_state blake2b_ctx; Err bitreich.org 70 i+ blake2bp_state blake2bp_ctx; Err bitreich.org 70 i+ } u; Err bitreich.org 70 i+ struct hash_ops *ops; Err bitreich.org 70 i+}; Err bitreich.org 70 i+ Err bitreich.org 70 i+int hash_init(struct hash_ctx *ctx, int type, size_t n); Err bitreich.org 70 i+int hash_update(struct hash_ctx *ctx, const void *buf, size_t n); Err bitreich.org 70 i+int hash_final(struct hash_ctx *ctx, void *buf, size_t n); Err bitreich.org 70 i+int hash_name2type(char *name); Err bitreich.org 70 .