예제 #1
0
        public unsafe void Compress27Test()
        {
            int dataLen = 27;

            byte[] data     = GetRandomBytes(dataLen);
            byte[] expected = ComputeSingleSha(data);

            using Sha256Fo sha = new Sha256Fo();
            fixed(uint *hPt = &sha.hashState[0], wPt = &sha.w[0])
            {
                int dIndex = 0;

                for (int i = 0; i < 6; i++, dIndex += 4)
                {
                    wPt[i] = (uint)((data[dIndex] << 24) | (data[dIndex + 1] << 16) | (data[dIndex + 2] << 8) | data[dIndex + 3]);
                }
                wPt[6] = (uint)data[24] << 24 | (uint)data[25] << 16 | (uint)data[26] << 8 | 0b00000000_00000000_00000000_10000000U;

                wPt[15] = (uint)dataLen * 8;
                sha.Init(hPt);
                sha.Compress27(hPt, wPt);
                byte[] actual = sha.GetBytes(hPt);

                Assert.Equal(expected, actual);
            }
        }
예제 #2
0
        public unsafe void CompressDouble39Test()
        {
            int dataLen = 39;

            byte[] data     = GetRandomBytes(dataLen);
            byte[] expected = ComputeDoubleSha(data);

            using Sha256Fo sha = new Sha256Fo();
            fixed(uint *hPt = &sha.hashState[0], wPt = &sha.w[0])
            {
                int dIndex = 0;

                for (int i = 0; i < 9; i++, dIndex += 4)
                {
                    wPt[i] = (uint)((data[dIndex] << 24) | (data[dIndex + 1] << 16) | (data[dIndex + 2] << 8) | data[dIndex + 3]);
                }
                wPt[9]  = (uint)((data[36] << 24) | (data[37] << 16) | (data[38] << 8) | 0b00000000_00000000_00000000_10000000U);
                wPt[15] = (uint)dataLen * 8;
                sha.Init(hPt);
                sha.CompressDouble39(hPt, wPt);
                byte[] actual = sha.GetBytes(hPt);

                Assert.Equal(expected, actual);
            }
        }
        public unsafe void Compare_Sha256HashStateTest()
        {
            PrvToPubComparer comp = new();
            uint *           pt   = stackalloc uint[Sha256Fo.UBufferSize];

            byte[] data = new byte[1];
            fixed(byte *dPt = &data[0])
            {
                Sha256Fo.CompressData(dPt, data.Length, data.Length, pt);

                Scalar key = new(pt, out int overflow);

                Assert.Equal(0, overflow);
                Calc   calc   = new();
                string pubHex = calc.GetPubkey(key, true).ToArray().ToBase16();

                bool b = comp.Init(pubHex);

                Assert.True(b);

                bool actual = comp.Compare(pt);

                Assert.True(actual);
            }
        }
예제 #4
0
        public unsafe void Compress64SecondBlockTest()
        {
            int dataLen = 64;

            byte[] data     = GetRandomBytes(dataLen);
            byte[] expected = ComputeSingleSha(data);

            using Sha256Fo sha = new Sha256Fo();
            fixed(uint *hPt = &sha.hashState[0], wPt = &sha.w[0])
            {
                int dIndex = 0;

                for (int i = 0; i < 16; i++, dIndex += 4)
                {
                    wPt[i] = (uint)((data[dIndex] << 24) | (data[dIndex + 1] << 16) | (data[dIndex + 2] << 8) | data[dIndex + 3]);
                }

                sha.Init(hPt);
                sha.CompressBlock(hPt, wPt);
                // Next block:
                wPt[0] = 0b10000000_00000000_00000000_00000000U;
                for (int i = 1; i < 15; i++)
                {
                    wPt[i] = 0;
                }
                wPt[15] = (uint)dataLen * 8;
                sha.Compress64SecondBlock(hPt, wPt);
                byte[] actual = sha.GetBytes(hPt);

                Assert.Equal(expected, actual);
            }
        }
