1 /** 2 * @namespace Hash functions 3 * @author Anonymized 4 * @description 5 * <p>Hash functions and hashing.</p> 6 * @requires encoding 7 */ 8 var hashing = (function() 9 { 10 var sha1 = 11 { 12 name: 'sha1', 13 identifier: '2b0e03021a', 14 size: 20, 15 block: 64, 16 17 hash: function(s) 18 { 19 var s = s+'\x80', len = s.length, blocks = len >> 6, 20 chunck = len&63, res = "", i = 0, j = 0, 21 H = [0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0], 22 w = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 23 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 24 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 25 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; 26 27 while(chunck++ != 56) 28 { 29 s+="\x00"; 30 if(chunck == 64){ blocks++; chunck = 0; } 31 } 32 33 for(s+="\x00\x00\x00\x00", chunck=3, len=8*(len-1); chunck >= 0; chunck--) 34 s += encoding.b2a(len >> (8*chunck)); 35 36 for(i=0; i < s.length; i++) 37 { 38 j = (j<<8) + encoding.a2b(s[i]); 39 if((i&3)==3){ w[(i>>2)&15] = j; j = 0; } 40 if((i&63)==63) this._round(H, w); 41 } 42 43 for(i=0; i < H.length; i++) 44 for(j=3; j >= 0; j--) 45 res += encoding.b2a(H[i] >> (8*j)); 46 47 return res; 48 }, 49 50 _round: function(H, w) 51 { 52 var a = H[0], b = H[1], c = H[2], d = H[3], e = H[4], i = 0, 53 k = [0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6], 54 S = function(n,x){return (x << n)|(x >>> 32-n)}, tmp = 0, 55 56 f = function(r, b, c, d) 57 { 58 if(r < 20) return (b & c) | (~b & d); 59 if(r < 40) return b ^ c ^ d; 60 if(r < 60) return (b & c) | (b & d) | (c & d); 61 return b ^ c ^ d; 62 } 63 64 for(i=0; i < 80; i++) 65 { 66 if(i >= 16) w[i&127] = S(1, w[(i-3)&127] ^ w[(i-8)&127] 67 ^ w[(i-14)&127] ^ w[(i-16)&127]); 68 tmp = (S(5, a) + f(i, b, c, d) + e + w[i&127] + k[(i/20)&3])|0; 69 e = d; d = c; c = S(30, b); b = a; a = tmp; 70 } 71 72 H[0] = (H[0]+a)|0; H[1] = (H[1]+b)|0; H[2] = (H[2]+c)|0; 73 H[3] = (H[3]+d)|0; H[4] = (H[4]+e)|0; 74 } 75 }; 76 77 var sha256 = 78 { 79 name: 'sha-256', 80 identifier: '608648016503040201', 81 size: 32, 82 block: 64, 83 84 key: [0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 85 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 86 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 87 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 88 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 89 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 90 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 91 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2], 92 93 hash: function(s) 94 { 95 var s = s + '\x80', len = s.length, blocks = len >> 6, chunck = len & 63, 96 res = '', p = '', i = 0, j = 0, k = 0, l = 0, 97 H = [0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19], 98 w = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; 99 100 while(chunck++ != 56) 101 { 102 s+="\x00"; 103 if(chunck == 64){ blocks++; chunck = 0; } 104 } 105 106 for(s+="\x00\x00\x00\x00", chunck=3, len=8*(len-1); chunck >= 0; chunck--) 107 s += encoding.b2a(len >> (8*chunck)); 108 109 for(i=0; i < s.length; i++) 110 { 111 j = (j<<8) + encoding.a2b(s[i]); 112 if((i&3)==3){ w[(i>>2)&15] = j; j = 0; } 113 if((i&63)==63) this._round(H,w); 114 } 115 116 for(i=0; i < H.length; i++) 117 for(j=3; j >= 0; j--) 118 res += encoding.b2a(H[i] >> (8*j)); 119 120 return res; 121 }, 122 123 _round: function(H,w) 124 { 125 var a = H[0], b = H[1], c = H[2], d = H[3], e = H[4], 126 f = H[5], g = H[6], h = H[7], t = 0, u = 0, v = 0, tmp = 0; 127 128 for(t=0; t < 64; t++) 129 { 130 if(t < 16) tmp = w[t&15]; 131 else 132 { 133 u = w[(t+1)&15]; v = w[(t+14)&15]; 134 tmp = w[t&15] = ((u>>>7 ^ u>>>18 ^ u>>>3 ^ u<<25 ^ u<<14) + 135 (v>>>17 ^ v>>>19 ^ v>>>10 ^ v<<15 ^ v<<13) + 136 w[t&15] + w[(t+9)&15]) | 0; 137 } 138 139 tmp = (tmp + h + (e>>>6 ^ e>>>11 ^ e>>>25 ^ e<<26 ^ e<<21 ^ e<<7) 140 + (g ^ e & (f^g)) + this.key[t&63]); 141 h = g; g = f; f = e; e = d + tmp | 0; d = c; c = b; b = a; 142 a = (tmp + ((b&c) ^ (d&(b^c))) + (b>>>2 ^ b>>>13 ^ b>>>22 ^ b<<30 ^ b<<19 ^ b<<10)) | 0; 143 } 144 145 H[0]=H[0]+a|0; H[1]=H[1]+b|0; H[2]=H[2]+c|0; H[3]=H[3]+d|0; 146 H[4]=H[4]+e|0; H[5]=H[5]+f|0; H[6]=H[6]+g|0; H[7]=H[7]+h|0; 147 } 148 }; 149 150 return { 151 /** SHA-256 hash function wrapper. This object can be used 152 * to configure primitives that rely on a hash function, 153 * for instance hashing.hmac_hash = hashing.sha256 154 */ 155 sha256: sha256, 156 157 /** SHA1 hash function wrapper. This object can be used 158 * to configure primitives that rely on a hash function, 159 * for instance rsa.pss_hash = hashing.sha1 160 */ 161 sha1: sha1, 162 163 /** SHA-256 helper function (hex output) 164 * @param {string} m ASCII message to digest with SHA-256. 165 * @returns {string} Hex string representing the hash. 166 */ 167 SHA256: function(s) 168 { 169 return encoding.astr2hstr(this.sha256.hash(s)); 170 }, 171 172 /** SHA1 helper function (hex output) 173 * @param {string} m ASCII message to digest with SHA1. 174 * @returns {string} Hex string representing the hash. 175 */ 176 SHA1: function(s) 177 { 178 return encoding.astr2hstr(this.sha1.hash(s)); 179 }, 180 181 /** The hash function to use for HMAC, hashing.sha256 by default 182 */ 183 hmac_hash: sha256, 184 185 /** Hash-based message authentication code 186 * @param {string} key key of the authentication 187 * @param {string} msg message to authenticate 188 * @returns {string} authentication code, as an hex string. 189 */ 190 HMAC: function(key, msg) 191 { 192 var key = key+'', msg = msg+'', i = 0, h = this.hmac_hash, 193 c = 0, p = '', inner = "", outer = ""; 194 195 if(key.length > h.block) key = h.hash(key); 196 while(key.length < h.block) key += "\x00"; 197 198 for(i=0; i < key.length; i++) 199 { 200 c = encoding.a2b(key[i]); 201 inner += encoding.b2a(c ^ 0x36); 202 outer += encoding.b2a(c ^ 0x5C); 203 } 204 205 return encoding.astr2hstr(h.hash(outer + h.hash(inner + msg))); 206 } 207 }; 208 })(); 209 210