1*7f2fe78bSCy Schubert /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2*7f2fe78bSCy Schubert /* util/support/t_hash.c - tests for hash table code */
3*7f2fe78bSCy Schubert /*
4*7f2fe78bSCy Schubert * Copyright (C) 2018 by the Massachusetts Institute of Technology.
5*7f2fe78bSCy Schubert * All rights reserved.
6*7f2fe78bSCy Schubert *
7*7f2fe78bSCy Schubert * Redistribution and use in source and binary forms, with or without
8*7f2fe78bSCy Schubert * modification, are permitted provided that the following conditions
9*7f2fe78bSCy Schubert * are met:
10*7f2fe78bSCy Schubert *
11*7f2fe78bSCy Schubert * * Redistributions of source code must retain the above copyright
12*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer.
13*7f2fe78bSCy Schubert *
14*7f2fe78bSCy Schubert * * Redistributions in binary form must reproduce the above copyright
15*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer in
16*7f2fe78bSCy Schubert * the documentation and/or other materials provided with the
17*7f2fe78bSCy Schubert * distribution.
18*7f2fe78bSCy Schubert *
19*7f2fe78bSCy Schubert * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20*7f2fe78bSCy Schubert * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21*7f2fe78bSCy Schubert * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22*7f2fe78bSCy Schubert * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23*7f2fe78bSCy Schubert * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24*7f2fe78bSCy Schubert * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25*7f2fe78bSCy Schubert * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26*7f2fe78bSCy Schubert * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27*7f2fe78bSCy Schubert * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28*7f2fe78bSCy Schubert * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29*7f2fe78bSCy Schubert * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30*7f2fe78bSCy Schubert * OF THE POSSIBILITY OF SUCH DAMAGE.
31*7f2fe78bSCy Schubert */
32*7f2fe78bSCy Schubert
33*7f2fe78bSCy Schubert /* hash.c has no linker dependencies, so we can simply include its source code
34*7f2fe78bSCy Schubert * to test its static functions and look inside its structures. */
35*7f2fe78bSCy Schubert #include "hashtab.c"
36*7f2fe78bSCy Schubert
37*7f2fe78bSCy Schubert /* These match the sip64 test vectors in the reference C implementation of
38*7f2fe78bSCy Schubert * siphash at https://github.com/veorq/SipHash */
39*7f2fe78bSCy Schubert const uint64_t vectors[64] = {
40*7f2fe78bSCy Schubert 0x726FDB47DD0E0E31,
41*7f2fe78bSCy Schubert 0x74F839C593DC67FD,
42*7f2fe78bSCy Schubert 0x0D6C8009D9A94F5A,
43*7f2fe78bSCy Schubert 0x85676696D7FB7E2D,
44*7f2fe78bSCy Schubert 0xCF2794E0277187B7,
45*7f2fe78bSCy Schubert 0x18765564CD99A68D,
46*7f2fe78bSCy Schubert 0xCBC9466E58FEE3CE,
47*7f2fe78bSCy Schubert 0xAB0200F58B01D137,
48*7f2fe78bSCy Schubert 0x93F5F5799A932462,
49*7f2fe78bSCy Schubert 0x9E0082DF0BA9E4B0,
50*7f2fe78bSCy Schubert 0x7A5DBBC594DDB9F3,
51*7f2fe78bSCy Schubert 0xF4B32F46226BADA7,
52*7f2fe78bSCy Schubert 0x751E8FBC860EE5FB,
53*7f2fe78bSCy Schubert 0x14EA5627C0843D90,
54*7f2fe78bSCy Schubert 0xF723CA908E7AF2EE,
55*7f2fe78bSCy Schubert 0xA129CA6149BE45E5,
56*7f2fe78bSCy Schubert 0x3F2ACC7F57C29BDB,
57*7f2fe78bSCy Schubert 0x699AE9F52CBE4794,
58*7f2fe78bSCy Schubert 0x4BC1B3F0968DD39C,
59*7f2fe78bSCy Schubert 0xBB6DC91DA77961BD,
60*7f2fe78bSCy Schubert 0xBED65CF21AA2EE98,
61*7f2fe78bSCy Schubert 0xD0F2CBB02E3B67C7,
62*7f2fe78bSCy Schubert 0x93536795E3A33E88,
63*7f2fe78bSCy Schubert 0xA80C038CCD5CCEC8,
64*7f2fe78bSCy Schubert 0xB8AD50C6F649AF94,
65*7f2fe78bSCy Schubert 0xBCE192DE8A85B8EA,
66*7f2fe78bSCy Schubert 0x17D835B85BBB15F3,
67*7f2fe78bSCy Schubert 0x2F2E6163076BCFAD,
68*7f2fe78bSCy Schubert 0xDE4DAAACA71DC9A5,
69*7f2fe78bSCy Schubert 0xA6A2506687956571,
70*7f2fe78bSCy Schubert 0xAD87A3535C49EF28,
71*7f2fe78bSCy Schubert 0x32D892FAD841C342,
72*7f2fe78bSCy Schubert 0x7127512F72F27CCE,
73*7f2fe78bSCy Schubert 0xA7F32346F95978E3,
74*7f2fe78bSCy Schubert 0x12E0B01ABB051238,
75*7f2fe78bSCy Schubert 0x15E034D40FA197AE,
76*7f2fe78bSCy Schubert 0x314DFFBE0815A3B4,
77*7f2fe78bSCy Schubert 0x027990F029623981,
78*7f2fe78bSCy Schubert 0xCADCD4E59EF40C4D,
79*7f2fe78bSCy Schubert 0x9ABFD8766A33735C,
80*7f2fe78bSCy Schubert 0x0E3EA96B5304A7D0,
81*7f2fe78bSCy Schubert 0xAD0C42D6FC585992,
82*7f2fe78bSCy Schubert 0x187306C89BC215A9,
83*7f2fe78bSCy Schubert 0xD4A60ABCF3792B95,
84*7f2fe78bSCy Schubert 0xF935451DE4F21DF2,
85*7f2fe78bSCy Schubert 0xA9538F0419755787,
86*7f2fe78bSCy Schubert 0xDB9ACDDFF56CA510,
87*7f2fe78bSCy Schubert 0xD06C98CD5C0975EB,
88*7f2fe78bSCy Schubert 0xE612A3CB9ECBA951,
89*7f2fe78bSCy Schubert 0xC766E62CFCADAF96,
90*7f2fe78bSCy Schubert 0xEE64435A9752FE72,
91*7f2fe78bSCy Schubert 0xA192D576B245165A,
92*7f2fe78bSCy Schubert 0x0A8787BF8ECB74B2,
93*7f2fe78bSCy Schubert 0x81B3E73D20B49B6F,
94*7f2fe78bSCy Schubert 0x7FA8220BA3B2ECEA,
95*7f2fe78bSCy Schubert 0x245731C13CA42499,
96*7f2fe78bSCy Schubert 0xB78DBFAF3A8D83BD,
97*7f2fe78bSCy Schubert 0xEA1AD565322A1A0B,
98*7f2fe78bSCy Schubert 0x60E61C23A3795013,
99*7f2fe78bSCy Schubert 0x6606D7E446282B93,
100*7f2fe78bSCy Schubert 0x6CA4ECB15C5F91E1,
101*7f2fe78bSCy Schubert 0x9F626DA15C9625F3,
102*7f2fe78bSCy Schubert 0xE51B38608EF25F57,
103*7f2fe78bSCy Schubert 0x958A324CEB064572
104*7f2fe78bSCy Schubert };
105*7f2fe78bSCy Schubert
106*7f2fe78bSCy Schubert static void
test_siphash()107*7f2fe78bSCy Schubert test_siphash()
108*7f2fe78bSCy Schubert {
109*7f2fe78bSCy Schubert uint8_t seq[64];
110*7f2fe78bSCy Schubert uint64_t k0, k1, hval;
111*7f2fe78bSCy Schubert size_t i;
112*7f2fe78bSCy Schubert
113*7f2fe78bSCy Schubert for (i = 0; i < sizeof(seq); i++)
114*7f2fe78bSCy Schubert seq[i] = i;
115*7f2fe78bSCy Schubert k0 = load_64_le(seq);
116*7f2fe78bSCy Schubert k1 = load_64_le(seq + 8);
117*7f2fe78bSCy Schubert
118*7f2fe78bSCy Schubert for (i = 0; i < sizeof(seq); i++) {
119*7f2fe78bSCy Schubert hval = siphash24(seq, i, k0, k1);
120*7f2fe78bSCy Schubert assert(hval == vectors[i]);
121*7f2fe78bSCy Schubert }
122*7f2fe78bSCy Schubert }
123*7f2fe78bSCy Schubert
124*7f2fe78bSCy Schubert static void
test_hashtab()125*7f2fe78bSCy Schubert test_hashtab()
126*7f2fe78bSCy Schubert {
127*7f2fe78bSCy Schubert int st;
128*7f2fe78bSCy Schubert struct k5_hashtab *ht;
129*7f2fe78bSCy Schubert size_t i;
130*7f2fe78bSCy Schubert char zeros[100] = { 0 };
131*7f2fe78bSCy Schubert
132*7f2fe78bSCy Schubert st = k5_hashtab_create(NULL, 4, &ht);
133*7f2fe78bSCy Schubert assert(st == 0 && ht != NULL && ht->nentries == 0);
134*7f2fe78bSCy Schubert
135*7f2fe78bSCy Schubert st = k5_hashtab_add(ht, "abc", 3, &st);
136*7f2fe78bSCy Schubert assert(st == 0 && ht->nentries == 1);
137*7f2fe78bSCy Schubert assert(k5_hashtab_get(ht, "abc", 3) == &st);
138*7f2fe78bSCy Schubert assert(k5_hashtab_get(ht, "bcde", 4) == NULL);
139*7f2fe78bSCy Schubert
140*7f2fe78bSCy Schubert st = k5_hashtab_add(ht, "bcde", 4, &ht);
141*7f2fe78bSCy Schubert assert(st == 0 && ht->nentries == 2);
142*7f2fe78bSCy Schubert assert(k5_hashtab_get(ht, "abc", 3) == &st);
143*7f2fe78bSCy Schubert assert(k5_hashtab_get(ht, "bcde", 4) == &ht);
144*7f2fe78bSCy Schubert
145*7f2fe78bSCy Schubert k5_hashtab_remove(ht, "abc", 3);
146*7f2fe78bSCy Schubert assert(ht->nentries == 1);
147*7f2fe78bSCy Schubert assert(k5_hashtab_get(ht, "abc", 3) == NULL);
148*7f2fe78bSCy Schubert assert(k5_hashtab_get(ht, "bcde", 4) == &ht);
149*7f2fe78bSCy Schubert
150*7f2fe78bSCy Schubert k5_hashtab_remove(ht, "bcde", 4);
151*7f2fe78bSCy Schubert assert(ht->nentries == 0);
152*7f2fe78bSCy Schubert assert(k5_hashtab_get(ht, "abc", 3) == NULL);
153*7f2fe78bSCy Schubert assert(k5_hashtab_get(ht, "bcde", 4) == NULL);
154*7f2fe78bSCy Schubert
155*7f2fe78bSCy Schubert for (i = 0; i < sizeof(zeros); i++) {
156*7f2fe78bSCy Schubert st = k5_hashtab_add(ht, zeros, i, zeros + i);
157*7f2fe78bSCy Schubert assert(st == 0 && ht->nentries == i + 1 && ht->nbuckets >= i + 1);
158*7f2fe78bSCy Schubert }
159*7f2fe78bSCy Schubert for (i = 0; i < sizeof(zeros); i++) {
160*7f2fe78bSCy Schubert assert(k5_hashtab_get(ht, zeros, i) == zeros + i);
161*7f2fe78bSCy Schubert k5_hashtab_remove(ht, zeros, i);
162*7f2fe78bSCy Schubert assert(ht->nentries == sizeof(zeros) - i - 1);
163*7f2fe78bSCy Schubert if (i > 0)
164*7f2fe78bSCy Schubert assert(k5_hashtab_get(ht, zeros, i - 1) == NULL);
165*7f2fe78bSCy Schubert }
166*7f2fe78bSCy Schubert
167*7f2fe78bSCy Schubert k5_hashtab_free(ht);
168*7f2fe78bSCy Schubert }
169*7f2fe78bSCy Schubert
170*7f2fe78bSCy Schubert int
main()171*7f2fe78bSCy Schubert main()
172*7f2fe78bSCy Schubert {
173*7f2fe78bSCy Schubert test_siphash();
174*7f2fe78bSCy Schubert test_hashtab();
175*7f2fe78bSCy Schubert return 0;
176*7f2fe78bSCy Schubert }
177