Nxt Forum

Please login or register.

Login with username, password and session length
Advanced search  

News:

Latest Nxt Client 1.11.5 - NEW RELEASE: Ardor 2.0.3e TestNet IS LAUNCHED!

Pages: [1]

Author Topic: NXT Client Passphrase - RNG, number of bits, etc  (Read 674 times)

sile16

  • Jr. Member
  • **
  • Offline Offline
  • Posts: 38
    • View Profile
    • Everyday Crypto
  • Karma: +6/-0


I've been looking at the passphrasegenerator.js and a couple thoughts came up

=====  RNG   ==============


1.  It looks like crypto.getRandomValues() is used directly if available and no other sources added.  While technically this should be okay, I believe this same function is what had issues on android.  So, I wonder if we should add in an additional random source via seedrandom.js + mouse movement.  I believe a valid way to combine two random sources is to just XOR both outputs together.  Of course that does put some risk that the XOR process could somehow be implemented incorrectly.  Just concerned at some future point in time another browser could have an issue with their RNG.

2.  For older browsers who don't implement crypto.getRandomValues(), we collect 512 mouse, x, y, and +Date values as entropy to the RNG by David Bau (seedrandom.js).  1st concern is that we collect the entropy and then call math.random() 12 times one for each word.  Because we collect all the entropy and then call math.random repeatedly, my concern is that by the last time we call random it may not be as of high quality.  Each call returns a double float with about 2^62 bits of entropy per call.  That is why i'm thinking we may be draining our entropy pool pretty quick.

(Disclaimer this goes beyond my knowledge of if this is really a concern or not but that's why I'm bringing it up here.)

Possible improvements (not sure if these are good or not):
Option 1.   Use fewer calls to Math.random (<12) , such as   Math.random() * wordCount^4 , so that we can encode our 12 word phrase with 4 calls to Math.random.

Option 2.  Instead of grabbing all the entropy up front and then calling Math.random, maybe break up the entropy collection so that you grab 128 data points and then generate the first 4 words and then grab another 128 data points and generate the next 4 words, etc.

3.  On each each mouse move for entropy collection we are grabbing x, y, +Date.  I think we should also include system.perfomance.now as it will uS resoutions giving a good bit more entropy than the mS resolution of +Date.  I know it also relatively new but I think we should fail rather than generate crappy private keys because some user tried to use NXT from IE7


========  Password Length   ========

I'm of the opinion that if we are going to derive all private key from a passphrase we should use the entire 256 bit keyspace.  Why use 256bit for private key if we are only going to use 128bits for the passphrase.  Using a word list of 20k words and 18 words you can get more than 256 bits.  I've got a list of the top 20000 words said on television and the words arn't that crazy even on the bottom of the list.  Or you could go a little longer and cut down the word list.  The point is that with a 12 word passphrase only our mensa users are going to be memorizing it.  I think everyone else is going to be writing it down or using a password manager.