예제 #5
0
        private unsafe bool Loop31()
        {
            var cartesian = CartesianProduct.Create(Enumerable.Repeat(Encoding.UTF8.GetBytes(ConstantsFO.Base58Chars), missCount));

            using Sha256Fo sha = new Sha256Fo();
            bool success = false;

            byte[] temp = new byte[precomputed.Length];
            fixed(uint *hPt = &sha.hashState[0], wPt = &sha.w[0])
            fixed(byte *pre = &precomputed[0], tmp = &temp[0])
            fixed(int *mi   = &missingIndexes[0])
            {
                foreach (var item in cartesian)
                {
                    Buffer.MemoryCopy(pre, tmp, 30, 30);
                    int mis = 0;
                    foreach (var keyItem in item)
                    {
                        tmp[mi[mis]] = keyItem;
                        mis++;
                    }

                    // The added value below is the fixed first char(S)=0x53 shifted left 24 places
                    wPt[0] = 0b01010011_00000000_00000000_00000000U | (uint)tmp[1] << 16 | (uint)tmp[2] << 8 | tmp[3];
                    wPt[1] = (uint)tmp[4] << 24 | (uint)tmp[5] << 16 | (uint)tmp[6] << 8 | tmp[7];
                    wPt[2] = (uint)tmp[8] << 24 | (uint)tmp[9] << 16 | (uint)tmp[10] << 8 | tmp[11];
                    wPt[3] = (uint)tmp[12] << 24 | (uint)tmp[13] << 16 | (uint)tmp[14] << 8 | tmp[15];
                    wPt[4] = (uint)tmp[16] << 24 | (uint)tmp[17] << 16 | (uint)tmp[18] << 8 | tmp[19];
                    wPt[5] = (uint)tmp[20] << 24 | (uint)tmp[21] << 16 | (uint)tmp[22] << 8 | tmp[23];
                    wPt[6] = (uint)tmp[24] << 24 | (uint)tmp[25] << 16 | (uint)tmp[26] << 8 | tmp[27];
                    // The added value below is the SHA padding and the last added ? char equal to 0x3f shifted right 8 places
                    wPt[7] = (uint)tmp[28] << 24 | (uint)tmp[29] << 16 | 0b00000000_00000000_00111111_10000000U;
                    // from 8 to 14 = 0
                    wPt[15] = 248; // 31 *8 = 184

                    sha.Init(hPt);
                    sha.Compress31(hPt, wPt);

                    if ((hPt[0] & 0b11111111_00000000_00000000_00000000U) == 0)
                    {
                        // Same as above
                        wPt[7] ^= 0b00000000_00000000_10111111_10000000U;
                        // from 8 to 14 (remain) = 0
                        wPt[15] = 240; // 30 *8 = 240

                        sha.Init(hPt);
                        sha.Compress30(hPt, wPt);

                        if (comparer.Compare(sha.GetBytes(hPt)))
                        {
                            SetResult(item);
                            success = true;
                            break;
                        }
                    }
                }
            }

            return(success);
        }
예제 #6
0
        public void ComputeHash_NistMonteCarloTest()
        {
            byte[]  seed  = Helper.HexToBytes("6d1e72ad03ddeb5de891e572e2396f8da015d899ef0e79503152d6010a3fe691");
            JObject jObjs = Helper.ReadResources <JObject>("Sha256NistTestData");
            int     size  = 32;

            byte[] toHash = new byte[3 * size];

            byte[] M0 = seed;
            byte[] M1 = seed;
            byte[] M2 = seed;

            Sha256Fo sha = new Sha256Fo(false);

            foreach (var item in jObjs["MonteCarlo"])
            {
                byte[] expected = Helper.HexToBytes(item.ToString());
                for (int i = 0; i < 1000; i++)
                {
                    Buffer.BlockCopy(M0, 0, toHash, 0, size);
                    Buffer.BlockCopy(M1, 0, toHash, size, size);
                    Buffer.BlockCopy(M2, 0, toHash, size * 2, size);

                    M0 = M1;
                    M1 = M2;
                    M2 = sha.ComputeHash(toHash);
                }
                M0 = M2;
                M1 = M2;

                Assert.Equal(expected, M2);
            }

            sha.Dispose();
        }
예제 #7
0
        private unsafe void Loop12()
        {
            if (missCount > 1)
            {
                report.AddMessageSafe("Running in parallel.");
                report.SetProgressStep(2048);
                int firstIndex = missingIndexes[0];
                Parallel.For(0, 2048, (firstItem, state) => Loop12(firstItem, firstIndex, state));
            }
            else
            {
                // We can't call the same parallel method due to usage of LoopState so we at least optimize this by
                // avoiding the inner loop over the IEnumerable
                using Sha512Fo sha512 = new Sha512Fo();
                ulong[] ipad = new ulong[80];
                ulong[] opad = new ulong[80];

                using Sha256Fo sha256 = new Sha256Fo();

                int misIndex = missingIndexes[0];

                fixed(ulong *iPt = ipad, oPt = opad)
                fixed(uint *wPt  = &sha256.w[0], hPt = &sha256.hashState[0], wrd = &wordIndexes[0])
                fixed(byte *mnPt = &mnBytes[0])
                {
                    wPt[4]  = 0b10000000_00000000_00000000_00000000U;
                    wPt[15] = 128;

                    for (uint item = 0; item < 2048; item++)
                    {
                        wrd[misIndex] = item;

                        wPt[0] = wrd[0] << 21 | wrd[1] << 10 | wrd[2] >> 1;
                        wPt[1] = wrd[2] << 31 | wrd[3] << 20 | wrd[4] << 9 | wrd[5] >> 2;
                        wPt[2] = wrd[5] << 30 | wrd[6] << 19 | wrd[7] << 8 | wrd[8] >> 3;
                        wPt[3] = wrd[8] << 29 | wrd[9] << 18 | wrd[10] << 7 | wrd[11] >> 4;

                        sha256.Init(hPt);
                        sha256.Compress16(hPt, wPt);

                        if ((wrd[11] & 0b1111) == hPt[0] >> 28)
                        {
                            int mnLen = 0;
                            for (int i = 0; i < 12; i++)
                            {
                                var temp = allWordsBytes[wrd[i]];
                                Buffer.BlockCopy(temp, 0, mnBytes, mnLen, temp.Length);
                                mnLen += temp.Length;
                            }

                            if (SetBip32(sha512, mnPt, --mnLen, iPt, oPt))
                            {
                                SetResultParallel(mnPt, mnLen);
                                break;
                            }
                        }
                    }
                }
            }
        }
