Remove CKey, add signature verification support to CPubKey plus some tests
authorCryptoManiac <balthazar@yandex.ru>
Mon, 17 Aug 2015 23:02:05 +0000 (02:02 +0300)
committerCryptoManiac <balthazar@yandex.ru>
Mon, 17 Aug 2015 23:02:05 +0000 (02:02 +0300)
Novacoin/CKey.cs [deleted file]
Novacoin/CKeyPair.cs
Novacoin/CPubKey.cs
Novacoin/CScript.cs
Novacoin/Novacoin.csproj
NovacoinTest/Program.cs

diff --git a/Novacoin/CKey.cs b/Novacoin/CKey.cs
deleted file mode 100644 (file)
index 875ac7f..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-\feffusing System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Novacoin
-{
-    /// <summary>
-    /// Representation of ECDSA private key
-    /// </summary>
-    public class CKey
-    {
-        /// <summary>
-        /// Private key bytes
-        /// </summary>
-        private List<byte> privKeyBytes;
-
-        /// <summary>
-        /// Initialize new instance of CKey as copy of another instance.
-        /// </summary>
-        /// <param name="key">New CKey instance.</param>
-        public CKey(CKey key)
-        {
-            privKeyBytes = key.privKeyBytes;
-        }
-
-        /// <summary>
-        /// Initialize new instance of CKey using supplied byte sequence.
-        /// </summary>
-        /// <param name="bytes">New CKey instance.</param>
-        public CKey(IEnumerable<byte> bytes)
-        {
-            privKeyBytes = new List<byte>(bytes);
-        }
-
-        /// <summary>
-        /// Calculate public key for this private key.
-        /// </summary>
-        /// <returns>New CPubKey instance.</returns>
-        public CPubKey GetPubKey()
-        {
-            // stub
-
-            return new CPubKey((CPubKey)null);
-        }
-    }
-}
index 034e331..0abbb25 100644 (file)
@@ -79,6 +79,20 @@ namespace Novacoin
             return signer.VerifySignature(signature.ToArray());
         }
 
+        public CPubKey GetPubKey()
+        {
+            return new CPubKey(Q);
+        }
+
+        /// <summary>
+        /// Calculate Hash160 and create new CKeyID instance.
+        /// </summary>
+        /// <returns>New key ID</returns>
+        public CKeyID GetKeyID()
+        {
+            return new CKeyID(Hash160.Compute160(Public));
+        }
+
         /// <summary>
         /// Secret part of key pair
         /// </summary>
