Pages:
Author

Topic: Nxt source code flaw reports - page 3. (Read 113312 times)

hero member
Activity: 687
Merit: 500
March 22, 2014, 02:45:56 PM
Plz be more specific:
Which input to the signing method are you changing? Can you give some code?

Something like that:
(some code)
Edit: I'm not sure this code is correct, though. Better read about "ephemeral" keys, how they r generated.

Now I get what you mean, thx Smiley
legendary
Activity: 2142
Merit: 1009
Newbie
March 22, 2014, 02:45:07 PM
Sure, the private key is just the number of times you incremented your Public Key by 9 (which has to be set to 9 itself in the beginning).

Check your comment in the core function of Curve25519.java.

Code:
/* P = kG   and  s = sign(P)/k  */

The public key is just a k * G ( G = 9 = basepoint). k is directly proportional to s which is the private key for signing.
Keep a counter which counts how many times you incremented P by 9, and this counter equals to the private key.
When staying inside a long data-field you do not even do stuff like montgomery or modulo operation for that.

You get a perfectly fine Public/Private Key pair, and if SHA256(PublicKey) matches the AccountID (targeted) in the first 8 bytes, you have taken over that account.

Great! We'll get "lost" NXT much sooner than expected.
legendary
Activity: 2142
Merit: 1009
Newbie
March 22, 2014, 02:36:47 PM
To be more precise, you can theoretically "mine" twice as fast as the BTC Mining Hardware (as you only need one round of sha256 and the Curve25519 stuff comes at no cost as it is just incerementing the pubkey by 9 = basepoint in each round). So on a FPGA you could try 1,6 billion accounts per second, and on a 7990 GPU around 4 billion accounts per second. Only a matter of time, until you find one public key, which SHA256 hash matches an existing account in the first 8 bytes.

Interesting approach! Can u get the private key out of this? Or sign a transaction?

PS: Ability to "mine" accounts not secured by a 256-bit key was made on purpose.
legendary
Activity: 2142
Merit: 1009
Newbie
March 22, 2014, 02:34:01 PM
Plz be more specific:
Which input to the signing method are you changing? Can you give some code?

Something like that:



      static byte[] sign(byte[] message, String secretPhrase) {
         
         try {
            
            byte[] P = new byte[32];
            byte[] s = new byte[32];
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            Curve25519.keygen(P, s, digest.digest(secretPhrase.getBytes("UTF-8")));
            
            byte[] m = digest.digest(message);
            
            digest.update(m);
            //byte[] x = digest.digest(s);
            digest.update(s);
            byte[] x = digest.digest(nonce);
            
            byte[] Y = new byte[32];
            Curve25519.keygen(Y, null, x);
            
            digest.update(m);
            byte[] h = digest.digest(Y);
            
            byte[] v = new byte[32];
            Curve25519.sign(v, h, x, s);
            
            byte[] signature = new byte[64];
            System.arraycopy(v, 0, signature, 0, 32);
            System.arraycopy(h, 0, signature, 32, 32);
            
            return signature;
            
         } catch (Exception e) {
            
            return null;
            
         }
         
      }


Edit: I'm not sure this code is correct, though. Better read about "ephemeral" keys, how they r generated.
legendary
Activity: 1260
Merit: 1168
March 22, 2014, 02:31:56 PM
This message was too old and has been purged
hero member
Activity: 687
Merit: 500
March 22, 2014, 02:28:36 PM
Plz be more specific:
Which input to the signing method are you changing? Can you give some code?
legendary
Activity: 2142
Merit: 1009
Newbie
March 22, 2014, 02:20:08 PM
So? If he uses a different private key this corresponds to a different account and that account doesn't have any nxt in it so he can't forge.
In real EC-KCDSA you get different signatures for the same private key every time you sign because a random number is involved.

Edit: That's the reason why you are not allowed to forge with some new account that has nxt on it with less than x confirmations.

Look at the code that generates ephemeral key for signing. It contains SHA256(message), but u can replace it with SHA256(message, nonce) and do good old mining by incrementing nonces. All such signatures will still be valid (if that sign issue is fixed) and noone will ever know if u used SHA256(message) or SHA256(message, nonce).
hero member
Activity: 910
Merit: 1000
March 22, 2014, 02:15:04 PM
Grats!
hero member
Activity: 687
Merit: 500
March 22, 2014, 02:11:05 PM
Grats!
But, what random k? Nxt implementation is not exactly EC-KCDSA. You get the same signature every time if the input message is the same.

Check code near this comment:

      /* Signature generation primitive, calculates (x-h)s mod q
       *   v  [out] signature value
       *   h  [in]  signature hash (of message, signature pub key, and context data)
       *   x  [in]  signature private key
       *   s  [in]  private key for signing
       * returns true on success, false on failure (use different x or h)
       */


So? If he uses a different private key this corresponds to a different account and that account doesn't have any nxt in it so he can't forge.
In real EC-KCDSA you get different signatures for the same private key every time you sign because a random number is involved.

Edit: That's the reason why you are not allowed to forge with some new account that has nxt on it with less than x confirmations.
legendary
Activity: 2142
Merit: 1009
Newbie
March 22, 2014, 02:06:25 PM
Grats!
But, what random k? Nxt implementation is not exactly EC-KCDSA. You get the same signature every time if the input message is the same.

