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