Come-from-Beyond (OP)
Legendary
Offline
Activity: 2142
Merit: 1010
Newbie
|
|
March 22, 2014, 05: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
|
|
|
|
Evil-Knievel
Legendary
Offline
Activity: 1260
Merit: 1168
|
|
March 22, 2014, 05:35:21 PM Last edit: April 15, 2016, 01:08:55 PM by Evil-Knievel |
|
This message was too old and has been purged
|
|
|
|
Come-from-Beyond (OP)
Legendary
Offline
Activity: 2142
Merit: 1010
Newbie
|
|
March 22, 2014, 05:39:29 PM |
|
I can only imagine this to be the flaw: 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: Curve25519-based EC-KCDSA is used for "generationSignature". This gives ability to generate blocks very fast using PoW approach. What is ur account id?
|
|
|
|
Evil-Knievel
Legendary
Offline
Activity: 1260
Merit: 1168
|
|
March 22, 2014, 05:49:01 PM Last edit: April 15, 2016, 01:08:49 PM by Evil-Knievel |
|
This message was too old and has been purged
|
|
|
|
CIYAM
Legendary
Offline
Activity: 1890
Merit: 1086
Ian Knowles - CIYAM Lead Developer
|
|
March 22, 2014, 05:50:13 PM |
|
WOOOOOOOOOOOOOOOOOOOOOOOOOOOW! THANKS!
Well done - you nailed it!
|
|
|
|
Come-from-Beyond (OP)
Legendary
Offline
Activity: 2142
Merit: 1010
Newbie
|
|
March 22, 2014, 05:51:12 PM |
|
WOOOOOOOOOOOOOOOOOOOOOOOOOOOW! THANKS!
Appreciate that bounty, my account is: 15421585458835302363
Tx id = 15276301139303497578
|
|
|
|
TwinWinNerD
Legendary
Offline
Activity: 1680
Merit: 1001
CEO Bitpanda.com
|
|
March 22, 2014, 05:53:16 PM |
|
I can only imagine this to be the flaw: 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: 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
|
|
|
|
BloodyRookie
|
|
March 22, 2014, 05: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.
|
Nothing Else Matters NEM: NALICE-LGU3IV-Y4DPJK-HYLSSV-YFFWYS-5QPLYE-ZDJJ NXT: 11095639652683007953
|
|
|
Conurtrol
|
|
March 22, 2014, 05:54:26 PM |
|
100,000 Nxt right now is worth ~4k. Congrats Evil-Kneivel!
|
|
|
|
Come-from-Beyond (OP)
Legendary
Offline
Activity: 2142
Merit: 1010
Newbie
|
|
March 22, 2014, 06: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) */
|
|
|
|
BloodyRookie
|
|
March 22, 2014, 06: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.
|
Nothing Else Matters NEM: NALICE-LGU3IV-Y4DPJK-HYLSSV-YFFWYS-5QPLYE-ZDJJ NXT: 11095639652683007953
|
|
|
|
Come-from-Beyond (OP)
Legendary
Offline
Activity: 2142
Merit: 1010
Newbie
|
|
March 22, 2014, 06: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).
|
|
|
|
BloodyRookie
|
|
March 22, 2014, 06:28:36 PM |
|
Plz be more specific: Which input to the signing method are you changing? Can you give some code?
|
Nothing Else Matters NEM: NALICE-LGU3IV-Y4DPJK-HYLSSV-YFFWYS-5QPLYE-ZDJJ NXT: 11095639652683007953
|
|
|
Evil-Knievel
Legendary
Offline
Activity: 1260
Merit: 1168
|
|
March 22, 2014, 06:31:56 PM Last edit: April 15, 2016, 01:08:39 PM by Evil-Knievel |
|
This message was too old and has been purged
|
|
|
|
Come-from-Beyond (OP)
Legendary
Offline
Activity: 2142
Merit: 1010
Newbie
|
|
March 22, 2014, 06: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.
|
|
|
|
Come-from-Beyond (OP)
Legendary
Offline
Activity: 2142
Merit: 1010
Newbie
|
|
March 22, 2014, 06: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.
|
|
|
|
Come-from-Beyond (OP)
Legendary
Offline
Activity: 2142
Merit: 1010
Newbie
|
|
March 22, 2014, 06: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. /* 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.
|
|
|
|
BloodyRookie
|
|
March 22, 2014, 06: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
|
Nothing Else Matters NEM: NALICE-LGU3IV-Y4DPJK-HYLSSV-YFFWYS-5QPLYE-ZDJJ NXT: 11095639652683007953
|
|
|
Evil-Knievel
Legendary
Offline
Activity: 1260
Merit: 1168
|
|
March 22, 2014, 06:48:04 PM Last edit: April 15, 2016, 02:14:01 PM by Evil-Knievel |
|
This message was too old and has been purged
|
|
|
|
|