0

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
Lakshitha Kanchana
  • 844
  • 2
  • 12
  • 32
  • Key should have exactly 32 bytes, while BigInteger can have any number of bytes in binary representation. – Evk Dec 14 '22 at 12:17

1 Answers1

1

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);
DrMaxB
  • 540
  • 1
  • 3
  • 13
  • 2
    You cannot require using only BigIntegers which are represented by exactly 32 bytes (because that removes a lot of valid keys). Instead, if `ToByteArray()` returns less than 32 bytes - you have extend it to 32 bytes with zeroes. – Evk Dec 14 '22 at 12:36
  • Good point. So I have added the update 1 so that below 32 length byte arrays can be converted into a 32 bit byte array. – Lakshitha Kanchana Dec 15 '22 at 04:15
  • 1
    I do not disagree. In fact, key derivation would typically invlove a KDF to make the result more cryptographically secure so zero padding is a common technique. I have added a 1 line solution using Array.Resize(T[], Int32) – DrMaxB Dec 15 '22 at 13:27
  • Title is about private key... – pbies Jun 08 '23 at 05:00