问题
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();
}
    回答1:
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();
    }
}
    回答2:
If you're dealing with DER encoded keys, it's even simpler:
  var privateKey = PrivateKeyFactory.CreateKey(bytes) as ECPrivateKeyParameters;
  if (privateKey == null)
       return null;
  Org.BouncyCastle.Math.EC.ECPoint q = privateKey.Parameters.G.Multiply(privateKey.D);
  var publicParams = new ECPublicKeyParameters(privateKey.AlgorithmName, q, privateKey.PublicKeyParamSet);
  return SubjectPublicKeyInfoFactory.CreateSubjectPublicKeyInfo(publicParams).GetDerEncoded();
    回答3:
take a look at the following code. the private key is given by as base64 encoded string in this example and also a base64 encoded string is given back. the commented keyParameters are working, so use this one if you want to have key and curve.
private static readonly Org.BouncyCastle.Asn1.X9.X9ECParameters curve = Org.BouncyCastle.Asn1.Sec.SecNamedCurves.GetByName("secp256r1");
private static readonly Org.BouncyCastle.Crypto.Parameters.ECDomainParameters domain = new Org.BouncyCastle.Crypto.Parameters.ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H);
public string GetPublicKey(string privKey)
{
      Org.BouncyCastle.Math.BigInteger d = new Org.BouncyCastle.Math.BigInteger(Convert.FromBase64String(privKey));
      //var privKeyParameters = new Org.BouncyCastle.Crypto.Parameters.ECPrivateKeyParameters(d, domain);
      Org.BouncyCastle.Math.EC.ECPoint q = domain.G.Multiply(d);
      //var pubKeyParameters = new Org.BouncyCastle.Crypto.Parameters.ECPublicKeyParameters(q, domain);
      return Convert.ToBase64String(q.GetEncoded());
}
    来源:https://stackoverflow.com/questions/22003407/bouncy-castle-ecdsa-create-public-key-from-private-key