93 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			93 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
'use strict';
 | 
						|
 | 
						|
var utils = require('./utils');
 | 
						|
var assert = require('minimalistic-assert');
 | 
						|
 | 
						|
function BlockHash() {
 | 
						|
  this.pending = null;
 | 
						|
  this.pendingTotal = 0;
 | 
						|
  this.blockSize = this.constructor.blockSize;
 | 
						|
  this.outSize = this.constructor.outSize;
 | 
						|
  this.hmacStrength = this.constructor.hmacStrength;
 | 
						|
  this.padLength = this.constructor.padLength / 8;
 | 
						|
  this.endian = 'big';
 | 
						|
 | 
						|
  this._delta8 = this.blockSize / 8;
 | 
						|
  this._delta32 = this.blockSize / 32;
 | 
						|
}
 | 
						|
exports.BlockHash = BlockHash;
 | 
						|
 | 
						|
BlockHash.prototype.update = function update(msg, enc) {
 | 
						|
  // Convert message to array, pad it, and join into 32bit blocks
 | 
						|
  msg = utils.toArray(msg, enc);
 | 
						|
  if (!this.pending)
 | 
						|
    this.pending = msg;
 | 
						|
  else
 | 
						|
    this.pending = this.pending.concat(msg);
 | 
						|
  this.pendingTotal += msg.length;
 | 
						|
 | 
						|
  // Enough data, try updating
 | 
						|
  if (this.pending.length >= this._delta8) {
 | 
						|
    msg = this.pending;
 | 
						|
 | 
						|
    // Process pending data in blocks
 | 
						|
    var r = msg.length % this._delta8;
 | 
						|
    this.pending = msg.slice(msg.length - r, msg.length);
 | 
						|
    if (this.pending.length === 0)
 | 
						|
      this.pending = null;
 | 
						|
 | 
						|
    msg = utils.join32(msg, 0, msg.length - r, this.endian);
 | 
						|
    for (var i = 0; i < msg.length; i += this._delta32)
 | 
						|
      this._update(msg, i, i + this._delta32);
 | 
						|
  }
 | 
						|
 | 
						|
  return this;
 | 
						|
};
 | 
						|
 | 
						|
BlockHash.prototype.digest = function digest(enc) {
 | 
						|
  this.update(this._pad());
 | 
						|
  assert(this.pending === null);
 | 
						|
 | 
						|
  return this._digest(enc);
 | 
						|
};
 | 
						|
 | 
						|
BlockHash.prototype._pad = function pad() {
 | 
						|
  var len = this.pendingTotal;
 | 
						|
  var bytes = this._delta8;
 | 
						|
  var k = bytes - ((len + this.padLength) % bytes);
 | 
						|
  var res = new Array(k + this.padLength);
 | 
						|
  res[0] = 0x80;
 | 
						|
  for (var i = 1; i < k; i++)
 | 
						|
    res[i] = 0;
 | 
						|
 | 
						|
  // Append length
 | 
						|
  len <<= 3;
 | 
						|
  if (this.endian === 'big') {
 | 
						|
    for (var t = 8; t < this.padLength; t++)
 | 
						|
      res[i++] = 0;
 | 
						|
 | 
						|
    res[i++] = 0;
 | 
						|
    res[i++] = 0;
 | 
						|
    res[i++] = 0;
 | 
						|
    res[i++] = 0;
 | 
						|
    res[i++] = (len >>> 24) & 0xff;
 | 
						|
    res[i++] = (len >>> 16) & 0xff;
 | 
						|
    res[i++] = (len >>> 8) & 0xff;
 | 
						|
    res[i++] = len & 0xff;
 | 
						|
  } else {
 | 
						|
    res[i++] = len & 0xff;
 | 
						|
    res[i++] = (len >>> 8) & 0xff;
 | 
						|
    res[i++] = (len >>> 16) & 0xff;
 | 
						|
    res[i++] = (len >>> 24) & 0xff;
 | 
						|
    res[i++] = 0;
 | 
						|
    res[i++] = 0;
 | 
						|
    res[i++] = 0;
 | 
						|
    res[i++] = 0;
 | 
						|
 | 
						|
    for (t = 8; t < this.padLength; t++)
 | 
						|
      res[i++] = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  return res;
 | 
						|
};
 |