If we want to create an easier way to login, we create an unlock password that is salted and PBKDF2, similar and use that result to unlock an AES256 encrypted version of the private key.  (I think a similar process is defined in Bitcoin as BIP38, I haven't read the details though)

You have your Account Recovery code (long passphrase), and your local account password that is specific to that device.  Actually this is how Qora works.

Oh, one other random thought... I think we should provide a warning before anyone sends over 1000 NXT to an address that hasn't broadcasted it's public key.  Otherwise, again we have people relying on 64bit security.
 

Eadeqa

  • Hero Member
  • *****
  • Offline Offline
  • Posts: 1888
    • View Profile
  • Karma: +83/-68


1.  It looks like crypto.getRandomValues() is used directly if available and no other sources added.  While technically this should be okay, I believe this same function is what had issues on android. 

This has nothing to do with Android problem (where apps are written in Java) where issue was that Android operating system was not seeding random function  properly but resortinng to 64-bit seed in some cases. Wesley client is written in Javascript (not Java) and the browser gets it's entropy from native operating system. 

No relation to Android, but Android bug was fixed a while ago.

Quote
2.  For older browsers who don't implement crypto.getRandomValues(), we collect 512 mouse, x, y, and +Date values as entropy to the RNG by David Bau (seedrandom.js). 

This would be used only for people who are using IE 10 (and older) as all newer browser support crypto.getRandomValues(). In any case, the person who looked at the code here thinks the code is fine:

http://security.stackexchange.com/questions/53659/is-this-password-generator-safe


Quote
I'm of the opinion that if we are going to derive all private key from a passphrase we should use the entire 256 bit keyspace.  Why use 256bit for private key if we are only going to use 128bits for the passphrase. 

Even though the public key is 256 bits, the security strength of curve25519 and bitcoin's Secp256k1  is only 128 bits. In other words, anyone who can break 128 bits random passwords (highly unlikely) can just as well break Secp256k1  /curve25519.

Just because the public key is 256 bits doesn't mean it has 256 bits of security. For example, RSA 1024 has 1024 bits of key but special algorithms can break RSA 1024 in 80 bits of operations,

128 bits is pretty safe from brute force attack

https://en.wikipedia.org/wiki/Brute-force_attack

Quote
There is a physical argument that a 128-bit symmetric key is computationally secure against brute-force attack. The so-called Landauer limit implied by the laws of physics sets a lower limit on the energy required to perform a computation of kT  · ln 2 per bit erased in a computation, where T is the temperature of the computing device in kelvins, k is the Boltzmann constant, and the natural logarithm of 2 is about 0.693. No irreversible computing device can use less energy than this, even in principle.[2] Thus, in order to simply flip through the possible values for a 128-bit symmetric key (ignoring doing the actual computing to check it) would theoretically require 2128 − 1 bit flips on a conventional processor. If it is assumed that the calculation occurs near room temperature (~300 K) the Von Neumann-Landauer Limit can be applied to estimate the energy required as ~1018 joules, which is equivalent to consuming 30 gigawatts of power for one year. This is equal to 30×109 W×365×24×3600 s = 9.46×1017 J or 262.7 TWh (more than 1/100th of the world energy production).[citation needed] The full actual computation – checking each key to see if you have found a solution – would consume many times this amount. Furthermore, this is simply the energy requirement for cycling through the key space; the actual time it takes to flip each bit is not considered, which is certainly greater than 0.

 
« Last Edit: July 02, 2014, 06:00:03 am by Eadeqa »
NXT-GZYP-FMRT-FQ9K-3YQGS

v39453

  • Full Member
  • ***
  • Offline Offline
  • Posts: 155
    • View Profile
  • Karma: +12/-2

Oh, one other random thought... I think we should provide a warning before anyone sends over 1000 NXT to an address that hasn't broadcasted it's public key.  Otherwise, again we have people relying on 64bit security.

Warnings are too easy to ignore. I would rather have the client register the public key automatically. Immediately after the first incoming transaction is received, a dialog is shown that says: "Your account has to be initialized. This will cost 1 NXT. Proceed?". There would be only one option: "Ok".

sile16

  • Jr. Member
  • **
  • Offline Offline
  • Posts: 38
    • View Profile
    • Everyday Crypto
  • Karma: +6/-0

First of all, thank you for taking the time to respond.  It's good that the community has people activity discussing these topics.  Also, btw, I found a similar thread (while looking for something else at : https://nxtforum.org/nxt-improvement-proposals/password-derivation-option/ )

Quick summary of this post:  There is nothing alarming here, but I think it could be improved slightly.

Still here? 
Details:

As for the 128bit strength of the crypto that was news to me, after reading more about ed25519, it seems as though 2^128 is the target strength but actually it has about 2^140 to the best of our knowledge.  (Curious if i'm reading that correctly or still missing something)

_http://ed25519.cr.yp.to/
Quote
High security level. This system has a 2^128 security target; breaking it has similar difficulty to breaking NIST P-256, RSA with ~3000-bit keys, strong 128-bit block ciphers, etc. The best attacks known actually cost more than 2^140 bit operations on average, and degrade quadratically in success probability as the number of bit operations drops.

Also, for the browsers who support windows.crypto.getRandomValues, we just read that data in directly... people with their tin foil hats on may be uncomfortable with that.

I think the best approach would be to utilize the SJCL library at: _https://github.com/bitwiseshiftleft/sjcl/blob/master/core/random.js

This library already has coded in the collection of entropy from:
1. Mouse movement
2. Keypress
3. Page Load Stats
4. Date
5. Window.crypto.getRandomValues as entropy source (if available)

Additionally it keeps track of how much entropy it has and will only provide values that are safe.  So, this takes care of all of my concerns in the original post about collecting enough entropy properly.  Also, it takes care of the tin foil hat guys around using getRandomValues directly as well as my concern that in any given browser it could have some kind of weakness. 

Finally, targeting 160, or even better 256 bits of entropy in the passphrase is just extra insurance that if for some reason a weakness was found in the sjcl prng that takes it from 2^n -> 2^n/2 we would still be okay because our implementation targeted a much higher than needed entropy.

The implementation on the NXT client side would simply be:

<pseudo code>
var prng = new sjcl.random(256 bits)
prng.startCollection()
... Wait until prng.isReady
var random = prng.getRandomValues(256 bits)
generatePhraseFromRandom(random)  // just a straight translation from bits to words.

All that being said I'm not sure if any of these reasons are enough to go back and makes changes at this point in time as there is so much to do.  But maybe at some point these changes can be made.

As far as the current implementation, I'd be willing to go in and add comments to the existing code that incorporates much of what we have talked about here so future reviewers can have this information inline.   Not sure how to go about doing that though. 

================    Sending to (non verified?) NXT Account    =====================

Auto registering of an account is a great idea.  However, that still doesn't stop someone from sending money to an account id that hasn't been verified.  If not a warning, just flat out don't allow it.  People who want to go around that can use the API directly.



 

Eadeqa

  • Hero Member
  • *****
  • Offline Offline
  • Posts: 1888
    • View Profile
  • Karma: +83/-68

As for the 128bit strength of the crypto that was news to me, after reading more about ed25519, it seems as though 2^128 is the target strength but actually it has about 2^140 to the best of our knowledge.  (Curious if i'm reading that correctly or still missing something)

Here is a quote from gmaxwell (bitcoin core developer) about

Quote
ECDSA is not a hash function. At attacker with the pubic key isn't confined to use the dumbest possible brute-force attack.

Pollard's lambda algorithm takes sqrt() operations— so roughly 2^128 security.

In a video lecture someone posted a while ago, same is true for curve25519
https://www.youtube.com/watch?v=dFUJmzcj0iw

NXT-GZYP-FMRT-FQ9K-3YQGS

Brangdon

  • Hero Member
  • *****
  • Offline Offline
  • Posts: 1218
  • Quality is addictive.
    • View Profile
  • Karma: +203/-25

Auto registering of an account is a great idea.  However, that still doesn't stop someone from sending money to an account id that hasn't been verified.  If not a warning, just flat out don't allow it.  People who want to go around that can use the API directly.
Sending coins to an unverified account is the only way to give it a balance so that it can make an out-going transaction. One problem with trying to limit the amount is that the initial send often comes from an exchange. New users go to an exchange, buy NXT, and try to send them to their account. So to mess with that initial transaction we would need cooperation from the exchanges. They control the user experience and would need to be on board with reporting a nice error message to the user.

A second problem is that it adds an extra step to setting up an account; a process which is fairly complicated already, especially if you need to buy BTC before you can buy NXT.
NXT-RTYD-LJXQ-EPNJ-H7AQ5. Sponsoring 1 public node at brangdon.duckdns.org.
Pages: [1]