// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// MD5 hash algorithm.  See RFC 1321.

package md5

import "os"

package const (
	Chunk = 64
)

const (
	A = 0x67452301;
	B = 0xEFCDAB89;
	C = 0x98BADCFE;
	D = 0x10325476;
)

export type Digest struct {
	s [4]uint32;
	x [Chunk]byte;
	nx int;
	len uint64;
}

export func NewDigest() *Digest {
	d := new(Digest);
	d.s[0] = A;
	d.s[1] = B;
	d.s[2] = C;
	d.s[3] = D;
	return d;
}

package func Block(dig *Digest, p *[]byte) int

func (d *Digest) Write(p *[]byte) (nn int, err *os.Error) {
	nn = len(p);
	d.len += uint64(nn);
	if d.nx > 0 {
		n := len(p);
		if n > Chunk-d.nx {
			n = Chunk-d.nx;
		}
		for i := 0; i < n; i++ {
			d.x[d.nx+i] = p[i];
		}
		d.nx += n;
		if d.nx == Chunk {
			Block(d, &d.x);
			d.nx = 0;
		}
		p = p[n:len(p)];
	}
	n := Block(d, p);
	p = p[n:len(p)];
	if len(p) > 0 {
		for i := 0; i < len(p); i++ {
			d.x[i] = p[i];
		}
		d.nx = len(p);
	}
	return;
}

func (d *Digest) Sum() *[]byte {
	// Padding.  Add a 1 bit and 0 bits until 56 bytes mod 64.
	len := d.len;
	var tmp [64]byte;
	tmp[0] = 0x80;
	if len%64 < 56 {
		d.Write((&tmp)[0:56-len%64]);
	} else {
		d.Write((&tmp)[0:64+56-len%64]);
	}

	// Length in bits.
	len <<= 3;
	for i := uint(0); i < 8; i++ {
		tmp[i] = byte(len>>(8*i));
	}
	d.Write((&tmp)[0:8]);

	if d.nx != 0 {
		panicln("oops");
	}

	p := new([]byte, 16);
	j := 0;
	for i := 0; i < 4; i++ {
		s := d.s[i];
		p[j] = byte(s); j++;
		p[j] = byte(s>>8); j++;
		p[j] = byte(s>>16); j++;
		p[j] = byte(s>>24); j++;
	}
	return p;
}

