1

For some reason, my React Native 0.68.0 app needs to generate private key for the Ethers wallet providing accessing to crypto.getRandomValues. The crypto.getRandomValues is polyfilled by react-native-get-random-values. I am not certain if the key generated as such is valid and cryptographically secure to serve as ether wallet private key. Any comments would be appreciated. Here is the code:

  const uint8Arr = (n) => {. //generate an insecure uint8 array
    let arr = new Uint8Array(n);
    for (let i=0;i<n;i++) {
      let t = Math.floor(Math.random()*256) ;  //0-255
      arr[i] = t;
    };
    return arr;
  };

      //code to generate private key
      let arr8 = uint8Arr(32); //get an insecure uint8 array     
      console.log("uint8 array x 32 : ", arr8);
      global.crypto.getRandomValues(arr8);  //feed the uint8 array above to crypto.getRandomValues for a secure random uint8 array
      console.log("global.crypto.getrandomvalues(32) : ", arr8);
      console.log("ethers.utils.hexlify : ", ethers.utils.hexlify(arr8));  //convert uint8 array to private key in hex format

Here is the console output:

 LOG  uint8 array x 32 :  [119, 76, 149, 66, 179, 200, 114, 164, 68, 245, 67, 243, 107, 67, 102, 84, 247, 218, 83, 235, 244, 236, 138, 202, 10, 216, 193, 240, 55, 151, 148, 39]
 LOG  global.crypto.getrandomvalues(32) :  [61, 44, 150, 52, 36, 4, 112, 127, 66, 105, 128, 176, 63, 94, 238, 213, 176, 58, 154, 210, 114, 68, 185, 20, 79, 240, 229, 110, 198, 207, 20, 209]
 LOG  ethers.utils.hexlify :  0x3d2c96342404707f426980b03f5eeed5b03a9ad27244b9144ff0e56ec6cf14d1. //<<==private key generated

Is the key generated by code above valid and cryptographically secure as ether wallet private key?

1

2 Answers 2

1

I don't think there is a way to generate fully random keys with regular hardware. All the keys you generate are pseudo-random - but in most of the cases that's just fine.

Nothing stops you from generating your key analogically. You could for example roll a die enough times to generate a key. I'm not an expert in this, but my guess is that that will give you even worse results, regarding randomness.

In the end, you should trust some code/tool to generate the randomness for you. Yes, it won't be 100% random, but it will be random enough that nobody else has any way to determine the key. That's how 99,99% of keys are formed anyway - some tool somewhere generates the key, and I doubt many keys are cracked based on their lack of randomness. Keys are exposed mostly due to human error.

2
  • It is true that there is hardly a true random implementation programatically. Here the critical piece is the crypto.getRandomValues polyfilled by react-native-get-random-values which claims cryptographically secure randomness. But with security it seems always have something we don't know now. Trying to avoid known pitfalls.
    – user938363
    Commented May 6, 2022 at 19:59
  • Sorry, questions like "how good randomness does a JS function X provide" is a bit out of my league, and not very suited for this community either. You should probably ask in some math/js forum Commented May 7, 2022 at 13:15
0

Using the crypto.getRandomValues is cryptographically secure, using Math.random is not (in general).

In some browsers, Math.random uses cryptographically secure sources, but that should not be relied on.

The crypto.getRandomValues uses an OS level random source, which is regularly stirred with keystrokes, network packets, BLE noise and these days using hardware RNGs that are usually built into CPUs and secure enclaves.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.