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