[Pkg-javascript-commits] [node-hash.js] 04/29: hash: add ripemd160

Bastien Roucariès rouca at moszumanska.debian.org
Thu Apr 20 19:30:36 UTC 2017


This is an automated email from the git hooks/post-receive script.

rouca pushed a commit to branch master
in repository node-hash.js.

commit 87a71ed590df413f4a2f7f6675029ca1429762a0
Author: Fedor Indutny <fedor at indutny.com>
Date:   Sat Apr 26 15:55:05 2014 +0400

    hash: add ripemd160
---
 lib/hash.js        |  10 ++-
 lib/hash/common.js |  81 +++++++++++++++++++
 lib/hash/hash.js   | 222 -----------------------------------------------------
 lib/hash/ripemd.js | 145 ++++++++++++++++++++++++++++++++++
 lib/hash/sha.js    | 140 +++++++++++++++++++++++++++++++++
 lib/hash/utils.js  |  84 +++++++++++++++++---
 test/hash-test.js  |  32 ++++++++
 7 files changed, 477 insertions(+), 237 deletions(-)

diff --git a/lib/hash.js b/lib/hash.js
index b2479f8..c6a62da 100644
--- a/lib/hash.js
+++ b/lib/hash.js
@@ -1,10 +1,12 @@
 var hash = exports;
 
 hash.utils = require('./hash/utils');
-hash.hash = require('./hash/hash');
+hash.common = require('./hash/common');
+hash.sha = require('./hash/sha');
+hash.ripemd = require('./hash/ripemd');
 hash.hmac = require('./hash/hmac');
 
 // Proxy hash functions to the main object
