utils.js 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. "use strict";
  2. /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
  3. Object.defineProperty(exports, "__esModule", { value: true });
  4. exports.randomBytes = exports.wrapXOFConstructorWithOpts = exports.wrapConstructorWithOpts = exports.wrapConstructor = exports.checkOpts = exports.Hash = exports.concatBytes = exports.toBytes = exports.utf8ToBytes = exports.asyncLoop = exports.nextTick = exports.hexToBytes = exports.bytesToHex = exports.isLE = exports.rotr = exports.createView = exports.u32 = exports.u8 = void 0;
  5. // We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
  6. // node.js versions earlier than v19 don't declare it in global scope.
  7. // For node.js, package.json#exports field mapping rewrites import
  8. // from `crypto` to `cryptoNode`, which imports native module.
  9. // Makes the utils un-importable in browsers without a bundler.
  10. // Once node.js 18 is deprecated, we can just drop the import.
  11. const crypto_1 = require("@noble/hashes/crypto");
  12. const u8a = (a) => a instanceof Uint8Array;
  13. // Cast array to different type
  14. const u8 = (arr) => new Uint8Array(arr.buffer, arr.byteOffset, arr.byteLength);
  15. exports.u8 = u8;
  16. const u32 = (arr) => new Uint32Array(arr.buffer, arr.byteOffset, Math.floor(arr.byteLength / 4));
  17. exports.u32 = u32;
  18. // Cast array to view
  19. const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
  20. exports.createView = createView;
  21. // The rotate right (circular right shift) operation for uint32
  22. const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);
  23. exports.rotr = rotr;
  24. // big-endian hardware is rare. Just in case someone still decides to run hashes:
  25. // early-throw an error because we don't support BE yet.
  26. exports.isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
  27. if (!exports.isLE)
  28. throw new Error('Non little-endian hardware is not supported');
  29. const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
  30. /**
  31. * @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
  32. */
  33. function bytesToHex(bytes) {
  34. if (!u8a(bytes))
  35. throw new Error('Uint8Array expected');
  36. // pre-caching improves the speed 6x
  37. let hex = '';
  38. for (let i = 0; i < bytes.length; i++) {
  39. hex += hexes[bytes[i]];
  40. }
  41. return hex;
  42. }
  43. exports.bytesToHex = bytesToHex;
  44. /**
  45. * @example hexToBytes('cafe0123') // Uint8Array.from([0xca, 0xfe, 0x01, 0x23])
  46. */
  47. function hexToBytes(hex) {
  48. if (typeof hex !== 'string')
  49. throw new Error('hex string expected, got ' + typeof hex);
  50. const len = hex.length;
  51. if (len % 2)
  52. throw new Error('padded hex string expected, got unpadded hex of length ' + len);
  53. const array = new Uint8Array(len / 2);
  54. for (let i = 0; i < array.length; i++) {
  55. const j = i * 2;
  56. const hexByte = hex.slice(j, j + 2);
  57. const byte = Number.parseInt(hexByte, 16);
  58. if (Number.isNaN(byte) || byte < 0)
  59. throw new Error('Invalid byte sequence');
  60. array[i] = byte;
  61. }
  62. return array;
  63. }
  64. exports.hexToBytes = hexToBytes;
  65. // There is no setImmediate in browser and setTimeout is slow.
  66. // call of async fn will return Promise, which will be fullfiled only on
  67. // next scheduler queue processing step and this is exactly what we need.
  68. const nextTick = async () => { };
  69. exports.nextTick = nextTick;
  70. // Returns control to thread each 'tick' ms to avoid blocking
  71. async function asyncLoop(iters, tick, cb) {
  72. let ts = Date.now();
  73. for (let i = 0; i < iters; i++) {
  74. cb(i);
  75. // Date.now() is not monotonic, so in case if clock goes backwards we return return control too
  76. const diff = Date.now() - ts;
  77. if (diff >= 0 && diff < tick)
  78. continue;
  79. await (0, exports.nextTick)();
  80. ts += diff;
  81. }
  82. }
  83. exports.asyncLoop = asyncLoop;
  84. /**
  85. * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
  86. */
  87. function utf8ToBytes(str) {
  88. if (typeof str !== 'string')
  89. throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
  90. return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
  91. }
  92. exports.utf8ToBytes = utf8ToBytes;
  93. /**
  94. * Normalizes (non-hex) string or Uint8Array to Uint8Array.
  95. * Warning: when Uint8Array is passed, it would NOT get copied.
  96. * Keep in mind for future mutable operations.
  97. */
  98. function toBytes(data) {
  99. if (typeof data === 'string')
  100. data = utf8ToBytes(data);
  101. if (!u8a(data))
  102. throw new Error(`expected Uint8Array, got ${typeof data}`);
  103. return data;
  104. }
  105. exports.toBytes = toBytes;
  106. /**
  107. * Copies several Uint8Arrays into one.
  108. */
  109. function concatBytes(...arrays) {
  110. const r = new Uint8Array(arrays.reduce((sum, a) => sum + a.length, 0));
  111. let pad = 0; // walk through each item, ensure they have proper type
  112. arrays.forEach((a) => {
  113. if (!u8a(a))
  114. throw new Error('Uint8Array expected');
  115. r.set(a, pad);
  116. pad += a.length;
  117. });
  118. return r;
  119. }
  120. exports.concatBytes = concatBytes;
  121. // For runtime check if class implements interface
  122. class Hash {
  123. // Safe version that clones internal state
  124. clone() {
  125. return this._cloneInto();
  126. }
  127. }
  128. exports.Hash = Hash;
  129. const toStr = {}.toString;
  130. function checkOpts(defaults, opts) {
  131. if (opts !== undefined && toStr.call(opts) !== '[object Object]')
  132. throw new Error('Options should be object or undefined');
  133. const merged = Object.assign(defaults, opts);
  134. return merged;
  135. }
  136. exports.checkOpts = checkOpts;
  137. function wrapConstructor(hashCons) {
  138. const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
  139. const tmp = hashCons();
  140. hashC.outputLen = tmp.outputLen;
  141. hashC.blockLen = tmp.blockLen;
  142. hashC.create = () => hashCons();
  143. return hashC;
  144. }
  145. exports.wrapConstructor = wrapConstructor;
  146. function wrapConstructorWithOpts(hashCons) {
  147. const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();
  148. const tmp = hashCons({});
  149. hashC.outputLen = tmp.outputLen;
  150. hashC.blockLen = tmp.blockLen;
  151. hashC.create = (opts) => hashCons(opts);
  152. return hashC;
  153. }
  154. exports.wrapConstructorWithOpts = wrapConstructorWithOpts;
  155. function wrapXOFConstructorWithOpts(hashCons) {
  156. const hashC = (msg, opts) => hashCons(opts).update(toBytes(msg)).digest();
  157. const tmp = hashCons({});
  158. hashC.outputLen = tmp.outputLen;
  159. hashC.blockLen = tmp.blockLen;
  160. hashC.create = (opts) => hashCons(opts);
  161. return hashC;
  162. }
  163. exports.wrapXOFConstructorWithOpts = wrapXOFConstructorWithOpts;
  164. /**
  165. * Secure PRNG. Uses `crypto.getRandomValues`, which defers to OS.
  166. */
  167. function randomBytes(bytesLength = 32) {
  168. if (crypto_1.crypto && typeof crypto_1.crypto.getRandomValues === 'function') {
  169. return crypto_1.crypto.getRandomValues(new Uint8Array(bytesLength));
  170. }
  171. throw new Error('crypto.getRandomValues must be defined');
  172. }
  173. exports.randomBytes = randomBytes;
  174. //# sourceMappingURL=utils.js.map