browser-random.ts 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. "use strict";
  2. import { arrayify } from "@ethersproject/bytes";
  3. import { Logger } from "@ethersproject/logger";
  4. import { version } from "./_version";
  5. const logger = new Logger(version);
  6. // Debugging line for testing browser lib in node
  7. //const window = { crypto: { getRandomValues: () => { } } };
  8. // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis
  9. function getGlobal(): any {
  10. if (typeof self !== 'undefined') { return self; }
  11. if (typeof window !== 'undefined') { return window; }
  12. if (typeof global !== 'undefined') { return global; }
  13. throw new Error('unable to locate global object');
  14. };
  15. const anyGlobal = getGlobal();
  16. let crypto: any = anyGlobal.crypto || anyGlobal.msCrypto;
  17. if (!crypto || !crypto.getRandomValues) {
  18. logger.warn("WARNING: Missing strong random number source");
  19. crypto = {
  20. getRandomValues: function(buffer: Uint8Array): Uint8Array {
  21. return logger.throwError("no secure random source avaialble", Logger.errors.UNSUPPORTED_OPERATION, {
  22. operation: "crypto.getRandomValues"
  23. });
  24. }
  25. };
  26. }
  27. export function randomBytes(length: number): Uint8Array {
  28. if (length <= 0 || length > 1024 || (length % 1) || length != length) {
  29. logger.throwArgumentError("invalid length", "length", length);
  30. }
  31. const result = new Uint8Array(length);
  32. crypto.getRandomValues(result);
  33. return arrayify(result);
  34. };