-
Notifications
You must be signed in to change notification settings - Fork 4
/
bloom.c
56 lines (50 loc) · 1.06 KB
/
bloom.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <endian.h>
#include "crypto.h"
#include "sha3.h"
#include "bloom.h"
struct bloom *bloom_create(int k, size_t l)
{
struct bloom *b = calloc(1, sizeof *b + l + 32);
if (k>8) return 0;
if (b) {
if (getentropy(b->bits, 31)) {
free(b);
return 0;
}
b->bits[31] = k;
b->l = l;
}
return b;
}
static int bloom_op(struct bloom *b, const unsigned char *d, size_t n, int add)
{
unsigned char *bits = b->bits + 32;
int k = bits[-1];
uint64_t hashes[256];
sha3_ctx_t hc;
sha3_init(&hc, 8*k);
sha3_update(&hc, bits-32, 32);
sha3_update(&hc, d, n);
sha3_final(hashes, &hc);
for (int i=0; i<k; i++) {
size_t j = le64toh(hashes[i]) % (8*b->l);
if (add) bits[j/8] |= 1<<(j%8);
else if (!(bits[j/8] & 1<<(j%8))) return 0;
}
return 1;
}
void bloom_add(struct bloom *b, const unsigned char *d, size_t n)
{
bloom_op(b, d, n, 1);
}
int bloom_query(const struct bloom *b, const unsigned char *d, size_t n)
{
return bloom_op((struct bloom *)b, d, n, 0);
}
void bloom_free(struct bloom *b)
{
free(b);
}