hmac.js 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.hmac = exports.HMAC = void 0;
  4. const _assert_js_1 = require("./_assert.js");
  5. const utils_js_1 = require("./utils.js");
  6. // HMAC (RFC 2104)
  7. class HMAC extends utils_js_1.Hash {
  8. constructor(hash, _key) {
  9. super();
  10. this.finished = false;
  11. this.destroyed = false;
  12. (0, _assert_js_1.hash)(hash);
  13. const key = (0, utils_js_1.toBytes)(_key);
  14. this.iHash = hash.create();
  15. if (typeof this.iHash.update !== 'function')
  16. throw new Error('Expected instance of class which extends utils.Hash');
  17. this.blockLen = this.iHash.blockLen;
  18. this.outputLen = this.iHash.outputLen;
  19. const blockLen = this.blockLen;
  20. const pad = new Uint8Array(blockLen);
  21. // blockLen can be bigger than outputLen
  22. pad.set(key.length > blockLen ? hash.create().update(key).digest() : key);
  23. for (let i = 0; i < pad.length; i++)
  24. pad[i] ^= 0x36;
  25. this.iHash.update(pad);
  26. // By doing update (processing of first block) of outer hash here we can re-use it between multiple calls via clone
  27. this.oHash = hash.create();
  28. // Undo internal XOR && apply outer XOR
  29. for (let i = 0; i < pad.length; i++)
  30. pad[i] ^= 0x36 ^ 0x5c;
  31. this.oHash.update(pad);
  32. pad.fill(0);
  33. }
  34. update(buf) {
  35. (0, _assert_js_1.exists)(this);
  36. this.iHash.update(buf);
  37. return this;
  38. }
  39. digestInto(out) {
  40. (0, _assert_js_1.exists)(this);
  41. (0, _assert_js_1.bytes)(out, this.outputLen);
  42. this.finished = true;
  43. this.iHash.digestInto(out);
  44. this.oHash.update(out);
  45. this.oHash.digestInto(out);
  46. this.destroy();
  47. }
  48. digest() {
  49. const out = new Uint8Array(this.oHash.outputLen);
  50. this.digestInto(out);
  51. return out;
  52. }
  53. _cloneInto(to) {
  54. // Create new instance without calling constructor since key already in state and we don't know it.
  55. to || (to = Object.create(Object.getPrototypeOf(this), {}));
  56. const { oHash, iHash, finished, destroyed, blockLen, outputLen } = this;
  57. to = to;
  58. to.finished = finished;
  59. to.destroyed = destroyed;
  60. to.blockLen = blockLen;
  61. to.outputLen = outputLen;
  62. to.oHash = oHash._cloneInto(to.oHash);
  63. to.iHash = iHash._cloneInto(to.iHash);
  64. return to;
  65. }
  66. destroy() {
  67. this.destroyed = true;
  68. this.oHash.destroy();
  69. this.iHash.destroy();
  70. }
  71. }
  72. exports.HMAC = HMAC;
  73. /**
  74. * HMAC: RFC2104 message authentication code.
  75. * @param hash - function that would be used e.g. sha256
  76. * @param key - message key
  77. * @param message - message data
  78. */
  79. const hmac = (hash, key, message) => new HMAC(hash, key).update(message).digest();
  80. exports.hmac = hmac;
  81. exports.hmac.create = (hash, key) => new HMAC(hash, key);
  82. //# sourceMappingURL=hmac.js.map