hmac.js 3.1 KB

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