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.

13
  • 1
    How did you create and import that private key? Commented Jun 9, 2017 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
    Commented Jun 9, 2017 at 17:47
  • @PieterWuille I updated my question with information about how I created/imported the private key
    – tobi
    Commented Jun 9, 2017 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
    Commented Jun 9, 2017 at 21:16
  • 3
    Shouldn't privkeybytes be {255,255,255,...}? Commented Jun 9, 2017 at 22:30

1 Answer 1

3

since the group is cyclic with order N, then this key will be equal to 0x14551231950b75fc4402da1732fc9bebd (your key modulo N)

>>> hex(N)
'0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141'
>>> y=0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE
>>> multiply(y)
(101611976893179986611445456504760352678020054910766426941542489291446644113297, 62728409327141118228093362610154100530630533850909349244575637074165425046447)
>>> y%N
432420386565659656852420866394968145597
>>> multiply(y%N)
(101611976893179986611445456504760352678020054910766426941542489291446644113297, 62728409327141118228093362610154100530630533850909349244575637074165425046447)
>>> hex(y%N)
'0x14551231950b75fc4402da1732fc9bebd'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.