From 0fe762d6eee8a8a23033f813217c1675a34f2d6a Mon Sep 17 00:00:00 2001 From: CryptoManiac Date: Wed, 2 Sep 2015 13:16:29 +0300 Subject: [PATCH] Improve CryptoUtils with wrappers for managed implementations of standard hashing functions. --- Novacoin/CBlock.cs | 2 +- Novacoin/CScript.cs | 4 +- Novacoin/CryptoUtils.cs | 76 ++++++++++++++++++++++++++++++++++++++++++++++- Novacoin/ScriptCode.cs | 12 ++++---- Novacoin/base_uint.cs | 10 ++++++ 5 files changed, 94 insertions(+), 10 deletions(-) diff --git a/Novacoin/CBlock.cs b/Novacoin/CBlock.cs index 3f72c68..a620d26 100644 --- a/Novacoin/CBlock.cs +++ b/Novacoin/CBlock.cs @@ -426,7 +426,7 @@ namespace Novacoin var left = merkleTree.GetRange((levelOffset + nLeft) * 32, 32).ToArray(); var right = merkleTree.GetRange((levelOffset + nRight) * 32, 32).ToArray(); - merkleTree.AddRange(Hash256.ComputeRaw256(ref left, ref right)); + merkleTree.AddRange(CryptoUtils.ComputeHash256(ref left, ref right)); } levelOffset += nLevelSize; } diff --git a/Novacoin/CScript.cs b/Novacoin/CScript.cs index cd6d27a..95ca17a 100644 --- a/Novacoin/CScript.cs +++ b/Novacoin/CScript.cs @@ -73,7 +73,7 @@ namespace Novacoin /// New items are added in this format: /// hash_length_byte hash_bytes /// - /// Hash160 instance + /// uint160 instance public void AddHash(uint160 hash) { codeBytes.Add((byte)hash.Size); @@ -85,7 +85,7 @@ namespace Novacoin /// New items are added in this format: /// hash_length_byte hash_bytes /// - /// Hash256 instance + /// uint256 instance public void AddHash(uint256 hash) { codeBytes.Add((byte)hash.Size); diff --git a/Novacoin/CryptoUtils.cs b/Novacoin/CryptoUtils.cs index 4ba7ee0..12e4bfd 100644 --- a/Novacoin/CryptoUtils.cs +++ b/Novacoin/CryptoUtils.cs @@ -17,12 +17,86 @@ */ using System; +using System.IO; using System.Security.Cryptography; namespace Novacoin { public class CryptoUtils { + private static SHA1Managed _sha1 = new SHA1Managed(); + private static SHA256Managed _sha256 = new SHA256Managed(); + private static RIPEMD160Managed _ripe160 = new RIPEMD160Managed(); + + /// + /// Sha1 calculation + /// + /// Bytes to hash + /// Hashing result + public static byte[] ComputeSha1(byte[] inputBytes) + { + return _sha1.ComputeHash(inputBytes, 0, inputBytes.Length); + } + + /// + /// Sha256 calculation + /// + /// Bytes to hash + /// Hashing result + public static byte[] ComputeSha256(byte[] inputBytes) + { + return _sha256.ComputeHash(inputBytes, 0, inputBytes.Length); + } + + /// + /// RIPEMD-160 calculation + /// + /// Bytes to hash + /// Hashing result + public static byte[] ComputeRipeMD160(byte[] inputBytes) + { + return _ripe160.ComputeHash(inputBytes, 0, inputBytes.Length); + } + + /// + /// RipeMD160(Sha256(X)) calculation + /// + /// Bytes to hash + /// Hashing result + public static byte[] ComputeHash160(byte[] inputBytes) + { + var digest1 = _sha256.ComputeHash(inputBytes, 0, inputBytes.Length); + return _ripe160.ComputeHash(digest1, 0, digest1.Length); + } + + /// + /// Sha256(Sha256(X)) calculation + /// + /// Bytes to hash + /// Hashing result + public static byte[] ComputeHash256(byte[] dataBytes) + { + var digest1 = _sha256.ComputeHash(dataBytes, 0, dataBytes.Length); + return _sha256.ComputeHash(digest1, 0, digest1.Length); + } + + /// + /// Sha256(Sha256(X)) calculation + /// + /// Reference to first half of data + /// Reference to second half of data + /// Hashing result + public static byte[] ComputeHash256(ref byte[] input1, ref byte[] input2) + { + var buffer = new byte[64]; + + input1.CopyTo(buffer, 0); + input2.CopyTo(buffer, input1.Length); + + var digest1 = _sha256.ComputeHash(buffer, 0, buffer.Length); + return _sha256.ComputeHash(digest1, 0, digest1.Length); + } + public static byte[] PBKDF2_Sha256(int dklen, byte[] password, byte[] salt, int iterationCount) { /* Init HMAC state. */ @@ -44,7 +118,7 @@ namespace Novacoin } var extendedkey = new byte[salt.Length + 4]; Buffer.BlockCopy(salt, 0, extendedkey, 0, salt.Length); - using (var ms = new System.IO.MemoryStream()) + using (var ms = new MemoryStream()) { /* Iterate through the blocks. */ for (int i = 0; i < keyLength; i++) diff --git a/Novacoin/ScriptCode.cs b/Novacoin/ScriptCode.cs index df1d773..14bc2e5 100644 --- a/Novacoin/ScriptCode.cs +++ b/Novacoin/ScriptCode.cs @@ -1492,25 +1492,25 @@ namespace Novacoin { return false; } - Hash hash = null; + byte[] hash = null; var data = stacktop(ref stack, -1); switch (opcode) { case instruction.OP_HASH160: - hash = Hash160.Compute160(data); + hash = CryptoUtils.ComputeHash160(data); break; case instruction.OP_HASH256: - hash = Hash256.Compute256(data); + hash = CryptoUtils.ComputeHash256(data); break; case instruction.OP_SHA1: - hash = SHA1.Compute1(data); + hash = CryptoUtils.ComputeSha1(data); break; case instruction.OP_SHA256: - hash = SHA256.Compute256(data); + hash = CryptoUtils.ComputeSha256(data); break; case instruction.OP_RIPEMD160: - hash = RIPEMD160.Compute160(data); + hash = CryptoUtils.ComputeRipeMD160(data); break; } popstack(ref stack); diff --git a/Novacoin/base_uint.cs b/Novacoin/base_uint.cs index 072111f..502d871 100644 --- a/Novacoin/base_uint.cs +++ b/Novacoin/base_uint.cs @@ -250,6 +250,12 @@ namespace Novacoin } #endregion + /// + /// Arrays equality checking helper method. + /// + /// Array 1 + /// Array 2 + /// Result. private static bool ArraysEqual(uint[] a, uint[] b) { Contract.Requires(a.Length == b.Length, "Array length mismatch."); @@ -329,6 +335,10 @@ namespace Novacoin } #endregion + /// + /// Serialize to string. + /// + /// public override string ToString() { return Interop.ToHex(Interop.ReverseBytes(this)); -- 1.7.1