Example #1
0
            public void AddRange(ChecksummedByteCollection aCollection)
            {
                if (_bytes.Count == 0)
                {
                    // Is empty so just copy checksum from argument
                    _computedIndex = aCollection._computedIndex;
                    _checksum      = aCollection.Checksum;
                    _murMur3       = (Murmur3_x86_32Digest)aCollection._murMur3.Copy();
                }

                _bytes.AddRange(aCollection._bytes);
            }
Example #2
0
            public ChecksummedByteCollection Clone()
            {
                ChecksummedByteCollection result = new ChecksummedByteCollection {
                    _bytes = new List <byte[]>()
                };

                result._bytes.AddRange(_bytes);
                result._computedIndex = _computedIndex;
                result._checksum      = Checksum;
                result._murMur3       = (Murmur3_x86_32Digest)_murMur3.Copy();
                return(result);
            }
Example #3
0
        private byte[] Compress(ChecksummedByteCollection aInputs)
        {
            byte[]     result     = new byte[100];
            uint       seed       = aInputs.Checksum;
            Mersenne32 gen        = new Mersenne32(seed);
            int        inputCount = aInputs.Count;

            for (int i = 0; i < 100; i++)
            {
                byte[] source = aInputs.Get((int)(gen.NextUInt32() % inputCount));
                result[i] = source[gen.NextUInt32() % source.Length];
            }

            return(result);
        }
Example #4
0
        private ChecksummedByteCollection Hash(byte[] aBlockHeader, int aRound)
        {
            if ((aRound < 1) || (aRound > N))
            {
                throw new ArgumentOutOfRangeException(string.Format("Round '{0}' must be between 0 and N inclusive",
                                                                    nameof(aRound)));
            }

            // NOTE: instance is destroyed by caller!
            ChecksummedByteCollection roundOutputs = new ChecksummedByteCollection();

            Mersenne32 gen = new Mersenne32(0);

            byte[] roundInput;
            uint   seed;

            if (aRound == 1)
            {
                seed = Checksum(aBlockHeader);
                gen.Initialize(seed);
                roundInput = aBlockHeader;
            }
            else
            {
                ChecksummedByteCollection parentOutputs;
                if ((aRound == N) && (aBlockHeader.Length >= 4) && (NextNonce == GetNonce(aBlockHeader)) &&
                    Arrays.AreEqual(aBlockHeader, _cachedHeader))
                {
                    // Parent (round N - 1) has already been calculated so re-use values. This saves 50% of calculations!
                    parentOutputs = _cachedOutput;
                }
                else
                {
                    // Need to calculate parent output
                    parentOutputs = Hash(aBlockHeader, aRound - 1);
                }

                seed = parentOutputs.Checksum;

                gen.Initialize(seed);
                roundOutputs.AddRange(parentOutputs);

                // Determine the neighbouring nonce
                uint   neighbourNonce       = gen.NextUInt32();
                byte[] neighbourNonceHeader = ChangeNonce(aBlockHeader, neighbourNonce);
                ChecksummedByteCollection neighbourOutputs = Hash(neighbourNonceHeader, aRound - 1);

                // Cache neighbour nonce n-1 calculation if on final round (neighbour will be next nonce)
                if (aRound == N)
                {
                    _cachedNonce  = neighbourNonce;
                    _cachedHeader = neighbourNonceHeader;
                    _cachedOutput = neighbourOutputs.Clone();
                }

                roundOutputs.AddRange(neighbourOutputs);
                roundInput = Compress(roundOutputs);
            }

            Func <byte[], byte[]> hashFunc = _hashAlg[gen.NextUInt32() % 18];

            byte[] output = hashFunc(roundInput);
            output = Expand(output, N - aRound);
            roundOutputs.Add(output);

            return(roundOutputs);
        }
Example #5
0
        private byte[] Hash(byte[] aBlockHeader)
        {
            ChecksummedByteCollection allOutputs = Hash(aBlockHeader, N);

            return(_hashAlg[0](Compress(allOutputs)));
        }