1/*	$NetBSD: hash.c,v 1.1.1.3 2010/12/12 15:22:08 adam Exp $	*/
2
3/* OpenLDAP: pkg/ldap/libraries/liblutil/hash.c,v 1.8.2.5 2010/04/13 20:23:06 kurt Exp */
4/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 *
6 * Copyright 2000-2010 The OpenLDAP Foundation.
7 * Portions Copyright 2000-2003 Kurt D. Zeilenga.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted only as authorized by the OpenLDAP
12 * Public License.
13 *
14 * A copy of this license is available in the file LICENSE in the
15 * top-level directory of the distribution or, alternatively, at
16 * <http://www.OpenLDAP.org/license.html>.
17 */
18
19/* This implements the Fowler / Noll / Vo (FNV-1) hash algorithm.
20 * A summary of the algorithm can be found at:
21 *   http://www.isthe.com/chongo/tech/comp/fnv/index.html
22 */
23
24#include "portable.h"
25
26#include <lutil_hash.h>
27
28/* offset and prime for 32-bit FNV-1 */
29#define HASH_OFFSET	0x811c9dc5U
30#define HASH_PRIME	16777619
31
32
33/*
34 * Initialize context
35 */
36void
37lutil_HASHInit( struct lutil_HASHContext *ctx )
38{
39	ctx->hash = HASH_OFFSET;
40}
41
42/*
43 * Update hash
44 */
45void
46lutil_HASHUpdate(
47    struct lutil_HASHContext	*ctx,
48    const unsigned char		*buf,
49    ber_len_t		len )
50{
51	const unsigned char *p, *e;
52	ber_uint_t h;
53
54	p = buf;
55	e = &buf[len];
56
57	h = ctx->hash;
58
59	while( p < e ) {
60		h *= HASH_PRIME;
61		h ^= *p++;
62	}
63
64	ctx->hash = h;
65}
66
67/*
68 * Save hash
69 */
70void
71lutil_HASHFinal( unsigned char *digest, struct lutil_HASHContext *ctx )
72{
73	ber_uint_t h = ctx->hash;
74
75	digest[0] = h & 0xffU;
76	digest[1] = (h>>8) & 0xffU;
77	digest[2] = (h>>16) & 0xffU;
78	digest[3] = (h>>24) & 0xffU;
79}
80