Public key compression
[NovacoinLibrary.git] / Novacoin / CKeyPair.cs
1 \feffusing System.Collections.Generic;
2 using System.Linq;
3 using System.Text;
4
5 using Org.BouncyCastle.Math;
6 using Org.BouncyCastle.Math.EC;
7
8 using Org.BouncyCastle.Crypto;
9 using Org.BouncyCastle.Crypto.Generators;
10 using Org.BouncyCastle.Crypto.Parameters;
11 using Org.BouncyCastle.Security;
12
13
14 namespace Novacoin
15 {
16     public class CKeyPair : CKey
17     {
18         private ECPrivateKeyParameters _Private;
19
20         /// <summary>
21         /// Initialize new CKeyPair instance with random secret.
22         /// </summary>
23         public CKeyPair(bool Compressed=true)
24         {
25             ECKeyGenerationParameters genParams = new ECKeyGenerationParameters(domain, new SecureRandom());
26             ECKeyPairGenerator generator = new ECKeyPairGenerator("ECDSA");
27             generator.Init(genParams);
28             AsymmetricCipherKeyPair ecKeyPair = generator.GenerateKeyPair();
29
30             _Private = (ECPrivateKeyParameters)ecKeyPair.Private;
31             _Public = (ECPublicKeyParameters)ecKeyPair.Public;
32
33             if (Compressed)
34             {
35                 _Public = Compress(_Public);
36             }
37         }
38
39         /// <summary>
40         /// Init key pair using secret sequence of bytes
41         /// </summary>
42         /// <param name="secretBytes">Byte sequence</param>
43         public CKeyPair(IEnumerable<byte> secretBytes, bool Compressed=true)
44         {
45             // Deserialize secret value
46             BigInteger D = new BigInteger(secretBytes.ToArray());
47
48             // Calculate public key
49             ECPoint Q = curve.G.Multiply(D);
50
51             _Private = new ECPrivateKeyParameters(D, domain);
52             _Public = new ECPublicKeyParameters(Q, domain);
53
54             if (Compressed)
55             {
56                 _Public = Compress(_Public);
57             }
58         }
59
60         /// <summary>
61         /// Create signature for supplied data
62         /// </summary>
63         /// <param name="data">Data bytes sequence</param>
64         /// <returns>Signature bytes sequence</returns>
65         public IEnumerable<byte> Sign(IEnumerable<byte> data)
66         {
67             byte[] dataBytes = data.ToArray();
68
69             ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");
70             signer.Init(true, _Private);
71             signer.BlockUpdate(dataBytes, 0, dataBytes.Length);
72
73             return signer.GenerateSignature();
74         }
75
76         public CPubKey GetPubKey()
77         {
78             return new CPubKey(Public);
79         }
80
81         /// <summary>
82         /// Secret part of key pair
83         /// </summary>
84         public IEnumerable<byte> Secret
85         {
86             get { return _Private.D.ToByteArray(); }
87         }
88
89         public override string ToString()
90         {
91             StringBuilder sb = new StringBuilder();
92
93             sb.AppendFormat("CKeyPair(Secret={0}, Public={1})", Interop.ToHex(Secret), Interop.ToHex(Public));
94
95             return sb.ToString();
96         }
97     }
98 }