1 \feffusing System.Collections.Generic;
5 using Org.BouncyCastle.Math;
6 using Org.BouncyCastle.Math.EC;
8 using Org.BouncyCastle.Crypto;
9 using Org.BouncyCastle.Crypto.Generators;
10 using Org.BouncyCastle.Crypto.Parameters;
11 using Org.BouncyCastle.Security;
16 public class CKeyPair : CKey
18 private ECPrivateKeyParameters _Private;
21 /// Initialize new CKeyPair instance with random secret.
23 public CKeyPair(bool Compressed=true)
25 ECKeyGenerationParameters genParams = new ECKeyGenerationParameters(domain, new SecureRandom());
26 ECKeyPairGenerator generator = new ECKeyPairGenerator("ECDSA");
27 generator.Init(genParams);
28 AsymmetricCipherKeyPair ecKeyPair = generator.GenerateKeyPair();
30 _Private = (ECPrivateKeyParameters)ecKeyPair.Private;
31 _Public = (ECPublicKeyParameters)ecKeyPair.Public;
35 _Public = Compress(_Public);
40 /// Init key pair using secret sequence of bytes
42 /// <param name="secretBytes">Byte sequence</param>
43 public CKeyPair(IEnumerable<byte> secretBytes, bool Compressed=true)
45 // Deserialize secret value
46 BigInteger D = new BigInteger(secretBytes.ToArray());
48 // Calculate public key
49 ECPoint Q = curve.G.Multiply(D);
51 _Private = new ECPrivateKeyParameters(D, domain);
52 _Public = new ECPublicKeyParameters(Q, domain);
56 _Public = Compress(_Public);
60 public CKeyPair(string strBase58)
62 List<byte> rawBytes = AddressTools.Base58DecodeCheck(strBase58).ToList();
63 rawBytes.RemoveAt(0); // Remove key version byte
65 int nSecretLen = rawBytes[0] == 0x00 ? 33 : 32;
66 int nTaggedSecretLen = nSecretLen + 1;
68 if (rawBytes.Count > nTaggedSecretLen || rawBytes.Count < nSecretLen)
70 throw new FormatException("Invalid private key");
73 // Deserialize secret value
74 BigInteger D = new BigInteger(rawBytes.Take(nSecretLen).ToArray());
76 // Calculate public key
77 ECPoint Q = curve.G.Multiply(D);
79 _Private = new ECPrivateKeyParameters(D, domain);
80 _Public = new ECPublicKeyParameters(Q, domain);
82 if (rawBytes.Count == nTaggedSecretLen && rawBytes.Last() == 0x01) // Check compression tag
84 _Public = Compress(_Public);
89 /// Create signature for supplied data
91 /// <param name="data">Data bytes sequence</param>
92 /// <returns>Signature bytes sequence</returns>
93 public IEnumerable<byte> Sign(IEnumerable<byte> data)
95 byte[] dataBytes = data.ToArray();
97 ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");
98 signer.Init(true, _Private);
99 signer.BlockUpdate(dataBytes, 0, dataBytes.Length);
101 return signer.GenerateSignature();
104 public CPubKey GetPubKey()
106 return new CPubKey(Public);
110 /// Secret part of key pair
112 public IEnumerable<byte> Secret
114 get { return _Private.D.ToByteArray(); }
117 public string ToHex()
119 List<byte> r = new List<byte>(Secret);
126 return Interop.ToHex(r);
129 public override string ToString()
131 List<byte> r = new List<byte>();
133 r.Add((byte)(128 + AddrType.PUBKEY_ADDRESS));
142 return AddressTools.Base58EncodeCheck(r);