|
Packit Service |
3749ba |
/*
|
|
Packit Service |
3749ba |
* Copyright (C) 2004, 2005, 2007, 2011 Internet Systems Consortium, Inc. ("ISC")
|
|
Packit Service |
3749ba |
* Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
|
|
Packit Service |
3749ba |
*
|
|
Packit Service |
3749ba |
* Permission to use, copy, modify, and/or distribute this software for any
|
|
Packit Service |
3749ba |
* purpose with or without fee is hereby granted, provided that the above
|
|
Packit Service |
3749ba |
* copyright notice and this permission notice appear in all copies.
|
|
Packit Service |
3749ba |
*
|
|
Packit Service |
3749ba |
* THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
|
|
Packit Service |
3749ba |
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
Packit Service |
3749ba |
* AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
Packit Service |
3749ba |
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
Packit Service |
3749ba |
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
|
|
Packit Service |
3749ba |
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
Packit Service |
3749ba |
* PERFORMANCE OF THIS SOFTWARE.
|
|
Packit Service |
3749ba |
*/
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
/*! \file
|
|
Packit Service |
3749ba |
* SHA-1 in C
|
|
Packit Service |
3749ba |
* \author By Steve Reid <steve@edmweb.com>
|
|
Packit Service |
3749ba |
* 100% Public Domain
|
|
Packit Service |
3749ba |
* \verbatim
|
|
Packit Service |
3749ba |
* Test Vectors
|
|
Packit Service |
3749ba |
* "abc"
|
|
Packit Service |
3749ba |
* A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
|
|
Packit Service |
3749ba |
* "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
|
|
Packit Service |
3749ba |
* 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
|
|
Packit Service |
3749ba |
* A million repetitions of "a"
|
|
Packit Service |
3749ba |
* 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
|
|
Packit Service |
3749ba |
* \endverbatim
|
|
Packit Service |
3749ba |
*/
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
#include "config.h"
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
#include "hash.h"
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
#include <assert.h>
|
|
Packit Service |
3749ba |
#include <stdarg.h>
|
|
Packit Service |
3749ba |
#include <stdint.h>
|
|
Packit Service |
3749ba |
#include <string.h>
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
/* This code is based on the public domain MurmurHash3 from Austin Appleby:
|
|
Packit Service |
3749ba |
* http://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp
|
|
Packit Service |
3749ba |
*
|
|
Packit Service |
3749ba |
* We use only the 32 bit variant, and slow it down a bit to support unaligned
|
|
Packit Service |
3749ba |
* reads.
|
|
Packit Service |
3749ba |
*/
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
#if !defined(__cplusplus) && (__GNUC__ > 2)
|
|
Packit Service |
3749ba |
#define GNUC_INLINE __attribute__((always_inline))
|
|
Packit Service |
3749ba |
#else
|
|
Packit Service |
3749ba |
#define GNUC_INLINE
|
|
Packit Service |
3749ba |
#endif
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
GNUC_INLINE static inline uint32_t
|
|
Packit Service |
3749ba |
rotl (uint32_t x,
|
|
Packit Service |
3749ba |
int8_t r)
|
|
Packit Service |
3749ba |
{
|
|
Packit Service |
3749ba |
return (x << r) | (x >> (32 - r));
|
|
Packit Service |
3749ba |
}
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
/*
|
|
Packit Service |
3749ba |
* Finalization mix - force all bits of a hash block to avalanche
|
|
Packit Service |
3749ba |
*/
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
GNUC_INLINE static inline uint32_t
|
|
Packit Service |
3749ba |
fmix (uint32_t h)
|
|
Packit Service |
3749ba |
{
|
|
Packit Service |
3749ba |
h ^= h >> 16;
|
|
Packit Service |
3749ba |
h *= 0x85ebca6b;
|
|
Packit Service |
3749ba |
h ^= h >> 13;
|
|
Packit Service |
3749ba |
h *= 0xc2b2ae35;
|
|
Packit Service |
3749ba |
h ^= h >> 16;
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
return h;
|
|
Packit Service |
3749ba |
}
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
void
|
|
Packit Service |
3749ba |
p11_hash_murmur3 (void *hash,
|
|
Packit Service |
3749ba |
const void *input,
|
|
Packit Service |
3749ba |
size_t len,
|
|
Packit Service |
3749ba |
...)
|
|
Packit Service |
3749ba |
{
|
|
Packit Service |
3749ba |
uint8_t overflow[4];
|
|
Packit Service |
3749ba |
const uint8_t *data;
|
|
Packit Service |
3749ba |
va_list va;
|
|
Packit Service |
3749ba |
uint32_t h1;
|
|
Packit Service |
3749ba |
uint32_t k1;
|
|
Packit Service |
3749ba |
uint32_t c1;
|
|
Packit Service |
3749ba |
uint32_t c2;
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
h1 = 42; /* arbitrary choice of seed */
|
|
Packit Service |
3749ba |
c1 = 0xcc9e2d51;
|
|
Packit Service |
3749ba |
c2 = 0x1b873593;
|
|
Packit Service |
3749ba |
data = input;
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
/* body */
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
/* Mix 4 bytes at a time into the hash */
|
|
Packit Service |
3749ba |
va_start (va, len);
|
|
Packit Service |
3749ba |
for (;;) {
|
|
Packit Service |
3749ba |
if (len >= 4) {
|
|
Packit Service |
3749ba |
memcpy (&k1, data, 4);
|
|
Packit Service |
3749ba |
data += 4;
|
|
Packit Service |
3749ba |
len -= 4;
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
} else {
|
|
Packit Service |
3749ba |
size_t num = len;
|
|
Packit Service |
3749ba |
memcpy (overflow, data, len);
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
while (num < 4) {
|
|
Packit Service |
3749ba |
size_t part;
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
data = va_arg (va, const void *);
|
|
Packit Service |
3749ba |
if (!data)
|
|
Packit Service |
3749ba |
break;
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
/* Combine uint32 from old and new */
|
|
Packit Service |
3749ba |
len = va_arg (va, size_t);
|
|
Packit Service |
3749ba |
part = 4 - num;
|
|
Packit Service |
3749ba |
if (part > len)
|
|
Packit Service |
3749ba |
part = len;
|
|
Packit Service |
3749ba |
memcpy (overflow + num, data, part);
|
|
Packit Service |
3749ba |
data += part;
|
|
Packit Service |
3749ba |
len -= part;
|
|
Packit Service |
3749ba |
num += part;
|
|
Packit Service |
3749ba |
}
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
if (num < 4) {
|
|
Packit Service |
3749ba |
len = num;
|
|
Packit Service |
3749ba |
break;
|
|
Packit Service |
3749ba |
}
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
memcpy (&k1, overflow, 4);
|
|
Packit Service |
3749ba |
}
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
k1 *= c1;
|
|
Packit Service |
3749ba |
k1 = rotl (k1, 15);
|
|
Packit Service |
3749ba |
k1 *= c2;
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
h1 ^= k1;
|
|
Packit Service |
3749ba |
h1 = rotl (h1, 13);
|
|
Packit Service |
3749ba |
h1 = h1 * 5 + 0xe6546b64;
|
|
Packit Service |
3749ba |
}
|
|
Packit Service |
3749ba |
va_end (va);
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
/* tail */
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
k1 = 0;
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
switch (len) {
|
|
Packit Service |
3749ba |
case 3:
|
|
Packit Service |
3749ba |
k1 ^= overflow[2] << 16;
|
|
Packit Service |
3749ba |
case 2:
|
|
Packit Service |
3749ba |
k1 ^= overflow[1] << 8;
|
|
Packit Service |
3749ba |
case 1:
|
|
Packit Service |
3749ba |
k1 ^= overflow[0];
|
|
Packit Service |
3749ba |
k1 *= c1;
|
|
Packit Service |
3749ba |
k1 = rotl (k1, 15);
|
|
Packit Service |
3749ba |
k1 *= c2;
|
|
Packit Service |
3749ba |
h1 ^= k1;
|
|
Packit Service |
3749ba |
default:
|
|
Packit Service |
3749ba |
break;
|
|
Packit Service |
3749ba |
}
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
/* finalization */
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
h1 ^= len;
|
|
Packit Service |
3749ba |
h1 = fmix(h1);
|
|
Packit Service |
3749ba |
|
|
Packit Service |
3749ba |
assert (sizeof (h1) == P11_HASH_MURMUR3_LEN);
|
|
Packit Service |
3749ba |
memcpy (hash, &h1, sizeof (h1));
|
|
Packit Service |
3749ba |
}
|