hash_ppc.c 1.43 KB
Newer Older
1
/*
schu committed
2
 * Copyright (C) 2009-2012 the libgit2 contributors
3
 *
Vicent Marti committed
4 5
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
6
 */
7

8 9 10
#include <stdio.h>
#include <string.h>

11 12 13 14
#include "common.h"
#include "hash.h"

extern void hash_ppc_core(uint32_t *hash, const unsigned char *p,
Vicent Marti committed
15
			 unsigned int nblocks);
16

17
int git_hash_init(git_hash_ctx *c)
18 19 20 21 22 23 24 25 26 27 28
{
	c->hash[0] = 0x67452301;
	c->hash[1] = 0xEFCDAB89;
	c->hash[2] = 0x98BADCFE;
	c->hash[3] = 0x10325476;
	c->hash[4] = 0xC3D2E1F0;
	c->len = 0;
	c->cnt = 0;
	return 0;
}

29
int git_hash_update(git_hash_ctx *c, const void *ptr, size_t n)
30 31 32 33 34 35 36 37 38 39 40 41
{
	unsigned long nb;
	const unsigned char *p = ptr;

	c->len += (uint64_t) n << 3;
	while (n != 0) {
		if (c->cnt || n < 64) {
			nb = 64 - c->cnt;
			if (nb > n)
				nb = n;
			memcpy(&c->buf.b[c->cnt], p, nb);
			if ((c->cnt += nb) == 64) {
42
				hash_ppc_core(c->hash, c->buf.b, 1);
43 44 45 46
				c->cnt = 0;
			}
		} else {
			nb = n >> 6;
47
			hash_ppc_core(c->hash, p, nb);
48 49 50 51 52 53 54 55
			nb <<= 6;
		}
		n -= nb;
		p += nb;
	}
	return 0;
}

56
int git_hash_final(git_oid *oid, git_hash_ctx *c)
57 58 59 60 61 62 63
{
	unsigned int cnt = c->cnt;

	c->buf.b[cnt++] = 0x80;
	if (cnt > 56) {
		if (cnt < 64)
			memset(&c->buf.b[cnt], 0, 64 - cnt);
64
		hash_ppc_core(c->hash, c->buf.b, 1);
65 66 67 68 69
		cnt = 0;
	}
	if (cnt < 56)
		memset(&c->buf.b[cnt], 0, 56 - cnt);
	c->buf.l[7] = c->len;
70 71
	hash_ppc_core(c->hash, c->buf.b, 1);
	memcpy(oid->id, c->hash, 20);
72 73
	return 0;
}
74