Remove Hash, Hash256, Hash160 and ScryptHash256 classes.
authorCryptoManiac <balthazar.ad@gmail.com>
Wed, 2 Sep 2015 14:01:29 +0000 (17:01 +0300)
committerCryptoManiac <balthazar.ad@gmail.com>
Wed, 2 Sep 2015 14:01:29 +0000 (17:01 +0300)
22 files changed:
Novacoin/AddressTools.cs
Novacoin/CBlock.cs
Novacoin/CBlockHeader.cs
Novacoin/CBlockStore.cs
Novacoin/CKey.cs
Novacoin/CKeyID.cs
Novacoin/CKeyPair.cs
Novacoin/COutPoint.cs
Novacoin/CScript.cs
Novacoin/CScriptID.cs
Novacoin/CTransaction.cs
Novacoin/CryptoUtils.cs
Novacoin/Hash.cs [deleted file]
Novacoin/Hash160.cs [deleted file]
Novacoin/Hash256.cs [deleted file]
Novacoin/Novacoin.csproj
Novacoin/ScriptCode.cs
Novacoin/ScryptHash256.cs [deleted file]
Novacoin/base_uint.cs
Novacoin/uint160.cs
Novacoin/uint256.cs
NovacoinTest/Program.cs

index 9ca95b4..b740987 100644 (file)
@@ -67,7 +67,7 @@ namespace Novacoin
         {
             var dataBytes = new byte[bytes.Length + 4];
             bytes.CopyTo(dataBytes, 0);
-            var checkSum = Hash256.ComputeRaw256(bytes).Take(4).ToArray();
+            var checkSum = CryptoUtils.ComputeHash256(bytes).Take(4).ToArray();
             checkSum.CopyTo(dataBytes, dataBytes.Length - 4); // add 4-byte hash check to the end
 
             return Base58Encode(dataBytes);
@@ -128,7 +128,7 @@ namespace Novacoin
             Array.Copy(rawData, result, result.Length);
             Array.Copy(rawData, result.Length, resultCheckSum, 0, 4);
 
-            var checkSum = Hash256.ComputeRaw256(result).Take(4).ToArray();
+            var checkSum = CryptoUtils.ComputeHash256(result).Take(4).ToArray();
 
             if (!checkSum.SequenceEqual(resultCheckSum))
             {
index a620d26..d80e68e 100644 (file)
@@ -128,7 +128,7 @@ namespace Novacoin
 
         public bool CheckBlock(bool fCheckPOW = true, bool fCheckMerkleRoot = true, bool fCheckSig = true)
         {
-            var uniqueTX = new List<Hash256>(); // tx hashes
+            var uniqueTX = new List<uint256>(); // tx hashes
             uint nSigOps = 0; // total sigops
 
             // Basic sanity checkings
@@ -269,7 +269,7 @@ namespace Novacoin
             return true;
         }
 
-        private bool CheckProofOfWork(ScryptHash256 hash, uint nBits)
+        private bool CheckProofOfWork(uint256 hash, uint nBits)
         {
             // TODO: stub!
 
@@ -405,7 +405,7 @@ namespace Novacoin
         /// <summary>
         /// Merkle root
         /// </summary>
-        public Hash256 hashMerkleRoot
+        public uint256 hashMerkleRoot
         {
             get {
                 
@@ -413,7 +413,7 @@ namespace Novacoin
 
                 foreach (var tx in vtx)
                 {
-                    merkleTree.AddRange(Hash256.ComputeRaw256(tx));
+                    merkleTree.AddRange(CryptoUtils.ComputeHash256(tx));
                 }
 
                 int levelOffset = 0;
@@ -431,7 +431,7 @@ namespace Novacoin
                     levelOffset += nLevelSize;
                 }
 
-                return (merkleTree.Count == 0) ? new Hash256() : new Hash256(merkleTree.GetRange(merkleTree.Count-32, 32).ToArray());
+                return (merkleTree.Count == 0) ? 0 : (uint256)merkleTree.GetRange(merkleTree.Count-32, 32).ToArray();
             }
         }
 
index e5557c3..09cbd1b 100644 (file)
@@ -37,12 +37,12 @@ namespace Novacoin
                /// <summary>
                /// Previous block hash.
                /// </summary>
-               public ScryptHash256 prevHash;
+               public uint256 prevHash;
 
                /// <summary>
                /// Merkle root hash.
                /// </summary>
-               public Hash256 merkleRoot;
+               public uint256 merkleRoot;
 
                /// <summary>
                /// Block timestamp.
@@ -65,8 +65,8 @@ namespace Novacoin
                public CBlockHeader ()
                {
             nVersion = 6;
-            prevHash = new ScryptHash256();
-            merkleRoot = new Hash256();
+            prevHash = new uint256();
+            merkleRoot = new uint256();
             nTime = Interop.GetTime();
             nBits = 0;
             nNonce = 0;
@@ -75,8 +75,8 @@ namespace Novacoin
         public CBlockHeader(CBlockHeader header)
         {
             nVersion = header.nVersion;
-            prevHash = new ScryptHash256(header.prevHash);
-            merkleRoot = new Hash256(header.merkleRoot);
+            prevHash = header.prevHash;
+            merkleRoot = header.merkleRoot;
             nTime = header.nTime;
             nBits = header.nBits;
             nNonce = header.nNonce;
@@ -85,8 +85,8 @@ namespace Novacoin
         internal CBlockHeader(ref BinaryReader reader)
         {
             nVersion = reader.ReadUInt32();
-            prevHash = new ScryptHash256(reader.ReadBytes(32));
-            merkleRoot = new Hash256(reader.ReadBytes(32));
+            prevHash = reader.ReadBytes(32);
+            merkleRoot = reader.ReadBytes(32);
             nTime = reader.ReadUInt32();
             nBits = reader.ReadUInt32();
             nNonce = reader.ReadUInt32();
@@ -104,8 +104,8 @@ namespace Novacoin
             var reader = new BinaryReader(stream);
 
             nVersion = reader.ReadUInt32();
-            prevHash = new ScryptHash256(reader.ReadBytes(32));
-            merkleRoot = new Hash256(reader.ReadBytes(32));
+            prevHash = reader.ReadBytes(32);
+            merkleRoot = reader.ReadBytes(32);
             nTime = reader.ReadUInt32();
             nBits = reader.ReadUInt32();
             nNonce = reader.ReadUInt32();
@@ -136,10 +136,10 @@ namespace Novacoin
             return resultBytes;
         }
 
-        public ScryptHash256 Hash
+        public uint256 Hash
         {
             get {
-                return ScryptHash256.Compute256(this);
+                return CryptoUtils.ComputeScryptHash256(this);
             }
         }
 
index cf6c515..6753bfe 100644 (file)
@@ -100,9 +100,9 @@ namespace Novacoin
         /// </summary>
         /// <param name="header">Block header</param>
         /// <returns>Header hash</returns>
-        public ScryptHash256 FillHeader(CBlockHeader header)
+        public uint256 FillHeader(CBlockHeader header)
         {
-            ScryptHash256 _hash;
+            uint256 _hash;
             Hash = _hash = header.Hash;
 
             nVersion = header.nVersion;
@@ -125,8 +125,8 @@ namespace Novacoin
                 CBlockHeader header = new CBlockHeader();
 
                 header.nVersion = nVersion;
-                header.prevHash = new ScryptHash256(prevHash);
-                header.merkleRoot = new Hash256(merkleRoot);
+                header.prevHash = prevHash;
+                header.merkleRoot = merkleRoot;
                 header.nTime = nTime;
                 header.nBits = nBits;
                 header.nNonce = nNonce;
@@ -327,18 +327,18 @@ namespace Novacoin
         /// <summary>
         /// Map of block tree nodes.
         /// </summary>
-        private ConcurrentDictionary<ScryptHash256, CBlockStoreItem> blockMap = new ConcurrentDictionary<ScryptHash256, CBlockStoreItem>();
+        private ConcurrentDictionary<uint256, CBlockStoreItem> blockMap = new ConcurrentDictionary<uint256, CBlockStoreItem>();
 
         /// <summary>
         /// Orphaned blocks map.
         /// </summary>
-        private ConcurrentDictionary<ScryptHash256, CBlock> orphanMap = new ConcurrentDictionary<ScryptHash256, CBlock>();
-        private ConcurrentDictionary<ScryptHash256, CBlock> orphanMapByPrev = new ConcurrentDictionary<ScryptHash256, CBlock>();
+        private ConcurrentDictionary<uint256, CBlock> orphanMap = new ConcurrentDictionary<uint256, CBlock>();
+        private ConcurrentDictionary<uint256, CBlock> orphanMapByPrev = new ConcurrentDictionary<uint256, CBlock>();
 
         /// <summary>
         /// Map of unspent items.
         /// </summary>
-        private ConcurrentDictionary<Hash256, CTransactionStoreItem> txMap = new ConcurrentDictionary<Hash256, CTransactionStoreItem>();
+        private ConcurrentDictionary<uint256, CTransactionStoreItem> txMap = new ConcurrentDictionary<uint256, CTransactionStoreItem>();
 
         public static CBlockStore Instance;
 
@@ -415,14 +415,14 @@ namespace Novacoin
                 // Init list of block items
                 foreach (var item in blockTreeItems)
                 {
-                    blockMap.TryAdd(new ScryptHash256(item.Hash), item);
+                    blockMap.TryAdd(item.Hash, item);
                 }
             }
 
             Instance = this;
         }
 
-        public bool GetTransaction(Hash256 TxID, ref CTransaction tx)
+        public bool GetTransaction(uint256 TxID, ref CTransaction tx)
         {
             var reader = new BinaryReader(fStreamReadWrite).BaseStream;
             var QueryTx = dbConn.Query<CTransactionStoreItem>("select * from [TransactionStorage] where [TransactionHash] = ?", (byte[])TxID);
@@ -440,7 +440,7 @@ namespace Novacoin
         private bool AddItemToIndex(ref CBlockStoreItem itemTemplate, ref CBlock block)
         {
             var writer = new BinaryWriter(fStreamReadWrite).BaseStream;
-            var blockHash = new ScryptHash256(itemTemplate.Hash);
+            uint256 blockHash = itemTemplate.Hash;
 
             if (blockMap.ContainsKey(blockHash))
             {
@@ -501,7 +501,7 @@ namespace Novacoin
 
         public bool AcceptBlock(ref CBlock block)
         {
-            ScryptHash256 hash = block.header.Hash;
+            uint256 hash = block.header.Hash;
 
             if (blockMap.ContainsKey(hash))
             {
@@ -555,7 +555,7 @@ namespace Novacoin
             return true;
         }
 
-        public bool GetBlock(ScryptHash256 blockHash, ref CBlock block)
+        public bool GetBlock(uint256 blockHash, ref CBlock block)
         {
             var reader = new BinaryReader(fStreamReadWrite).BaseStream;
 
@@ -573,7 +573,7 @@ namespace Novacoin
 
         public bool ProcessBlock(ref CBlock block)
         {
-            ScryptHash256 blockHash = block.header.Hash;
+            var blockHash = block.header.Hash;
 
             if (blockMap.ContainsKey(blockHash))
             {
@@ -631,12 +631,12 @@ namespace Novacoin
             }
 
             // Recursively process any orphan blocks that depended on this one
-            var orphansQueue = new List<ScryptHash256>();
+            var orphansQueue = new List<uint256>();
             orphansQueue.Add(blockHash);
 
             for (int i = 0; i < orphansQueue.Count; i++)
             {
-                ScryptHash256 hashPrev = orphansQueue[i];
+                var hashPrev = orphansQueue[i];
 
                 foreach (var pair in orphanMap)
                 {
index 355c66e..672f0be 100644 (file)
@@ -82,11 +82,11 @@ namespace Novacoin
         /// <param name="sigHash">Data hash</param>
         /// <param name="signature">Signature bytes</param>
         /// <returns>Checking result</returns>
-        public bool VerifySignature(Hash sigHash, byte[] signature)
+        public bool VerifySignature(uint256 sigHash, byte[] signature)
         {
             var signer = SignerUtilities.GetSigner("NONEwithECDSA");
             signer.Init(false, _Public);
-            signer.BlockUpdate(sigHash, 0, sigHash.hashSize);
+            signer.BlockUpdate(sigHash, 0, sigHash.Size);
 
             return signer.VerifySignature(signature);
         }
@@ -97,7 +97,7 @@ namespace Novacoin
         /// <returns>New key ID</returns>
         public CKeyID KeyID
         {
-            get { return new CKeyID(Hash160.Compute160(_Public.Q.GetEncoded())); }
+            get { return new CKeyID(CryptoUtils.ComputeHash160(_Public.Q.GetEncoded())); }
         }
 
         /// <summary>
index 62639a1..be51bf1 100644 (file)
@@ -23,11 +23,12 @@ namespace Novacoin
     /// </summary>
     public class CKeyID : uint160
     {
+        #region Constructors
         public CKeyID() : base()
         {
         }
 
-        public CKeyID(CKeyID KeyID) : base(KeyID)
+        public CKeyID(CKeyID KeyID) : base(KeyID as uint160)
         {
         }
 
@@ -38,6 +39,7 @@ namespace Novacoin
         public CKeyID(byte[] hashBytes) : base(hashBytes)
         {
         }
+        #endregion
 
         /// <summary>
         /// Generate Pay-to-PubkeyHash address
index a1d50a8..5dcedbb 100644 (file)
@@ -142,11 +142,11 @@ namespace Novacoin
         /// </summary>
         /// <param name="data">Hash to sigh</param>
         /// <returns>Signature bytes sequence</returns>
-        public byte[] Sign(Hash sigHash)
+        public byte[] Sign(uint256 sigHash)
         {
             var signer = SignerUtilities.GetSigner("NONEwithECDSA");
             signer.Init(true, _Private);
-            signer.BlockUpdate(sigHash, 0, sigHash.hashSize);
+            signer.BlockUpdate(sigHash, 0, sigHash.Size);
 
             return signer.GenerateSignature();
         }
index 9e628e9..09d0690 100644 (file)
@@ -20,6 +20,7 @@ using System;
 using System.Collections.Generic;
 using System.Diagnostics.Contracts;
 using System.IO;
+using System.Linq;
 using System.Text;
 
 namespace Novacoin
@@ -29,7 +30,7 @@ namespace Novacoin
         /// <summary>
         /// Hash of parent transaction.
         /// </summary>
-        public Hash256 hash;
+        public uint256 hash;
 
         /// <summary>
         /// Parent input number.
@@ -43,11 +44,11 @@ namespace Novacoin
 
         public COutPoint()
         {
-            hash = new Hash256();
+            hash = new uint256();
             n = uint.MaxValue;
         }
 
-        public COutPoint(Hash256 hashIn, uint nIn)
+        public COutPoint(uint256 hashIn, uint nIn)
         {
             hash = hashIn;
             n = nIn;
@@ -55,7 +56,7 @@ namespace Novacoin
 
         public COutPoint(COutPoint o)
         {
-            hash = new Hash256(o.hash);
+            hash = o.hash;
             n = o.n;
         }
 
@@ -63,13 +64,13 @@ namespace Novacoin
         {
             Contract.Requires<ArgumentException>(bytes.Length == 36, "Any valid outpoint reference data item is exactly 36 bytes long.");
 
-            hash = new Hash256(bytes);
+            hash = bytes.Take(32).ToArray();
             n = BitConverter.ToUInt32(bytes, 32);
         }
 
         public bool IsNull
         {
-            get { return hash.IsZero && n == uint.MaxValue; }
+            get { return !hash && n == uint.MaxValue; }
         }
 
         public static implicit operator byte[] (COutPoint o)
index 95ca17a..817d2fa 100644 (file)
@@ -510,7 +510,7 @@ namespace Novacoin
 
         public CScriptID ScriptID
         {
-            get { return new CScriptID(Hash160.Compute160(codeBytes.ToArray())); }
+            get { return new CScriptID(CryptoUtils.ComputeHash160(codeBytes.ToArray())); }
         }
 
         /// <summary>
index b9ead5a..9035de5 100644 (file)
@@ -23,11 +23,12 @@ namespace Novacoin
     /// </summary>
     public class CScriptID : uint160
     {
+        #region Constructors
         public CScriptID() : base()
         {
         }
 
-        public CScriptID(CScriptID KeyID) : base(KeyID)
+        public CScriptID(CScriptID KeyID) : base(KeyID as uint160)
         {
         }
 
@@ -38,6 +39,7 @@ namespace Novacoin
         public CScriptID(byte[] hashBytes) : base(hashBytes)
         {
         }
+        #endregion
 
         /// <summary>
         /// Generate Pay-to-ScriptHash address
index 1070703..fb865a4 100644 (file)
@@ -398,9 +398,9 @@ namespace Novacoin
         /// <summary>
         /// Transaction hash
         /// </summary>
-        public Hash256 Hash
+        public uint256 Hash
         {
-            get { return Hash256.Compute256(this); }
+            get { return CryptoUtils.ComputeHash256(this); }
         }
 
         /// <summary>
index 12e4bfd..72cc210 100644 (file)
  */
 
 using System;
+using System.Diagnostics.Contracts;
 using System.IO;
 using System.Security.Cryptography;
 
 namespace Novacoin
 {
+    /// <summary>
+    /// Hashing functionality.
+    /// </summary>
     public class CryptoUtils
     {
+        #region Private instances for various hashing algorithm implementations.
+        /// <summary>
+        /// Computes the SHA1 hash for the input data using the managed library.
+        /// </summary>
         private static SHA1Managed _sha1 = new SHA1Managed();
+        
+        /// <summary>
+        /// Computes the SHA256 hash for the input data using the managed library.
+        /// </summary>
         private static SHA256Managed _sha256 = new SHA256Managed();
+
+        /// <summary>
+        /// Computes the SHA1 hash for the input data using the managed library.
+        /// </summary>
         private static RIPEMD160Managed _ripe160 = new RIPEMD160Managed();
+        #endregion
 
         /// <summary>
         /// Sha1 calculation
@@ -88,8 +105,9 @@ namespace Novacoin
         /// <returns>Hashing result</returns>
         public static byte[] ComputeHash256(ref byte[] input1, ref byte[] input2)
         {
-            var buffer = new byte[64];
+            var buffer = new byte[input1.Length + input2.Length];
 
+            // Fill the buffer
             input1.CopyTo(buffer, 0);
             input2.CopyTo(buffer, input1.Length);
 
@@ -97,6 +115,51 @@ namespace Novacoin
             return _sha256.ComputeHash(digest1, 0, digest1.Length);
         }
 
+        /// <summary>
+        /// Calculate PBKDF2-SHA256(SALSA20/8(PBKDF2-SHA256(X)))
+        /// </summary>
+        /// <param name="inputBytes">Bytes to hash</param>
+        /// <returns>Hashing result</returns>
+        public static byte[] ComputeScryptHash256(byte[] inputBytes)
+        {
+            var V = new uint[(131072 + 63) / sizeof(uint)];
+
+            var keyBytes1 = PBKDF2_Sha256(128, inputBytes, inputBytes, 1);
+            var X = Interop.ToUInt32Array(keyBytes1);
+
+            for (var i = 0; i < 1024; i++)
+            {
+                Array.Copy(X, 0, V, i * 32, 32);
+
+                xor_salsa8(ref X, 0, ref X, 16);
+                xor_salsa8(ref X, 16, ref X, 0);
+            }
+            for (var i = 0; i < 1024; i++)
+            {
+                var j = 32 * (X[16] & 1023);
+                for (var k = 0; k < 32; k++)
+                {
+                    X[k] ^= V[j + k];
+                }
+                xor_salsa8(ref X, 0, ref X, 16);
+                xor_salsa8(ref X, 16, ref X, 0);
+            }
+
+            var xBytes = Interop.LEBytes(X);
+
+            return PBKDF2_Sha256(32, inputBytes, xBytes, 1);
+        }
+
+
+        #region PBKDF2-SHA256
+        /// <summary>
+        /// Managed implementation of PBKDF2-SHA256.
+        /// </summary>
+        /// <param name="dklen">Key length</param>
+        /// <param name="password">Password</param>
+        /// <param name="salt">Salt</param>
+        /// <param name="iterationCount">Amount of derive iterations.</param>
+        /// <returns>Derived key</returns>
         public static byte[] PBKDF2_Sha256(int dklen, byte[] password, byte[] salt, int iterationCount)
         {
             /* Init HMAC state. */
@@ -169,5 +232,79 @@ namespace Novacoin
                 }
             }
         }
+        #endregion
+
+        #region SALSA20/8
+        private static void xor_salsa8(ref uint[] B, int indexB, ref uint[] Bx, int indexBx)
+        {
+            uint x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15;
+            byte i;
+
+            x00 = (B[indexB + 0] ^= Bx[indexBx + 0]);
+            x01 = (B[indexB + 1] ^= Bx[indexBx + 1]);
+            x02 = (B[indexB + 2] ^= Bx[indexBx + 2]);
+            x03 = (B[indexB + 3] ^= Bx[indexBx + 3]);
+            x04 = (B[indexB + 4] ^= Bx[indexBx + 4]);
+            x05 = (B[indexB + 5] ^= Bx[indexBx + 5]);
+            x06 = (B[indexB + 6] ^= Bx[indexBx + 6]);
+            x07 = (B[indexB + 7] ^= Bx[indexBx + 7]);
+            x08 = (B[indexB + 8] ^= Bx[indexBx + 8]);
+            x09 = (B[indexB + 9] ^= Bx[indexBx + 9]);
+            x10 = (B[indexB + 10] ^= Bx[indexBx + 10]);
+            x11 = (B[indexB + 11] ^= Bx[indexBx + 11]);
+            x12 = (B[indexB + 12] ^= Bx[indexBx + 12]);
+            x13 = (B[indexB + 13] ^= Bx[indexBx + 13]);
+            x14 = (B[indexB + 14] ^= Bx[indexBx + 14]);
+            x15 = (B[indexB + 15] ^= Bx[indexBx + 15]);
+
+            Func<uint, int, uint> R = (a, b) => (((a) << (b)) | ((a) >> (32 - (b))));
+
+            for (i = 0; i < 8; i += 2)
+            {
+                /* Operate on columns. */
+                x04 ^= R(x00 + x12, 7); x09 ^= R(x05 + x01, 7);
+                x14 ^= R(x10 + x06, 7); x03 ^= R(x15 + x11, 7);
+
+                x08 ^= R(x04 + x00, 9); x13 ^= R(x09 + x05, 9);
+                x02 ^= R(x14 + x10, 9); x07 ^= R(x03 + x15, 9);
+
+                x12 ^= R(x08 + x04, 13); x01 ^= R(x13 + x09, 13);
+                x06 ^= R(x02 + x14, 13); x11 ^= R(x07 + x03, 13);
+
+                x00 ^= R(x12 + x08, 18); x05 ^= R(x01 + x13, 18);
+                x10 ^= R(x06 + x02, 18); x15 ^= R(x11 + x07, 18);
+
+                /* Operate on rows. */
+                x01 ^= R(x00 + x03, 7); x06 ^= R(x05 + x04, 7);
+                x11 ^= R(x10 + x09, 7); x12 ^= R(x15 + x14, 7);
+
+                x02 ^= R(x01 + x00, 9); x07 ^= R(x06 + x05, 9);
+                x08 ^= R(x11 + x10, 9); x13 ^= R(x12 + x15, 9);
+
+                x03 ^= R(x02 + x01, 13); x04 ^= R(x07 + x06, 13);
+                x09 ^= R(x08 + x11, 13); x14 ^= R(x13 + x12, 13);
+
+                x00 ^= R(x03 + x02, 18); x05 ^= R(x04 + x07, 18);
+                x10 ^= R(x09 + x08, 18); x15 ^= R(x14 + x13, 18);
+            }
+
+            B[indexB + 0] += x00;
+            B[indexB + 1] += x01;
+            B[indexB + 2] += x02;
+            B[indexB + 3] += x03;
+            B[indexB + 4] += x04;
+            B[indexB + 5] += x05;
+            B[indexB + 6] += x06;
+            B[indexB + 7] += x07;
+            B[indexB + 8] += x08;
+            B[indexB + 9] += x09;
+            B[indexB + 10] += x10;
+            B[indexB + 11] += x11;
+            B[indexB + 12] += x12;
+            B[indexB + 13] += x13;
+            B[indexB + 14] += x14;
+            B[indexB + 15] += x15;
+        }
+        #endregion
     }
 }
diff --git a/Novacoin/Hash.cs b/Novacoin/Hash.cs
deleted file mode 100644 (file)
index 5b1d3b7..0000000
+++ /dev/null
@@ -1,227 +0,0 @@
-\feff/**
- *  Novacoin classes library
- *  Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com)
-
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as
- *  published by the Free Software Foundation, either version 3 of the
- *  License, or (at your option) any later version.
-
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
-
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-using System;
-using System.Diagnostics.Contracts;
-using System.Linq;
-
-namespace Novacoin
-{
-    public abstract class Hash : IEquatable<Hash>, IComparable<Hash>
-    {
-        /// <summary>
-        /// Array of digest bytes.
-        /// </summary>
-        protected byte[] _hashBytes;
-
-        /// <summary>
-        /// Hash size, must be overriden
-        /// </summary>
-        public abstract int hashSize 
-        {
-            get; 
-        }
-
-        /// <summary>
-        /// Initializes an empty instance of the Hash class.
-        /// </summary>
-        public Hash()
-        {
-            _hashBytes = new byte[hashSize];
-        }
-
-        /// <summary>
-        /// Initializes a new instance of Hash class
-        /// </summary>
-        /// <param name="bytesList">Array of bytes</param>
-        public Hash(byte[] bytes, int offset = 0)
-        {
-            if (bytes.Length - offset < hashSize)
-            {
-                throw new ArgumentException("You need to provide a sufficient amount of data to initialize new instance of hash object.");
-            }
-
-            _hashBytes = new byte[hashSize];
-            Array.Copy(bytes, offset, _hashBytes, 0, hashSize);
-        }
-
-        /// <summary>
-        /// Initializes a new instance of Hash class as a copy of another one
-        /// </summary>
-        /// <param name="bytesList">Instance of hash class</param>
-        public Hash(Hash h)
-        {
-            _hashBytes = new byte[h.hashSize];
-            h._hashBytes.CopyTo(_hashBytes, 0);
-        }
-
-        public bool IsZero
-        {
-            get { return !_hashBytes.Any(b => b != 0); }
-        }
-
-        public static implicit operator byte[](Hash h)
-        {
-            return h._hashBytes;
-        }
-
-        public bool Equals(Hash item)
-        {
-            if ((object)item == null)
-            {
-                return false;
-            }
-            return _hashBytes.SequenceEqual((byte[])item);
-        }
-
-        public override bool Equals(object o)
-        {
-            if (o == null)
-            {
-                return false;
-            }
-
-            return _hashBytes.SequenceEqual(((Hash)o)._hashBytes);
-        }
-
-        public override int GetHashCode()
-        {
-            int hash = 17;
-            unchecked
-            {
-                foreach (var element in _hashBytes)
-                {
-                    hash = hash * 31 + element.GetHashCode();
-                }
-            }
-            return hash;
-        }
-
-        public int CompareTo(Hash item)
-        {
-            if (this > item)
-            {
-                return 1;
-            }
-            else if (this < item)
-            {
-                return -1;
-            }
-
-            return 0;
-        }
-
-        public static bool operator <(Hash a, Hash b)
-        {
-            Contract.Requires<NullReferenceException>((object)a != null && (object)b != null, "Null references are not allowed.");
-            Contract.Requires<ArgumentException>(a.hashSize == b.hashSize, "Hashes must have the same size.");
-            
-            for (int i = a.hashSize - 1; i >= 0; i--)
-            {
-                if (a._hashBytes[i] < b._hashBytes[i])
-                {
-                    return true;
-                }
-                else if (a._hashBytes[i] > b._hashBytes[i])
-                {
-                    return false;
-                }
-            }
-
-            return false;
-        }
-
-        public static bool operator <=(Hash a, Hash b)
-        {
-            Contract.Requires<NullReferenceException>((object)a != null && (object)b != null, "Null references are not allowed.");
-            Contract.Requires<ArgumentException>(a.hashSize == b.hashSize, "Hashes must have the same size.");
-
-            for (int i = a.hashSize - 1; i >= 0; i--)
-            {
-                if (a._hashBytes[i] < b._hashBytes[i])
-                {
-                    return true;
-                }
-                else if (a._hashBytes[i] > b._hashBytes[i])
-                {
-                    return false;
-                }
-            }
-
-            return false;
-        }
-
-        public static bool operator >(Hash a, Hash b)
-        {
-            Contract.Requires<NullReferenceException>((object)a != null && (object)b != null, "Null references are not allowed.");
-            Contract.Requires<ArgumentException>(a.hashSize == b.hashSize, "Hashes must have the same size.");
-
-            for (int i = a.hashSize - 1; i >= 0; i--)
-            {
-                if (a._hashBytes[i] > b._hashBytes[i])
-                {
-                    return true;
-                }
-                else if (a._hashBytes[i] < b._hashBytes[i])
-                {
-                    return false;
-                }
-            }
-
-            return false;
-        }
-
-        public static bool operator >=(Hash a, Hash b)
-        {
-            Contract.Requires<NullReferenceException>((object)a != null && (object)b != null, "Null references are not allowed.");
-            Contract.Requires<ArgumentException>(a.hashSize == b.hashSize, "Hashes must have the same size.");
-
-            for (int i = a.hashSize - 1; i >= 0; i--)
-            {
-                if (a._hashBytes[i] > b._hashBytes[i])
-                {
-                    return true;
-                }
-                else if (a._hashBytes[i] < b._hashBytes[i])
-                {
-                    return false;
-                }
-            }
-
-            return true;
-        }
-
-        public static bool operator ==(Hash a, Hash b)
-        {
-            Contract.Requires<NullReferenceException>((object)a != null && (object)b != null, "Null references are not allowed.");
-            Contract.Requires<ArgumentException>(a.hashSize == b.hashSize, "Hashes must have the same size.");
-
-            return a._hashBytes.SequenceEqual(b._hashBytes);
-        }
-
-        public static bool operator !=(Hash a, Hash b)
-        {
-            return !(a == b);
-        }
-
-        public override string ToString()
-        {
-            return Interop.ToHex(Interop.ReverseBytes(_hashBytes));
-        }
-    }
-}
diff --git a/Novacoin/Hash160.cs b/Novacoin/Hash160.cs
deleted file mode 100644 (file)
index f95165b..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-\feff/**
- *  Novacoin classes library
- *  Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com)
-
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as
- *  published by the Free Software Foundation, either version 3 of the
- *  License, or (at your option) any later version.
-
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
-
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-using System.Linq;
-using Org.BouncyCastle.Crypto.Digests;
-
-namespace Novacoin
-{
-    /// <summary>
-    /// Representation of pubkey/script hash.
-    /// </summary>
-    public class Hash160 : Hash
-       {
-        /// <summary>
-        /// Computes RIPEMD160 hash using managed library
-        /// </summary>
-        //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 _hasher160.GetDigestSize(); }
-        }
-
-        public Hash160() : base() { }
-        public Hash160(byte[] bytes, int offset = 0) : base(bytes, offset) { }
-        public Hash160(Hash160 h) : base(h) { }
-
-        public static Hash160 Compute160(byte[] inputBytes)
-        {
-            var dataBytes = inputBytes.ToArray();
-
-                       var digest1 = new byte[_hasher256.GetDigestSize()];
-                       var digest2 = new byte[_hasher160.GetDigestSize()];
-
-            _hasher256.BlockUpdate(dataBytes, 0, dataBytes.Length);
-            _hasher256.DoFinal(digest1, 0);
-            _hasher160.BlockUpdate(digest1, 0, digest1.Length);
-            _hasher160.DoFinal(digest2, 0);
-
-            return new Hash160(digest2);
-        }
-       }
-}
-
diff --git a/Novacoin/Hash256.cs b/Novacoin/Hash256.cs
deleted file mode 100644 (file)
index 3d3a360..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-\feff/**
- *  Novacoin classes library
- *  Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com)
-
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as
- *  published by the Free Software Foundation, either version 3 of the
- *  License, or (at your option) any later version.
-
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
-
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-
-using Org.BouncyCastle.Crypto.Digests;
-
-namespace Novacoin
-{
-    /// <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 _hasher256.GetDigestSize(); }
-        }
-
-        public Hash256() : base() { }
-        public Hash256(byte[] bytes, int offset=0) : base(bytes, offset) { }
-        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(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 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 b7b6318..dfd1b81 100644 (file)
     <Compile Include="CPubKey.cs" />
     <Compile Include="CryptoUtils.cs" />
     <Compile Include="CScriptID.cs" />
-    <Compile Include="Hash.cs" />
     <Compile Include="Interop.cs" />
     <Compile Include="NetInfo.cs" />
-    <Compile Include="ScryptHash256.cs" />
     <Compile Include="uint160.cs" />
     <Compile Include="uint256.cs" />
     <Compile Include="VarInt.cs" />
     <Compile Include="CTxIn.cs" />
     <Compile Include="CTransaction.cs" />
     <Compile Include="CTxOut.cs" />
-    <Compile Include="Hash256.cs" />
-    <Compile Include="Hash160.cs" />
     <Compile Include="CBlockHeader.cs" />
     <Compile Include="CBlock.cs" />
     <Compile Include="CScript.cs" />
index 14bc2e5..ab0db3f 100644 (file)
@@ -656,7 +656,7 @@ namespace Novacoin
         /// <param name="nIn">Input number</param>
         /// <param name="nHashType">Hash type flag</param>
         /// <returns></returns>
-        public static Hash256 SignatureHash(CScript script, CTransaction txTo, int nIn, int nHashType)
+        public static uint256 SignatureHash(CScript script, CTransaction txTo, int nIn, int nHashType)
         {
             Contract.Requires<ArgumentOutOfRangeException>(nIn < txTo.vin.Length, "nIn out of range.");
 
@@ -727,7 +727,7 @@ namespace Novacoin
             var txBytes = (byte[])txTmp;
             var nHashTypeBytes = BitConverter.GetBytes(nHashType);
 
-            return Hash256.Compute256(ref txBytes, ref nHashTypeBytes);
+            return CryptoUtils.ComputeHash256(ref txBytes, ref nHashTypeBytes);
         }
 
         //
diff --git a/Novacoin/ScryptHash256.cs b/Novacoin/ScryptHash256.cs
deleted file mode 100644 (file)
index 4f95926..0000000
+++ /dev/null
@@ -1,145 +0,0 @@
-\feff/**
- *  Novacoin classes library
- *  Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com)
-
- *  This program is free software: you can redistribute it and/or modify
- *  it under the terms of the GNU Affero General Public License as
- *  published by the Free Software Foundation, either version 3 of the
- *  License, or (at your option) any later version.
-
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Affero General Public License for more details.
-
- *  You should have received a copy of the GNU Affero General Public License
- *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-using System;
-
-namespace Novacoin
-{
-    /// <summary>
-    /// Representation of scrypt hash
-    /// </summary>
-    public class ScryptHash256 : Hash
-    {
-        // 32 bytes
-        public override int hashSize
-        {
-            get { return 32; }
-        }
-
-        public ScryptHash256() : base() { }
-        public ScryptHash256(byte[] bytes, int offset = 0) : base(bytes, offset) { }
-        public ScryptHash256(ScryptHash256 h) : base(h) { }
-
-        /// <summary>
-        /// Calculate scrypt hash and return new instance of ScryptHash256 class
-        /// </summary>
-        /// <param name="inputBytes">Byte sequence to hash</param>
-        /// <returns>Hashing result instance</returns>
-        public static ScryptHash256 Compute256(byte[] inputBytes)
-        {
-            var V = new uint[(131072 + 63) / sizeof(uint)];
-
-            var keyBytes1 = CryptoUtils.PBKDF2_Sha256(128, (byte[])inputBytes, (byte[])inputBytes, 1);
-            var X = Interop.ToUInt32Array(keyBytes1);
-
-            for (var i = 0; i < 1024; i++)
-            {
-                Array.Copy(X, 0, V, i * 32, 32);
-
-                xor_salsa8(ref X, 0, ref X, 16);
-                xor_salsa8(ref X, 16, ref X, 0);
-            }
-            for (var i = 0; i < 1024; i++)
-            {
-                var j = 32 * (X[16] & 1023);
-                for (var k = 0; k < 32; k++)
-                {
-                    X[k] ^= V[j + k];
-                }
-                xor_salsa8(ref X, 0, ref X, 16);
-                xor_salsa8(ref X, 16, ref X, 0);
-            }
-
-            var xBytes = Interop.LEBytes(X);
-            var keyBytes2 = CryptoUtils.PBKDF2_Sha256(32, (byte[])inputBytes, xBytes, 1);
-
-            return new ScryptHash256(keyBytes2);
-        }
-
-        private static void xor_salsa8(ref uint[] B, int indexB, ref uint[] Bx, int indexBx)
-        {
-            uint x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x10, x11, x12, x13, x14, x15;
-            byte i;
-
-            x00 = (B[indexB + 0] ^= Bx[indexBx + 0]);
-            x01 = (B[indexB + 1] ^= Bx[indexBx + 1]);
-            x02 = (B[indexB + 2] ^= Bx[indexBx + 2]);
-            x03 = (B[indexB + 3] ^= Bx[indexBx + 3]);
-            x04 = (B[indexB + 4] ^= Bx[indexBx + 4]);
-            x05 = (B[indexB + 5] ^= Bx[indexBx + 5]);
-            x06 = (B[indexB + 6] ^= Bx[indexBx + 6]);
-            x07 = (B[indexB + 7] ^= Bx[indexBx + 7]);
-            x08 = (B[indexB + 8] ^= Bx[indexBx + 8]);
-            x09 = (B[indexB + 9] ^= Bx[indexBx + 9]);
-            x10 = (B[indexB + 10] ^= Bx[indexBx + 10]);
-            x11 = (B[indexB + 11] ^= Bx[indexBx + 11]);
-            x12 = (B[indexB + 12] ^= Bx[indexBx + 12]);
-            x13 = (B[indexB + 13] ^= Bx[indexBx + 13]);
-            x14 = (B[indexB + 14] ^= Bx[indexBx + 14]);
-            x15 = (B[indexB + 15] ^= Bx[indexBx + 15]);
-
-            Func<uint, int, uint> R = (a, b) => (((a) << (b)) | ((a) >> (32 - (b))));
-
-            for (i = 0; i < 8; i += 2)
-            {
-                /* Operate on columns. */
-                x04 ^= R(x00 + x12, 7); x09 ^= R(x05 + x01, 7);
-                x14 ^= R(x10 + x06, 7); x03 ^= R(x15 + x11, 7);
-
-                x08 ^= R(x04 + x00, 9); x13 ^= R(x09 + x05, 9);
-                x02 ^= R(x14 + x10, 9); x07 ^= R(x03 + x15, 9);
-
-                x12 ^= R(x08 + x04, 13); x01 ^= R(x13 + x09, 13);
-                x06 ^= R(x02 + x14, 13); x11 ^= R(x07 + x03, 13);
-
-                x00 ^= R(x12 + x08, 18); x05 ^= R(x01 + x13, 18);
-                x10 ^= R(x06 + x02, 18); x15 ^= R(x11 + x07, 18);
-
-                /* Operate on rows. */
-                x01 ^= R(x00 + x03, 7); x06 ^= R(x05 + x04, 7);
-                x11 ^= R(x10 + x09, 7); x12 ^= R(x15 + x14, 7);
-
-                x02 ^= R(x01 + x00, 9); x07 ^= R(x06 + x05, 9);
-                x08 ^= R(x11 + x10, 9); x13 ^= R(x12 + x15, 9);
-
-                x03 ^= R(x02 + x01, 13); x04 ^= R(x07 + x06, 13);
-                x09 ^= R(x08 + x11, 13); x14 ^= R(x13 + x12, 13);
-
-                x00 ^= R(x03 + x02, 18); x05 ^= R(x04 + x07, 18);
-                x10 ^= R(x09 + x08, 18); x15 ^= R(x14 + x13, 18);
-            }
-
-            B[indexB + 0] += x00;
-            B[indexB + 1] += x01;
-            B[indexB + 2] += x02;
-            B[indexB + 3] += x03;
-            B[indexB + 4] += x04;
-            B[indexB + 5] += x05;
-            B[indexB + 6] += x06;
-            B[indexB + 7] += x07;
-            B[indexB + 8] += x08;
-            B[indexB + 9] += x09;
-            B[indexB + 10] += x10;
-            B[indexB + 11] += x11;
-            B[indexB + 12] += x12;
-            B[indexB + 13] += x13;
-            B[indexB + 14] += x14;
-            B[indexB + 15] += x15;
-        }
-    }
-}
index 502d871..adfa75f 100644 (file)
@@ -28,31 +28,43 @@ namespace Novacoin
     /// </summary>
     public class base_uint : IComparable<base_uint>, IEquatable<base_uint>, IEqualityComparer<base_uint>
     {
+        #region Internal representation
+        /// <summary>
+        /// Length of internal representation
+        /// </summary>
         protected int nWidth;
+        /// <summary>
+        /// Big numbers are stored as array of unsigned 32-bit integers.
+        /// </summary>
         protected uint[] pn;
+        #endregion
 
-        public double getDouble()
+        #region Helper properties
+        public double Double
         {
-            double ret = 0.0;
-            double fact = 1.0;
-
-            for (int i = 0; i < nWidth; i++)
+            get
             {
-                ret += fact * pn[i];
-                fact *= 4294967296.0;
-            }
+                double ret = 0.0;
+                double fact = 1.0;
 
-            return ret;
+                for (int i = 0; i < nWidth; i++)
+                {
+                    ret += fact * pn[i];
+                    fact *= 4294967296.0;
+                }
+
+                return ret;
+            }
         }
 
-        public ulong GetLow64()
+        public ulong Low64
         {
-            return pn[0] | (ulong)pn[1] << 32;
+            get { return pn[0] | (ulong)pn[1] << 32; }
         }
 
-        public uint GetLow32()
+        public uint Low32
         {
-            return pn[0];
+            get { return pn[0]; }
         }
 
         /// <summary>
@@ -75,11 +87,11 @@ namespace Novacoin
             {
                 for (int pos = nWidth - 1; pos >= 0; pos--)
                 {
-                    if (pn[pos]!=0)
+                    if (pn[pos] != 0)
                     {
                         for (int bits = 31; bits > 0; bits--)
                         {
-                            if ((pn[pos] & 1 << bits)!=0)
+                            if ((pn[pos] & 1 << bits) != 0)
                                 return 32 * pos + bits + 1;
                         }
                         return 32 * pos + 1;
@@ -88,7 +100,14 @@ namespace Novacoin
                 return 0;
             }
         }
+        #endregion
 
+
+        /// <summary>
+        /// Negation operator
+        /// </summary>
+        /// <param name="a">Value</param>
+        /// <returns>True if value is zero, false otherwise.</returns>
         public static bool operator !(base_uint a)
         {
             for (int i = 0; i < a.nWidth; i++)
@@ -308,7 +327,7 @@ namespace Novacoin
         #region IEquatable
         public bool Equals(base_uint a)
         {
-            if (a == null)
+            if (object.ReferenceEquals(a, null))
             {
                 return false;
             }
index 595aa1a..4da1929 100644 (file)
@@ -1,14 +1,29 @@
-\feffusing System;
-using System.Collections.Generic;
+\feff/**
+ *  Novacoin classes library
+ *  Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com)
+
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as
+ *  published by the Free Software Foundation, either version 3 of the
+ *  License, or (at your option) any later version.
+
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+using System;
 using System.Diagnostics.Contracts;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
 
 namespace Novacoin
 {
     public class uint160 : base_uint
     {
+        #region Access to internal representation
         new protected int nWidth
         {
             get { return base.nWidth; }
@@ -19,7 +34,9 @@ namespace Novacoin
             get { return base.pn; }
             private set { base.pn = value; }
         }
+        #endregion
 
+        #region Constructors
         public uint160()
         {
             nWidth = 5;
@@ -57,60 +74,66 @@ namespace Novacoin
             var bytes = Interop.ReverseBytes(Interop.HexToArray(hex));
             pn = Interop.ToUInt32Array(bytes);
         }
+        #endregion
 
-        public static uint160 operator ~(uint160 a)
+        #region Cast operators
+        public static implicit operator uint160(byte[] bytes)
         {
-            var ret = new uint160();
-            for (int i = 0; i < a.nWidth; i++)
-            {
-                ret.pn[i] = ~a.pn[i];
-            }
-            return ret;
+            return new uint160(bytes);
         }
 
-        public static uint160 operator -(uint160 a)
+        public static implicit operator uint160(ulong n)
+        {
+            return new uint160(n);
+        }
+        #endregion
+
+        #region Bitwise operations
+        public static uint160 operator ~(uint160 a)
         {
             var ret = new uint160();
             for (int i = 0; i < a.nWidth; i++)
             {
                 ret.pn[i] = ~a.pn[i];
             }
-            ret++;
             return ret;
         }
 
-
-        public static uint160 operator ++(uint160 a)
+        public static uint160 operator ^(uint160 a, uint160 b)
         {
-            int i = 0;
-            while (++a.pn[i] == 0 && i < a.nWidth - 1)
+            var result = new uint160();
+            result.pn = new uint[a.nWidth];
+            for (int i = 0; i < result.nWidth; i++)
             {
-                i++;
+                result.pn[i] = a.pn[i] ^ b.pn[i];
             }
-            return a;
+            return result;
         }
 
-        public static uint160 operator --(uint160 a)
+        public static uint160 operator &(uint160 a, uint160 b)
         {
-            int i = 0;
-            while (--a.pn[i] == uint.MaxValue && i < a.nWidth - 1)
+            var result = new uint160();
+            result.pn = new uint[a.nWidth];
+            for (int i = 0; i < result.nWidth; i++)
             {
-                i++;
+                result.pn[i] = a.pn[i] & b.pn[i];
             }
-            return a;
+            return result;
         }
 
-        public static uint160 operator ^(uint160 a, uint160 b)
+        public static uint160 operator |(uint160 a, uint160 b)
         {
             var result = new uint160();
             result.pn = new uint[a.nWidth];
             for (int i = 0; i < result.nWidth; i++)
             {
-                result.pn[i] = a.pn[i] ^ b.pn[i];
+                result.pn[i] = a.pn[i] | b.pn[i];
             }
             return result;
         }
+        #endregion
 
+        #region Basic arithmetics
         public static uint160 operator +(uint160 a, uint160 b)
         {
             var result = new uint160();
@@ -139,28 +162,41 @@ namespace Novacoin
             return a - new uint160(b);
         }
 
-        public static uint160 operator &(uint160 a, uint160 b)
+        public static uint160 operator -(uint160 a)
         {
-            var result = new uint160();
-            result.pn = new uint[a.nWidth];
-            for (int i = 0; i < result.nWidth; i++)
+            var ret = new uint160();
+            for (int i = 0; i < a.nWidth; i++)
             {
-                result.pn[i] = a.pn[i] & b.pn[i];
+                ret.pn[i] = ~a.pn[i];
             }
-            return result;
+            ret++;
+            return ret;
         }
 
-        public static uint160 operator |(uint160 a, uint160 b)
+
+        public static uint160 operator ++(uint160 a)
         {
-            var result = new uint160();
-            result.pn = new uint[a.nWidth];
-            for (int i = 0; i < result.nWidth; i++)
+            int i = 0;
+            while (++a.pn[i] == 0 && i < a.nWidth - 1)
             {
-                result.pn[i] = a.pn[i] | b.pn[i];
+                i++;
             }
-            return result;
+            return a;
         }
 
+        public static uint160 operator --(uint160 a)
+        {
+            int i = 0;
+            while (--a.pn[i] == uint.MaxValue && i < a.nWidth - 1)
+            {
+                i++;
+            }
+            return a;
+        }
+
+        #endregion
+
+        #region Shift
         public static uint160 operator <<(uint160 a, int shift)
         {
             var result = new uint160();
@@ -204,5 +240,6 @@ namespace Novacoin
 
             return result;
         }
+        #endregion
     }
 }
index 0c451ef..317b8d6 100644 (file)
@@ -1,15 +1,29 @@
-\feffusing System;
-using System.Collections.Generic;
+\feff/**
+ *  Novacoin classes library
+ *  Copyright (C) 2015 Alex D. (balthazar.ad@gmail.com)
+
+ *  This program is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Affero General Public License as
+ *  published by the Free Software Foundation, either version 3 of the
+ *  License, or (at your option) any later version.
+
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU Affero General Public License for more details.
+
+ *  You should have received a copy of the GNU Affero General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+using System;
 using System.Diagnostics.Contracts;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using System.Numerics;
 
 namespace Novacoin
 {
     public class uint256 : base_uint
     {
+        #region Access to internal representation
         new protected int nWidth {
             get { return base.nWidth; }
             private set { base.nWidth = value; }
@@ -18,7 +32,9 @@ namespace Novacoin
             get { return base.pn; }
             private set { base.pn = value; }
         }
+        #endregion
 
+        #region Constructors
         public uint256()
         {
             nWidth = 8;
@@ -57,7 +73,21 @@ namespace Novacoin
             var bytes = Interop.ReverseBytes(Interop.HexToArray(hex));
             pn = Interop.ToUInt32Array(bytes);
         }
+        #endregion
+
+        #region Cast operators
+        public static implicit operator uint256(byte[] bytes)
+        {
+            return new uint256(bytes);
+        }
+
+        public static implicit operator uint256(ulong n)
+        {
+            return new uint256(n);
+        }
+        #endregion
 
+        #region Compact representation
         /// <summary>
         /// Compact representation of unsigned 256bit numbers.
         /// 
@@ -72,11 +102,11 @@ namespace Novacoin
                 int nSize = (bits + 7) / 8;
                 uint nCompact = 0;
                 if (nSize <= 3)
-                    nCompact = ((uint)GetLow64()) << 8 * (3 - nSize);
+                    nCompact = ((uint)Low64) << 8 * (3 - nSize);
                 else
                 {
                     uint256 bn = this >> 8 * (nSize - 3);
-                    nCompact = (uint)bn.GetLow64();
+                    nCompact = (uint)bn.Low64;
                 }
 
                 if ((nCompact & 0x00800000) != 0)
@@ -113,12 +143,9 @@ namespace Novacoin
                 pn = i.pn;
             }
         }
+        #endregion
 
-        private void SetBytes(byte[] bytes)
-        {
-            pn = Interop.ToUInt32Array(Interop.ReverseBytes(bytes));
-        }
-
+        #region Bitwise operations
         public static uint256 operator ~(uint256 a)
         {
             var ret = new uint256();
@@ -129,6 +156,41 @@ namespace Novacoin
             return ret;
         }
 
+        public static uint256 operator ^(uint256 a, uint256 b)
+        {
+            var result = new uint256();
+            result.pn = new uint[a.nWidth];
+            for (int i = 0; i < result.nWidth; i++)
+            {
+                result.pn[i] = a.pn[i] ^ b.pn[i];
+            }
+            return result;
+        }
+
+        public static uint256 operator &(uint256 a, uint256 b)
+        {
+            var result = new uint256();
+            result.pn = new uint[a.nWidth];
+            for (int i = 0; i < result.nWidth; i++)
+            {
+                result.pn[i] = a.pn[i] & b.pn[i];
+            }
+            return result;
+        }
+
+        public static uint256 operator |(uint256 a, uint256 b)
+        {
+            var result = new uint256();
+            result.pn = new uint[a.nWidth];
+            for (int i = 0; i < result.nWidth; i++)
+            {
+                result.pn[i] = a.pn[i] | b.pn[i];
+            }
+            return result;
+        }
+        #endregion
+
+        #region Basic arithmetics
         public static uint256 operator -(uint256 a)
         {
             var ret = new uint256();
@@ -161,16 +223,6 @@ namespace Novacoin
             return a;
         }
 
-        public static uint256 operator ^(uint256 a, uint256 b)
-        {
-            var result = new uint256();
-            result.pn = new uint[a.nWidth];
-            for (int i = 0; i < result.nWidth; i++)
-            {
-                result.pn[i] = a.pn[i] ^ b.pn[i];
-            }
-            return result;
-        }
 
         public static uint256 operator +(uint256 a, uint256 b)
         {
@@ -199,29 +251,9 @@ namespace Novacoin
         {
             return a - new uint256(b);
         }
+        #endregion
 
-        public static uint256 operator &(uint256 a, uint256 b)
-        {
-            var result = new uint256();
-            result.pn = new uint[a.nWidth];
-            for (int i = 0; i < result.nWidth; i++)
-            {
-                result.pn[i] = a.pn[i] & b.pn[i];
-            }
-            return result;
-        }
-
-        public static uint256 operator |(uint256 a, uint256 b)
-        {
-            var result = new uint256();
-            result.pn = new uint[a.nWidth];
-            for (int i = 0; i < result.nWidth; i++)
-            {
-                result.pn[i] = a.pn[i] | b.pn[i];
-            }
-            return result;
-        }
-
+        #region Shift
         public static uint256 operator <<(uint256 a, int shift)
         {
             var result = new uint256();
@@ -265,5 +297,6 @@ namespace Novacoin
 
             return result;
         }
+        #endregion
     }
 }
index 4b9c63d..c8295c2 100644 (file)
@@ -79,7 +79,7 @@ namespace NovacoinTest
             /// ECDSA keypair signing test
 
             var data = "Превед!";
-            var sigHash = Hash256.Compute256(Encoding.UTF8.GetBytes(data));
+            uint256 sigHash = CryptoUtils.ComputeHash256(Encoding.UTF8.GetBytes(data));
             var signature = keyPair1.Sign(sigHash);
 
             Console.WriteLine("Signature: {0}", Interop.ToHex(signature));
@@ -102,7 +102,7 @@ namespace NovacoinTest
 
             /// Block header hashing test
             byte[] dataBytesForScrypt = b1.header;
-            var scryptHash = ScryptHash256.Compute256(dataBytesForScrypt);
+            uint256 scryptHash = CryptoUtils.ComputeScryptHash256(dataBytesForScrypt);
 
             Console.WriteLine("\nblock1 header hash: {0}", scryptHash);
 
@@ -117,7 +117,7 @@ namespace NovacoinTest
             Console.WriteLine("scriptPubKey address: {0}\n", new CPubKey(solutions.First()).KeyID.ToString());
 
             Console.WriteLine("scriptPubKeyHash solved: {0}", ScriptCode.Solver(scriptPubKeyHash, out typeRet, out solutions));
-            Console.WriteLine("scriptPubKeyHash address: {0}\n", new CKeyID(new Hash160(solutions.First())).ToString());
+            Console.WriteLine("scriptPubKeyHash address: {0}\n", new CKeyID(solutions.First()).ToString());
 
             /// Some SetDestination tests
             var scriptDestinationTest = new CScript();
@@ -137,7 +137,7 @@ namespace NovacoinTest
             scriptDestinationTest.SetDestination(keyPair1.PubKey.KeyID);
 
             Console.WriteLine("\tscriptDestinationTest solved: {0}", ScriptCode.Solver(scriptDestinationTest, out typeRet, out solutions));
-            Console.WriteLine("\tscriptDestinationTest address: {0}\n", new CKeyID(new Hash160(solutions.First())));
+            Console.WriteLine("\tscriptDestinationTest address: {0}\n", new CKeyID(solutions.First()));
 
             Console.WriteLine("Multisig with three random keys:");
 
@@ -166,15 +166,15 @@ namespace NovacoinTest
             scriptP2SHTest.SetDestination(scriptDestinationTest.ScriptID);
 
             Console.WriteLine("\tscriptP2SHTest solved: {0}", ScriptCode.Solver(scriptP2SHTest, out typeRet, out solutions));
-            Console.WriteLine("\tscriptP2SHTest address: {0}\n", new CScriptID(new Hash160(solutions.First())));
+            Console.WriteLine("\tscriptP2SHTest address: {0}\n", new CScriptID(solutions.First()));
 
             // SignatureHash tests
             var txS = new CTransaction(Interop.HexToArray("01000000ccfe9e550d083902781746c80954e3af56e930235befb798f987667021a2f32dc0099499cd010000006b483045022100b5f6783af4f7f60866c889fd668c93ee110ecc3751208fe0b49cc7ace47e52e8022075652e1e960a50b27436ab04f2728b3bba09d07a858691559d99c1ac5dd74f16012103fe065856d7fa8cd41d0047600af2ec1ebe8c6198c1a889e90d8ce6b2f1f8afd7ffffffff2c6009a7494f38f7797bb9ef2aeafb093ae433208171a504367373df4164399d010000004847304402205f1b74bbc37219918f3de13ff645ecc7093512fecda4fcbcac2174c44144361102202149f1adcfcd473ec8a662b5b166b600208d92596e30b33fb402b4720bac3da101ffffffffbf1dd11394d2c0d3cbd4e0b56c74e7463ed5a19f22fe219ee700c61f834b3948010000006a473044022004824a9e071c40707e5309e510fd2cc105fd430504ceefce48aeed1c8fcf3bd7022023f4a43c58e4012284d8df25b55940199d19d4ca664053e2d5c1cc93ef441c3c012103fe065856d7fa8cd41d0047600af2ec1ebe8c6198c1a889e90d8ce6b2f1f8afd7ffffffffea06d18d8034a3645a8d5da75ed5c5f68a9dd09a798a876bef5d2cc9db8819390100000048473044022018e016973d87a53d6f14ae9929aa3c426d3d3a76eb81b3f1e996f0ec24ebacb302203668f165e6e9d5818eb3d108d23e2390213a6921ddfd51dbfca4ffebad73029601ffffffff5bda9a2a98debbda4ddad400a340190fcba4f4b3268f0a9d88eb5541bd7dadfc0100000049483045022100c4d210a6cd3edc6bc9cbfee1a8506ff239ef60baf7ebd46ffefb43e20a575d6c022019ea10cf480dadbb6332a03a404a3991437ffc9fef044c07112e2d15f3de74de01ffffffff5bda9a2a98debbda4ddad400a340190fcba4f4b3268f0a9d88eb5541bd7dadfc020000004948304502210084f5781ff88c201caca29b724f89fad5d72320a578239a3a2834ba669ea92b7e02207651ef9f7c60c2cc4fe187c98587252f3196fb1c31ed8f6c1f1f41e9a90d75ff01ffffffff61a9d75745092786bcbd48cc5860845beea607b8994790e9734f9fa68951bb66010000006b483045022100d2d3f925472970b9a0d365a120a9a6c9b7b0b3b3aacedaa40532397c6252da2f02206939d3cade4bada339799a4d651a7a33cb381640f6acef5fbecbe55ae1fa2364012103fe065856d7fa8cd41d0047600af2ec1ebe8c6198c1a889e90d8ce6b2f1f8afd7ffffffff635c711ba32bd587d349521475d2bd133a402c178543183c027cc1414a7837500100000049483045022100aece1ca9d902eaece08ec9704005196046f3a0b6f561cd17e9b09c01fed1447602207e68e21be4fcb895f045337741b42f43d218bb5c681f8e2eac5f9f3ffc8caf8301ffffffff7ddd7385fd7b81f19ccaa6ccd629bd2ab2a0af7ca69831c6dbb3b02c31de95db0100000049483045022100b260f2065dea407006e424d3cbb20009c807f422cee4ac8fb3553e4a81d62a7702204c67c99e792542cfe19a6956b101b4fd754a01fb1538b54e5f2141210729f09b01ffffffff8faebe377bc4211e41bd7e4a551e1de530040f8a55797f82e12d4d3c6a0b9fff010000004847304402204637911286c073fa0a8211e8427a6c63201bdac73e7b2760d3d9c7d748c9267c02205df709fdd06e3fb600ab81a17a1becc829769f1cb117b1520755d4f2a38429f001fffffffff1be969005bfcab4bcdaf835470680e2a309290b97d79fe63f7cbe904560b2d601000000484730440220352ad1a1ea5d92ddc13b7507a05180574c7309822f684ecf7321b7e925e5104302201e6a06e2f2d05a3d665cc6180fafacb658514a2f1bb632de99e88e4c26149e2501fffffffffa2019204a766fb4614be3d12bfb1ab35ad756e144193249e83660ca78898b3b0200000048473044022024f21eaf955291a9aec2cd45f42add62d8a30626aa9246664226fb3b56bf632f02205a3b46ec2857fec2fcb73663a57f99e4fcda328e8f1283198e8e9c5b4a2a3e0f01ffffffffd25e023fbdcd571ae346bf7aa142f5e32ca1aec23adae314ee209af22572cf1f000000006a4730440220551627592cbb7d970222a4d57a32aed50f1e93e81ae69958f26e56ca3b561715022019b12e560ff31013d0941ca2100ecdf9a3c3602b5c76b83d3b3c87d723d32ce3012103fe065856d7fa8cd41d0047600af2ec1ebe8c6198c1a889e90d8ce6b2f1f8afd7ffffffff02402d0000000000001976a91479f1d300be0da277e7ae217e99c6cc8a4f8717fe88ac00943577000000001976a914cbc5a055ae068d34b4a93e4c9adb9cb10262ae4f88ac00000000"));
 
-            Hash256 sigHashAll = ScriptCode.SignatureHash(txS.vout[0].scriptPubKey, txS, 1, (int)sigflag.SIGHASH_ALL);
-            Hash256 sigHashNone = ScriptCode.SignatureHash(txS.vout[0].scriptPubKey, txS, 1, (int)sigflag.SIGHASH_NONE);
-            Hash256 sigHashSingle = ScriptCode.SignatureHash(txS.vout[0].scriptPubKey, txS, 1, (int)sigflag.SIGHASH_SINGLE);
-            Hash256 sigHashAnyone = ScriptCode.SignatureHash(txS.vout[0].scriptPubKey, txS, 1, (int)sigflag.SIGHASH_ANYONECANPAY);
+            uint256 sigHashAll = ScriptCode.SignatureHash(txS.vout[0].scriptPubKey, txS, 1, (int)sigflag.SIGHASH_ALL);
+            uint256 sigHashNone = ScriptCode.SignatureHash(txS.vout[0].scriptPubKey, txS, 1, (int)sigflag.SIGHASH_NONE);
+            uint256 sigHashSingle = ScriptCode.SignatureHash(txS.vout[0].scriptPubKey, txS, 1, (int)sigflag.SIGHASH_SINGLE);
+            uint256 sigHashAnyone = ScriptCode.SignatureHash(txS.vout[0].scriptPubKey, txS, 1, (int)sigflag.SIGHASH_ANYONECANPAY);
 
             Console.WriteLine("sigHashAll={0}", sigHashAll);
             Console.WriteLine("sigHashNone={0}", sigHashNone);
@@ -228,8 +228,7 @@ namespace NovacoinTest
             elapsedMs = watch.ElapsedMilliseconds;
             Console.WriteLine("Unserialization time: {0} ms\n", elapsedMs);
 
-
-            Hash256 merkleroot = null;
+            uint256 merkleroot = null;
 
             Console.WriteLine("\nRinning 100 iterations of merkle tree computation for very big block...");