From e146a3f4459a37884b7a546265fcdd4187103d94 Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Sat, 22 Aug 2015 22:30:32 +0300 Subject: [PATCH] CheckSig implementation --- Novacoin/CKey.cs | 8 ++--- Novacoin/CKeyPair.cs | 8 ++--- Novacoin/ScriptCode.cs | 75 +++++++++++++++++++++++++++++++++------------- NovacoinTest/Program.cs | 8 ++-- 4 files changed, 64 insertions(+), 35 deletions(-) diff --git a/Novacoin/CKey.cs b/Novacoin/CKey.cs index 46b1387..2976e62 100644 --- a/Novacoin/CKey.cs +++ b/Novacoin/CKey.cs @@ -63,16 +63,14 @@ namespace Novacoin /// /// Does the signature matches our public key? /// - /// Data bytes + /// Data hash /// Signature bytes /// Checking result - public bool VerifySignature(IEnumerable data, IEnumerable signature) + public bool VerifySignature(Hash256 sigHash, IEnumerable 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()); } diff --git a/Novacoin/CKeyPair.cs b/Novacoin/CKeyPair.cs index a729d50..cec6ad9 100644 --- a/Novacoin/CKeyPair.cs +++ b/Novacoin/CKeyPair.cs @@ -116,15 +116,13 @@ namespace Novacoin /// /// Create signature for supplied data /// - /// Data bytes sequence + /// Hash to sigh /// Signature bytes sequence - public IEnumerable Sign(IEnumerable data) + public IEnumerable 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(); } diff --git a/Novacoin/ScriptCode.cs b/Novacoin/ScriptCode.cs index 5736e1b..8cd7239 100644 --- a/Novacoin/ScriptCode.cs +++ b/Novacoin/ScriptCode.cs @@ -603,7 +603,7 @@ namespace Novacoin /// /// Small integer opcode (OP_1_NEGATE and OP_0 - OP_16) /// Small integer - 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 /// /// Small integer from the range of -1 up to 16. /// Corresponding opcode. - 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 pushArg; + + while (GetOp(ref CodeQueue, out opcode, out pushArg)) // Read instructions { bool fExec = vfExec.IndexOf(false) != -1; - // - // Read instruction - // - IEnumerable 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 sigBytes, IList pubKeyBytes, CScript scriptCode, CTransaction txTo, int nIn, int nHashType, int flags) + static bool CheckSig(IList vchSig, IList 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; } - -}; + }; } diff --git a/NovacoinTest/Program.cs b/NovacoinTest/Program.cs index 83f5a00..e4c3c14 100644 --- a/NovacoinTest/Program.cs +++ b/NovacoinTest/Program.cs @@ -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 -- 1.7.1