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); } }
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); } }
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); } }
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); }
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(); }
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; } } } } } }
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); }
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)); }
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); }
public void ComputeHash_DoubleTest() { byte[] data = Helper.HexToBytes("fb8049137747e712628240cf6d7056ea2870170cb7d9bc713d91e901b514c6ae7d7dda3cd03ea1b99cf85046a505f3590541123d3f8f2c22c4d7d6e65de65c4ebb9251f09619"); byte[] actualHash = Sha256Fo.ComputeHashTwice(data); byte[] expectedHash = Helper.HexToBytes("d2cee8d3cfaf1819c55cce1214d01cdef1d97446719ccfaad4d76d912a8126f9"); Assert.Equal(expectedHash, actualHash); }
public void ComputeHash_AMillionATest() { using Sha256Fo sha = new Sha256Fo(); byte[] actualHash = sha.ComputeHash(HashTestCaseHelper.GetAMillionA()); byte[] expectedHash = Helper.HexToBytes("cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0"); Assert.Equal(expectedHash, actualHash); }
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); }
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)); }
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); }
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(); }
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); }
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); }
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)); } }
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)); }
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"; }
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); } }
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"; }
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); } }
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)); } }
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)); } }
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)); } }
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; } }
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)); } }
/// <summary> /// Initializes a new instance of the <see cref="Hash160"/>. /// </summary> public Hash160() { rip = new Ripemd160(); sha = new Sha256Fo(); }