index 03bbb19..a6227a6 100644 (file)
@@ -4,6 +4,17 @@ using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 
+using Org.BouncyCastle.Math;
+using Org.BouncyCastle.Math.EC;
+
+using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Generators;
+using Org.BouncyCastle.Crypto.Parameters;
+
+using Org.BouncyCastle.Asn1.X9;
+using Org.BouncyCastle.Security;
+using Org.BouncyCastle.Asn1.Sec;
+
 namespace Novacoin
 {
     /// <summary>
@@ -11,10 +22,9 @@ namespace Novacoin
     /// </summary>
     public class CPubKey
     {
-        /// <summary>
-        /// Public key bytes
-        /// </summary>
-        private List<byte> pubKeyBytes;
+        private ECPoint Q;
+        private static X9ECParameters curve = SecNamedCurves.GetByName("secp256k1");
+        private static ECDomainParameters domain = new ECDomainParameters(curve.Curve, curve.G, curve.N, curve.H, curve.GetSeed());
 
         /// <summary>
         /// Initializes a new instance of CPubKey class as the copy of another instance
@@ -22,35 +32,39 @@ namespace Novacoin
         /// <param name="pubKey">Another CPubKey instance</param>
         public CPubKey(CPubKey pubKey)
         {
-            pubKeyBytes = pubKey.pubKeyBytes;
+            Q = pubKey.Q;
         }
 
         /// <summary>
         /// Initializes a new instance of CPubKey class using supplied sequence of bytes
         /// </summary>
-        /// <param name="bytesList"></param>
-        public CPubKey(IEnumerable<byte> bytesList)
+        /// <param name="bytes">Byte sequence</param>
+        public CPubKey(IEnumerable<byte> bytes)
+        {
+            Q = ((ECPublicKeyParameters)PublicKeyFactory.CreateKey(bytes.ToArray())).Q;
+        }
+
+        public CPubKey(ECPoint pQ)
         {
-            pubKeyBytes = new List<byte>(bytesList);
+            Q = pQ;
         }
 
         /// <summary>
         /// Quick validity test
         /// </summary>
         /// <returns>Validation result</returns>
-        public bool IsValid()
+        public bool IsValid
         {
-            return pubKeyBytes.Count == 33 || pubKeyBytes.Count == 65;
+            get { return !Q.IsInfinity; }
         }
 
         /// <summary>
         /// Is this a compressed public key?
         /// </summary>
         /// <returns></returns>
-        public bool IsCompressed()
+        public bool IsCompressed
         {
-            // Compressed public keys are 33 bytes long
-            return pubKeyBytes.Count == 33;
+            get { return Q.IsCompressed; }
         }
 
         /// <summary>
@@ -59,15 +73,32 @@ namespace Novacoin
         /// <returns>New key ID</returns>
         public CKeyID GetKeyID()
         {
-            return new CKeyID(Hash160.Compute160(this.Raw));
+            return new CKeyID(Hash160.Compute160(Raw));
+        }
+
+        public bool Verify(IEnumerable<byte> data, IEnumerable<byte> signature)
+        {
+            byte[] dataBytes = data.ToArray();
+
+            ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");
+            ECPublicKeyParameters keyParameters = new ECPublicKeyParameters(Q, domain);
+            signer.Init(false, keyParameters);
+            signer.BlockUpdate(dataBytes, 0, dataBytes.Length);
+
+            return signer.VerifySignature(signature.ToArray());
         }
 
         /// <summary>
         /// Accessor for internal representation
         /// </summary>
-        public IList<byte> Raw
+        public IEnumerable<byte> Raw
+        {
+            get { return Q.GetEncoded(); }
+        }
+
+        public override string ToString()
         {
-            get { return pubKeyBytes; }
+            return Interop.ToHex(Raw);
         }
     }
 }
index f5ce417..65b824a 100644 (file)
@@ -345,14 +345,14 @@ namespace Novacoin
             AddOp(opcodetype.OP_EQUAL);
         }
 
-        public void SetMultiSig(int nRequired, IEnumerable<CKey> keys)
+        public void SetMultiSig(int nRequired, IEnumerable<CPubKey> keys)
         {
             codeBytes.Clear();
             AddOp(ScriptOpcode.EncodeOP_N(nRequired));
 
-            foreach (CKey key in keys)
+            foreach (CPubKey key in keys)
             {
-                PushData(key.GetPubKey().Raw);
+                PushData(key.Raw.ToList());
             }
             AddOp(ScriptOpcode.EncodeOP_N(keys.Count()));
             AddOp(opcodetype.OP_CHECKMULTISIG);
index 5e158c0..c8d8539 100644 (file)
@@ -35,7 +35,6 @@
     <Reference Include="System" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="CKey.cs" />
     <Compile Include="CKeyID.cs" />
     <Compile Include="CKeyPair.cs" />
     <Compile Include="CPubKey.cs" />
index d0106d1..2270b8c 100644 (file)
@@ -45,8 +45,10 @@ namespace NovacoinTest
 
             CKeyPair keyPair1 = new CKeyPair();
             CKeyPair keyPair2 = new CKeyPair(keyPair1.Secret);
+            CPubKey pubKey = keyPair2.GetPubKey();
        
             Console.WriteLine(keyPair1.ToString());
+            Console.WriteLine("PubKey: {0}", pubKey.ToString());
             Console.WriteLine("OK: {0}\n", keyPair1.ToString() == keyPair2.ToString());
 
             /// ECDSA keypair signing test
@@ -56,7 +58,8 @@ namespace NovacoinTest
             byte[] signature = keyPair1.Sign(dataBytes).ToArray();
 
             Console.WriteLine("Signature: {0}", Interop.ToHex(signature));
-            Console.WriteLine("Signature is OK: {0}", keyPair1.Verify(dataBytes, signature));
+            Console.WriteLine("Signature is OK: {0} (CKeyPair)", keyPair1.Verify(dataBytes, signature));
+            Console.WriteLine("Signature is OK: {0} (CPubKey)", pubKey.Verify(dataBytes, signature));
 
             Console.ReadLine();
         }