aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_hash.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/crypto_hash.c')
-rw-r--r--src/util/crypto_hash.c143
1 files changed, 100 insertions, 43 deletions
diff --git a/src/util/crypto_hash.c b/src/util/crypto_hash.c
index d62ec8012..b51ecd242 100644
--- a/src/util/crypto_hash.c
+++ b/src/util/crypto_hash.c
@@ -135,18 +135,57 @@ GNUNET_CRYPTO_hash_xor (const struct GNUNET_HashCode *a,
135 const struct GNUNET_HashCode *b, 135 const struct GNUNET_HashCode *b,
136 struct GNUNET_HashCode *result) 136 struct GNUNET_HashCode *result)
137{ 137{
138 for (ssize_t i = (sizeof(struct GNUNET_HashCode) / sizeof(unsigned int)) - 1; 138 const unsigned long long *lla = (const unsigned long long *) a;
139 i >= 0; 139 const unsigned long long *llb = (const unsigned long long *) b;
140 i--) 140 unsigned long long *llr = (unsigned long long *) result;
141 result->bits[i] = a->bits[i] ^ b->bits[i]; 141
142 GNUNET_static_assert (8 == sizeof (unsigned long long));
143 GNUNET_static_assert (0 == sizeof (*a) % sizeof (unsigned long long));
144 for (int i = sizeof (*result) / sizeof (*llr) - 1; i>=0; i--)
145 llr[i] = lla[i] ^ llb[i];
146}
147
148
149uint64_t
150GNUNET_CRYPTO_hash_bucket_distance (const struct GNUNET_HashCode *xor,
151 unsigned int bucket)
152{
153 const uint64_t *u = (const uint64_t *) xor;
154 unsigned int idx;
155 unsigned int bits;
156 uint64_t rval;
157
158 if (bucket == 8 * sizeof(*xor))
159 return 0;
160 bucket++;
161 idx = bucket / 64;
162 bits = bucket % 64;
163 if (idx >= sizeof (*xor) / sizeof (*u))
164 return 0;
165 if (0 == bits)
166 {
167 /* keeps no bits */
168 rval = 0;
169 }
170 else
171 {
172 /* keeps lowest (64-bits) bits */
173 rval = GNUNET_ntohll (u[idx]) << bits;
174 }
175 if (idx + 1 < sizeof (*xor) / sizeof (*u))
176 {
177 /* discards lowest (bits) bits */
178 rval |= GNUNET_ntohll (u[idx + 1]) >> (64 - bits);
179 }
180 return rval;
142} 181}
143 182
144 183
145void 184void
146GNUNET_CRYPTO_hash_to_aes_key (const struct GNUNET_HashCode *hc, 185GNUNET_CRYPTO_hash_to_aes_key (
147 struct GNUNET_CRYPTO_SymmetricSessionKey *skey, 186 const struct GNUNET_HashCode *hc,
148 struct 187 struct GNUNET_CRYPTO_SymmetricSessionKey *skey,
149 GNUNET_CRYPTO_SymmetricInitializationVector *iv) 188 struct GNUNET_CRYPTO_SymmetricInitializationVector *iv)
150{ 189{
151 GNUNET_assert (GNUNET_YES == 190 GNUNET_assert (GNUNET_YES ==
152 GNUNET_CRYPTO_kdf ( 191 GNUNET_CRYPTO_kdf (
@@ -167,33 +206,47 @@ GNUNET_CRYPTO_hash_to_aes_key (const struct GNUNET_HashCode *hc,
167} 206}
168 207
169 208
170int 209unsigned int
171GNUNET_CRYPTO_hash_get_bit_ltr (const struct GNUNET_HashCode *code, 210GNUNET_CRYPTO_hash_count_leading_zeros (const struct GNUNET_HashCode *h)
172 unsigned int bit)
173{ 211{
174 GNUNET_assert (bit < 8 * sizeof(struct GNUNET_HashCode)); 212 const unsigned long long *llp = (const unsigned long long *) h;
175 return (((unsigned char *) code)[bit >> 3] & (128 >> (bit & 7))) > 0; 213 unsigned int ret = 0;
176} 214 unsigned int i;
177
178 215
179int 216 GNUNET_static_assert (8 == sizeof (unsigned long long));
180GNUNET_CRYPTO_hash_get_bit_rtl (const struct GNUNET_HashCode *code, 217 GNUNET_static_assert (0 == sizeof (*h) % sizeof (unsigned long long));
181 unsigned int bit) 218 for (i = 0; i<sizeof (*h) / sizeof (*llp); i++)
182{ 219 {
183 GNUNET_assert (bit < 8 * sizeof(struct GNUNET_HashCode)); 220 if (0LLU != llp[i])
184 return (((unsigned char *) code)[bit >> 3] & (1 << (bit & 7))) > 0; 221 break;
222 ret += sizeof (*llp) * 8;
223 }
224 if (ret == 8 * sizeof (*h))
225 return ret;
226 ret += __builtin_clzll (GNUNET_ntohll ((uint64_t) llp[i]));
227 return ret;
185} 228}
186 229
187 230
188unsigned int 231unsigned int
189GNUNET_CRYPTO_hash_matching_bits (const struct GNUNET_HashCode *first, 232GNUNET_CRYPTO_hash_count_tailing_zeros (const struct GNUNET_HashCode *h)
190 const struct GNUNET_HashCode *second)
191{ 233{
192 for (unsigned int i = 0; i < sizeof(struct GNUNET_HashCode) * 8; i++) 234 const unsigned long long *llp = (const unsigned long long *) h;
193 if (GNUNET_CRYPTO_hash_get_bit_rtl (first, i) != 235 unsigned int ret = 0;
194 GNUNET_CRYPTO_hash_get_bit_rtl (second, i)) 236 int i;
195 return i; 237
196 return sizeof(struct GNUNET_HashCode) * 8; 238 GNUNET_static_assert (8 == sizeof (unsigned long long));
239 GNUNET_static_assert (0 == sizeof (*h) % sizeof (unsigned long long));
240 for (i = sizeof (*h) / sizeof (*llp) - 1; i>=0; i--)
241 {
242 if (0LLU != llp[i])
243 break;
244 ret += sizeof (*llp) * 8;
245 }
246 if (ret == 8 * sizeof (*h))
247 return ret;
248 ret += __builtin_ctzll (GNUNET_ntohll ((uint64_t) llp[i]));
249 return ret;
197} 250}
198 251
199 252
@@ -243,25 +296,30 @@ GNUNET_CRYPTO_hash_xorcmp (const struct GNUNET_HashCode *h1,
243 296
244 297
245void 298void
246GNUNET_CRYPTO_hmac_derive_key (struct GNUNET_CRYPTO_AuthKey *key, 299GNUNET_CRYPTO_hmac_derive_key (
247 const struct 300 struct GNUNET_CRYPTO_AuthKey *key,
248 GNUNET_CRYPTO_SymmetricSessionKey *rkey, 301 const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey,
249 const void *salt, size_t salt_len, ...) 302 const void *salt, size_t salt_len,
303 ...)
250{ 304{
251 va_list argp; 305 va_list argp;
252 306
253 va_start (argp, salt_len); 307 va_start (argp,
254 GNUNET_CRYPTO_hmac_derive_key_v (key, rkey, salt, salt_len, argp); 308 salt_len);
309 GNUNET_CRYPTO_hmac_derive_key_v (key,
310 rkey,
311 salt, salt_len,
312 argp);
255 va_end (argp); 313 va_end (argp);
256} 314}
257 315
258 316
259void 317void
260GNUNET_CRYPTO_hmac_derive_key_v (struct GNUNET_CRYPTO_AuthKey *key, 318GNUNET_CRYPTO_hmac_derive_key_v (
261 const struct 319 struct GNUNET_CRYPTO_AuthKey *key,
262 GNUNET_CRYPTO_SymmetricSessionKey *rkey, 320 const struct GNUNET_CRYPTO_SymmetricSessionKey *rkey,
263 const void *salt, size_t salt_len, 321 const void *salt, size_t salt_len,
264 va_list argp) 322 va_list argp)
265{ 323{
266 GNUNET_CRYPTO_kdf_v (key->key, sizeof(key->key), 324 GNUNET_CRYPTO_kdf_v (key->key, sizeof(key->key),
267 salt, salt_len, 325 salt, salt_len,
@@ -283,7 +341,9 @@ GNUNET_CRYPTO_hmac_raw (const void *key, size_t key_len,
283 { 341 {
284 once = 1; 342 once = 1;
285 GNUNET_assert (GPG_ERR_NO_ERROR == 343 GNUNET_assert (GPG_ERR_NO_ERROR ==
286 gcry_md_open (&md, GCRY_MD_SHA512, GCRY_MD_FLAG_HMAC)); 344 gcry_md_open (&md,
345 GCRY_MD_SHA512,
346 GCRY_MD_FLAG_HMAC));
287 } 347 }
288 else 348 else
289 { 349 {
@@ -323,15 +383,12 @@ GNUNET_CRYPTO_hash_context_start ()
323 struct GNUNET_HashContext *hc; 383 struct GNUNET_HashContext *hc;
324 384
325 BENCHMARK_START (hash_context_start); 385 BENCHMARK_START (hash_context_start);
326
327 hc = GNUNET_new (struct GNUNET_HashContext); 386 hc = GNUNET_new (struct GNUNET_HashContext);
328 GNUNET_assert (0 == 387 GNUNET_assert (0 ==
329 gcry_md_open (&hc->hd, 388 gcry_md_open (&hc->hd,
330 GCRY_MD_SHA512, 389 GCRY_MD_SHA512,
331 0)); 390 0));
332
333 BENCHMARK_END (hash_context_start); 391 BENCHMARK_END (hash_context_start);
334
335 return hc; 392 return hc;
336} 393}
337 394