예제 #8
0
        public unsafe void Compress72SecondBlockTest()
        {
            int dataLen = 72;

            byte[] data     = GetRandomBytes(dataLen);
            byte[] expected = ComputeSingleSha(data);

            uint *hPt = stackalloc uint[Sha256Fo.UBufferSize];
            uint *wPt = hPt + Sha256Fo.HashStateSize;

            int dIndex = 0;

            for (int i = 0; i < 16; i++, dIndex += 4)
            {
                wPt[i] = (uint)((data[dIndex] << 24) | (data[dIndex + 1] << 16) | (data[dIndex + 2] << 8) | data[dIndex + 3]);
            }

            Sha256Fo.Init(hPt);
            Sha256Fo.SetW(wPt);
            Sha256Fo.CompressBlockWithWSet(hPt);
            // Next block:
            wPt[0]  = (uint)((data[dIndex] << 24) | (data[dIndex + 1] << 16) | (data[dIndex + 2] << 8) | data[dIndex + 3]);
            dIndex += 4;
            wPt[1]  = (uint)((data[dIndex] << 24) | (data[dIndex + 1] << 16) | (data[dIndex + 2] << 8) | data[dIndex + 3]);
            wPt[2]  = 0b10000000_00000000_00000000_00000000U;
            for (int i = 3; i < 15; i++)
            {
                wPt[i] = 0;
            }
            wPt[15] = (uint)dataLen * 8;
            Sha256Fo.Compress72SecondBlock(hPt);
            byte[] actual = Sha256Fo.GetBytes(hPt);

            Assert.Equal(expected, actual);
        }
