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,
byte[] checksum = getChecksum(versionPrivateAndCompressed);
byte[] versionPrivateCompressedAndChecksum = MyUtils.concatenateByteArrays(versionPrivateAndCompressed,
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.

  • 1
    How did you create and import that private key? – Pieter Wuille Jun 9 '17 at 17:31
  • 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 Jun 9 '17 at 17:47
  • @PieterWuille I updated my question with information about how I created/imported the private key – tobi Jun 9 '17 at 21:14
  • @Gopoi I see, but I think I also tried it with all FFFFs and it works. Will try it again tomorrow – tobi Jun 9 '17 at 21:16
  • 2
    Shouldn't privkeybytes be {255,255,255,...}? – Pieter Wuille Jun 9 '17 at 22:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.