1
1
In secp256k1 (Bitcoin's elliptic curve) it is defined that valid private keys may range from 1 to FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE BAAEDCE6 AF48A03B BFD25E8C D0364141 - 1. (https://crypto.stackexchange.com/questions/30269/are-all-possible-ec-private-keys-valid)
However I created an EC Keypair with the private key being FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFFE imported it into bitcoin core and sent a small amount of btc to the corresponding bitcoin address. I was able to spend these coins. Does that mean that bitcoin does not follow this restriction and any combination of 256 bits is a valid private key for bitcoin? Or might it be a bug that could get fixed in future?
I'm currently myself deriving bitcoin private keys/addresses from a seed and importing them via json-rpc. I saw that implementations of e.g. BouncyCastle check whether an EC is in that forbidden range. I currently don't do that but I also think that even if bitcoin wouldn't accept such keys the probability of deriving a private key in that forbidden range is too low to justify the additional implementation complexity (at least in my case). Is that problematic?
Update - Here's how I created the private key:
byte[] privKeyBytes = {1,1,1,1,1,1,1,1,...,1,1,1,0};
byte[] version = { (byte) 128 }
byte[] privateBytesPlusVersion = MyUtils.concatenateByteArrays(version, privKeyBytes);
byte[] versionPrivateAndCompressed = MyUtils.concatenateByteArrays(privateBytesPlusVersion,
COMPRESS_BYTE);
byte[] checksum = getChecksum(versionPrivateAndCompressed);
byte[] versionPrivateCompressedAndChecksum = MyUtils.concatenateByteArrays(versionPrivateAndCompressed,
checksum);
String privKeyDump = Base58.encode(versionPrivateCompressedAndChecksum);
The Base58 class is from BitcoinJ. I then imported this string via json-rpc with importprivkey
Update2 - As Pieter Wuille pointed out I had an error as privKeyBytes {1,1,1,...,1} is not 'FFFFF...FFF'. I tried to import such a private key again and bitcoins rpc interface answered with an error: "Private key outside allowed range". I'm still tempted to not check for this range as the probability of me generating something with 120 1 bits at the beginning seems low enough to discard that case.
1How did you create and import that private key? – Pieter Wuille – 2017-06-09T17:31:08.427
Thing is the way it was imported may have considered it a little endian 256 bit number, that would lead to FEFFFFFF .... which is lower than the maximum. – Gopoi – 2017-06-09T17:47:32.243
@PieterWuille I updated my question with information about how I created/imported the private key – tobi – 2017-06-09T21:14:53.070
@Gopoi I see, but I think I also tried it with all FFFFs and it works. Will try it again tomorrow – tobi – 2017-06-09T21:16:01.297
2Shouldn't privkeybytes be {255,255,255,...}? – Pieter Wuille – 2017-06-09T22:30:44.697
@PieterWuille: Java
byteis signed (two's-complement), so255is not permitted;-1is, and(byte)255is the same as-1but in this context clearer. It is treated as unsigned in some contexts, including bitcoin and crypto, by masking with&0xFF. – dave_thompson_085 – 2017-06-09T23:31:08.990why not to use byte[] privKeyBytes ={0xFF,0xFF,0xFF,0xFF,....,0x00} – Badr Bellaj – 2017-06-09T23:32:28.337
The code you pasted is {1,1,1,1,...} not {-1,-1,-1,...}. – Pieter Wuille – 2017-06-10T00:00:27.673
Can you share the address you generated? – Pieter Wuille – 2017-06-10T00:00:40.613
@PieterWuille you're totally right and I'm quite sure I did not use {1,1,1,..,1} It was just temporary test code that I don't have anymore so I recalled from my memory. I'll right now play it through again and update my post – tobi – 2017-06-10T12:21:03.717
@PieterWuille alright, I tried it again and this time bitcoind answered with "Private key outside allowed range". So probably I also did that wrong the first time I tried it. Do you see a problem with me still not checking that case? When I maybe generate a couple thousand private keys a day it seems not really realistic to generate one with FFFFFFFF FFFFFFFF FFFFFFFF FFFFFFF at the beginning – tobi – 2017-06-10T14:13:10.360
well.. I'm checking the range now anyway. – tobi – 2017-06-10T15:34:43.783
Accidentally hitting one of those numbers outside of the range is about as hard as solving the ECDLP problem (what you'd need to do if you wanted to steal coins with just the public key). That's only the case for secp256k1; other curves may have a ln order that's far further from a power of 2. – Pieter Wuille – 2017-06-11T17:13:15.980