// this is a javascript implementation of RFC 2104 (HMAC) keyed message
// authentication code. it includes a copy of RFC 2045's Base64 encoding
// procedure. All code is copyright (C) 1999 vengeance software. written by
// graydon hoare <graydon@pobox.com>, released under the terms of the GNU GPL
// v2.0+

function HMAC(hashcomputer) {

    this.context = hashcomputer;

    function myToBase64(binarray) {
	var i,j;
	var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	var res = new String();
	for(i=0; i<binarray.length; i++) {	    
	    var triple = ((i > 0) ? ((binarray[i-1] << ( ( 3-(i%4) )*8) ) & 0x00FFFFFF) : 0x00) | 
		((binarray[i] >> (((i%4)+1)*8)) & 0x00FFFFFF);
	    for (j = 0; j < 4; j++) res += tab.charAt((triple >> ((3-j) * 6)) & 0x0000003F);
	}
	return res;
    }
    this.toBase64 = myToBase64;

    function myH(input) {
	this.context.clear();
	this.context.add(input);
	var hn = this.context.hash();
	return this.toBase64(hn);
    }
    this.h = myH;
    
    function myHmac(key,msg) {
	var ipad = 0x36;
	var opad = 0x5c;
	var B = 64;
	if (key.length > B) {
	    key = this.h(key);
	    key = key.slice(0,Math.min(key.length - 1,B));
	}
	while(key.length < B) key += String.fromCharCode(0x00);	
	var scratch = new String();
	for (i = 0; i < B; i++) scratch += String.fromCharCode(key.charCodeAt(i) ^ ipad);
	msg = this.h(scratch + msg);	
	scratch = new String();
	for (i = 0; i < B; i++) scratch += String.fromCharCode(key.charCodeAt(i) ^ opad);
	return this.h(scratch + msg);
    }
    this.hmac = myHmac;
}


