Remove CKey, add signature verification support to CPubKey plus some tests
[NovacoinLibrary.git] / Novacoin / CPubKey.cs
1 \feffusing System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6
7 using Org.BouncyCastle.Math;
8 using Org.BouncyCastle.Math.EC;
9
10 using Org.BouncyCastle.Crypto;
11 using Org.BouncyCastle.Crypto.Generators;
12 using Org.BouncyCastle.Crypto.Parameters;
13
14 using Org.BouncyCastle.Asn1.X9;
15 using Org.BouncyCastle.Security;
16 using Org.BouncyCastle.Asn1.Sec;
17
18 namespace Novacoin
19 {
20     /// <summary>
21     /// Representation of ECDSA public key
22     /// </summary>
23     public class CPubKey
24     {
25         private ECPoint Q;
26         private static X9ECParameters curve = SecNamedCurves.GetByName("secp256k1");
27         private static ECDomainParameters domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H, curve.GetSeed());
28
29         /// <summary>
30         /// Initializes a new instance of CPubKey class as the copy of another instance
31         /// </summary>
32         /// <param name="pubKey">Another CPubKey instance</param>
33         public CPubKey(CPubKey pubKey)
34         {
35             Q = pubKey.Q;
36         }
37
38         /// <summary>
39         /// Initializes a new instance of CPubKey class using supplied sequence of bytes
40         /// </summary>
41         /// <param name="bytes">Byte sequence</param>
42         public CPubKey(IEnumerable<byte> bytes)
43         {
44             Q = ((ECPublicKeyParameters)PublicKeyFactory.CreateKey(bytes.ToArray())).Q;
45         }
46
47         public CPubKey(ECPoint pQ)
48         {
49             Q = pQ;
50         }
51
52         /// <summary>
53         /// Quick validity test
54         /// </summary>
55         /// <returns>Validation result</returns>
56         public bool IsValid
57         {
58             get { return !Q.IsInfinity; }
59         }
60
61         /// <summary>
62         /// Is this a compressed public key?
63         /// </summary>
64         /// <returns></returns>
65         public bool IsCompressed
66         {
67             get { return Q.IsCompressed; }
68         }
69
70         /// <summary>
71         /// Calculate Hash160 and create new CKeyID instance.
72         /// </summary>
73         /// <returns>New key ID</returns>
74         public CKeyID GetKeyID()
75         {
76             return new CKeyID(Hash160.Compute160(Raw));
77         }
78
79         public bool Verify(IEnumerable<byte> data, IEnumerable<byte> signature)
80         {
81             byte[] dataBytes = data.ToArray();
82
83             ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");
84             ECPublicKeyParameters keyParameters = new ECPublicKeyParameters(Q, domain);
85             signer.Init(false, keyParameters);
86             signer.BlockUpdate(dataBytes, 0, dataBytes.Length);
87
88             return signer.VerifySignature(signature.ToArray());
89         }
90
91         /// <summary>
92         /// Accessor for internal representation
93         /// </summary>
94         public IEnumerable<byte> Raw
95         {
96             get { return Q.GetEncoded(); }
97         }
98
99         public override string ToString()
100         {
101             return Interop.ToHex(Raw);
102         }
103     }
104 }