/// <summary> /// Initializes a new instance of the <see cref="AesPmac"/> class with the specified key. /// </summary> /// <param name="key">The secret key for <see cref="AesPmac"> authentication.</param> public AesPmac(byte[] key) { if (key == null) { throw new ArgumentNullException(nameof(key)); } aes = Utils.CreateAes(CipherMode.ECB); encryptor = aes.CreateEncryptor(key, null); byte[] temp = new byte[BlockSize]; encryptor.TransformBlock(temp, 0, BlockSize, temp, 0); for (int i = 0; i < l.Length; ++i) { l[i] = (byte[])temp.Clone(); Utils.Multiply(temp); } inv = (byte[])l[0].Clone(); int lastBit = inv[BlockSize - 1] & 1; for (int i = BlockSize - 1; i > 0; --i) { int carry = Subtle.ConstantTimeSelect(inv[i - 1] & 1, 0x80, 0); inv[i] = (byte)((inv[i] >> 1) | carry); } inv[0] >>= 1; inv[0] ^= (byte)Subtle.ConstantTimeSelect(lastBit, 0x80, 0); inv[BlockSize - 1] ^= (byte)Subtle.ConstantTimeSelect(lastBit, Constants.R >> 1, 0); }
public static void Multiply(byte[] input) { Debug.Assert(input.Length == Constants.BlockSize); int carry = input[0] >> 7; for (int i = 0; i < Constants.BlockSize - 1; ++i) { input[i] = (byte)((input[i] << 1) | (input[i + 1] >> 7)); } byte last = input[Constants.BlockSize - 1]; input[Constants.BlockSize - 1] = (byte)((last << 1) ^ Subtle.ConstantTimeSelect(carry, Constants.R, 0)); }