2 * Novacoin classes library
3 * Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com)
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 using Org.BouncyCastle.Crypto;
20 using Org.BouncyCastle.Crypto.Generators;
21 using Org.BouncyCastle.Crypto.Parameters;
22 using Org.BouncyCastle.Math;
23 using Org.BouncyCastle.Security;
24 using System.Collections.Generic;
30 public class CKeyPair : CKey
32 private ECPrivateKeyParameters _Private;
35 /// Initialize new CKeyPair instance with random secret.
37 public CKeyPair(bool Compressed=true)
39 var genParams = new ECKeyGenerationParameters(domain, new SecureRandom());
40 var generator = new ECKeyPairGenerator("ECDSA");
41 generator.Init(genParams);
42 var ecKeyPair = generator.GenerateKeyPair();
44 _Private = (ECPrivateKeyParameters)ecKeyPair.Private;
45 _Public = (ECPublicKeyParameters)ecKeyPair.Public;
49 _Public = Compress(_Public);
54 /// Init key pair using secret sequence of bytes
56 /// <param name="secretBytes">Byte sequence</param>
57 /// <param name="Compressed">Compression flag</param>
58 public CKeyPair(byte[] secretBytes, bool Compressed=true)
60 // Deserialize secret value
61 var D = new BigInteger(secretBytes.Take(32).ToArray());
63 if (D.SignValue == -1)
65 var fixedKeyBytes = secretBytes.Take(32).ToList();
66 fixedKeyBytes.Insert(0, 0x00); // prepend with sign byte
68 D = new BigInteger(fixedKeyBytes.ToArray());
71 // Calculate public key
72 var Q = curve.G.Multiply(D);
74 _Private = new ECPrivateKeyParameters(D, domain);
75 _Public = new ECPublicKeyParameters(Q, domain);
79 _Public = Compress(_Public);
84 /// Init key pair using secret sequence of bytes
86 /// <param name="secretBytes">Byte sequence</param>
87 public CKeyPair(byte[] secretBytes) :
88 this (secretBytes.Take(32).ToArray(), (secretBytes.Count() == 33 && secretBytes.Last() == 0x01))
92 public CKeyPair(string strBase58)
94 var rawBytes = AddressTools.Base58DecodeCheck(strBase58).ToList();
95 rawBytes.RemoveAt(0); // Remove key version byte
97 // Deserialize secret value
98 var D = new BigInteger(rawBytes.Take(32).ToArray());
100 if (D.SignValue == -1)
102 var secretbytes = rawBytes.Take(32).ToList(); // Copy secret
103 secretbytes.Insert(0, 0x00); // Prepend with sign byte
105 D = new BigInteger(secretbytes.ToArray()); // Try decoding again
108 // Calculate public key
109 var Q = curve.G.Multiply(D);
111 _Private = new ECPrivateKeyParameters(D, domain);
112 _Public = new ECPublicKeyParameters(Q, domain);
114 if (rawBytes.Count == 33 && rawBytes.Last() == 0x01) // Check compression tag
116 _Public = Compress(_Public);
121 /// Initialize a copy of CKeyPair instance
123 /// <param name="pair">CKyPair instance</param>
124 public CKeyPair(CKeyPair pair)
126 _Public = pair._Public;
127 _Private = pair._Private;
131 /// Create signature for supplied data
133 /// <param name="data">Hash to sigh</param>
134 /// <returns>Signature bytes sequence</returns>
135 public byte[] Sign(Hash sigHash)
137 var signer = SignerUtilities.GetSigner("NONEwithECDSA");
138 signer.Init(true, _Private);
139 signer.BlockUpdate(sigHash.hashBytes, 0, sigHash.hashSize);
141 return signer.GenerateSignature();
144 public CPubKey PubKey
146 get { return new CPubKey(PublicBytes); }
150 /// SecretBytes part of key pair
152 public byte[] SecretBytes
156 var secretBytes = new List<byte>(_Private.D.ToByteArray());
158 if (secretBytes[0] == 0x00)
161 secretBytes.RemoveAt(0);
166 // Set compression flag
167 secretBytes.Add(0x01);
170 return secretBytes.ToArray();
174 public string ToHex()
176 return Interop.ToHex(SecretBytes);
179 public override string ToString()
181 var r = new List<byte>();
183 r.Add((byte)(128 + AddrType.PUBKEY_ADDRESS)); // Key version
184 r.AddRange(SecretBytes); // Key data
186 return AddressTools.Base58EncodeCheck(r.ToArray());