public unsafe void Compress32Test() { int dataLen = 32; 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 < 8; i++, dIndex += 4) { wPt[i] = (uint)((data[dIndex] << 24) | (data[dIndex + 1] << 16) | (data[dIndex + 2] << 8) | data[dIndex + 3]); } wPt[8] = 0b10000000_00000000_00000000_00000000U; wPt[15] = (uint)dataLen * 8; sha.Init(hPt); sha.Compress32(hPt, wPt); byte[] actual = sha.GetBytes(hPt); Assert.Equal(expected, actual); } }
private unsafe bool Loop24() { 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[8] = 0b10000000_00000000_00000000_00000000U; wPt[15] = 256; foreach (var item in cartesian) { int j = 0; foreach (var k in item) { wrd[mi[j]] = (uint)k; j++; } // 0000_0000 0000_0000 0000_0111 1111_1111 -> 1111_1111 1110_0000 0000_0000 0000_0000 // 0000_0000 0000_0000 0000_0222 2222_2222 -> 0000_0000 0002_2222 2222_2200 0000_0000 // 0000_0000 0000_0000 0000_0333 3333_3333 -> 0000_0000 0000_0000 0000_0033 3333_3333 -> 3 // 1111_1111 1112_2222 2222_2233 3333_3333 wPt[0] = wrd[0] << 21 | wrd[1] << 10 | wrd[2] >> 1; // 0000_0000 0000_0000 0000_0000 0000_0003 -> 3000_0000 0000_0000 0000_0000 0000_0000 // 0000_0000 0000_0000 0000_0444 4444_4444 -> 0444_4444 4444_0000 0000_0000 0000_0000 // 0000_0000 0000_0000 0000_0555 5555_5555 -> 0000_0000 0000_5555 5555_5550 0000_0000 // 0000_0000 0000_0000 0000_0666 6666_6666 -> 0000_0000 0000_0000 0000_0006 6666_6666 -> 66 // 3444_4444 4444_5555 5555_5556 6666_6666 wPt[1] = wrd[2] << 31 | wrd[3] << 20 | wrd[4] << 9 | wrd[5] >> 2; // 0000_0000 0000_0000 0000_0000 0000_0066 -> 6600_0000 0000_0000 0000_0000 0000_0000 // 0000_0000 0000_0000 0000_0777 7777_7777 -> 0077_7777 7777_7000 0000_0000 0000_0000 // 0000_0000 0000_0000 0000_0888 8888_8888 -> 0000_0000 0000_0888 8888_8888 0000_0000 // 0000_0000 0000_0000 0000_0999 9999_9999 -> 0000_0000 0000_0000 0000_0000 9999_9999 -> 999 // 6677_7777 7777_7888 8888_8888 9999_9999 wPt[2] = wrd[5] << 30 | wrd[6] << 19 | wrd[7] << 8 | wrd[8] >> 3; // 0000_0000 0000_0000 0000_0000 0000_0999 -> 9990_0000 0000_0000 0000_0000 0000_0000 // 0000_0000 0000_0000 0000_0AAA AAAA_AAAA -> 000A_AAAA AAAA_AA00 0000_0000 0000_0000 // 0000_0000 0000_0000 0000_0BBB BBBB_BBBB -> 0000_0000 0000_00BB BBBB_BBBB B000_0000 // 0000_0000 0000_0000 0000_0CCC CCCC_CCCC -> 0000_0000 0000_0000 0000_0000 0CCC_CCCC -> CCCC // 999A_AAAA AAAA_AABB BBBB_BBBB BCCC_CCCC wPt[3] = wrd[8] << 29 | wrd[9] << 18 | wrd[10] << 7 | wrd[11] >> 4; // 0000_0000 0000_0000 0000_0000 0000_CCCC -> CCCC_0000 0000_0000 0000_0000 0000_0000 // 0000_0000 0000_0000 0000_0DDD DDDD_DDDD -> 0000_DDDD DDDD_DDD0 0000_0000 0000_0000 // 0000_0000 0000_0000 0000_0EEE EEEE_EEEE -> 0000_0000 0000_000E EEEE_EEEE EE00_0000 // 0000_0000 0000_0000 0000_0FFF FFFF_FFFF -> 0000_0000 0000_0000 0000_0000 00FF_FFFF -> FFFF_F // CCCC_DDDD DDDD_DDDE EEEE_EEEE EEFF_FFFF wPt[4] = wrd[11] << 28 | wrd[12] << 17 | wrd[13] << 6 | wrd[14] >> 5; // 0000_0000 0000_0000 0000_0000 000F_FFFF -> FFFF_F000 0000_0000 0000_0000 0000_0000 // 0000_0000 0000_0000 0000_0GGG GGGG_GGGG -> 0000_0GGG GGGG_GGGG 0000_0000 0000_0000 // 0000_0000 0000_0000 0000_0HHH HHHH_HHHH -> 0000_0000 0000_0000 HHHH_HHHH HHH0_0000 // 0000_0000 0000_0000 0000_0III IIII_IIII -> 0000_0000 0000_0000 0000_0000 000I_IIII -> IIII_II // -> FFFF_FGGG GGGG_GGGG HHHH_HHHH HHHI_IIII wPt[5] = wrd[14] << 27 | wrd[15] << 16 | wrd[16] << 5 | wrd[17] >> 6; // 0000_0000 0000_0000 0000_0000 00II_IIII -> IIII_II00 0000_0000 0000_0000 0000_0000 // 0000_0000 0000_0000 0000_0JJJ JJJJ_JJJJ -> 0000_00JJ JJJJ_JJJJ J000_0000 0000_0000 // 0000_0000 0000_0000 0000_0KKK KKKK_KKKK -> 0000_0000 0000_0000 0KKK_KKKK KKKK_0000 // 0000_0000 0000_0000 0000_0LLL LLLL_LLLL -> 0000_0000 0000_0000 0000_0000 0000_LLLL -> LLLL_LLL // -> IIII_IIJJ JJJJ_JJJJ JKKK_KKKK KKKK_LLLL wPt[6] = wrd[17] << 26 | wrd[18] << 15 | wrd[19] << 4 | wrd[20] >> 7; // 0000_0000 0000_0000 0000_0000 0LLL_LLLL -> LLLL_LLL0 0000_0000 0000_0000 0000_0000 // 0000_0000 0000_0000 0000_0MMM MMMM_MMMM -> 0000_000M MMMM_MMMM MM00_0000 0000_0000 // 0000_0000 0000_0000 0000_0NNN NNNN_NNNN -> 0000_0000 0000_0000 00NN_NNNN NNNN_N000 // 0000_0000 0000_0000 0000_0OOO OOOO_OOOO -> 0000_0000 0000_0000 0000_0000 0000_0OOO -> OOOO_OOOO // -> LLLL_LLLM MMMM_MMMM MMNN_NNNN NNNN_NOOO wPt[7] = wrd[20] << 25 | wrd[21] << 14 | wrd[22] << 3 | wrd[23] >> 8; sha256.Init(hPt); sha256.Compress32(hPt, wPt); if ((byte)wrd[23] == hPt[0] >> 24) { int mnLen = 0; for (int i = 0; i < 24; 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); }