1 jls.loader.provide('jls.security.Sha1');
  2 
  3 jls.loader.require('jls.security.MessageDigest');
  4 
  5 (function () {
  6 
  7 /*
  8  * A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
  9  * in FIPS 180-1
 10  * Version 2.2 Copyright Paul Johnston 2000 - 2009.
 11  * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 12  * Distributed under the BSD License
 13  * See http://pajhome.org.uk/crypt/md5 for details.
 14  */
 15 
 16 /*
 17  * Perform the appropriate triplet combination function for the current iteration
 18  */
 19 var sha1_ft = function(t, b, c, d) {
 20   if(t < 20) return (b & c) | ((~b) & d);
 21   if(t < 40) return b ^ c ^ d;
 22   if(t < 60) return (b & c) | (b & d) | (c & d);
 23   return b ^ c ^ d;
 24 };
 25 
 26 /*
 27  * Determine the appropriate additive constant for the current iteration
 28  */
 29 var sha1_kt = function(t) {
 30   return (t < 20) ?  1518500249 : (t < 40) ?  1859775393 :
 31          (t < 60) ? -1894007588 : -899497514;
 32 };
 33 
 34 /*
 35  * Add integers, wrapping at 2^32. This uses 16-bit operations internally to work around bugs in some JS interpreters.
 36  */
 37 var safe_add = function(x, y) {
 38   var lsw = (x & 0xFFFF) + (y & 0xFFFF);
 39   var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
 40   return (msw << 16) | (lsw & 0xFFFF);
 41 };
 42 
 43 /*
 44  * Bitwise rotate a 32-bit number to the left.
 45  */
 46 var bit_rol = function(num, cnt) {
 47   return (num << cnt) | (num >>> (32 - cnt));
 48 };
 49 
 50 /*
 51  * Calculate the SHA-1 of an array of big-endian 32-bits words, and a bit length
 52  */
 53 var computeArray = function(x, len) {
 54   /* append padding */
 55   x[len >> 5] |= 0x80 << (24 - len % 32);
 56   x[((len + 64 >> 9) << 4) + 15] = len;
 57 
 58   var w = Array(80);
 59   var a =  1732584193;
 60   var b = -271733879;
 61   var c = -1732584194;
 62   var d =  271733878;
 63   var e = -1009589776;
 64 
 65   for(var i = 0; i < x.length; i += 16) {
 66     var olda = a;
 67     var oldb = b;
 68     var oldc = c;
 69     var oldd = d;
 70     var olde = e;
 71     for(var j = 0; j < 80; j++) {
 72       if(j < 16) w[j] = x[i + j];
 73       else w[j] = bit_rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1);
 74       var t = safe_add(safe_add(bit_rol(a, 5), sha1_ft(j, b, c, d)),
 75                        safe_add(safe_add(e, w[j]), sha1_kt(j)));
 76       e = d;
 77       d = c;
 78       c = bit_rol(b, 30);
 79       b = a;
 80       a = t;
 81     }
 82     a = safe_add(a, olda);
 83     b = safe_add(b, oldb);
 84     c = safe_add(c, oldc);
 85     d = safe_add(d, oldd);
 86     e = safe_add(e, olde);
 87   }
 88   return Array(a, b, c, d, e);
 89 };
 90 
 91 
 92 /*
 93  * Message digest implementation for SHA1 algorithm.
 94  */
 95 jls.security.Sha1 = jls.lang.Class.create(jls.security.MessageDigest,
 96 {
 97     initialize : function($super) {
 98     	$super('SHA1');
 99     },
100     digest : function() {
101         this._buffer.flip();
102         var length = this._buffer.remaining();
103         var wa = [];
104         for (var i = 0; this._buffer.remaining() > 0; i++) {
105             var b = this._buffer.getByte();
106             var m = i % 4
107             var d = i >>> 2;
108             if (m == 0) {
109                 wa[d] = 0;
110             }
111             wa[d] |= b << (24 - (m * 8));
112         }
113         wa = computeArray(wa, length * 8);
114         this._buffer.clear();
115         for (var i = 0; i < wa.length; i++) {
116             var w = wa[i];
117             this._buffer.putByte((w >>> 24) & 0xff);
118             this._buffer.putByte((w >>> 16) & 0xff);
119             this._buffer.putByte((w >>> 8) & 0xff);
120             this._buffer.putByte(w & 0xff);
121         }
122         this._buffer.flip();
123         return this._buffer;
124     }
125 });
126 
127 // static
128 jls.security.MessageDigest.addMessageDigest(new jls.security.Sha1());
129 
130 })();
131