예제 #9
0
        private static unsafe bool Loop23Hash(Sha256Fo sha, uint *wPt, uint *hPt, byte *tmp, ICompareService comparer)
        {
            // The added value below is the fixed first char('S')=0x53 shifted left 24 places
            wPt[0] = 0b01010011_00000000_00000000_00000000U | (uint)tmp[1] << 16 | (uint)tmp[2] << 8 | tmp[3];
            wPt[1] = (uint)tmp[4] << 24 | (uint)tmp[5] << 16 | (uint)tmp[6] << 8 | tmp[7];
            wPt[2] = (uint)tmp[8] << 24 | (uint)tmp[9] << 16 | (uint)tmp[10] << 8 | tmp[11];
            wPt[3] = (uint)tmp[12] << 24 | (uint)tmp[13] << 16 | (uint)tmp[14] << 8 | tmp[15];
            wPt[4] = (uint)tmp[16] << 24 | (uint)tmp[17] << 16 | (uint)tmp[18] << 8 | tmp[19];
            // The added value below is the SHA padding and the last added ? char equal to 0x3f shifted right 8 places
            wPt[5] = (uint)tmp[20] << 24 | (uint)tmp[21] << 16 | 0b00000000_00000000_00111111_10000000U;
            // from 6 to 14 = 0
            wPt[15] = 184; // 23 *8 = 184

            sha.Init(hPt);
            sha.Compress23(hPt, wPt);

            if ((hPt[0] & 0b11111111_00000000_00000000_00000000U) == 0)
            {
                // The actual key is SHA256 of 22 char key (without '?')
                // SHA working vector is already set, only the last 2 bytes ('?' and pad) and the length have to change
                wPt[5] ^= 0b00000000_00000000_10111111_10000000U;
                // from 6 to 14 (remain) = 0
                wPt[15] = 176; // 22 *8 = 176

                sha.Init(hPt);
                sha.Compress22(hPt, wPt);

                return(comparer.Compare(hPt));
            }
예제 #10
0
        private unsafe bool Loop21()
        {
            using Sha512Fo sha512 = new Sha512Fo();
            ulong[] ipad = new ulong[80];
            ulong[] opad = new ulong[80];

            using Sha256Fo sha256 = new Sha256Fo();
            var cartesian = CartesianProduct.Create(Enumerable.Repeat(Enumerable.Range(0, 2048), missCount));

            fixed(ulong *iPt = ipad, oPt = opad)
            fixed(uint *wPt  = &sha256.w[0], hPt = &sha256.hashState[0], wrd = &wordIndexes[0])
            fixed(int *mi    = &missingIndexes[0])
            fixed(byte *mnPt = &mnBytes[0])
            {
                wPt[7]  = 0b10000000_00000000_00000000_00000000U;
                wPt[15] = 224;

                foreach (var item in cartesian)
                {
                    int j = 0;
                    foreach (var k in item)
                    {
                        wrd[mi[j]] = (uint)k;
                        j++;
                    }

                    wPt[0] = wrd[0] << 21 | wrd[1] << 10 | wrd[2] >> 1;
                    wPt[1] = wrd[2] << 31 | wrd[3] << 20 | wrd[4] << 9 | wrd[5] >> 2;
                    wPt[2] = wrd[5] << 30 | wrd[6] << 19 | wrd[7] << 8 | wrd[8] >> 3;
                    wPt[3] = wrd[8] << 29 | wrd[9] << 18 | wrd[10] << 7 | wrd[11] >> 4;
                    wPt[4] = wrd[11] << 28 | wrd[12] << 17 | wrd[13] << 6 | wrd[14] >> 5;
                    wPt[5] = wrd[14] << 27 | wrd[15] << 16 | wrd[16] << 5 | wrd[17] >> 6;
                    wPt[6] = wrd[17] << 26 | wrd[18] << 15 | wrd[19] << 4 | wrd[20] >> 7;

                    sha256.Init(hPt);
                    sha256.Compress28(hPt, wPt);

                    if ((wrd[20] & 0b111_1111) == hPt[0] >> 25)
                    {
                        int mnLen = 0;
                        for (int i = 0; i < 21; i++)
                        {
                            foreach (byte b in wordBytes[wrd[i]])
                            {
                                mnPt[mnLen++] = b;
                            }
                            mnPt[mnLen++] = SpaceByte;
                        }

                        if (SetBip32(sha512, mnPt, --mnLen, iPt, oPt))
                        {
                            return(SetResult(mnLen));
                        }
                    }
                }
            }

            return(false);
        }
예제 #11
0
        public void ComputeHash_DoubleTest()
        {
            byte[] data         = Helper.HexToBytes("fb8049137747e712628240cf6d7056ea2870170cb7d9bc713d91e901b514c6ae7d7dda3cd03ea1b99cf85046a505f3590541123d3f8f2c22c4d7d6e65de65c4ebb9251f09619");
            byte[] actualHash   = Sha256Fo.ComputeHashTwice(data);
            byte[] expectedHash = Helper.HexToBytes("d2cee8d3cfaf1819c55cce1214d01cdef1d97446719ccfaad4d76d912a8126f9");

            Assert.Equal(expectedHash, actualHash);
        }
예제 #12
0
        public void ComputeHash_AMillionATest()
        {
            using Sha256Fo sha = new Sha256Fo();
            byte[] actualHash   = sha.ComputeHash(HashTestCaseHelper.GetAMillionA());
            byte[] expectedHash = Helper.HexToBytes("cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");

            Assert.Equal(expectedHash, actualHash);
        }
예제 #13
0
        private unsafe bool Loop27()
        {
            // Same as above but key is 26 chars
            var cartesian = CartesianProduct.Create(Enumerable.Repeat(Encoding.UTF8.GetBytes(ConstantsFO.Base58Chars), missCount));

            using Sha256Fo sha = new Sha256Fo();
            bool success = false;

            byte[] temp = new byte[precomputed.Length];
            fixed(uint *hPt = &sha.hashState[0], wPt = &sha.w[0])
            fixed(byte *pre = &precomputed[0], tmp = &temp[0])
            fixed(int *mi   = &missingIndexes[0])
            {
                foreach (var item in cartesian)
                {
                    Buffer.MemoryCopy(pre, tmp, 26, 26);
                    int mis = 0;
                    foreach (var keyItem in item)
                    {
                        tmp[mi[mis]] = keyItem;
                        mis++;
                    }

                    wPt[0] = 0b01010011_00000000_00000000_00000000U | (uint)tmp[1] << 16 | (uint)tmp[2] << 8 | tmp[3];
                    wPt[1] = (uint)tmp[4] << 24 | (uint)tmp[5] << 16 | (uint)tmp[6] << 8 | tmp[7];
                    wPt[2] = (uint)tmp[8] << 24 | (uint)tmp[9] << 16 | (uint)tmp[10] << 8 | tmp[11];
                    wPt[3] = (uint)tmp[12] << 24 | (uint)tmp[13] << 16 | (uint)tmp[14] << 8 | tmp[15];
                    wPt[4] = (uint)tmp[16] << 24 | (uint)tmp[17] << 16 | (uint)tmp[18] << 8 | tmp[19];
                    wPt[5] = (uint)tmp[20] << 24 | (uint)tmp[21] << 16 | (uint)tmp[22] << 8 | tmp[23];
                    wPt[6] = (uint)tmp[24] << 24 | (uint)tmp[25] << 16 | 0b00000000_00000000_00111111_10000000U;
                    // from 7 to 14 = 0
                    wPt[15] = 216; // 27 *8 = 216

                    sha.Init(hPt);
                    sha.Compress27(hPt, wPt);

                    if ((hPt[0] & 0b11111111_00000000_00000000_00000000U) == 0)
                    {
                        wPt[6] ^= 0b00000000_00000000_10111111_10000000U;
                        // from 7 to 14 (remain) = 0
                        wPt[15] = 208; // 26 *8 = 208

                        sha.Init(hPt);
                        sha.Compress26(hPt, wPt);

                        if (comparer.Compare(sha.GetBytes(hPt)))
                        {
                            SetResult(item);
                            success = true;
                            break;
                        }
                    }
                }
            }

            return(success);
        }
예제 #14
0
        public void ComputeHash_ExceptionsTest()
        {
            byte[]   goodBa = { 1, 2, 3 };
            Sha256Fo sha    = new Sha256Fo();

            Assert.Throws <ArgumentNullException>(() => sha.ComputeHash(null));

            sha.Dispose();
            Assert.Throws <ObjectDisposedException>(() => sha.ComputeHash(goodBa));
        }
예제 #15
0
        private unsafe bool LoopComp()
        {
            report.ChangeProgressVisibilitySafe(false);
            var cartesian = CartesianProduct.Create(Enumerable.Repeat(Enumerable.Range(0, 58), missCount));

            using Sha256Fo sha = new Sha256Fo();
            bool success = false;

            uint[] temp = new uint[precomputed.Length];
            fixed(uint *hPt = &sha.hashState[0], wPt = &sha.w[0])
            fixed(uint *pow = &powers58[0], res = &precomputed[0], tmp = &temp[0])
            fixed(int *mi   = &missingIndexes[0])
            {
                foreach (var item in cartesian)
                {
                    Buffer.MemoryCopy(res, tmp, 40, 40);
                    int mis = 0;
                    foreach (var keyItem in item)
                    {
                        ulong carry = 0;
                        for (int k = 9, j = 0; k >= 0; k--, j++)
                        {
                            ulong result = (pow[(mi[mis] * 10) + j] * (ulong)keyItem) + tmp[k] + carry;
                            tmp[k] = (uint)result;
                            carry  = (uint)(result >> 32);
                        }
                        mis++;
                    }

                    wPt[0] = (tmp[0] << 16) | (tmp[1] >> 16);
                    wPt[1] = (tmp[1] << 16) | (tmp[2] >> 16);
                    wPt[2] = (tmp[2] << 16) | (tmp[3] >> 16);
                    wPt[3] = (tmp[3] << 16) | (tmp[4] >> 16);
                    wPt[4] = (tmp[4] << 16) | (tmp[5] >> 16);
                    wPt[5] = (tmp[5] << 16) | (tmp[6] >> 16);
                    wPt[6] = (tmp[6] << 16) | (tmp[7] >> 16);
                    wPt[7] = (tmp[7] << 16) | (tmp[8] >> 16);
                    wPt[8] = (tmp[8] << 16) | 0b00000000_00000000_10000000_00000000U;
                    // from 9 to 14 =0
                    wPt[15] = 272; // 34 *8 = 272

                    sha.Init(hPt);
                    sha.CompressDouble34(hPt, wPt);

                    if (hPt[0] == tmp[9])
                    {
                        SetResult(item);
                        success = true;
                    }
                }
            }

            return(success);
        }
예제 #16
0
        private unsafe void LoopUncomp(uint[] precomputed, int firstItem, int misStart, uint[] missingItems)
        {
            using Sha256Fo sha = new Sha256Fo();

            uint[] temp = new uint[precomputed.Length];
            fixed(uint *hPt = &sha.hashState[0], wPt = &sha.w[0])
            fixed(uint *pow     = &powers58[0], pre = &precomputed[0], tmp = &temp[0])
            fixed(uint *itemsPt = &missingItems[0])
            fixed(int *mi       = &missingIndexes[misStart])
            {
                do
                {
                    Buffer.MemoryCopy(pre, tmp, 40, 40);
                    int i = 0;
                    foreach (var keyItem in missingItems)
                    {
                        ulong carry = 0;
                        for (int k = 9, j = 0; k >= 0; k--, j++)
                        {
                            ulong result = (pow[(mi[i] * 10) + j] * (ulong)keyItem) + tmp[k] + carry;
                            tmp[k] = (uint)result;
                            carry  = (uint)(result >> 32);
                        }
                        i++;
                    }

                    if (tmp[0] == 0x00000080)
                    {
                        wPt[0] = (tmp[0] << 24) | (tmp[1] >> 8);
                        wPt[1] = (tmp[1] << 24) | (tmp[2] >> 8);
                        wPt[2] = (tmp[2] << 24) | (tmp[3] >> 8);
                        wPt[3] = (tmp[3] << 24) | (tmp[4] >> 8);
                        wPt[4] = (tmp[4] << 24) | (tmp[5] >> 8);
                        wPt[5] = (tmp[5] << 24) | (tmp[6] >> 8);
                        wPt[6] = (tmp[6] << 24) | (tmp[7] >> 8);
                        wPt[7] = (tmp[7] << 24) | (tmp[8] >> 8);
                        wPt[8] = (tmp[8] << 24) | 0b00000000_10000000_00000000_00000000U;
                        // from 9 to 14 = 0
                        wPt[15] = 264; // 33 *8 = 264

                        sha.Init(hPt);
                        sha.CompressDouble33(hPt, wPt);

                        if (hPt[0] == tmp[9])
                        {
                            SetResultParallel(missingItems, firstItem);
                        }
                    }
                } while (MoveNext(itemsPt, missingItems.Length));
            }

            report.IncrementProgress();
        }
예제 #17
0
        public void CompressDouble65Test()
        {
            int dataLen = 65;

            byte[] data     = GetRandomBytes(dataLen);
            byte[] expected = ComputeDoubleSha(data);

            using Sha256Fo sha = new Sha256Fo();
            byte[] actual = sha.CompressDouble65(data);

            Assert.Equal(expected, actual);
        }
예제 #18
0
        public void ComputeHash_ReuseTest()
        {
            byte[] msg1 = Encoding.UTF8.GetBytes("The quick brown fox jumps over the lazy dog");
            byte[] msg2 = Encoding.UTF8.GetBytes("The quick brown fox jumps over the lazy cog");
            byte[] exp1 = Helper.HexToBytes("d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592");
            byte[] exp2 = Helper.HexToBytes("e4c4d8f3bf76b692de791a173e05321150f7a345b46484fe427f6acc7ecc81be");

            byte[] act1 = Sha256Fo.ComputeHash(msg1);
            byte[] act2 = Sha256Fo.ComputeHash(msg2);

            Assert.Equal(exp1, act1);
            Assert.Equal(exp2, act2);
        }
예제 #19
0
        private unsafe void Loop2NoCS(byte[] preComputed, int missCount1, int missCount2)
        {
            using Sha256Fo sha = new Sha256Fo();
            byte *kPt   = stackalloc byte[32 + missingIndexes.Length];
            byte *item1 = kPt + 32;
            byte *item2 = item1 + missCount1;
            uint *oPt   = stackalloc uint[8];

            fixed(byte *pre = &preComputed[0])
            fixed(int *mi   = &missingIndexes[0])
            fixed(uint *wPt = &sha.w[0], hPt = &sha.hashState[0])
            {
                do
                {
                    *(Block32 *)kPt = *(Block32 *)pre;
                    int mIndex = 0;
                    for (int i = 0; i < missCount1; i++)
                    {
                        int index = mi[mIndex++];
                        kPt[index / 2] |= (index % 2 == 0) ? (byte)(item1[i] << 4) : item1[i];
                    }

                    int mIndexInternal = mIndex;
                    do
                    {
                        for (int i = 0; i < missCount2; i++)
                        {
                            int index = mi[mIndex++];
                            kPt[(index / 2) + 16] |= (index % 2 == 0) ? (byte)(item2[i] << 4) : item2[i];
                        }

                        BigInteger secexp = ComputeKey(sha, hPt, wPt, oPt, kPt);
                        if (comparer.Compare(secexp))
                        {
                            SetResult(kPt);
                            return;
                        }

                        // Reset second part for next round
                        *(Block16 *)(kPt + 16) = *(Block16 *)(pre + 16);
                        mIndex = mIndexInternal;
                    } while (MoveNext(item2, missCount2));

                    // Checking second line reached the end and failed, item2 must be reset to 0
                    for (int i = 0; i < missCount2; i++)
                    {
                        item2[i] = 0;
                    }
                } while (MoveNext(item1, missCount1));
            }
        }
예제 #20
0
        private static string EncodeLineWithChecksum(ReadOnlySpan <byte> data)
        {
            Debug.Assert(data.Length == 16);

            byte[] full = new byte[18];
            Buffer.BlockCopy(data.ToArray(), 0, full, 0, data.Length);

            using Sha256Fo sha256 = new Sha256Fo(true);
            byte[] cs = sha256.ComputeHash(data.ToArray()).SubArray(0, 2);
            full[16] = cs[0];
            full[17] = cs[1];

            return(EncodeLine(full));
        }
예제 #21
0
        public Address()
        {
            hashFunc    = new Hash160();
            witHashFunc = new Sha256Fo();

            versionByte_P2pkh_MainNet = 0;
            versionByte_P2pkh_TestNet = 111;
            versionByte_P2pkh_RegTest = 0;

            versionByte_P2sh_MainNet = 5;
            versionByte_P2sh_TestNet = 196;
            versionByte_P2sh_RegTest = 5;

            hrp_MainNet = "bc";
            hrp_TestNet = "tb";
            hrp_RegTest = "bcrt";
        }
예제 #22
0
        public unsafe void Compress65Test()
        {
            int dataLen = 65;

            byte[] data     = GetRandomBytes(dataLen);
            byte[] expected = ComputeSingleSha(data);

            using Sha256Fo sha = new Sha256Fo();
            fixed(byte *dPt = &data[0])
            fixed(uint *hPt = &sha.hashState[0], wPt = &sha.w[0])
            {
                sha.Init(hPt);
                sha.Compress65(dPt, hPt, wPt);
                byte[] actual = sha.GetBytes(hPt);

                Assert.Equal(expected, actual);
            }
        }
예제 #23
0
        public Address()
        {
            b58Encoder  = new Base58();
            b32Encoder  = new Bech32();
            hashFunc    = new Hash160();
            witHashFunc = new Sha256Fo();

            versionByte_P2pkh_MainNet = 0;
            versionByte_P2pkh_TestNet = 111;
            versionByte_P2pkh_RegTest = 0;

            versionByte_P2sh_MainNet = 5;
            versionByte_P2sh_TestNet = 196;
            versionByte_P2sh_RegTest = 5;

            hrp_MainNet = "bc";
            hrp_TestNet = "tb";
            hrp_RegTest = "bcrt";
        }
예제 #24
0
        public unsafe void Constructor_FromSha256Test()
        {
            byte[] data = new byte[] { 1, 2, 3 };

            uint *pt = stackalloc uint[Sha256Fo.UBufferSize];

            fixed(byte *dPt = &data[0])
            {
                Sha256Fo.CompressData(dPt, data.Length, data.Length, pt);
                byte[] hash = Sha256Fo.GetBytes(pt);

                Scalar val1 = new(hash, out int of1);
                Scalar val2 = new(pt, out int of2);

                Assert.Equal(val1, val2);
                Assert.Equal(of1, of2);
                Assert.Equal(0, of1);
            }
        }
예제 #25
0
        public static unsafe byte[] Compress33(Span <byte> data)
        {
            uint *pt = stackalloc uint[Sha256Fo.UBufferSize];

            fixed(byte *dPt = data)
            {
                pt[8]  = (uint)((dPt[0] << 24) | (dPt[1] << 16) | (dPt[2] << 8) | dPt[3]);
                pt[9]  = (uint)((dPt[4] << 24) | (dPt[5] << 16) | (dPt[6] << 8) | dPt[7]);
                pt[10] = (uint)((dPt[8] << 24) | (dPt[9] << 16) | (dPt[10] << 8) | dPt[11]);
                pt[11] = (uint)((dPt[12] << 24) | (dPt[13] << 16) | (dPt[14] << 8) | dPt[15]);
                pt[12] = (uint)((dPt[16] << 24) | (dPt[17] << 16) | (dPt[18] << 8) | dPt[19]);
                pt[13] = (uint)((dPt[20] << 24) | (dPt[21] << 16) | (dPt[22] << 8) | dPt[23]);
                pt[14] = (uint)((dPt[24] << 24) | (dPt[25] << 16) | (dPt[26] << 8) | dPt[27]);
                pt[15] = (uint)((dPt[28] << 24) | (dPt[29] << 16) | (dPt[30] << 8) | dPt[31]);
                pt[16] = (uint)((dPt[32] << 24) | 0b00000000_10000000_00000000_00000000U);
                pt[23] = 264;

                Sha256Fo.Init(pt);
                Sha256Fo.Compress33(pt);

                // Compute RIPEMD160
                pt[12] = (pt[7] >> 24) | (pt[7] << 24) | ((pt[7] >> 8) & 0xff00) | ((pt[7] << 8) & 0xff0000);
                pt[11] = (pt[6] >> 24) | (pt[6] << 24) | ((pt[6] >> 8) & 0xff00) | ((pt[6] << 8) & 0xff0000);
                pt[10] = (pt[5] >> 24) | (pt[5] << 24) | ((pt[5] >> 8) & 0xff00) | ((pt[5] << 8) & 0xff0000);
                pt[9]  = (pt[4] >> 24) | (pt[4] << 24) | ((pt[4] >> 8) & 0xff00) | ((pt[4] << 8) & 0xff0000);
                pt[8]  = (pt[3] >> 24) | (pt[3] << 24) | ((pt[3] >> 8) & 0xff00) | ((pt[3] << 8) & 0xff0000);
                pt[7]  = (pt[2] >> 24) | (pt[2] << 24) | ((pt[2] >> 8) & 0xff00) | ((pt[2] << 8) & 0xff0000);
                pt[6]  = (pt[1] >> 24) | (pt[1] << 24) | ((pt[1] >> 8) & 0xff00) | ((pt[1] << 8) & 0xff0000);
                pt[5]  = (pt[0] >> 24) | (pt[0] << 24) |                      // Swap byte 1 and 4
                         ((pt[0] >> 8) & 0xff00) | ((pt[0] << 8) & 0xff0000); // Swap byte 2 and 3
                pt[13] = 0b00000000_00000000_00000000_10000000U;
                pt[14] = 0;
                pt[15] = 0;
                pt[16] = 0;
                pt[19] = 256;

                Ripemd160Fo.Init(pt);
                Ripemd160Fo.CompressBlock(pt);

                return(Ripemd160Fo.GetBytes(pt));
            }
        }
예제 #26
0
        public static unsafe byte[] Compress22(Span <byte> data)
        {
            uint *pt = stackalloc uint[Sha256Fo.UBufferSize];

            fixed(byte *dPt = data)
            {
                // Step 1: compute SHA256 of data then copy result of hash (HashState) into RIPEMD160 block
                Sha256Fo.Init(pt);

                pt[8]  = (uint)((dPt[0] << 24) | (dPt[1] << 16) | (dPt[2] << 8) | dPt[3]);
                pt[9]  = (uint)((dPt[4] << 24) | (dPt[5] << 16) | (dPt[6] << 8) | dPt[7]);
                pt[10] = (uint)((dPt[8] << 24) | (dPt[9] << 16) | (dPt[10] << 8) | dPt[11]);
                pt[11] = (uint)((dPt[12] << 24) | (dPt[13] << 16) | (dPt[14] << 8) | dPt[15]);
                pt[12] = (uint)((dPt[16] << 24) | (dPt[17] << 16) | (dPt[18] << 8) | dPt[19]);
                pt[13] = (uint)((dPt[20] << 24) | (dPt[21] << 16) | 0b00000000_00000000_10000000_00000000U);
                pt[23] = 176; // 22*8

                Sha256Fo.Compress22(pt);

                // First 8 items (32 byte) of pt is SHA256 hashState now and has to be converted to RIPEMD160 block
                // SHA256 and RIPEMD160 use different endianness
                // RIPMED160 hashState is 20 bytes (or 5 items) and block starts from 6th item (index 5)
                // Set in reverse since each item is going to change
                pt[12] = (pt[7] >> 24) | (pt[7] << 24) | ((pt[7] >> 8) & 0xff00) | ((pt[7] << 8) & 0xff0000);
                pt[11] = (pt[6] >> 24) | (pt[6] << 24) | ((pt[6] >> 8) & 0xff00) | ((pt[6] << 8) & 0xff0000);
                pt[10] = (pt[5] >> 24) | (pt[5] << 24) | ((pt[5] >> 8) & 0xff00) | ((pt[5] << 8) & 0xff0000);
                pt[9]  = (pt[4] >> 24) | (pt[4] << 24) | ((pt[4] >> 8) & 0xff00) | ((pt[4] << 8) & 0xff0000);
                pt[8]  = (pt[3] >> 24) | (pt[3] << 24) | ((pt[3] >> 8) & 0xff00) | ((pt[3] << 8) & 0xff0000);
                pt[7]  = (pt[2] >> 24) | (pt[2] << 24) | ((pt[2] >> 8) & 0xff00) | ((pt[2] << 8) & 0xff0000);
                pt[6]  = (pt[1] >> 24) | (pt[1] << 24) | ((pt[1] >> 8) & 0xff00) | ((pt[1] << 8) & 0xff0000);
                pt[5]  = (pt[0] >> 24) | (pt[0] << 24) |                      // Swap byte 1 and 4
                         ((pt[0] >> 8) & 0xff00) | ((pt[0] << 8) & 0xff0000); // Swap byte 2 and 3
                pt[13] = 0b00000000_00000000_00000000_10000000U;
                pt[19] = 256;

                Ripemd160Fo.Init(pt);
                Ripemd160Fo.CompressBlock(pt);

                return(Ripemd160Fo.GetBytes(pt));
            }
        }
예제 #27
0
        public static unsafe byte[] ComputeHash_static(Span <byte> data)
        {
            if (data.Length == 33)
            {
                return(Compress33(data));
            }
            else if (data.Length == 65)
            {
                return(Compress65(data));
            }

            uint *pt = stackalloc uint[Sha256Fo.UBufferSize];

            fixed(byte *dPt = data)
            {
                Sha256Fo.Init(pt);
                Sha256Fo.CompressData(dPt, data.Length, data.Length, pt);

                // Compute RIPEMD160
                pt[12] = (pt[7] >> 24) | (pt[7] << 24) | ((pt[7] >> 8) & 0xff00) | ((pt[7] << 8) & 0xff0000);
                pt[11] = (pt[6] >> 24) | (pt[6] << 24) | ((pt[6] >> 8) & 0xff00) | ((pt[6] << 8) & 0xff0000);
                pt[10] = (pt[5] >> 24) | (pt[5] << 24) | ((pt[5] >> 8) & 0xff00) | ((pt[5] << 8) & 0xff0000);
                pt[9]  = (pt[4] >> 24) | (pt[4] << 24) | ((pt[4] >> 8) & 0xff00) | ((pt[4] << 8) & 0xff0000);
                pt[8]  = (pt[3] >> 24) | (pt[3] << 24) | ((pt[3] >> 8) & 0xff00) | ((pt[3] << 8) & 0xff0000);
                pt[7]  = (pt[2] >> 24) | (pt[2] << 24) | ((pt[2] >> 8) & 0xff00) | ((pt[2] << 8) & 0xff0000);
                pt[6]  = (pt[1] >> 24) | (pt[1] << 24) | ((pt[1] >> 8) & 0xff00) | ((pt[1] << 8) & 0xff0000);
                pt[5]  = (pt[0] >> 24) | (pt[0] << 24) |                      // Swap byte 1 and 4
                         ((pt[0] >> 8) & 0xff00) | ((pt[0] << 8) & 0xff0000); // Swap byte 2 and 3
                pt[13] = 0b00000000_00000000_00000000_10000000U;
                pt[14] = 0;
                pt[15] = 0;
                pt[16] = 0;
                pt[19] = 256;

                Ripemd160Fo.Init(pt);
                Ripemd160Fo.CompressBlock(pt);

                return(Ripemd160Fo.GetBytes(pt));
            }
        }
예제 #28
0
        protected virtual void Dispose(bool disposing)
        {
            if (!isDisposed)
            {
                if (disposing)
                {
                    if (rip != null)
                    {
                        rip.Dispose();
                    }
                    rip = null;

                    if (sha != null)
                    {
                        sha.Dispose();
                    }
                    sha = null;
                }

                isDisposed = true;
            }
        }
예제 #29
0
        public static unsafe byte[] Compress65(Span <byte> data)
        {
            Debug.Assert(data != null && data.Length == 65);

            uint *pt = stackalloc uint[Sha256Fo.UBufferSize];

            fixed(byte *dPt = &data[0])
            {
                Sha256Fo.Init(pt);
                Sha256Fo.Compress65(pt, dPt);

                // Compute RIPEMD160
                pt[12] = (pt[7] >> 24) | (pt[7] << 24) | ((pt[7] >> 8) & 0xff00) | ((pt[7] << 8) & 0xff0000);
                pt[11] = (pt[6] >> 24) | (pt[6] << 24) | ((pt[6] >> 8) & 0xff00) | ((pt[6] << 8) & 0xff0000);
                pt[10] = (pt[5] >> 24) | (pt[5] << 24) | ((pt[5] >> 8) & 0xff00) | ((pt[5] << 8) & 0xff0000);
                pt[9]  = (pt[4] >> 24) | (pt[4] << 24) | ((pt[4] >> 8) & 0xff00) | ((pt[4] << 8) & 0xff0000);
                pt[8]  = (pt[3] >> 24) | (pt[3] << 24) | ((pt[3] >> 8) & 0xff00) | ((pt[3] << 8) & 0xff0000);
                pt[7]  = (pt[2] >> 24) | (pt[2] << 24) | ((pt[2] >> 8) & 0xff00) | ((pt[2] << 8) & 0xff0000);
                pt[6]  = (pt[1] >> 24) | (pt[1] << 24) | ((pt[1] >> 8) & 0xff00) | ((pt[1] << 8) & 0xff0000);
                pt[5]  = (pt[0] >> 24) | (pt[0] << 24) |                      // Swap byte 1 and 4
                         ((pt[0] >> 8) & 0xff00) | ((pt[0] << 8) & 0xff0000); // Swap byte 2 and 3
                pt[13] = 0b00000000_00000000_00000000_10000000U;
                pt[14] = 0;
                pt[15] = 0;
                pt[16] = 0;
                pt[17] = 0;
                pt[18] = 0;
                pt[19] = 256;
                pt[20] = 0;

                Ripemd160Fo.Init(pt);
                Ripemd160Fo.CompressBlock(pt);

                return(Ripemd160Fo.GetBytes(pt));
            }
        }
예제 #30
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Hash160"/>.
 /// </summary>
 public Hash160()
 {
     rip = new Ripemd160();
     sha = new Sha256Fo();
 }