1/* 2* A JavaScript implementation of the SHA256 hash function. 3* 4* FILE: sha256.js 5* VERSION: 0.8 6* AUTHOR: Christoph Bichlmeier <[email protected]> 7* 8* NOTE: This version is not tested thoroughly! 9* 10* Copyright (c) 2003, Christoph Bichlmeier 11* All rights reserved. 12* 13* Redistribution and use in source and binary forms, with or without 14* modification, are permitted provided that the following conditions 15* are met: 16* 1. Redistributions of source code must retain the above copyright 17* notice, this list of conditions and the following disclaimer. 18* 2. Redistributions in binary form must reproduce the above copyright 19* notice, this list of conditions and the following disclaimer in the 20* documentation and/or other materials provided with the distribution. 21* 3. Neither the name of the copyright holder nor the names of contributors 22* may be used to endorse or promote products derived from this software 23* without specific prior written permission. 24* 25* ====================================================================== 26* 27* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS 28* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 29* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE 31* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 34* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 35* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 36* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 37* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38*/ 39 40/* SHA256 logical functions */ 41function rotateRight(n,x) { 42 return ((x >>> n) | (x << (32 - n))); 43} 44function choice(x,y,z) { 45 return ((x & y) ^ (~x & z)); 46} 47function majority(x,y,z) { 48 return ((x & y) ^ (x & z) ^ (y & z)); 49} 50function sha256_Sigma0(x) { 51 return (rotateRight(2, x) ^ rotateRight(13, x) ^ rotateRight(22, x)); 52} 53function sha256_Sigma1(x) { 54 return (rotateRight(6, x) ^ rotateRight(11, x) ^ rotateRight(25, x)); 55} 56function sha256_sigma0(x) { 57 return (rotateRight(7, x) ^ rotateRight(18, x) ^ (x >>> 3)); 58} 59function sha256_sigma1(x) { 60 return (rotateRight(17, x) ^ rotateRight(19, x) ^ (x >>> 10)); 61} 62function sha256_expand(W, j) { 63 return (W[j&0x0f] += sha256_sigma1(W[(j+14)&0x0f]) + W[(j+9)&0x0f] + 64sha256_sigma0(W[(j+1)&0x0f])); 65} 66 67/* Hash constant words K: */ 68var K256 = new Array( 69 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 70 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 71 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 72 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 73 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 74 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 75 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 76 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 77 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 78 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 79 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 80 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 81 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 82 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 83 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 84 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 85); 86 87/* global arrays */ 88var ihash, count, buffer; 89var sha256_hex_digits = "0123456789abcdef"; 90 91/* Add 32-bit integers with 16-bit operations (bug in some JS-interpreters: 92overflow) */ 93function safe_add(x, y) 94{ 95 var lsw = (x & 0xffff) + (y & 0xffff); 96 var msw = (x >> 16) + (y >> 16) + (lsw >> 16); 97 return (msw << 16) | (lsw & 0xffff); 98} 99 100/* Initialise the SHA256 computation */ 101function sha256_init() { 102 ihash = new Array(8); 103 count = new Array(2); 104 buffer = new Array(64); 105 count[0] = count[1] = 0; 106 ihash[0] = 0x6a09e667; 107 ihash[1] = 0xbb67ae85; 108 ihash[2] = 0x3c6ef372; 109 ihash[3] = 0xa54ff53a; 110 ihash[4] = 0x510e527f; 111 ihash[5] = 0x9b05688c; 112 ihash[6] = 0x1f83d9ab; 113 ihash[7] = 0x5be0cd19; 114} 115 116/* Transform a 512-bit message block */ 117function sha256_transform() { 118 var a, b, c, d, e, f, g, h, T1, T2; 119 var W = new Array(16); 120 121 /* Initialize registers with the previous intermediate value */ 122 a = ihash[0]; 123 b = ihash[1]; 124 c = ihash[2]; 125 d = ihash[3]; 126 e = ihash[4]; 127 f = ihash[5]; 128 g = ihash[6]; 129 h = ihash[7]; 130 131 /* make 32-bit words */ 132 for(var i=0; i<16; i++) 133 W[i] = ((buffer[(i<<2)+3]) | (buffer[(i<<2)+2] << 8) | (buffer[(i<<2)+1] 134<< 16) | (buffer[i<<2] << 24)); 135 136 for(var j=0; j<64; j++) { 137 T1 = h + sha256_Sigma1(e) + choice(e, f, g) + K256[j]; 138 if(j < 16) T1 += W[j]; 139 else T1 += sha256_expand(W, j); 140 T2 = sha256_Sigma0(a) + majority(a, b, c); 141 h = g; 142 g = f; 143 f = e; 144 e = safe_add(d, T1); 145 d = c; 146 c = b; 147 b = a; 148 a = safe_add(T1, T2); 149 } 150 151 /* Compute the current intermediate hash value */ 152 ihash[0] += a; 153 ihash[1] += b; 154 ihash[2] += c; 155 ihash[3] += d; 156 ihash[4] += e; 157 ihash[5] += f; 158 ihash[6] += g; 159 ihash[7] += h; 160} 161 162/* Read the next chunk of data and update the SHA256 computation */ 163function sha256_update(data, inputLen) { 164 var i, index, curpos = 0; 165 /* Compute number of bytes mod 64 */ 166 index = ((count[0] >> 3) & 0x3f); 167 var remainder = (inputLen & 0x3f); 168 169 /* Update number of bits */ 170 if ((count[0] += (inputLen << 3)) < (inputLen << 3)) count[1]++; 171 count[1] += (inputLen >> 29); 172 173 /* Transform as many times as possible */ 174 for(i=0; i+63<inputLen; i+=64) { 175 for(var j=index; j<64; j++) 176 buffer[j] = data.charCodeAt(curpos++); 177 sha256_transform(); 178 index = 0; 179 } 180 181 /* Buffer remaining input */ 182 for(var j=0; j<remainder; j++) 183 buffer[j] = data.charCodeAt(curpos++); 184} 185 186/* Finish the computation by operations such as padding */ 187function sha256_final() { 188 var index = ((count[0] >> 3) & 0x3f); 189 buffer[index++] = 0x80; 190 if(index <= 56) { 191 for(var i=index; i<56; i++) 192 buffer[i] = 0; 193 } else { 194 for(var i=index; i<64; i++) 195 buffer[i] = 0; 196 sha256_transform(); 197 for(var i=0; i<56; i++) 198 buffer[i] = 0; 199 } 200 buffer[56] = (count[1] >>> 24) & 0xff; 201 buffer[57] = (count[1] >>> 16) & 0xff; 202 buffer[58] = (count[1] >>> 8) & 0xff; 203 buffer[59] = count[1] & 0xff; 204 buffer[60] = (count[0] >>> 24) & 0xff; 205 buffer[61] = (count[0] >>> 16) & 0xff; 206 buffer[62] = (count[0] >>> 8) & 0xff; 207 buffer[63] = count[0] & 0xff; 208 sha256_transform(); 209} 210 211/* Split the internal hash values into an array of bytes */ 212function sha256_encode_bytes() { 213 var j=0; 214 var output = new Array(32); 215 for(var i=0; i<8; i++) { 216 output[j++] = ((ihash[i] >>> 24) & 0xff); 217 output[j++] = ((ihash[i] >>> 16) & 0xff); 218 output[j++] = ((ihash[i] >>> 8) & 0xff); 219 output[j++] = (ihash[i] & 0xff); 220 } 221 return output; 222} 223 224/* Get the internal hash as a hex string */ 225function sha256_encode_hex() { 226 var output = new String(); 227 for(var i=0; i<8; i++) { 228 for(var j=28; j>=0; j-=4) 229 output += sha256_hex_digits.charAt((ihash[i] >>> j) & 0x0f); 230 } 231 return output; 232} 233 234/* Main function: returns a hex string representing the SHA256 value of the 235given data */ 236function sha256_digest(data) {
237 sha256_init(); 238 sha256_update(data, data.length); 239 sha256_final(); 240 return sha256_encode_hex(); 241} 242 243/* test if the JS-interpreter is working properly */ 244function sha256_self_test() 245{ 246 return sha256_digest("message digest") == 247"f7846f55cf23e14eebeab5b4e1550cad5b509e3348fbc4efa3a1413d393cb650"; 248} 249
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.