Search code examples
c#nbitcoin

Get private key from a BigInteger in NBitcoin


Is there a way to create new "Key" object from an existing BigInteger?

Something like this?

var bigInt = new BigInteger(934157136952);
Key key = new Key(bigInt);

I tried searching documentation. But couldn't find.

Update 1

I also tried this. It gave me an exception with the message "Invalid String".

Key key = Key.Parse(bigInt.ToString(), Network.Main);

Seems It needed base58 string as the first argument.

Key key = Key.Parse(new Key().GetWif(Network.Main).ToString(), Network.Main); // Works fine

Solution

  • why don't you create a Key instance using a byte []. See the Key implementation of NBitcoin here

    C# supports converting BigInteger to byte arrays. So your code could hypothetically look like this:

    byte [] bytes = new BigInteger(934157136952).ToByteArray();
    Key key = new Key(bytes);
    

    The other parameters are optional. However, in the Key implementation, you can see that your Key must be 32 bytes long. See line 14. So your example will throw an ArgumentException.

    So creating an instance of BigInteger with a long wont work and you should instead parse a string. The code below gives a 32 byte BigInteger and compiles successfully on my machine.

    byte[] bytes = BigInteger.Parse("11725344435539341571369527625736255434253725643527635436353563846746536545463").ToByteArray();
    Key key = new Key(bytes);
    Console.WriteLine(key.PubKey);
    //prints : 0391c33d7a367471827b59372e79f7d727ec81ddf2abd5762c91151fe5a2b49f92
    

    Update 1

    Best thing do to covert a byte array of the BigInteger is to add leading zeros as follows.

    byte [] byteArr = new BigInteger(934157136952).ToByteArray();
    byte zero = (new BigInteger(0)).ToByteArray()[0]; // getting the byte representation of zero in the same encoding as BigInterger.ToByteArray()
    for (int i = 0; i < byteArr.Length; i++)
    {
          byteArr32[i] = byteArr[i];
    }
    for (int i = byteArr.Length; i < 32-(byteArr.Length); i++)
    {
          byteArr32[i] = zero; // leading zero means trailing zeros to the array.
    }
    Key key = new Key(byteArr32);
    
    

    Update 2

    C# provides a 1-line solution to resizing arrays in-situ. The result will be zero padded by default for byte arrays.

    byte[] bytes = new BigInteger(934157136952).ToByteArray();
    Array.Resize<byte>(ref bytes, 32);
    Key key = new Key(bytes);