You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by jo...@apache.org on 2010/06/29 01:17:03 UTC

svn commit: r958782 - in /shindig/trunk/features/src/main/javascript/features/shindig.random: ./ sha1.js

Author: johnh
Date: Mon Jun 28 23:17:02 2010
New Revision: 958782

URL: http://svn.apache.org/viewvc?rev=958782&view=rev
Log:
Bootstrapping more-secure random utility library impl by directly copying Closure Library's sha1.js to Shindig, to retain revision history on subsequent mods.

This code is not added to features.txt, has no feature.xml, etc so does nothing right now - @see follow-up CL.

sha1.js origin:
http://closure-library.googlecode.com/svn-history/r132/trunk/closure/goog/crypt/sha1.js
License: Apache 2.0 (safe)


Added:
    shindig/trunk/features/src/main/javascript/features/shindig.random/
    shindig/trunk/features/src/main/javascript/features/shindig.random/sha1.js

Added: shindig/trunk/features/src/main/javascript/features/shindig.random/sha1.js
URL: http://svn.apache.org/viewvc/shindig/trunk/features/src/main/javascript/features/shindig.random/sha1.js?rev=958782&view=auto
==============================================================================
--- shindig/trunk/features/src/main/javascript/features/shindig.random/sha1.js (added)
+++ shindig/trunk/features/src/main/javascript/features/shindig.random/sha1.js Mon Jun 28 23:17:02 2010
@@ -0,0 +1,248 @@
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Copyright 2005 Google Inc. All Rights Reserved
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS-IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/**
+ * @fileoverview SHA-1 cryptographic hash.
+ * Variable names follow the notation in FIPS PUB 180-3:
+ * http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf.
+ *
+ * Usage:
+ *   var sha1 = new goog.crypt.sha1();
+ *   sha1.update(bytes);
+ *   var hash = sha1.digest();
+ *
+ */
+
+goog.provide('goog.crypt.Sha1');
+
+/**
+ * SHA-1 cryptographic hash constructor.
+ *
+ * The properties declared here are discussed in the above algorithm document.
+ * @constructor
+ */
+goog.crypt.Sha1 = function() {
+  /**
+   * Holds the previous values of accumulated variables a-e in the compress_
+   * function.
+   * @type {Array.<number>}
+   * @private
+   */
+  this.chain_ = [];
+
+  /**
+   * A buffer holding the partially computed hash result.
+   * @type {Array.<number>}
+   * @private
+   */
+  this.buf_ = [];
+
+  /**
+   * An array of 80 bytes, each a part of the message to be hashed.  Referred to
+   * as the message schedule in the docs.
+   * @type {Array.<number>}
+   * @private
+   */
+  this.W_ = [];
+
+  /**
+   * Contains data needed to pad messages less than 64 bytes.
+   * @type {Array.<number>}
+   * @private
+   */
+  this.pad_ = [];
+
+  this.pad_[0] = 128;
+  for (var i = 1; i < 64; ++i) {
+    this.pad_[i] = 0;
+  }
+
+  this.reset();
+};
+
+
+/**
+ * Resets the internal accumulator.
+ */
+goog.crypt.Sha1.prototype.reset = function() {
+  this.chain_[0] = 0x67452301;
+  this.chain_[1] = 0xefcdab89;
+  this.chain_[2] = 0x98badcfe;
+  this.chain_[3] = 0x10325476;
+  this.chain_[4] = 0xc3d2e1f0;
+
+  this.inbuf_ = 0;
+  this.total_ = 0;
+};
+
+
+/**
+ * Internal helper performing 32 bit left rotate.
+ * @param {number} w 32-bit integer to rotate.
+ * @param {number} r Bits to rotate left by.
+ * @return {number} w rotated left by r bits.
+ * @private
+ */
+goog.crypt.Sha1.prototype.rotl_ = function(w, r) {
+  return ((w << r) | (w >>> (32 - r))) & 0xffffffff;
+};
+
+
+/**
+ * Internal compress helper function.
+ * @param {Array} buf containing block to compress.
+ * @private
+ */
+goog.crypt.Sha1.prototype.compress_ = function(buf) {
+  var W = this.W_;
+
+  // get 16 big endian words
+  for (var i = 0; i < 64; i += 4) {
+    var w = (buf[i] << 24) |
+            (buf[i + 1] << 16) |
+            (buf[i + 2] << 8) |
+            (buf[i + 3]);
+    W[i / 4] = w;
+  }
+
+  // expand to 80 words
+  for (var i = 16; i < 80; i++) {
+    W[i] = this.rotl_(W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16], 1);
+  }
+
+  var a = this.chain_[0];
+  var b = this.chain_[1];
+  var c = this.chain_[2];
+  var d = this.chain_[3];
+  var e = this.chain_[4];
+  var f, k;
+
+  for (var i = 0; i < 80; i++) {
+    if (i < 40) {
+      if (i < 20) {
+        f = d ^ (b & (c ^ d));
+        k = 0x5a827999;
+      } else {
+        f = b ^ c ^ d;
+        k = 0x6ed9eba1;
+      }
+    } else {
+      if (i < 60) {
+        f = (b & c) | (d & (b | c));
+        k = 0x8f1bbcdc;
+      } else {
+        f = b ^ c ^ d;
+        k = 0xca62c1d6;
+      }
+    }
+
+    var t = (this.rotl_(a, 5) + f + e + k + W[i]) & 0xffffffff;
+    e = d;
+    d = c;
+    c = this.rotl_(b, 30);
+    b = a;
+    a = t;
+  }
+
+  this.chain_[0] = (this.chain_[0] + a) & 0xffffffff;
+  this.chain_[1] = (this.chain_[1] + b) & 0xffffffff;
+  this.chain_[2] = (this.chain_[2] + c) & 0xffffffff;
+  this.chain_[3] = (this.chain_[3] + d) & 0xffffffff;
+  this.chain_[4] = (this.chain_[4] + e) & 0xffffffff;
+};
+
+
+/**
+ * Adds a byte array to internal accumulator.
+ * @param {Array.<number>} bytes to add to digest.
+ * @param {number=} opt_length is # of bytes to compress.
+ */
+goog.crypt.Sha1.prototype.update = function(bytes, opt_length) {
+  if (!opt_length) {
+    opt_length = bytes.length;
+  }
+
+  var n = 0;
+
+  // Optimize for 64 byte chunks at 64 byte boundaries.
+  if (this.inbuf_ == 0) {
+    while (n + 64 < opt_length) {
+      this.compress_(bytes.slice(n, n + 64));
+      n += 64;
+      this.total_ += 64;
+    }
+  }
+
+  while (n < opt_length) {
+    this.buf_[this.inbuf_++] = bytes[n++];
+    this.total_++;
+
+    if (this.inbuf_ == 64) {
+      this.inbuf_ = 0;
+      this.compress_(this.buf_);
+
+      // Pick up 64 byte chunks.
+      while (n + 64 < opt_length) {
+        this.compress_(bytes.slice(n, n + 64));
+        n += 64;
+        this.total_ += 64;
+      }
+    }
+  }
+};
+
+
+/**
+ * @return {Array} byte[20] containing finalized hash.
+ */
+goog.crypt.Sha1.prototype.digest = function() {
+  var digest = [];
+  var totalBits = this.total_ * 8;
+
+  // Add pad 0x80 0x00*.
+  if (this.inbuf_ < 56) {
+    this.update(this.pad_, 56 - this.inbuf_);
+  } else {
+    this.update(this.pad_, 64 - (this.inbuf_ - 56));
+  }
+
+  // Add # bits.
+  for (var i = 63; i >= 56; i--) {
+    this.buf_[i] = totalBits & 255;
+    totalBits >>>= 8;
+  }
+
+  this.compress_(this.buf_);
+
+  var n = 0;
+  for (var i = 0; i < 5; i++) {
+    for (var j = 24; j >= 0; j -= 8) {
+      digest[n++] = (this.chain_[i] >> j) & 255;
+    }
+  }
+
+  return digest;
+};