CheckSig implementation
authorCryptoManiac <balthazar@yandex.ru>
Sat, 22 Aug 2015 19:30:32 +0000 (22:30 +0300)
committerCryptoManiac <balthazar@yandex.ru>
Sat, 22 Aug 2015 19:30:32 +0000 (22:30 +0300)
Novacoin/CKey.cs
Novacoin/CKeyPair.cs
Novacoin/ScriptCode.cs
NovacoinTest/Program.cs

index 46b1387..2976e62 100644 (file)
@@ -63,16 +63,14 @@ namespace Novacoin
         /// <summary>
         /// Does the signature matches our public key?
         /// </summary>
-        /// <param name="data">Data bytes</param>
+        /// <param name="sigHash">Data hash</param>
         /// <param name="signature">Signature bytes</param>
         /// <returns>Checking result</returns>
-        public bool VerifySignature(IEnumerable<byte> data, IEnumerable<byte> signature)
+        public bool VerifySignature(Hash256 sigHash, IEnumerable<byte> signature)
         {
-            byte[] dataBytes = data.ToArray();
-
             ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");
             signer.Init(false, _Public);
-            signer.BlockUpdate(dataBytes, 0, dataBytes.Length);
+            signer.BlockUpdate(sigHash.hashBytes, 0, sigHash.hashSize);
 
             return signer.VerifySignature(signature.ToArray());
         }
index a729d50..cec6ad9 100644 (file)
@@ -116,15 +116,13 @@ namespace Novacoin
         /// <summary>
         /// Create signature for supplied data
         /// </summary>
-        /// <param name="data">Data bytes sequence</param>
+        /// <param name="data">Hash to sigh</param>
         /// <returns>Signature bytes sequence</returns>
-        public IEnumerable<byte> Sign(IEnumerable<byte> data)
+        public IEnumerable<byte> Sign(Hash256 sigHash)
         {
-            byte[] dataBytes = data.ToArray();
-
             ISigner signer = SignerUtilities.GetSigner("SHA-256withECDSA");
             signer.Init(true, _Private);
-            signer.BlockUpdate(dataBytes, 0, dataBytes.Length);
+            signer.BlockUpdate(sigHash.hashBytes, 0, sigHash.hashSize);
 
             return signer.GenerateSignature();
         }
index 5736e1b..8cd7239 100644 (file)
@@ -603,7 +603,7 @@ namespace Novacoin
         /// </summary>
         /// <param name="opcode">Small integer opcode (OP_1_NEGATE and OP_0 - OP_16)</param>
         /// <returns>Small integer</returns>
-        public static int DecodeOP_N(instruction opcode, bool AllowNegate=false)
+        public static int DecodeOP_N(instruction opcode, bool AllowNegate = false)
         {
             if (AllowNegate && opcode == instruction.OP_1NEGATE)
             {
@@ -629,7 +629,7 @@ namespace Novacoin
         /// </summary>
         /// <param name="n">Small integer from the range of -1 up to 16.</param>
         /// <returns>Corresponding opcode.</returns>
-        public static instruction EncodeOP_N(int n, bool allowNegate=false)
+        public static instruction EncodeOP_N(int n, bool allowNegate = false)
         {
             if (allowNegate && n == -1)
             {
@@ -1099,19 +1099,12 @@ namespace Novacoin
             int nOpCount = 0;
             int nCodeHashBegin = 0;
 
-            while (true)
+            IEnumerable<byte> pushArg;
+
+            while (GetOp(ref CodeQueue, out opcode, out pushArg)) // Read instructions
             {
                 bool fExec = vfExec.IndexOf(false) != -1;
 
-                //
-                // Read instruction
-                //
-                IEnumerable<byte> pushArg;
-                if (!GetOp(ref CodeQueue, out opcode, out pushArg))
-                {
-                    return false; // No instructions left
-                }
-
                 if (pushArg.Count() > 520)
                 {
                     return false; // Script element size limit failed
@@ -1620,8 +1613,7 @@ namespace Novacoin
                                         break;
 
                                     default:
-                                        throw new StackMachineException("invalid opcode");
-                                        break;
+                                        throw new StackMachineException("invalid instruction");
                                 }
 
                                 popstack(ref stack);
@@ -1696,8 +1688,7 @@ namespace Novacoin
                                         break;
 
                                     default:
-                                        throw new StackMachineException("invalid opcode");
-                                        break;
+                                        throw new StackMachineException("invalid instruction");
                                 }
 
                                 popstack(ref stack);
@@ -1987,12 +1978,54 @@ namespace Novacoin
             return true;
         }
 
-
-        static bool CheckSig(IList<byte> sigBytes, IList<byte> pubKeyBytes, CScript scriptCode, CTransaction txTo, int nIn, int nHashType, int flags)
+        static bool CheckSig(IList<byte> vchSig, IList<byte> vchPubKey, CScript scriptCode, CTransaction txTo, int nIn, int nHashType, int flags)
         {
-            // STUB
+            CPubKey pubkey;
+
+            try
+            {
+                // Trying to initialize the public key instance
+
+                pubkey = new CPubKey(vchPubKey);
+            }
+            catch (Exception)
+            {
+                // Exception occurred while initializing the public key
+
+                return false; 
+            }
+
+            if (!pubkey.IsValid)
+            {
+                return false;
+            }
+
+            if (vchSig.Count == 0)
+            {
+                return false;
+            }
+
+            // Hash type is one byte tacked on to the end of the signature
+            if (nHashType == 0)
+            {
+                nHashType = vchSig.Last();
+            }
+            else if (nHashType != vchSig.Last())
+            {
+                return false;
+            }
+
+            // Remove hash type
+            vchSig.RemoveAt(vchSig.Count - 1);
+
+            Hash256 sighash = SignatureHash(scriptCode, txTo, nIn, nHashType);
+
+            if (!pubkey.VerifySignature(sighash, vchSig))
+            {
+                return false;
+            }
+
             return true;
         }
-
-};
+    };
 }
index 83f5a00..e4c3c14 100644 (file)
@@ -79,12 +79,12 @@ namespace NovacoinTest
             /// ECDSA keypair signing test
 
             string data = "Превед!";
-            byte[] dataBytes = Encoding.UTF8.GetBytes(data);
-            byte[] signature = keyPair1.Sign(dataBytes).ToArray();
+            Hash256 sigHash =  Hash256.Compute256(Encoding.UTF8.GetBytes(data));
+            byte[] signature = keyPair1.Sign(sigHash).ToArray();
 
             Console.WriteLine("Signature: {0}", Interop.ToHex(signature));
-            Console.WriteLine("Signature is OK: {0} (CKeyPair)", keyPair1.VerifySignature(dataBytes, signature));
-            Console.WriteLine("Signature is OK: {0} (CPubKey)", pubKey.VerifySignature(dataBytes, signature));
+            Console.WriteLine("Signature is OK: {0} (CKeyPair)", keyPair1.VerifySignature(sigHash, signature));
+            Console.WriteLine("Signature is OK: {0} (CPubKey)", pubKey.VerifySignature(sigHash, signature));
 
             /// Donation address