Check code near this comment:

      /* Signature generation primitive, calculates (x-h)s mod q
       *   v  [out] signature value
       *   h  [in]  signature hash (of message, signature pub key, and context data)
       *   x  [in]  signature private key
       *   s  [in]  private key for signing
       * returns true on success, false on failure (use different x or h)
       */
sr. member
Activity: 478
Merit: 250
March 22, 2014, 01:54:26 PM
100,000 Nxt right now is worth ~4k. Congrats Evil-Kneivel!
hero member
Activity: 687
Merit: 500
March 22, 2014, 01:53:56 PM
Grats!
But, what random k? Nxt implementation is not exactly EC-KCDSA. You get the same signature every time if the input message is the same.
legendary
Activity: 1680
Merit: 1001
CEO Bitpanda.com
March 22, 2014, 01:53:16 PM
I can only imagine this to be the flaw:

Code:
if (lastBlock.getHeight() < Constants.TRANSPARENT_FORGING_BLOCK) {
                byte[] generationSignature = Crypto.sign(lastBlock.getGenerationSignature(), secretPhrase);
                generationSignatureHash = digest.digest(generationSignature);
            } else {
                digest.update(lastBlock.getGenerationSignature());
                generationSignatureHash = digest.digest(publicKey);
            }

            BigInteger hit = new BigInteger(1, new byte[] {generationSignatureHash[7], generationSignatureHash[6], generationSignatureHash[5], generationSignatureHash[4], generationSignatureHash[3], generationSignatureHash[2], generationSignatureHash[1], generationSignatureHash[0]});

So forging before the Transparent Forging Block is really vulnerable to "Mining".
After the transparent forging block you take the generation signature and use the hash of it to look which user gets rewarded with the fees. Before the transparent forging block, the hash of a SIGNATURE of the GenerationSignature has to meet certain criteria. Due to the random "k" in the signing process, you get different values when resigning.

Here you can just start mining with a decent hardware, resigning the generation signature until one of their hashes meets the requirements to collect the fees.

Description of the flaw:

Code:
Curve25519-based EC-KCDSA is used for "generationSignature". This gives ability to generate blocks very fast using PoW approach.

What is ur account id?


WOOOOOOOOOOOOOOOOOOOOOOOOOOOW! THANKS!

Appreciate that bounty,
my account is: 15421585458835302363

And now you share with the community! Do a giveaway Wink
legendary
Activity: 2142
Merit: 1009
Newbie
March 22, 2014, 01:51:12 PM
WOOOOOOOOOOOOOOOOOOOOOOOOOOOW! THANKS!

Appreciate that bounty,
my account is: 15421585458835302363

Tx id = 15276301139303497578
legendary
Activity: 1890
Merit: 1078
Ian Knowles - CIYAM Lead Developer
March 22, 2014, 01:50:13 PM
WOOOOOOOOOOOOOOOOOOOOOOOOOOOW! THANKS!

Well done - you nailed it!
legendary
Activity: 1260
Merit: 1168
March 22, 2014, 01:49:01 PM
This message was too old and has been purged
legendary
Activity: 2142
Merit: 1009
Newbie
March 22, 2014, 01:39:29 PM
I can only imagine this to be the flaw:

Code:
if (lastBlock.getHeight() < Constants.TRANSPARENT_FORGING_BLOCK) {
                byte[] generationSignature = Crypto.sign(lastBlock.getGenerationSignature(), secretPhrase);
                generationSignatureHash = digest.digest(generationSignature);
            } else {
                digest.update(lastBlock.getGenerationSignature());
                generationSignatureHash = digest.digest(publicKey);
            }

            BigInteger hit = new BigInteger(1, new byte[] {generationSignatureHash[7], generationSignatureHash[6], generationSignatureHash[5], generationSignatureHash[4], generationSignatureHash[3], generationSignatureHash[2], generationSignatureHash[1], generationSignatureHash[0]});

So forging before the Transparent Forging Block is really vulnerable to "Mining".
After the transparent forging block you take the generation signature and use the hash of it to look which user gets rewarded with the fees. Before the transparent forging block, the hash of a SIGNATURE of the GenerationSignature has to meet certain criteria. Due to the random "k" in the signing process, you get different values when resigning.

Here you can just start mining with a decent hardware, resigning the generation signature until one of their hashes meets the requirements to collect the fees.

Description of the flaw:

Code:
Curve25519-based EC-KCDSA is used for "generationSignature". This gives ability to generate blocks very fast using PoW approach.

What is ur account id?
legendary
Activity: 1260
Merit: 1168
March 22, 2014, 01:35:21 PM
This message was too old and has been purged
legendary
Activity: 2142
Merit: 1009
Newbie
March 22, 2014, 01:33:15 PM
Also being an intresting riddle, the description "It is a fatal flaw but NXT is safe from that" from the logical point of view implies, that this is no flaw at all. Am I correct on this one?

No
legendary
Activity: 2142
Merit: 1009
Newbie
March 22, 2014, 01:31:25 PM
I didn't take a look at the current version, so let's say we take some version before JL removed "some code". Could you bring it down in a day?


If I answered then u could compare these versions and claim the price.  Wink
Pages:
Jump to: