Use BouncyCastle hashing functions
authorCryptoManiac <balthazar@yandex.ru>
Sun, 23 Aug 2015 21:02:23 +0000 (00:02 +0300)
committerCryptoManiac <balthazar@yandex.ru>
Sun, 23 Aug 2015 21:02:23 +0000 (00:02 +0300)
12 files changed:
Novacoin/CBlock.cs
Novacoin/CBlockHeader.cs
Novacoin/CScript.cs
Novacoin/CTransaction.cs
Novacoin/Hash.cs
Novacoin/Hash160.cs
Novacoin/Hash256.cs
Novacoin/RIPEMD160.cs
Novacoin/SHA1.cs
Novacoin/SHA256.cs
Novacoin/ScriptCode.cs
Novacoin/ScryptHash256.cs

index 9964edd..7511fdf 100644 (file)
@@ -178,33 +178,25 @@ namespace Novacoin
 
                 foreach (var tx in vtx)
                 {
-                    merkleTree.AddRange(tx.Hash.hashBytes);
+                    merkleTree.AddRange(Hash256.ComputeRaw256(tx.Bytes));
                 }
 
-                var hasher = new SHA256Managed();
-                hasher.Initialize();
-
-                int j = 0;
-                for (int nSize = vtx.Length; nSize > 1; nSize = (nSize + 1) / 2)
+                int levelOffset = 0;
+                for (int nLevelSize = vtx.Length; nLevelSize > 1; nLevelSize = (nLevelSize + 1) / 2)
                 {
-                    for (int i = 0; i < nSize; i += 2)
+                    for (int nLeft = 0; nLeft < nLevelSize; nLeft += 2)
                     {
-                        int i2 = Math.Min(i + 1, nSize - 1);
-
-                        var pair = new List<byte>();
-
-                        pair.AddRange(merkleTree.GetRange((j + i)*32, 32));
-                        pair.AddRange(merkleTree.GetRange((j + i2)*32, 32));
+                        int nRight = Math.Min(nLeft + 1, nLevelSize - 1);
 
-                        var digest1 = hasher.ComputeHash(pair.ToArray());
-                        var digest2 = hasher.ComputeHash(digest1);
+                        var left = merkleTree.GetRange((levelOffset + nLeft) * 32, 32).ToArray();
+                        var right = merkleTree.GetRange((levelOffset + nRight) * 32, 32).ToArray();
 
-                        merkleTree.AddRange(digest2);
+                        merkleTree.AddRange(Hash256.ComputeRaw256(ref left, ref right));
                     }
-                    j += nSize;
+                    levelOffset += nLevelSize;
                 }
 
-                return (merkleTree.Count == 0) ? new Hash256() : new Hash256(merkleTree.GetRange(merkleTree.Count-32, 32));
+                return (merkleTree.Count == 0) ? new Hash256() : new Hash256(merkleTree.GetRange(merkleTree.Count-32, 32).ToArray());
             }
         }
 
index cc753c4..167e32e 100644 (file)
@@ -89,7 +89,7 @@ namespace Novacoin
         /// Convert current block header instance into sequence of bytes
         /// </summary>
         /// <returns>Byte sequence</returns>
-        public IList<byte> Bytes
+        public byte[] Bytes
         {
             get
             {
@@ -102,7 +102,7 @@ namespace Novacoin
                 r.AddRange(BitConverter.GetBytes(nBits));
                 r.AddRange(BitConverter.GetBytes(nNonce));
 
-                return r;
+                return r.ToArray();
             }
         }
 
index 1bc347a..9149d34 100644 (file)
@@ -451,7 +451,7 @@ namespace Novacoin
 
         public CScriptID ScriptID
         {
-            get { return new CScriptID(Hash160.Compute160(codeBytes)); }
+            get { return new CScriptID(Hash160.Compute160(codeBytes.ToArray())); }
         }
 
         /// <summary>
index 3557398..091b442 100644 (file)
@@ -189,7 +189,7 @@ namespace Novacoin
         /// <summary>
         /// A sequence of bytes, which corresponds to the current state of CTransaction.
         /// </summary>
-        public IList<byte> Bytes
+        public byte[] Bytes
         {
             get
             {
@@ -257,7 +257,7 @@ namespace Novacoin
 
                 resultBytes.AddRange(BitConverter.GetBytes(nLockTime));
 
-                return resultBytes;
+                return resultBytes.ToArray();
             }
         }
 
index 3d757f1..b9e6d0c 100644 (file)
  */
 
 using System;
-using System.Security.Cryptography;
-using System.Collections.Generic;
 using System.Linq;
 
-using System.Numerics;
-
 namespace Novacoin
 {
     public abstract class Hash
     {
         /// <summary>
-        /// Computes the SHA256 hash for the input data using the managed library.
-        /// </summary>
-        protected static SHA256Managed _hasher256 = new SHA256Managed();
-        
-        /// <summary>
         /// Array of digest bytes.
         /// </summary>
         protected byte[] _hashBytes = null;
@@ -61,15 +52,6 @@ namespace Novacoin
         /// <summary>
         /// Initializes a new instance of Hash class
         /// </summary>
-        /// <param name="bytesList">List of bytes</param>
-        public Hash(IEnumerable<byte> bytes, int skip = 0)
-        {
-            _hashBytes = bytes.Skip(skip).Take(hashSize).ToArray();
-        }
-
-        /// <summary>
-        /// Initializes a new instance of Hash class
-        /// </summary>
         /// <param name="bytesList">Array of bytes</param>
         public Hash(byte[] bytes, int offset = 0)
         {
index 272527b..df73f99 100644 (file)
@@ -17,8 +17,7 @@
  */
 
 using System.Linq;
-using System.Collections.Generic;
-using System.Security.Cryptography;
+using Org.BouncyCastle.Crypto.Digests;
 
 namespace Novacoin
 {
@@ -30,24 +29,32 @@ namespace Novacoin
         /// <summary>
         /// Computes RIPEMD160 hash using managed library
         /// </summary>
-        private static readonly RIPEMD160Managed _hasher160 = new RIPEMD160Managed();
-        
+        //private static readonly RIPEMD160Managed _hasher160 = new RIPEMD160Managed();
+
+        private static RipeMD160Digest _hasher160 = new RipeMD160Digest();
+        private static Sha256Digest _hasher256 = new Sha256Digest();
+
         // 20 bytes
         public override int hashSize
         {
-            get { return 20; }
+            get { return _hasher160.GetDigestSize(); }
         }
 
         public Hash160() : base() { }
         public Hash160(byte[] bytes, int offset = 0) : base(bytes, offset) { }
-        public Hash160(IEnumerable<byte> bytes, int skip = 0) : base(bytes, skip) { }
         public Hash160(Hash160 h) : base(h) { }
 
-        public static Hash160 Compute160(IEnumerable<byte> inputBytes)
+        public static Hash160 Compute160(byte[] inputBytes)
         {
             var dataBytes = inputBytes.ToArray();
-            var digest1 = _hasher256.ComputeHash(dataBytes, 0, dataBytes.Length);
-            var digest2 = _hasher160.ComputeHash(digest1, 0, digest1.Length);
+
+            var digest1 = new byte[32];
+            var digest2 = new byte[20];
+
+            _hasher256.BlockUpdate(dataBytes, 0, dataBytes.Length);
+            _hasher256.DoFinal(digest1, 0);
+            _hasher160.BlockUpdate(digest1, 0, digest1.Length);
+            _hasher160.DoFinal(digest2, 0);
 
             return new Hash160(digest2);
         }
index 2615855..3d3a360 100644 (file)
  */
 
 
-using System.Linq;
-using System.Collections.Generic;
+using Org.BouncyCastle.Crypto.Digests;
 
 namespace Novacoin
 {
-       /// <summary>
-       /// Representation of Double SHA-256 hash
-       /// </summary>
+    /// <summary>
+    /// Representation of Double SHA-256 hash
+    /// </summary>
     public class Hash256 : Hash
     {
+        private static Sha256Digest _hasher256 = new Sha256Digest();
+
         // 32 bytes
         public override int hashSize
         {
-            get { return 32; }
+            get { return _hasher256.GetDigestSize(); }
         }
 
         public Hash256() : base() { }
         public Hash256(byte[] bytes, int offset=0) : base(bytes, offset) { }
-        public Hash256(IEnumerable<byte> bytes, int skip=0) : base(bytes, skip) { }
         public Hash256(Hash256 h) : base(h) { }
 
+        public static Hash256 Compute256(byte[] dataBytes)
+        {
+            var digest1 = new byte[32];
+            var digest2 = new byte[32];
+
+            _hasher256.BlockUpdate(dataBytes, 0, dataBytes.Length);            
+            _hasher256.DoFinal(digest1, 0);
+            _hasher256.BlockUpdate(digest1, 0, digest1.Length);            
+            _hasher256.DoFinal(digest2, 0);
+
+            return new Hash256(digest2);
+        }
 
-        public static Hash256 Compute256(IEnumerable<byte> inputBytes)
+        public static Hash256 Compute256(ref byte[] input1, ref byte[] input2)
         {
-            var dataBytes = inputBytes.ToArray();
-            var digest1 = _hasher256.ComputeHash(dataBytes, 0, dataBytes.Length);
-            var digest2 = _hasher256.ComputeHash(digest1, 0, digest1.Length);
+            var digest1 = new byte[_hasher256.GetDigestSize()];
+            var digest2 = new byte[_hasher256.GetDigestSize()];
+
+            _hasher256.BlockUpdate(input1, 0, input1.Length);
+            _hasher256.BlockUpdate(input2, 0, input2.Length);
+            _hasher256.DoFinal(digest1, 0);
+
+            _hasher256.BlockUpdate(digest1, 0, digest1.Length);
+            _hasher256.DoFinal(digest2, 0);
 
             return new Hash256(digest2);
         }
+
+        public static byte[] ComputeRaw256(byte[] dataBytes)
+        {
+            var digest1 = new byte[32];
+            var digest2 = new byte[32];
+
+            _hasher256.BlockUpdate(dataBytes, 0, dataBytes.Length);
+            _hasher256.DoFinal(digest1, 0);
+            _hasher256.BlockUpdate(digest1, 0, digest1.Length);
+            _hasher256.DoFinal(digest2, 0);
+
+            return digest2;
+        }
+
+        public static byte[] ComputeRaw256(ref byte[] input1, ref byte[] input2)
+        {
+            var digest1 = new byte[_hasher256.GetDigestSize()];
+            var digest2 = new byte[_hasher256.GetDigestSize()];
+
+            _hasher256.BlockUpdate(input1, 0, input1.Length);
+            _hasher256.BlockUpdate(input2, 0, input2.Length);
+            _hasher256.DoFinal(digest1, 0);
+
+            _hasher256.BlockUpdate(digest1, 0, digest1.Length);
+            _hasher256.DoFinal(digest2, 0);
+
+            return digest2;
+        }
     }
 }
-
index 74e25b8..84ce67f 100644 (file)
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-
+using Org.BouncyCastle.Crypto.Digests;
 using System.Collections.Generic;
 using System.Linq;
-using System.Security.Cryptography;
 
 namespace Novacoin
 {
@@ -29,23 +28,24 @@ namespace Novacoin
         /// <summary>
         /// Computes RIPEMD160 hash using managed library
         /// </summary>
-        private static readonly RIPEMD160Managed _hasher160 = new RIPEMD160Managed();
-
+        // private static readonly RIPEMD160Managed _hasher160 = new RIPEMD160Managed();
+        private static RipeMD160Digest _hasher160 = new RipeMD160Digest();
+        
         // 20 bytes
         public override int hashSize
         {
-            get { return 20; }
+            get { return _hasher160.GetDigestSize(); }
         }
 
         public RIPEMD160() : base() { }
         public RIPEMD160(byte[] bytes, int offset = 0) : base(bytes, offset) { }
-        public RIPEMD160(IEnumerable<byte> bytes, int skip = 0) : base(bytes, skip) { }
         public RIPEMD160(RIPEMD160 h) : base(h) { }
 
-        public static RIPEMD160 Compute160(IEnumerable<byte> inputBytes)
+        public static RIPEMD160 Compute160(byte[] inputBytes)
         {
-            var dataBytes = inputBytes.ToArray();
-            var digest1 = _hasher160.ComputeHash(dataBytes, 0, dataBytes.Length);
+            var digest1 = new byte[_hasher160.GetDigestSize()];
+            _hasher160.BlockUpdate(inputBytes, 0, inputBytes.Length);
+            _hasher160.DoFinal(digest1, 0);
 
             return new RIPEMD160(digest1);
         }
index 9d31cfa..7ef1755 100644 (file)
@@ -17,7 +17,7 @@
 
 using System.Collections.Generic;
 using System.Linq;
-using System.Security.Cryptography;
+using Org.BouncyCastle.Crypto.Digests;
 
 namespace Novacoin
 {
@@ -29,24 +29,25 @@ namespace Novacoin
         /// <summary>
         /// Computes RIPEMD160 hash using managed library
         /// </summary>
-        private static readonly SHA1Managed _hasher1 = new SHA1Managed();
+        private static Sha1Digest _hasher1 = new Sha1Digest();
 
         // 32 bytes
         public override int hashSize
         {
-            get { return 20; }
+            get { return _hasher1.GetDigestSize(); }
         }
 
         public SHA1() : base() { }
         public SHA1(byte[] bytes, int offset = 0) : base(bytes, offset) { }
-        public SHA1(IEnumerable<byte> bytes, int skip = 0) : base(bytes, skip) { }
         public SHA1(SHA1 h) : base(h) { }
 
 
-        public static SHA1 Compute1(IEnumerable<byte> inputBytes)
+        public static SHA1 Compute1(byte[] inputBytes)
         {
-            var dataBytes = inputBytes.ToArray();
-            var digest1 = _hasher1.ComputeHash(dataBytes, 0, dataBytes.Length);
+            var digest1 = new byte[_hasher1.GetDigestSize()];
+
+            _hasher1.BlockUpdate(inputBytes, 0, inputBytes.Length);
+            _hasher1.DoFinal(digest1, 0);
 
             return new SHA1(digest1);
         }
index 953eaf4..4ceda48 100644 (file)
@@ -16,8 +16,7 @@
  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-using System.Linq;
-using System.Collections.Generic;
+using Org.BouncyCastle.Crypto.Digests;
 
 namespace Novacoin
 {
@@ -26,22 +25,25 @@ namespace Novacoin
     /// </summary>
     public class SHA256 : Hash
     {
+        private static Sha256Digest _hasher256 = new Sha256Digest();
+
         // 32 bytes
         public override int hashSize
         {
-            get { return 32; }
+            get { return _hasher256.GetDigestSize(); }
         }
 
         public SHA256() : base() { }
         public SHA256(byte[] bytes, int offset = 0) : base(bytes, offset) { }
-        public SHA256(IEnumerable<byte> bytes, int skip = 0) : base(bytes, skip) { }
         public SHA256(SHA256 h) : base(h) { }
 
 
-        public static SHA256 Compute256(IEnumerable<byte> inputBytes)
+        public static SHA256 Compute256(byte[] inputBytes)
         {
-            var dataBytes = inputBytes.ToArray();
-            var digest1 = _hasher256.ComputeHash(dataBytes, 0, dataBytes.Length);
+            var digest1 = new byte[_hasher256.GetDigestSize()];
+
+            _hasher256.BlockUpdate(inputBytes, 0, inputBytes.Length);
+            _hasher256.DoFinal(digest1, 0);
 
             return new SHA256(digest1);
         }
index 658a74c..c90bf87 100644 (file)
@@ -741,12 +741,11 @@ namespace Novacoin
                 Array.Resize(ref txTmp.vin, 1);
             }
 
-            // Serialize and hash
-            var b = new List<byte>();
-            b.AddRange(txTmp.Bytes);
-            b.AddRange(BitConverter.GetBytes(nHashType));
+            // Concatenate and hash
+            var txBytes = txTmp.Bytes;
+            var nHashTypeBytes = BitConverter.GetBytes(nHashType);
 
-            return Hash256.Compute256(b);
+            return Hash256.Compute256(ref txBytes, ref nHashTypeBytes);
         }
 
         //
index 0bf4ac4..96b017f 100644 (file)
@@ -16,7 +16,7 @@
 
 using System;
 using System.Collections.Generic;
-using System.Linq;
+//using System.Linq;
 
 namespace Novacoin
 {
@@ -33,7 +33,6 @@ namespace Novacoin
 
         public ScryptHash256() : base() { }
         public ScryptHash256(byte[] bytes, int offset = 0) : base(bytes, offset) { }
-        public ScryptHash256(IEnumerable<byte> bytes, int skip = 0) : base(bytes, skip) { }
         public ScryptHash256(ScryptHash256 h) : base(h) { }
 
         /// <summary>
@@ -41,12 +40,11 @@ namespace Novacoin
         /// </summary>
         /// <param name="inputBytes">Byte sequence to hash</param>
         /// <returns>Hashing result instance</returns>
-        public static ScryptHash256 Compute256(IEnumerable<byte> inputBytes)
+        public static ScryptHash256 Compute256(byte[] inputBytes)
         {
             var V = new uint[(131072 + 63) / sizeof(uint)];
 
-            var dataBytes = inputBytes.ToArray();
-            var keyBytes1 = CryptoUtils.PBKDF2_Sha256(128, dataBytes, dataBytes, 1);
+            var keyBytes1 = CryptoUtils.PBKDF2_Sha256(128, (byte[])inputBytes, (byte[])inputBytes, 1);
             var X = Interop.ToUInt32Array(keyBytes1);
 
             for (var i = 0; i < 1024; i++)
@@ -68,7 +66,7 @@ namespace Novacoin
             }
 
             var xBytes = Interop.LEBytes(X);
-            var keyBytes2 = CryptoUtils.PBKDF2_Sha256(32, dataBytes, xBytes, 1);
+            var keyBytes2 = CryptoUtils.PBKDF2_Sha256(32, (byte[])inputBytes, xBytes, 1);
 
             return new ScryptHash256(keyBytes2);
         }