sha1.js 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. import {
  2. WordArray,
  3. Hasher,
  4. } from './core.js';
  5. // Reusable object
  6. const W = [];
  7. /**
  8. * SHA-1 hash algorithm.
  9. */
  10. export class SHA1Algo extends Hasher {
  11. _doReset() {
  12. this._hash = new WordArray([
  13. 0x67452301,
  14. 0xefcdab89,
  15. 0x98badcfe,
  16. 0x10325476,
  17. 0xc3d2e1f0,
  18. ]);
  19. }
  20. _doProcessBlock(M, offset) {
  21. // Shortcut
  22. const H = this._hash.words;
  23. // Working variables
  24. let a = H[0];
  25. let b = H[1];
  26. let c = H[2];
  27. let d = H[3];
  28. let e = H[4];
  29. // Computation
  30. for (let i = 0; i < 80; i += 1) {
  31. if (i < 16) {
  32. W[i] = M[offset + i] | 0;
  33. } else {
  34. const n = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16];
  35. W[i] = (n << 1) | (n >>> 31);
  36. }
  37. let t = ((a << 5) | (a >>> 27)) + e + W[i];
  38. if (i < 20) {
  39. t += ((b & c) | (~b & d)) + 0x5a827999;
  40. } else if (i < 40) {
  41. t += (b ^ c ^ d) + 0x6ed9eba1;
  42. } else if (i < 60) {
  43. t += ((b & c) | (b & d) | (c & d)) - 0x70e44324;
  44. } else /* if (i < 80) */ {
  45. t += (b ^ c ^ d) - 0x359d3e2a;
  46. }
  47. e = d;
  48. d = c;
  49. c = (b << 30) | (b >>> 2);
  50. b = a;
  51. a = t;
  52. }
  53. // Intermediate hash value
  54. H[0] = (H[0] + a) | 0;
  55. H[1] = (H[1] + b) | 0;
  56. H[2] = (H[2] + c) | 0;
  57. H[3] = (H[3] + d) | 0;
  58. H[4] = (H[4] + e) | 0;
  59. }
  60. _doFinalize() {
  61. // Shortcuts
  62. const data = this._data;
  63. const dataWords = data.words;
  64. const nBitsTotal = this._nDataBytes * 8;
  65. const nBitsLeft = data.sigBytes * 8;
  66. // Add padding
  67. dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - (nBitsLeft % 32));
  68. dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
  69. dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
  70. data.sigBytes = dataWords.length * 4;
  71. // Hash final blocks
  72. this._process();
  73. // Return final computed hash
  74. return this._hash;
  75. }
  76. clone() {
  77. const clone = super.clone.call(this);
  78. clone._hash = this._hash.clone();
  79. return clone;
  80. }
  81. }
  82. /**
  83. * Shortcut function to the hasher's object interface.
  84. *
  85. * @param {WordArray|string} message The message to hash.
  86. *
  87. * @return {WordArray} The hash.
  88. *
  89. * @static
  90. *
  91. * @example
  92. *
  93. * var hash = CryptoJS.SHA1('message');
  94. * var hash = CryptoJS.SHA1(wordArray);
  95. */
  96. export const SHA1 = Hasher._createHelper(SHA1Algo);
  97. /**
  98. * Shortcut function to the HMAC's object interface.
  99. *
  100. * @param {WordArray|string} message The message to hash.
  101. * @param {WordArray|string} key The secret key.
  102. *
  103. * @return {WordArray} The HMAC.
  104. *
  105. * @static
  106. *
  107. * @example
  108. *
  109. * var hmac = CryptoJS.HmacSHA1(message, key);
  110. */
  111. export const HmacSHA1 = Hasher._createHmacHelper(SHA1Algo);