crypto/siphash: new module.
[ccan] / ccan / crypto / siphash24 / siphash24.h
1 /* CC0 license (public domain) - see LICENSE file for details */
2 #ifndef CCAN_CRYPTO_SIPHASH24_H
3 #define CCAN_CRYPTO_SIPHASH24_H
4 /* Public domain - see LICENSE file for details */
5 #include "config.h"
6 #include <stdint.h>
7 #include <stdlib.h>
8
9 /**
10  * struct siphash_seed - random bytes to seed the siphash
11  * @u.u8: an unsigned char array.
12  * @u.u32: a 32-bit integer array.
13  *
14  * Other fields may be added to the union in future.
15  */
16 struct siphash_seed {
17         union {
18                 /* Array of chars */
19                 unsigned char u8[16];
20                 /* Array of uint32_t */
21                 uint32_t u32[4];
22                 /* Array of uint64_t */
23                 uint64_t u64[2];
24         } u;
25 };
26
27 /**
28  * siphash24 - return SipHash-2-4 of an object.
29  * @seed: the seed for the hash.
30  * @p: pointer to memory,
31  * @size: the number of bytes pointed to by @p
32  *
33  * The bytes pointed to by @p is SIPHASH24 hashed into @siphash24,
34  * using seed @seed.  This is equivalent to siphash24_init(),
35  * siphash24_update() then siphash24_done().
36  */
37 uint64_t siphash24(const struct siphash_seed *seed, const void *p, size_t size);
38
39 /**
40  * struct siphash24_ctx - structure to store running context for siphash24
41  */
42 struct siphash24_ctx {
43         uint64_t v[4];
44         uint64_t bytes;
45         union {
46                 uint64_t u64;
47                 unsigned char u8[8];
48         } buf;
49 };
50
51 /**
52  * siphash24_init - initialize an SIPHASH24 context.
53  * @ctx: the siphash24_ctx to initialize
54  * @seed: the siphash_seed.
55  *
56  * This must be called before siphash24_update or siphash24_done, or
57  * alternately you can assign SIPHASH24_INIT.
58  *
59  * If it was already initialized, this forgets anything which was
60  * hashed before.
61  *
62  * Example:
63  * static void hash_all(const char **arr, uint64_t *hash)
64  * {
65  *      size_t i;
66  *      struct siphash24_ctx ctx;
67  *      struct siphash_seed seed;
68  *
69  *      // Use a random seed, not this!
70  *      memset(seed.u.u64, 7, sizeof(seed.u.u64));
71  *      siphash24_init(&ctx, &seed);
72  *      for (i = 0; arr[i]; i++)
73  *              siphash24_update(&ctx, arr[i], strlen(arr[i]));
74  *      *hash = siphash24_done(&ctx);
75  * }
76  */
77 void siphash24_init(struct siphash24_ctx *ctx, const struct siphash_seed *seed);
78
79 /**
80  * SIPHASH24_INIT - initializer for an SIPHASH24 context.
81  * @seed1, @seed2: two 64-bit words for seed.
82  *
83  * This can be used to staticly initialize an SIPHASH24 context (instead
84  * of siphash24_init()).
85  *
86  * Example:
87  * static uint64_t hash_all(const char **arr)
88  * {
89  *      size_t i;
90  *      struct siphash24_ctx ctx = SIPHASH24_INIT(0x0707070707070707ULL,
91  *                                                0x0707070707070707ULL);
92  *
93  *      for (i = 0; arr[i]; i++)
94  *              siphash24_update(&ctx, arr[i], strlen(arr[i]));
95  *      return siphash24_done(&ctx);
96  * }
97  */
98 #define SIPHASH24_INIT(seed1, seed2)            \
99         { { 0x736f6d6570736575ULL ^ (seed1),    \
100             0x646f72616e646f6dULL ^ (seed2),    \
101             0x6c7967656e657261ULL ^ (seed1),    \
102             0x7465646279746573ULL ^ (seed2) } }
103
104 /**
105  * siphash24_update - include some memory in the hash.
106  * @ctx: the siphash24_ctx to use
107  * @p: pointer to memory,
108  * @size: the number of bytes pointed to by @p
109  *
110  * You can call this multiple times to hash more data, before calling
111  * siphash24_done().
112  */
113 void siphash24_update(struct siphash24_ctx *ctx, const void *p, size_t size);
114
115 /**
116  * siphash24_done - finish SIPHASH24 and return the hash
117  * @ctx: the siphash24_ctx to complete
118  *
119  * Note that @ctx is *destroyed* by this, and must be reinitialized.
120  * To avoid that, pass a copy instead.
121  */
122 uint64_t siphash24_done(struct siphash24_ctx *siphash24);
123
124 /* Add various types to an SIPHASH24 hash */
125 void siphash24_u8(struct siphash24_ctx *ctx, uint8_t v);
126 void siphash24_u16(struct siphash24_ctx *ctx, uint16_t v);
127 void siphash24_u32(struct siphash24_ctx *ctx, uint32_t v);
128 void siphash24_u64(struct siphash24_ctx *ctx, uint64_t v);
129
130 /* Add as little-endian */
131 void siphash24_le16(struct siphash24_ctx *ctx, uint16_t v);
132 void siphash24_le32(struct siphash24_ctx *ctx, uint32_t v);
133 void siphash24_le64(struct siphash24_ctx *ctx, uint64_t v);
134
135 /* Add as big-endian */
136 void siphash24_be16(struct siphash24_ctx *ctx, uint16_t v);
137 void siphash24_be32(struct siphash24_ctx *ctx, uint32_t v);
138 void siphash24_be64(struct siphash24_ctx *ctx, uint64_t v);
139 #endif /* CCAN_CRYPTO_SIPHASH24_H */