public unsafe void BlockHeaderHashTest()
{
// allocate buffers to hold hashing work
byte[] round1Blocks = Sha256.AllocateInputBuffer(80);
uint[] round1State = Sha256.AllocateStateBuffer();
byte[] round2Blocks = Sha256.AllocateInputBuffer(Sha256.SHA256_HASH_SIZE);
uint[] round2State = Sha256.AllocateStateBuffer();
byte[] hash = Sha256.AllocateHashBuffer();
fixed (byte* round1BlocksPtr = round1Blocks, round2BlocksPtr = round2Blocks, hashPtr = hash, targetPtr = Utils.Work.Target)
fixed (uint* round1StatePtr = round1State, round2StatePtr = round2State)
{
byte* round1Block1Ptr = round1BlocksPtr;
byte* round1Block2Ptr = round1BlocksPtr + Sha256.SHA256_BLOCK_SIZE;
byte* round2Block1Ptr = round2BlocksPtr;
// header arrives in big endian, convert to host
fixed (byte* workHeaderPtr = Utils.Work.Header)
Memory.ReverseEndian((uint*)workHeaderPtr, (uint*)round1BlocksPtr, 20);
// prepare states and blocks
Sha256.Initialize(round1StatePtr);
Sha256.Initialize(round2StatePtr);
Sha256.Prepare(round1Block1Ptr, 80, 0);
Sha256.Prepare(round1Block2Ptr, 80, 1);
Sha256.Prepare(round2BlocksPtr, Sha256.SHA256_HASH_SIZE, 0);
// hash first half of header
Sha256.Transform(round1StatePtr, round1Block1Ptr);
Sha256.Transform(round1StatePtr, round1Block2Ptr, (uint*)round2Block1Ptr);
Sha256.Transform(round2StatePtr, round2Block1Ptr);
Sha256.Finalize(round2StatePtr, hashPtr);
for (int i = 7; i >= 0; i--)
Assert.IsFalse(((uint*)hashPtr)[i] > ((uint*)targetPtr)[i]);
}
}