public static byte[] Encrypt(byte[] key, byte[] nonce, byte[] data, byte[] associatedData, int signatureLength, out byte[] signature) { if (nonce.Length < 7 || nonce.Length > 13) { throw new ArgumentException("nonce length must be between 7 and 13 bytes"); } if (signatureLength < 4 || signatureLength > 16 || (signatureLength % 2 == 1)) { throw new ArgumentException("signature length must be an even number between 4 and 16 bytes"); } byte[] keyStream = BuildKeyStream(key, nonce, data.Length); byte[] mac = CalculateMac(key, nonce, data, associatedData, signatureLength); signature = ByteUtils.XOR(keyStream, 0, mac, 0, mac.Length); return(ByteUtils.XOR(data, 0, keyStream, 16, data.Length)); }
public static byte[] DecryptAndAuthenticate(byte[] key, byte[] nonce, byte[] encryptedData, byte[] associatedData, byte[] signature) { if (nonce.Length < 7 || nonce.Length > 13) { throw new ArgumentException("nonce length must be between 7 and 13 bytes"); } if (signature.Length < 4 || signature.Length > 16 || (signature.Length % 2 == 1)) { throw new ArgumentException("signature length must be an even number between 4 and 16 bytes"); } byte[] keyStream = BuildKeyStream(key, nonce, encryptedData.Length); byte[] data = ByteUtils.XOR(encryptedData, 0, keyStream, 16, encryptedData.Length); byte[] mac = CalculateMac(key, nonce, data, associatedData, signature.Length); byte[] expectedSignature = ByteUtils.XOR(keyStream, 0, mac, 0, mac.Length); if (!ByteUtils.AreByteArraysEqual(expectedSignature, signature)) { throw new CryptographicException("The computed authentication value did not match the input"); } return(data); }