3

I've read the article from Unciphered about it, multiple times, and still fail to understand it

It basically says that wallets generated by BitcoinJs front end library from 2011 to 2015 are vulnerable because of the poor randomness generation. Especially those generated between May 4, 2011 to March 2012

But it's really vague on explaining what the actual exploit is. It could be just summarized as: it used Math.random() for randomness before March 2014, and it is a bad function

Let's look at the initial commit from March 4, 2011 : eckey.js is used for generating the private key, while rng.js and prng4.js in the jsbn folder are used for harvesting randomness.

rng.js

If rng_pool is not already initialized, it is filled with random values from Math.random()

while(rng_pptr < rng_psize) {  // extract some randomness from Math.random()
    t = Math.floor(65536 * Math.random());
    rng_pool[rng_pptr++] = t >>> 8;
    rng_pool[rng_pptr++] = t & 255;
  }

Math.random() according to the article has the cycle of 2^60 values before they repeat. The article also mentions that it fails modern benchmark tests, but I'm not sure about them

Is Math.random() the whole weakness of the story? What is the weakness actually about?

Later, the time in milliseconds is seeded to the pool

function rng_seed_time() {
  rng_seed_int(new Date().getTime());
}

And later for

SecureRandom.prototype.nextBytes = rng_get_bytes;

we initialize the state, and pass the pool as the key into the RC4 cipher

rng_state = prng_newstate();
rng_state.init(rng_pool);

from prng4.js

prng4.js

which creates a 256 value array

this.S = new Array();

and fills it with the loop

for(i = 0; i < 256; ++i) {
    j = (j + this.S[i] + key[i % key.length]) & 255;
    t = this.S[i];
    this.S[i] = this.S[j];
    this.S[j] = t;
  }

eckey.js

eckey.js uses SecureRandom() and creates our private key

var rng = new SecureRandom();
....
this.priv = ECDSA.getBigRandom(n);

But again, this tells us next to nothing about the actual vulnerability and what attacks might be used. Unciphered's article suggests that if we have GUID or IV (I guess that's a public key?), then we can do the work with just 2^32 to 2^64 values (2^48 most commonly)

Also, not sure about the clicks being added in the entropy pool, apart from:

<body onClick='rng_seed_time();' onKeyPress='rng_seed_time();'> comment.

In what way, other things are added into entropy pool apart from the initial timestamp seed?

Edit July 23, 2024:

Sorry, I forgot that ecdsa.js also has its own context

ecdsa.js

Basically, getBigRandom() method is realized in this file with rng = new SecureRandom();

Bitcoin.ECDSA = (function () {
var ecparams = getSECCurveByName("secp256k1");
var rng = new SecureRandom();
....
var ECDSA = {
getBigRandom: function (limit) {
return new BigInteger(limit.bitLength(), rng)
.mod(limit.subtract(BigInteger.ONE))
.add(BigInteger.ONE)
;
},

.

0

Your Answer

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