CheckSig implementation
[NovacoinLibrary.git] / Novacoin / CKey.cs
1 \feffusing System.Collections.Generic;
2 using System.Linq;
3
4 using Org.BouncyCastle.Crypto;
5 using Org.BouncyCastle.Crypto.Parameters;
6
7 using Org.BouncyCastle.Asn1.X9;
8 using Org.BouncyCastle.Security;
9 using Org.BouncyCastle.Asn1.Sec;
10
11 using Org.BouncyCastle.Math.EC;
12
13
14 namespace Novacoin
15 {
16     /// <summary>
17     /// Basic pubkey functionality
18     /// </summary>
19     public abstract class CKey
20     {
21         // These fields are inherited by CPubKey and CKeyPair
22         protected ECPublicKeyParameters _Public;
23
24         protected static X9ECParameters curve = SecNamedCurves.GetByName("secp256k1");
25         protected static ECDomainParameters domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H, curve.GetSeed());
26
27         /// <summary>
28         /// Regenerate public key parameters (ECPoint compression)
29         /// </summary>
30         /// <param name="pubKeyParams">Non-compressed key parameters</param>
31         /// <returns>Parameters for compressed key</returns>
32         protected ECPublicKeyParameters Compress(ECPublicKeyParameters pubKeyParams)
33         {
34             if (pubKeyParams.Q.IsCompressed)
35             {
36                 // Already compressed
37                 return pubKeyParams;
38             }
39
40             ECPoint q = new FpPoint(curve.Curve, pubKeyParams.Q.X, pubKeyParams.Q.Y, true);
41
42             return new ECPublicKeyParameters(q, domain);
43         }
44
45         /// <summary>
46         /// Regenerate public key parameters (ECPoint decompression)
47         /// </summary>
48         /// <param name="pubKeyParams">Compressed key parameters</param>
49         /// <returns>Parameters for non-compressed key</returns>
50         protected ECPublicKeyParameters Decompress(ECPublicKeyParameters pubKeyParams)
51         {
52             if (!pubKeyParams.Q.IsCompressed)
53             {
54                 // Isn't compressed
55                 return pubKeyParams;
56             }
57
58             ECPoint q = new FpPoint(curve.Curve, pubKeyParams.Q.X, pubKeyParams.Q.Y, false);
59
60             return new ECPublicKeyParameters(q, domain);
61         }
62
63         /// <summary>
64         /// Does the signature matches our public key?
65         /// </summary>
66         /// <param name="sigHash">Data hash</param>
67         /// <param name="signature">Signature bytes</param>
68         /// <returns>Checking result</returns>
69         public bool VerifySignature(Hash256 sigHash, IEnumerable<byte> signature)
70         {
71             ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");
72             signer.Init(false, _Public);
73             signer.BlockUpdate(sigHash.hashBytes, 0, sigHash.hashSize);
74
75             return signer.VerifySignature(signature.ToArray());
76         }
77
78         /// <summary>
79         /// Calculate Hash160 and create new CKeyID instance.
80         /// </summary>
81         /// <returns>New key ID</returns>
82         public CKeyID KeyID
83         {
84             get { return new CKeyID(Hash160.Compute160(PublicBytes)); }
85         }
86
87         /// <summary>
88         /// PublicBytes part of key pair
89         /// </summary>
90         public IEnumerable<byte> PublicBytes
91         {
92             get { return _Public.Q.GetEncoded(); }
93         }
94
95         /// <summary>
96         /// Is this a compressed public key?
97         /// </summary>
98         /// <returns></returns>
99         public bool IsCompressed
100         {
101             get { return _Public.Q.IsCompressed; }
102         }
103
104     }
105 }