Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bouncy Castle ECDSA Create Public Key from Private Key

I am trying to sign a bitcoin transaction in c#. I have 2 bits of code I am trying to complete. I can create a set of private and public keys using Bouncy castle. I can convert this to wallet import format ok.

I can also generate a bitcoin address from the ECDSA public key.

However, I want to sign a transaction and all I have is my private key. I don't want to have to import into a wallet and sign. So how can I generate the public key, given only the private key?

I have found a javascript method that does this:

ecparams.getG().multiply(this.priv).getEncoded();

The only way I've seen in Bouncy Castle is to generate a random pair.

private static AsymmetricCipherKeyPair GenerateKeys(int keySize)
{
  ECKeyPairGenerator gen = new ECKeyPairGenerator();
  SecureRandom secureRandom = new SecureRandom();
  KeyGenerationParameters keyGenParam = new KeyGenerationParameters(secureRandom, keySize);
  gen.Init(keyGenParam);
  return gen.GenerateKeyPair();
}
like image 311
user123976 Avatar asked Mar 20 '23 11:03

user123976


1 Answers

From steininger's answer, I got the following to work with the sample keys I had.

using Org.BouncyCastle.Asn1.Sec;
using Org.BouncyCastle.Asn1.X9;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.Math;
using Org.BouncyCastle.Math.EC;

public static class Example
{
    private static X9ECParameters curve = SecNamedCurves.GetByName("secp256k1");
    private static ECDomainParameters domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H);

    public static byte[] ToPublicKey(byte[] privateKey)
    {
        BigInteger d = new BigInteger(privateKey);
        ECPoint q = domain.G.Multiply(d);

        var publicParams = new ECPublicKeyParameters(q, domain);
        return publicParams.Q.GetEncoded();
    }
}
like image 128
Ryan Avatar answered Mar 23 '23 01:03

Ryan