-Object.keys(hash.hash).forEach(function(name) {
-  hash[name] = hash.hash[name];
-});
+hash.sha256 = hash.sha.sha256;
+hash.sha224 = hash.sha.sha224;
+hash.ripemd160 = hash.ripemd.ripemd160;
diff --git a/lib/hash/common.js b/lib/hash/common.js
new file mode 100644
index 0000000..a186377
--- /dev/null
+++ b/lib/hash/common.js
@@ -0,0 +1,81 @@
+var assert = require('assert');
+var hash = require('../hash');
+var utils = hash.utils;
+
+function BlockHash() {
+  this.pending = null;
+  this.pendingTotal = 0;
+  this.blockSize = this.constructor.blockSize;
+  this.outSize = this.constructor.outSize;
+  this.hmacStrength = this.constructor.hmacStrength;
+  this.endian = 'big';
+}
+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.blockSize / 8) {
+    msg = this.pending;
+
+    // Process pending data in blocks
+    var r = msg.length % (this.blockSize / 8);
+    this.pending = msg.slice(msg.length - r, msg.length);
+    if (this.pending.length === 0)
+      this.pending = null;
+
+    msg = utils.join32(msg.slice(0, msg.length - r), this.endian);
+    for (var i = 0; i < msg.length; i += this.blockSize / 32)
+      this._update(msg.slice(i, i + this.blockSize / 32));
+  }
+
+  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.blockSize / 8;
+  var k = bytes - ((len + 8) % bytes);
+  var res = new Array(k + 8);
+  res[0] = 0x80;
+  for (var i = 1; i < k; i++)
+    res[i] = 0;
+
+  // Append length
+  len <<= 3;
+  if (this.endian === 'big') {
+    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;
+  }
+
+  return res;
+}
diff --git a/lib/hash/hash.js b/lib/hash/hash.js
deleted file mode 100644
index e616f88..0000000
--- a/lib/hash/hash.js
+++ /dev/null
@@ -1,222 +0,0 @@
-var assert = require('assert');
-var util = require('util');
-var hash = require('../hash');
-var utils = hash.utils;
-
-var sha256_K = [
-  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
-  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
-  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
-  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
-  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
-  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
-  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
-  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
-  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
-  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
-  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
-  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
-  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
-  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
-  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
-  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-];
-
-function SHA256() {
-  if (!(this instanceof SHA256))
-    return new SHA256();
-
-  this.h = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
-             0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ];
-  this.k = sha256_K;
-  this.pending = null;
-  this.pendingTotal = 0;
-
-  this.blockSize = this.constructor.blockSize;
-  this.outSize = this.constructor.outSize;
-  this.hmacStrength = this.constructor.hmacStrength;
-}
-exports.sha256 = SHA256;
-
-SHA256.blockSize = 512;
-SHA256.outSize = 256;
-SHA256.hmacStrength = 192;
-
-SHA256.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;
-
-  // Try updating
-  this._update();
-
-  return this;
-};
-
-SHA256.prototype._update = function _update() {
-  var msg = this.pending;
-  if (msg.length < this.blockSize / 8)
-    return;
-
-  // Process pending data in blocks
-  var r = msg.length % (this.blockSize / 8);
-  this.pending = msg.slice(msg.length - r, msg.length);
-  if (this.pending.length === 0)
-    this.pending = null;
-
-  msg = utils.join32(msg.slice(0, msg.length - r));
-  assert.equal(msg.length % 16, 0);
-
-  var W = new Array(64);
-  for (var off = 0; off < msg.length; off += 16) {
-    for (var i = 0; i < 16; i++)
-      W[i] = msg[i + off];
-    for (; i < W.length; i++)
-      W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);
-
-    var a = this.h[0];
-    var b = this.h[1];
-    var c = this.h[2];
-    var d = this.h[3];
-    var e = this.h[4];
-    var f = this.h[5];
-    var g = this.h[6];
-    var h = this.h[7];
-
-    assert.equal(this.k.length, W.length);
-    for (var i = 0; i < W.length; i++) {
-      var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);
-      var T2 = sum32(s0_256(a), maj32(a, b, c));
-      h = g;
-      g = f;
-      f = e;
-      e = sum32(d, T1);
-      d = c;
-      c = b;
-      b = a;
-      a = sum32(T1, T2);
-    }
-
-    this.h[0] = sum32(this.h[0], a);
-    this.h[1] = sum32(this.h[1], b);
-    this.h[2] = sum32(this.h[2], c);
-    this.h[3] = sum32(this.h[3], d);
-    this.h[4] = sum32(this.h[4], e);
-    this.h[5] = sum32(this.h[5], f);
-    this.h[6] = sum32(this.h[6], g);
-    this.h[7] = sum32(this.h[7], h);
-  }
-};
-
-SHA256.prototype.digest = function digest(enc) {
-  if (this.pending !== null)
-    this.update(pad(this.pendingTotal, this.blockSize / 8));
-  assert(this.pending === null);
-
-  return this._digest(enc);
-};
-
-SHA256.prototype._digest = function digest(enc) {
-  if (enc === 'hex')
-    return utils.toHex32(this.h);
-  else
-    return utils.split32(this.h);
-};
-
-function SHA224() {
-  if (!(this instanceof SHA224))
-    return new SHA224();
-
-  SHA256.call(this);
-  this.h = [ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
-             0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];
-}
-util.inherits(SHA224, SHA256);
-exports.sha224 = SHA224;
-
-SHA224.blockSize = 512;
-SHA224.outSize = 224;
-SHA224.hmacStrength = 192;
-
-SHA224.prototype._digest = function digest(enc) {
-  // Just truncate output
-  if (enc === 'hex')
-    return utils.toHex32(this.h.slice(0, 7));
-  else
-    return utils.split32(this.h.slice(0, 7));
-};
-
-function pad(len, bytes) {
-  var k = bytes - ((len + 8) % bytes);
-  var res = new Array(k + 8);
-  res[0] = 0x80;
-  for (var i = 1; i < k + 4; i++)
-    res[i] = 0;
-
-  // Append big-endian length
-  len <<= 3;
-  res[i++] = (len >>> 24) & 0xff;
-  res[i++] = (len >>> 16) & 0xff;
-  res[i++] = (len >>> 8) & 0xff;
-  res[i++] = len & 0xff;
-
-  return res;
-}
-
-
-function rotr32(w, b) {
-  return (w >>> b) | (w << (32 - b));
-}
-
-function rotl32(w, b) {
-  return (w << b) | (w >>> (32 - b));
-}
-
-function sum32(a, b) {
-  var r = (a + b) & 0xffffffff;
-  if (r < 0)
-    r += 0x100000000;
-  return r;
-}
-
-function sum32_4(a, b, c, d) {
-  var r = (a + b + c + d) & 0xffffffff;
-  if (r < 0)
-    r += 0x100000000;
-  return r;
-}
-
-function sum32_5(a, b, c, d, e) {
-  var r = (a + b + c + d + e) & 0xffffffff;
-  if (r < 0)
-    r += 0x100000000;
-  return r;
-}
-
-function ch32(x, y, z) {
-  return (x & y) ^ ((~x) & z);
-}
-
-function maj32(x, y, z) {
-  return (x & y) ^ (x & z) ^ (y & z);
-}
-
-function s0_256(x) {
-  return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);
-}
-
-function s1_256(x) {
-  return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);
-}
-
-function g0_256(x) {
-  return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);
-}
-
-function g1_256(x) {
-  return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);
-}
diff --git a/lib/hash/ripemd.js b/lib/hash/ripemd.js
new file mode 100644
index 0000000..9f37f5b
--- /dev/null
+++ b/lib/hash/ripemd.js
@@ -0,0 +1,145 @@
+var assert = require('assert');
+var util = require('util');
+var hash = require('../hash');
+var utils = hash.utils;
+
+var rotl32 = utils.rotl32;
+var sum32 = utils.sum32;
+var sum32_3 = utils.sum32_3;
+var sum32_4 = utils.sum32_4;
+var BlockHash = hash.common.BlockHash;
+
+function RIPEMD160() {
+  if (!(this instanceof RIPEMD160))
+    return new RIPEMD160();
+
+  BlockHash.call(this);
+
+  this.h = [ 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476, 0xc3d2e1f0 ];
+  this.endian = 'little';
+}
+util.inherits(RIPEMD160, BlockHash);
+exports.ripemd160 = RIPEMD160;
+
+RIPEMD160.blockSize = 512;
+RIPEMD160.outSize = 160;
+RIPEMD160.hmacStrength = 192;
+
+RIPEMD160.prototype._update = function update(msg) {
+  var A = this.h[0];
+  var B = this.h[1];
+  var C = this.h[2];
+  var D = this.h[3];
+  var E = this.h[4];
+  var Ah = A;
+  var Bh = B;
+  var Ch = C;
+  var Dh = D;
+  var Eh = E;
+  for (var j = 0; j < 80; j++) {
+    var T = sum32(
+      rotl32(
+        sum32_4(A, f(j, B, C, D), msg[r[j]], K(j)),
+        s[j]),
+      E);
+    A = E;
+    E = D;
+    D = rotl32(C, 10);
+    C = B;
+    B = T;
+    T = sum32(
+      rotl32(
+        sum32_4(Ah, f(79 - j, Bh, Ch, Dh), msg[rh[j]], Kh(j)),
+        sh[j]),
+      Eh);
+    Ah = Eh;
+    Eh = Dh;
+    Dh = rotl32(Ch, 10);
+    Ch = Bh;
+    Bh = T;
+  }
+  T = sum32_3(this.h[1], C, Dh);
+  this.h[1] = sum32_3(this.h[2], D, Eh);
+  this.h[2] = sum32_3(this.h[3], E, Ah);
+  this.h[3] = sum32_3(this.h[4], A, Bh);
+  this.h[4] = sum32_3(this.h[0], B, Ch);
+  this.h[0] = T;
+};
+
+RIPEMD160.prototype._digest = function digest(enc) {
+  if (enc === 'hex')
+    return utils.toHex32(this.h, 'little');
+  else
+    return utils.split32(this.h, 'little');
+};
+
+function f(j, x, y, z) {
+  if (j <= 15)
+    return x ^ y ^ z;
+  else if (j <= 31)
+    return (x & y) | ((~x) & z);
+  else if (j <= 47)
+    return (x | (~y)) ^ z;
+  else if (j <= 63)
+    return (x & z) | (y & (~z));
+  else
+    return x ^ (y | (~z));
+}
+
+function K(j) {
+  if (j <= 15)
+    return 0x00000000;
+  else if (j <= 31)
+    return 0x5a827999;
+  else if (j <= 47)
+    return 0x6ed9eba1;
+  else if (j <= 63)
+    return 0x8f1bbcdc;
+  else
+    return 0xa953fd4e;
+}
+
+function Kh(j) {
+  if (j <= 15)
+    return 0x50a28be6;
+  else if (j <= 31)
+    return 0x5c4dd124;
+  else if (j <= 47)
+    return 0x6d703ef3;
+  else if (j <= 63)
+    return 0x7a6d76e9;
+  else
+    return 0x00000000;
+}
+
+var r = [
+  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+  7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8,
+  3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12,
+  1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2,
+  4, 0, 5, 9, 7, 12, 2, 10, 14, 1, 3, 8, 11, 6, 15, 13,
+];
+
+var rh = [
+  5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12,
+  6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2,
+  15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13,
+  8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14,
+  12, 15, 10, 4, 1, 5, 8, 7, 6, 2, 13, 14, 0, 3, 9, 11
+];
+
+var s = [
+  11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8,
+  7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12,
+  11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5,
+  11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12,
+  9, 15, 5, 11, 6, 8, 13, 12, 5, 12, 13, 14, 11, 8, 5, 6,
+];
+
+var sh = [
+  8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6,
+  9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11,
+  9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5,
+  15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8,
+  8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11
+];
diff --git a/lib/hash/sha.js b/lib/hash/sha.js
new file mode 100644
index 0000000..80fe84e
--- /dev/null
+++ b/lib/hash/sha.js
@@ -0,0 +1,140 @@
+var assert = require('assert');
+var util = require('util');
+var hash = require('../hash');
+var utils = hash.utils;
+
+var rotr32 = utils.rotr32;
+var rotl32 = utils.rotl32;
+var sum32 = utils.sum32;
+var sum32_4 = utils.sum32_4;
+var sum32_5 = utils.sum32_5;
+var BlockHash = hash.common.BlockHash;
+
+var sha256_K = [
+  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
+  0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
+  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
+  0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+  0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
+  0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
+  0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
+  0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
+  0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+  0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
+  0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
+  0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
+  0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
+  0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+  0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+];
+
+function SHA256() {
+  if (!(this instanceof SHA256))
+    return new SHA256();
+
+  BlockHash.call(this);
+  this.h = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
+             0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19 ];
+  this.k = sha256_K;
+}
+util.inherits(SHA256, BlockHash);
+exports.sha256 = SHA256;
+
+SHA256.blockSize = 512;
+SHA256.outSize = 256;
+SHA256.hmacStrength = 192;
+
+SHA256.prototype._update = function _update(msg) {
+  var W = new Array(64);
+  for (var i = 0; i < 16; i++)
+    W[i] = msg[i];
+  for (; i < W.length; i++)
+    W[i] = sum32_4(g1_256(W[i - 2]), W[i - 7], g0_256(W[i - 15]), W[i - 16]);
+
+  var a = this.h[0];
+  var b = this.h[1];
+  var c = this.h[2];
+  var d = this.h[3];
+  var e = this.h[4];
+  var f = this.h[5];
+  var g = this.h[6];
+  var h = this.h[7];
+
+  assert.equal(this.k.length, W.length);
+  for (var i = 0; i < W.length; i++) {
+    var T1 = sum32_5(h, s1_256(e), ch32(e, f, g), this.k[i], W[i]);
+    var T2 = sum32(s0_256(a), maj32(a, b, c));
+    h = g;
+    g = f;
+    f = e;
+    e = sum32(d, T1);
+    d = c;
+    c = b;
+    b = a;
+    a = sum32(T1, T2);
+  }
+
+  this.h[0] = sum32(this.h[0], a);
+  this.h[1] = sum32(this.h[1], b);
+  this.h[2] = sum32(this.h[2], c);
+  this.h[3] = sum32(this.h[3], d);
+  this.h[4] = sum32(this.h[4], e);
+  this.h[5] = sum32(this.h[5], f);
+  this.h[6] = sum32(this.h[6], g);
+  this.h[7] = sum32(this.h[7], h);
+};
+
+SHA256.prototype._digest = function digest(enc) {
+  if (enc === 'hex')
+    return utils.toHex32(this.h, 'big');
+  else
+    return utils.split32(this.h, 'big');
+};
+
+function SHA224() {
+  if (!(this instanceof SHA224))
+    return new SHA224();
+
+  SHA256.call(this);
+  this.h = [ 0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
+             0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4 ];
+}
+util.inherits(SHA224, SHA256);
+exports.sha224 = SHA224;
+
+SHA224.blockSize = 512;
+SHA224.outSize = 224;
+SHA224.hmacStrength = 192;
+
+SHA224.prototype._digest = function digest(enc) {
+  // Just truncate output
+  if (enc === 'hex')
+    return utils.toHex32(this.h.slice(0, 7), 'big');
+  else
+    return utils.split32(this.h.slice(0, 7), 'big');
+};
+
+function ch32(x, y, z) {
+  return (x & y) ^ ((~x) & z);
+}
+
+function maj32(x, y, z) {
+  return (x & y) ^ (x & z) ^ (y & z);
+}
+
+function s0_256(x) {
+  return rotr32(x, 2) ^ rotr32(x, 13) ^ rotr32(x, 22);
+}
+
+function s1_256(x) {
+  return rotr32(x, 6) ^ rotr32(x, 11) ^ rotr32(x, 25);
+}
+
+function g0_256(x) {
+  return rotr32(x, 7) ^ rotr32(x, 18) ^ (x >>> 3);
+}
+
+function g1_256(x) {
+  return rotr32(x, 17) ^ rotr32(x, 19) ^ (x >>> 10);
+}
diff --git a/lib/hash/utils.js b/lib/hash/utils.js
index bcf49f9..b2797c8 100644
--- a/lib/hash/utils.js
+++ b/lib/hash/utils.js
@@ -42,10 +42,20 @@ function toHex(msg) {
 }
 utils.toHex = toHex;
 
