lyra2.go
func reducedDuplexRowSetup(state []uint64, rowIn []uint64,
	rowInOut []uint64, rowOut []uint64, nCols int) {
	ptrIn := 0
	ptrInOut := 0
	ptrOut := (nCols - 1) * blockLenInt64

	for i := 0; i < nCols; i++ {
		ptrWordIn := rowIn[ptrIn:]          //In Lyra2: pointer to prev
		ptrWordOut := rowOut[ptrOut:]       //In Lyra2: pointer to row
		ptrWordInOut := rowInOut[ptrInOut:] //In Lyra2: pointer to row

		//Absorbing "M[prev] [+] M[row*]"
		state[0] ^= (ptrWordIn[0] + ptrWordInOut[0])
		state[1] ^= (ptrWordIn[1] + ptrWordInOut[1])
		state[2] ^= (ptrWordIn[2] + ptrWordInOut[2])
		state[3] ^= (ptrWordIn[3] + ptrWordInOut[3])
		state[4] ^= (ptrWordIn[4] + ptrWordInOut[4])
		state[5] ^= (ptrWordIn[5] + ptrWordInOut[5])
		state[6] ^= (ptrWordIn[6] + ptrWordInOut[6])
		state[7] ^= (ptrWordIn[7] + ptrWordInOut[7])
		state[8] ^= (ptrWordIn[8] + ptrWordInOut[8])
		state[9] ^= (ptrWordIn[9] + ptrWordInOut[9])
		state[10] ^= (ptrWordIn[10] + ptrWordInOut[10])
		state[11] ^= (ptrWordIn[11] + ptrWordInOut[11])

		//Applies the reduced-round transformation f to the sponge's state
		reducedBlake2bLyra(state)

		//M[row][col] = M[prev][col] XOR rand
		ptrWordOut[0] = ptrWordIn[0] ^ state[0]
		ptrWordOut[1] = ptrWordIn[1] ^ state[1]
		ptrWordOut[2] = ptrWordIn[2] ^ state[2]
		ptrWordOut[3] = ptrWordIn[3] ^ state[3]
		ptrWordOut[4] = ptrWordIn[4] ^ state[4]
		ptrWordOut[5] = ptrWordIn[5] ^ state[5]
		ptrWordOut[6] = ptrWordIn[6] ^ state[6]
		ptrWordOut[7] = ptrWordIn[7] ^ state[7]
		ptrWordOut[8] = ptrWordIn[8] ^ state[8]
		ptrWordOut[9] = ptrWordIn[9] ^ state[9]
		ptrWordOut[10] = ptrWordIn[10] ^ state[10]
		ptrWordOut[11] = ptrWordIn[11] ^ state[11]

		//M[row*][col] = M[row*][col] XOR rotW(rand)
		ptrWordInOut[0] ^= state[11]
		ptrWordInOut[1] ^= state[0]
		ptrWordInOut[2] ^= state[1]
		ptrWordInOut[3] ^= state[2]
		ptrWordInOut[4] ^= state[3]
		ptrWordInOut[5] ^= state[4]
		ptrWordInOut[6] ^= state[5]
		ptrWordInOut[7] ^= state[6]
		ptrWordInOut[8] ^= state[7]
		ptrWordInOut[9] ^= state[8]
		ptrWordInOut[10] ^= state[9]
		ptrWordInOut[11] ^= state[10]

		//Inputs: next column (i.e., next block in sequence)
		ptrInOut += blockLenInt64
		ptrIn += blockLenInt64
		//Output: goes to previous column
		ptrOut -= blockLenInt64
	}
}
func reducedDuplexRowSetup(state []uint64, rowIn []uint64,
	rowInOut []uint64, rowOut []uint64, nCols int) {
	ptrIn := 0
	ptrInOut := 0
	ptrOut := (nCols - 1) * blockLenInt64

	for i := 0; i < nCols; i++ {
		ptrWordIn := rowIn[ptrIn:]          //In Lyra2: pointer to prev
		ptrWordOut := rowOut[ptrOut:]       //In Lyra2: pointer to row
		ptrWordInOut := rowInOut[ptrInOut:] //In Lyra2: pointer to row

		//Absorbing "M[prev] [+] M[row*]"
		state[0] ^= (ptrWordIn[0] + ptrWordInOut[0])
		state[1] ^= (ptrWordIn[1] + ptrWordInOut[1])
		state[2] ^= (ptrWordIn[2] + ptrWordInOut[2])
		state[3] ^= (ptrWordIn[3] + ptrWordInOut[3])
		state[4] ^= (ptrWordIn[4] + ptrWordInOut[4])
		state[5] ^= (ptrWordIn[5] + ptrWordInOut[5])
		state[6] ^= (ptrWordIn[6] + ptrWordInOut[6])
		state[7] ^= (ptrWordIn[7] + ptrWordInOut[7])
		state[8] ^= (ptrWordIn[8] + ptrWordInOut[8])
		state[9] ^= (ptrWordIn[9] + ptrWordInOut[9])
		state[10] ^= (ptrWordIn[10] + ptrWordInOut[10])
		state[11] ^= (ptrWordIn[11] + ptrWordInOut[11])

		//Applies the reduced-round transformation f to the sponge's state
		reducedBlake2bLyra(state)

		//M[row][col] = M[prev][col] XOR rand
		ptrWordOut[0] = ptrWordIn[0] ^ state[0]
		ptrWordOut[1] = ptrWordIn[1] ^ state[1]
		ptrWordOut[2] = ptrWordIn[2] ^ state[2]
		ptrWordOut[3] = ptrWordIn[3] ^ state[3]
		ptrWordOut[4] = ptrWordIn[4] ^ state[4]
		ptrWordOut[5] = ptrWordIn[5] ^ state[5]
		ptrWordOut[6] = ptrWordIn[6] ^ state[6]
		ptrWordOut[7] = ptrWordIn[7] ^ state[7]
		ptrWordOut[8] = ptrWordIn[8] ^ state[8]
		ptrWordOut[9] = ptrWordIn[9] ^ state[9]
		ptrWordOut[10] = ptrWordIn[10] ^ state[10]
		ptrWordOut[11] = ptrWordIn[11] ^ state[11]

		//M[row*][col] = M[row*][col] XOR rotW(rand)
		ptrWordInOut[0] ^= state[11]
		ptrWordInOut[1] ^= state[0]
		ptrWordInOut[2] ^= state[1]
		ptrWordInOut[3] ^= state[2]
		ptrWordInOut[4] ^= state[3]
		ptrWordInOut[5] ^= state[4]
		ptrWordInOut[6] ^= state[5]
		ptrWordInOut[7] ^= state[6]
		ptrWordInOut[8] ^= state[7]
		ptrWordInOut[9] ^= state[8]
		ptrWordInOut[10] ^= state[9]
		ptrWordInOut[11] ^= state[10]

		//Inputs: next column (i.e., next block in sequence)
		ptrInOut += blockLenInt64
		ptrIn += blockLenInt64
		//Output: goes to previous column
		ptrOut -= blockLenInt64
	}
}
/**
 * reducedDuplexRowSetup Performs a duplexing operation over "M[rowInOut][col] [+] M[rowIn][col]" (i.e.,
 * the wordwise addition of two columns, ignoring carries between words). The
 * output of this operation, "rand", is then used to make
 * "M[rowOut][(N_COLS-1)-col] = M[rowIn][col] XOR rand" and
 * "M[rowInOut][col] =  M[rowInOut][col] XOR rotW(rand)", where rotW is a 64-bit
 * rotation to the left and N_COLS is a system parameter.
 *
 * @param state          The current state of the sponge
 * @param rowIn          Row used only as input
 * @param rowInOut       Row used as input and to receive output after rotation
 * @param rowOut         Row receiving the output
 *
 */