md5.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. // Copyright 2011 The Closure Library Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS-IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. /**
  15. * @fileoverview MD5 cryptographic hash.
  16. * Implementation of http://tools.ietf.org/html/rfc1321 with common
  17. * optimizations and tweaks (see http://en.wikipedia.org/wiki/MD5).
  18. *
  19. * Usage:
  20. * var md5 = new goog.crypt.Md5();
  21. * md5.update(bytes);
  22. * var hash = md5.digest();
  23. *
  24. * Performance:
  25. * Chrome 23 ~680 Mbit/s
  26. * Chrome 13 (in a VM) ~250 Mbit/s
  27. * Firefox 6.0 (in a VM) ~100 Mbit/s
  28. * IE9 (in a VM) ~27 Mbit/s
  29. * Firefox 3.6 ~15 Mbit/s
  30. * IE8 (in a VM) ~13 Mbit/s
  31. *
  32. */
  33. goog.provide('goog.crypt.Md5');
  34. goog.require('goog.crypt.Hash');
  35. /**
  36. * MD5 cryptographic hash constructor.
  37. * @constructor
  38. * @extends {goog.crypt.Hash}
  39. * @final
  40. * @struct
  41. */
  42. goog.crypt.Md5 = function() {
  43. goog.crypt.Md5.base(this, 'constructor');
  44. this.blockSize = 512 / 8;
  45. /**
  46. * Holds the current values of accumulated A-D variables (MD buffer).
  47. * @type {!Array<number>}
  48. * @private
  49. */
  50. this.chain_ = new Array(4);
  51. /**
  52. * A buffer holding the data until the whole block can be processed.
  53. * @type {!Array<number>}
  54. * @private
  55. */
  56. this.block_ = new Array(this.blockSize);
  57. /**
  58. * The length of yet-unprocessed data as collected in the block.
  59. * @type {number}
  60. * @private
  61. */
  62. this.blockLength_ = 0;
  63. /**
  64. * The total length of the message so far.
  65. * @type {number}
  66. * @private
  67. */
  68. this.totalLength_ = 0;
  69. this.reset();
  70. };
  71. goog.inherits(goog.crypt.Md5, goog.crypt.Hash);
  72. /**
  73. * Integer rotation constants used by the abbreviated implementation.
  74. * They are hardcoded in the unrolled implementation, so it is left
  75. * here commented out.
  76. * @type {Array<number>}
  77. * @private
  78. *
  79. goog.crypt.Md5.S_ = [
  80. 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
  81. 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
  82. 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
  83. 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
  84. ];
  85. */
  86. /**
  87. * Sine function constants used by the abbreviated implementation.
  88. * They are hardcoded in the unrolled implementation, so it is left
  89. * here commented out.
  90. * @type {Array<number>}
  91. * @private
  92. *
  93. goog.crypt.Md5.T_ = [
  94. 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
  95. 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
  96. 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
  97. 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
  98. 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
  99. 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
  100. 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
  101. 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
  102. 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
  103. 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
  104. 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
  105. 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
  106. 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
  107. 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
  108. 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
  109. 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391
  110. ];
  111. */
  112. /** @override */
  113. goog.crypt.Md5.prototype.reset = function() {
  114. this.chain_[0] = 0x67452301;
  115. this.chain_[1] = 0xefcdab89;
  116. this.chain_[2] = 0x98badcfe;
  117. this.chain_[3] = 0x10325476;
  118. this.blockLength_ = 0;
  119. this.totalLength_ = 0;
  120. };
  121. /**
  122. * Internal compress helper function. It takes a block of data (64 bytes)
  123. * and updates the accumulator.
  124. * @param {Array<number>|Uint8Array|string} buf The block to compress.
  125. * @param {number=} opt_offset Offset of the block in the buffer.
  126. * @private
  127. */
  128. goog.crypt.Md5.prototype.compress_ = function(buf, opt_offset) {
  129. if (!opt_offset) {
  130. opt_offset = 0;
  131. }
  132. // We allocate the array every time, but it's cheap in practice.
  133. var X = new Array(16);
  134. // Get 16 little endian words. It is not worth unrolling this for Chrome 11.
  135. if (goog.isString(buf)) {
  136. for (var i = 0; i < 16; ++i) {
  137. X[i] = (buf.charCodeAt(opt_offset++)) |
  138. (buf.charCodeAt(opt_offset++) << 8) |
  139. (buf.charCodeAt(opt_offset++) << 16) |
  140. (buf.charCodeAt(opt_offset++) << 24);
  141. }
  142. } else {
  143. for (var i = 0; i < 16; ++i) {
  144. X[i] = (buf[opt_offset++]) | (buf[opt_offset++] << 8) |
  145. (buf[opt_offset++] << 16) | (buf[opt_offset++] << 24);
  146. }
  147. }
  148. var A = this.chain_[0];
  149. var B = this.chain_[1];
  150. var C = this.chain_[2];
  151. var D = this.chain_[3];
  152. var sum = 0;
  153. /*
  154. * This is an abbreviated implementation, it is left here commented out for
  155. * reference purposes. See below for an unrolled version in use.
  156. *
  157. var f, n, tmp;
  158. for (var i = 0; i < 64; ++i) {
  159. if (i < 16) {
  160. f = (D ^ (B & (C ^ D)));
  161. n = i;
  162. } else if (i < 32) {
  163. f = (C ^ (D & (B ^ C)));
  164. n = (5 * i + 1) % 16;
  165. } else if (i < 48) {
  166. f = (B ^ C ^ D);
  167. n = (3 * i + 5) % 16;
  168. } else {
  169. f = (C ^ (B | (~D)));
  170. n = (7 * i) % 16;
  171. }
  172. tmp = D;
  173. D = C;
  174. C = B;
  175. sum = (A + f + goog.crypt.Md5.T_[i] + X[n]) & 0xffffffff;
  176. B += ((sum << goog.crypt.Md5.S_[i]) & 0xffffffff) |
  177. (sum >>> (32 - goog.crypt.Md5.S_[i]));
  178. A = tmp;
  179. }
  180. */
  181. /*
  182. * This is an unrolled MD5 implementation, which gives ~30% speedup compared
  183. * to the abbreviated implementation above, as measured on Chrome 11. It is
  184. * important to keep 32-bit croppings to minimum and inline the integer
  185. * rotation.
  186. */
  187. sum = (A + (D ^ (B & (C ^ D))) + X[0] + 0xd76aa478) & 0xffffffff;
  188. A = B + (((sum << 7) & 0xffffffff) | (sum >>> 25));
  189. sum = (D + (C ^ (A & (B ^ C))) + X[1] + 0xe8c7b756) & 0xffffffff;
  190. D = A + (((sum << 12) & 0xffffffff) | (sum >>> 20));
  191. sum = (C + (B ^ (D & (A ^ B))) + X[2] + 0x242070db) & 0xffffffff;
  192. C = D + (((sum << 17) & 0xffffffff) | (sum >>> 15));
  193. sum = (B + (A ^ (C & (D ^ A))) + X[3] + 0xc1bdceee) & 0xffffffff;
  194. B = C + (((sum << 22) & 0xffffffff) | (sum >>> 10));
  195. sum = (A + (D ^ (B & (C ^ D))) + X[4] + 0xf57c0faf) & 0xffffffff;
  196. A = B + (((sum << 7) & 0xffffffff) | (sum >>> 25));
  197. sum = (D + (C ^ (A & (B ^ C))) + X[5] + 0x4787c62a) & 0xffffffff;
  198. D = A + (((sum << 12) & 0xffffffff) | (sum >>> 20));
  199. sum = (C + (B ^ (D & (A ^ B))) + X[6] + 0xa8304613) & 0xffffffff;
  200. C = D + (((sum << 17) & 0xffffffff) | (sum >>> 15));
  201. sum = (B + (A ^ (C & (D ^ A))) + X[7] + 0xfd469501) & 0xffffffff;
  202. B = C + (((sum << 22) & 0xffffffff) | (sum >>> 10));
  203. sum = (A + (D ^ (B & (C ^ D))) + X[8] + 0x698098d8) & 0xffffffff;
  204. A = B + (((sum << 7) & 0xffffffff) | (sum >>> 25));
  205. sum = (D + (C ^ (A & (B ^ C))) + X[9] + 0x8b44f7af) & 0xffffffff;
  206. D = A + (((sum << 12) & 0xffffffff) | (sum >>> 20));
  207. sum = (C + (B ^ (D & (A ^ B))) + X[10] + 0xffff5bb1) & 0xffffffff;
  208. C = D + (((sum << 17) & 0xffffffff) | (sum >>> 15));
  209. sum = (B + (A ^ (C & (D ^ A))) + X[11] + 0x895cd7be) & 0xffffffff;
  210. B = C + (((sum << 22) & 0xffffffff) | (sum >>> 10));
  211. sum = (A + (D ^ (B & (C ^ D))) + X[12] + 0x6b901122) & 0xffffffff;
  212. A = B + (((sum << 7) & 0xffffffff) | (sum >>> 25));
  213. sum = (D + (C ^ (A & (B ^ C))) + X[13] + 0xfd987193) & 0xffffffff;
  214. D = A + (((sum << 12) & 0xffffffff) | (sum >>> 20));
  215. sum = (C + (B ^ (D & (A ^ B))) + X[14] + 0xa679438e) & 0xffffffff;
  216. C = D + (((sum << 17) & 0xffffffff) | (sum >>> 15));
  217. sum = (B + (A ^ (C & (D ^ A))) + X[15] + 0x49b40821) & 0xffffffff;
  218. B = C + (((sum << 22) & 0xffffffff) | (sum >>> 10));
  219. sum = (A + (C ^ (D & (B ^ C))) + X[1] + 0xf61e2562) & 0xffffffff;
  220. A = B + (((sum << 5) & 0xffffffff) | (sum >>> 27));
  221. sum = (D + (B ^ (C & (A ^ B))) + X[6] + 0xc040b340) & 0xffffffff;
  222. D = A + (((sum << 9) & 0xffffffff) | (sum >>> 23));
  223. sum = (C + (A ^ (B & (D ^ A))) + X[11] + 0x265e5a51) & 0xffffffff;
  224. C = D + (((sum << 14) & 0xffffffff) | (sum >>> 18));
  225. sum = (B + (D ^ (A & (C ^ D))) + X[0] + 0xe9b6c7aa) & 0xffffffff;
  226. B = C + (((sum << 20) & 0xffffffff) | (sum >>> 12));
  227. sum = (A + (C ^ (D & (B ^ C))) + X[5] + 0xd62f105d) & 0xffffffff;
  228. A = B + (((sum << 5) & 0xffffffff) | (sum >>> 27));
  229. sum = (D + (B ^ (C & (A ^ B))) + X[10] + 0x02441453) & 0xffffffff;
  230. D = A + (((sum << 9) & 0xffffffff) | (sum >>> 23));
  231. sum = (C + (A ^ (B & (D ^ A))) + X[15] + 0xd8a1e681) & 0xffffffff;
  232. C = D + (((sum << 14) & 0xffffffff) | (sum >>> 18));
  233. sum = (B + (D ^ (A & (C ^ D))) + X[4] + 0xe7d3fbc8) & 0xffffffff;
  234. B = C + (((sum << 20) & 0xffffffff) | (sum >>> 12));
  235. sum = (A + (C ^ (D & (B ^ C))) + X[9] + 0x21e1cde6) & 0xffffffff;
  236. A = B + (((sum << 5) & 0xffffffff) | (sum >>> 27));
  237. sum = (D + (B ^ (C & (A ^ B))) + X[14] + 0xc33707d6) & 0xffffffff;
  238. D = A + (((sum << 9) & 0xffffffff) | (sum >>> 23));
  239. sum = (C + (A ^ (B & (D ^ A))) + X[3] + 0xf4d50d87) & 0xffffffff;
  240. C = D + (((sum << 14) & 0xffffffff) | (sum >>> 18));
  241. sum = (B + (D ^ (A & (C ^ D))) + X[8] + 0x455a14ed) & 0xffffffff;
  242. B = C + (((sum << 20) & 0xffffffff) | (sum >>> 12));
  243. sum = (A + (C ^ (D & (B ^ C))) + X[13] + 0xa9e3e905) & 0xffffffff;
  244. A = B + (((sum << 5) & 0xffffffff) | (sum >>> 27));
  245. sum = (D + (B ^ (C & (A ^ B))) + X[2] + 0xfcefa3f8) & 0xffffffff;
  246. D = A + (((sum << 9) & 0xffffffff) | (sum >>> 23));
  247. sum = (C + (A ^ (B & (D ^ A))) + X[7] + 0x676f02d9) & 0xffffffff;
  248. C = D + (((sum << 14) & 0xffffffff) | (sum >>> 18));
  249. sum = (B + (D ^ (A & (C ^ D))) + X[12] + 0x8d2a4c8a) & 0xffffffff;
  250. B = C + (((sum << 20) & 0xffffffff) | (sum >>> 12));
  251. sum = (A + (B ^ C ^ D) + X[5] + 0xfffa3942) & 0xffffffff;
  252. A = B + (((sum << 4) & 0xffffffff) | (sum >>> 28));
  253. sum = (D + (A ^ B ^ C) + X[8] + 0x8771f681) & 0xffffffff;
  254. D = A + (((sum << 11) & 0xffffffff) | (sum >>> 21));
  255. sum = (C + (D ^ A ^ B) + X[11] + 0x6d9d6122) & 0xffffffff;
  256. C = D + (((sum << 16) & 0xffffffff) | (sum >>> 16));
  257. sum = (B + (C ^ D ^ A) + X[14] + 0xfde5380c) & 0xffffffff;
  258. B = C + (((sum << 23) & 0xffffffff) | (sum >>> 9));
  259. sum = (A + (B ^ C ^ D) + X[1] + 0xa4beea44) & 0xffffffff;
  260. A = B + (((sum << 4) & 0xffffffff) | (sum >>> 28));
  261. sum = (D + (A ^ B ^ C) + X[4] + 0x4bdecfa9) & 0xffffffff;
  262. D = A + (((sum << 11) & 0xffffffff) | (sum >>> 21));
  263. sum = (C + (D ^ A ^ B) + X[7] + 0xf6bb4b60) & 0xffffffff;
  264. C = D + (((sum << 16) & 0xffffffff) | (sum >>> 16));
  265. sum = (B + (C ^ D ^ A) + X[10] + 0xbebfbc70) & 0xffffffff;
  266. B = C + (((sum << 23) & 0xffffffff) | (sum >>> 9));
  267. sum = (A + (B ^ C ^ D) + X[13] + 0x289b7ec6) & 0xffffffff;
  268. A = B + (((sum << 4) & 0xffffffff) | (sum >>> 28));
  269. sum = (D + (A ^ B ^ C) + X[0] + 0xeaa127fa) & 0xffffffff;
  270. D = A + (((sum << 11) & 0xffffffff) | (sum >>> 21));
  271. sum = (C + (D ^ A ^ B) + X[3] + 0xd4ef3085) & 0xffffffff;
  272. C = D + (((sum << 16) & 0xffffffff) | (sum >>> 16));
  273. sum = (B + (C ^ D ^ A) + X[6] + 0x04881d05) & 0xffffffff;
  274. B = C + (((sum << 23) & 0xffffffff) | (sum >>> 9));
  275. sum = (A + (B ^ C ^ D) + X[9] + 0xd9d4d039) & 0xffffffff;
  276. A = B + (((sum << 4) & 0xffffffff) | (sum >>> 28));
  277. sum = (D + (A ^ B ^ C) + X[12] + 0xe6db99e5) & 0xffffffff;
  278. D = A + (((sum << 11) & 0xffffffff) | (sum >>> 21));
  279. sum = (C + (D ^ A ^ B) + X[15] + 0x1fa27cf8) & 0xffffffff;
  280. C = D + (((sum << 16) & 0xffffffff) | (sum >>> 16));
  281. sum = (B + (C ^ D ^ A) + X[2] + 0xc4ac5665) & 0xffffffff;
  282. B = C + (((sum << 23) & 0xffffffff) | (sum >>> 9));
  283. sum = (A + (C ^ (B | (~D))) + X[0] + 0xf4292244) & 0xffffffff;
  284. A = B + (((sum << 6) & 0xffffffff) | (sum >>> 26));
  285. sum = (D + (B ^ (A | (~C))) + X[7] + 0x432aff97) & 0xffffffff;
  286. D = A + (((sum << 10) & 0xffffffff) | (sum >>> 22));
  287. sum = (C + (A ^ (D | (~B))) + X[14] + 0xab9423a7) & 0xffffffff;
  288. C = D + (((sum << 15) & 0xffffffff) | (sum >>> 17));
  289. sum = (B + (D ^ (C | (~A))) + X[5] + 0xfc93a039) & 0xffffffff;
  290. B = C + (((sum << 21) & 0xffffffff) | (sum >>> 11));
  291. sum = (A + (C ^ (B | (~D))) + X[12] + 0x655b59c3) & 0xffffffff;
  292. A = B + (((sum << 6) & 0xffffffff) | (sum >>> 26));
  293. sum = (D + (B ^ (A | (~C))) + X[3] + 0x8f0ccc92) & 0xffffffff;
  294. D = A + (((sum << 10) & 0xffffffff) | (sum >>> 22));
  295. sum = (C + (A ^ (D | (~B))) + X[10] + 0xffeff47d) & 0xffffffff;
  296. C = D + (((sum << 15) & 0xffffffff) | (sum >>> 17));
  297. sum = (B + (D ^ (C | (~A))) + X[1] + 0x85845dd1) & 0xffffffff;
  298. B = C + (((sum << 21) & 0xffffffff) | (sum >>> 11));
  299. sum = (A + (C ^ (B | (~D))) + X[8] + 0x6fa87e4f) & 0xffffffff;
  300. A = B + (((sum << 6) & 0xffffffff) | (sum >>> 26));
  301. sum = (D + (B ^ (A | (~C))) + X[15] + 0xfe2ce6e0) & 0xffffffff;
  302. D = A + (((sum << 10) & 0xffffffff) | (sum >>> 22));
  303. sum = (C + (A ^ (D | (~B))) + X[6] + 0xa3014314) & 0xffffffff;
  304. C = D + (((sum << 15) & 0xffffffff) | (sum >>> 17));
  305. sum = (B + (D ^ (C | (~A))) + X[13] + 0x4e0811a1) & 0xffffffff;
  306. B = C + (((sum << 21) & 0xffffffff) | (sum >>> 11));
  307. sum = (A + (C ^ (B | (~D))) + X[4] + 0xf7537e82) & 0xffffffff;
  308. A = B + (((sum << 6) & 0xffffffff) | (sum >>> 26));
  309. sum = (D + (B ^ (A | (~C))) + X[11] + 0xbd3af235) & 0xffffffff;
  310. D = A + (((sum << 10) & 0xffffffff) | (sum >>> 22));
  311. sum = (C + (A ^ (D | (~B))) + X[2] + 0x2ad7d2bb) & 0xffffffff;
  312. C = D + (((sum << 15) & 0xffffffff) | (sum >>> 17));
  313. sum = (B + (D ^ (C | (~A))) + X[9] + 0xeb86d391) & 0xffffffff;
  314. B = C + (((sum << 21) & 0xffffffff) | (sum >>> 11));
  315. this.chain_[0] = (this.chain_[0] + A) & 0xffffffff;
  316. this.chain_[1] = (this.chain_[1] + B) & 0xffffffff;
  317. this.chain_[2] = (this.chain_[2] + C) & 0xffffffff;
  318. this.chain_[3] = (this.chain_[3] + D) & 0xffffffff;
  319. };
  320. /** @override */
  321. goog.crypt.Md5.prototype.update = function(bytes, opt_length) {
  322. if (!goog.isDef(opt_length)) {
  323. opt_length = bytes.length;
  324. }
  325. var lengthMinusBlock = opt_length - this.blockSize;
  326. // Copy some object properties to local variables in order to save on access
  327. // time from inside the loop (~10% speedup was observed on Chrome 11).
  328. var block = this.block_;
  329. var blockLength = this.blockLength_;
  330. var i = 0;
  331. // The outer while loop should execute at most twice.
  332. while (i < opt_length) {
  333. // When we have no data in the block to top up, we can directly process the
  334. // input buffer (assuming it contains sufficient data). This gives ~30%
  335. // speedup on Chrome 14 and ~70% speedup on Firefox 6.0, but requires that
  336. // the data is provided in large chunks (or in multiples of 64 bytes).
  337. if (blockLength == 0) {
  338. while (i <= lengthMinusBlock) {
  339. this.compress_(bytes, i);
  340. i += this.blockSize;
  341. }
  342. }
  343. if (goog.isString(bytes)) {
  344. while (i < opt_length) {
  345. block[blockLength++] = bytes.charCodeAt(i++);
  346. if (blockLength == this.blockSize) {
  347. this.compress_(block);
  348. blockLength = 0;
  349. // Jump to the outer loop so we use the full-block optimization.
  350. break;
  351. }
  352. }
  353. } else {
  354. while (i < opt_length) {
  355. block[blockLength++] = bytes[i++];
  356. if (blockLength == this.blockSize) {
  357. this.compress_(block);
  358. blockLength = 0;
  359. // Jump to the outer loop so we use the full-block optimization.
  360. break;
  361. }
  362. }
  363. }
  364. }
  365. this.blockLength_ = blockLength;
  366. this.totalLength_ += opt_length;
  367. };
  368. /** @override */
  369. goog.crypt.Md5.prototype.digest = function() {
  370. // This must accommodate at least 1 padding byte (0x80), 8 bytes of
  371. // total bitlength, and must end at a 64-byte boundary.
  372. var pad = new Array(
  373. (this.blockLength_ < 56 ? this.blockSize : this.blockSize * 2) -
  374. this.blockLength_);
  375. // Add padding: 0x80 0x00*
  376. pad[0] = 0x80;
  377. for (var i = 1; i < pad.length - 8; ++i) {
  378. pad[i] = 0;
  379. }
  380. // Add the total number of bits, little endian 64-bit integer.
  381. var totalBits = this.totalLength_ * 8;
  382. for (var i = pad.length - 8; i < pad.length; ++i) {
  383. pad[i] = totalBits & 0xff;
  384. totalBits /= 0x100; // Don't use bit-shifting here!
  385. }
  386. this.update(pad);
  387. var digest = new Array(16);
  388. var n = 0;
  389. for (var i = 0; i < 4; ++i) {
  390. for (var j = 0; j < 32; j += 8) {
  391. digest[n++] = (this.chain_[i] >>> j) & 0xff;
  392. }
  393. }
  394. return digest;
  395. };