/* CryptoNight Step 3: Bounce randomly 1,048,576 times (1<<20) * through the mixing scratchpad, using 524,288 iterations of the * following mixing function. Each execution performs two reads * and writes from the mixing scratchpad. */ private static void MixScratchpadV0(CNState cnState, ICryptoNight cnParams, byte[] scratchpad) { MixScratchpadState mixingState = new MixScratchpadState(cnState); for (int i = 0; i < cnParams.Iterations() / 2; i++) { for (int iteration = 1; iteration < 3; iteration++) { /* Get our 'memory' address we're using for this round */ int j = E2I(mixingState.a, cnParams.Memory()); /* Load c from the scratchpad */ CopyBlockFromScratchpad(scratchpad, mixingState.c, j); /* Perform the mixing function */ if (iteration == 1) { MixScratchpadIterationOne(mixingState); } else { MixScratchpadIterationTwo(mixingState); } /* Write c back to the scratchpad */ CopyBlockToScratchpad(scratchpad, mixingState.c, j); SwapBlocks(ref mixingState.a, ref mixingState.b); } } }
private static void MixScratchpadIterationOne(MixScratchpadState mixingState) { AES.AES.AESBSingleRound(mixingState.a, mixingState.c, 0); XORBlocks(mixingState.b, mixingState.c); SwapBlocks(ref mixingState.b, ref mixingState.c); }
private static void MixScratchpadIterationTwo(MixScratchpadState mixingState) { /* Multiply a and c together, and place the result in * b, a and c are ulongs stored as byte arrays, d is a * 128 bit value stored as a byte array */ Multiply128(mixingState.a, mixingState.c, mixingState.d); SumHalfBlocks(mixingState.b, mixingState.d); SwapBlocks(ref mixingState.b, ref mixingState.c); XORBlocks(mixingState.b, mixingState.c); }