-function toHex32(msg) {
+function toHex32(msg, endian) {
   var res = '';
-  for (var i = 0; i < msg.length; i++)
-    res += zero8(msg[i].toString(16));
+  for (var i = 0; i < msg.length; i++) {
+    var w = msg[i];
+    if (endian === 'little') {
+      w = (w >>> 24) |
+          ((w >>> 8) & 0xff00) |
+          ((w << 8) & 0xff0000) |
+          ((w & 0xff) << 24);
+      if (w < 0)
+        w += 0x100000000;
+    }
+    res += zero8(w.toString(16));
+  }
   return res;
 }
 utils.toHex32 = toHex32;
@@ -78,12 +88,15 @@ function zero8(word) {
 }
 utils.zero8 = zero8;
 
-function join32(msg) {
+function join32(msg, endian) {
   assert.equal(msg.length % 4, 0);
   var res = new Array(msg.length / 4);
   for (var i = 0, k = 0; i < res.length; i++, k += 4) {
-    var w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) |
-            msg[k + 3];
+    var w;
+    if (endian === 'big')
+      w = (msg[k] << 24) | (msg[k + 1] << 16) | (msg[k + 2] << 8) | msg[k + 3];
+    else
+      w = (msg[k + 3] << 24) | (msg[k + 2] << 16) | (msg[k + 1] << 8) | msg[k];
     if (w < 0)
       w += 0x100000000;
     res[i] = w;
@@ -92,15 +105,64 @@ function join32(msg) {
 }
 utils.join32 = join32;
 
-function split32(msg) {
+function split32(msg, endian) {
   var res = new Array(msg.length * 4);
   for (var i = 0, k = 0; i < msg.length; i++, k += 4) {
     var m = msg[i];
-    res[k] = m >>> 24;
-    res[k + 1] = (m >>> 16) & 0xff;
-    res[k + 2] = (m >>> 8) & 0xff;
-    res[k + 3] = m & 0xff;
+    if (endian === 'big') {
+      res[k] = m >>> 24;
+      res[k + 1] = (m >>> 16) & 0xff;
+      res[k + 2] = (m >>> 8) & 0xff;
+      res[k + 3] = m & 0xff;
+    } else {
+      res[k + 3] = m >>> 24;
+      res[k + 2] = (m >>> 16) & 0xff;
+      res[k + 1] = (m >>> 8) & 0xff;
+      res[k] = m & 0xff;
+    }
   }
   return res;
 }
 utils.split32 = split32;
+
+function rotr32(w, b) {
+  return (w >>> b) | (w << (32 - b));
+}
+utils.rotr32 = rotr32;
+
+function rotl32(w, b) {
+  return (w << b) | (w >>> (32 - b));
+}
+utils.rotl32 = rotl32;
+
+function sum32(a, b) {
+  var r = (a + b) & 0xffffffff;
+  if (r < 0)
+    r += 0x100000000;
+  return r;
+}
+utils.sum32 = sum32;
+
+function sum32_3(a, b, c) {
+  var r = (a + b + c) & 0xffffffff;
+  if (r < 0)
+    r += 0x100000000;
+  return r;
+}
+utils.sum32_3 = sum32_3;
+
+function sum32_4(a, b, c, d) {
+  var r = (a + b + c + d) & 0xffffffff;
+  if (r < 0)
+    r += 0x100000000;
+  return r;
+}
+utils.sum32_4 = sum32_4;
+
+function sum32_5(a, b, c, d, e) {
+  var r = (a + b + c + d + e) & 0xffffffff;
+  if (r < 0)
+    r += 0x100000000;
+  return r;
+}
+utils.sum32_5 = sum32_5;
diff --git a/test/hash-test.js b/test/hash-test.js
index 77da2a6..35ac7b3 100644
--- a/test/hash-test.js
+++ b/test/hash-test.js
@@ -61,4 +61,36 @@ describe('Hash', function() {
       assert.equal(dgst, res);
     }
   });
+
+  it('should support ripemd160', function() {
+    assert.equal(hash.ripemd160.blockSize, 512);
+    assert.equal(hash.ripemd160.outSize, 160);
+
+    var test = [
+      [ '', '9c1185a5c5e9fc54612808977ee8f548b2258d31'],
+      [ 'abc',
+        '8eb208f7e05d987a9b044a8e98c6b087f15a0bfc' ],
+      [ 'message digest',
+        '5d0689ef49d2fae572b881b123a85ffa21595f36' ],
+      [ 'abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq',
+        '12a053384a9c0c88e405a06c27dcf49ada62eb2b' ],
+      [ 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',
+        'b0e20b6e3116640286ed3a87a5713079b21f5189' ],
+    ];
+    for (var i = 0; i < test.length; i++) {
+      var msg = test[i][0];
+      var res = test[i][1];
+      var enc = test[i][2];
+
+      var dgst = hash.ripemd160().update(msg, enc).digest('hex');
+      assert.equal(dgst, res);
+
+      // Split message on odd boundary
+      var dgst = hash.ripemd160()
+                     .update(msg.slice(0, 3), enc)
+                     .update(msg.slice(3), enc)
+                     .digest('hex');
+      assert.equal(dgst, res);
+    }
+  });
 });

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/node-hash.js.git



More information about the Pkg-javascript-commits mailing list