/// <summary> /// adapted from ethereumJ /// </summary> private byte[] UpdateMac(KeccakDigest mac, byte[] seed, int offset, byte[] output, int outOffset, bool egress) { byte[] aesBlock = new byte[mac.GetDigestSize()]; DoFinalNoReset(mac, aesBlock, 0); // TODO: check if need to make a new one each time MakeMacCipher().ProcessBlock(aesBlock, 0, aesBlock, 0); // Note that although the mac digest size is 32 bytes, we only use 16 bytes in the computation int length = 16; for (int i = 0; i < length; i++) { aesBlock[i] ^= seed[i + offset]; } mac.BlockUpdate(aesBlock, 0, length); byte[] result = new byte[mac.GetDigestSize()]; DoFinalNoReset(mac, result, 0); if (egress) { Array.Copy(result, 0, output, outOffset, length); } else { bool isMacSame = true; for (int i = 0; i < length; i++) { if (output[i + outOffset] != result[i]) { isMacSame = false; break; } } if (!isMacSame) { throw new IOException($"MAC mismatch from {_remoteNodeId.ToFullString()}"); } } return(result); }