public static byte[] DecryptChaCha20(byte[] cipherText, byte[] nonce, byte[] key) { //validate the length of the key if (key == null || key.Length != CHACHA20_KEY_BYTES) { throw new Exception(); } //throw new Exception("key", (key == null) ? 0 : key.Length, // string.Format("key must be {0} bytes in length.", CHACHA20_KEY_BYTES)); //validate the length of the nonce if (nonce == null || nonce.Length != CHACHA20_NONCEBYTES) { throw new Exception(); } //throw new Exception("nonce", (nonce == null) ? 0 : nonce.Length, // string.Format("nonce must be {0} bytes in length.", CHACHA20_NONCEBYTES)); var buffer = new byte[cipherText.Length]; var ret = NativeLibsodium.crypto_stream_chacha20_xor(buffer, cipherText, cipherText.Length, nonce, key); if (ret != 0) { throw new Exception("Error derypting message."); } return(buffer); }
unsafe public static byte[] EncryptChaCha20(byte[] message, byte[] nonce, byte[] key) { //validate the length of the key if (key == null || key.Length != CHACHA20_KEY_BYTES) { throw new Exception(); } //throw new Exception("key", (key == null) ? 0 : key.Length, // string.Format("key must be {0} bytes in length.", CHACHA20_KEY_BYTES)); //validate the length of the nonce if (nonce == null || nonce.Length != CHACHA20_NONCEBYTES) { throw new Exception(); } //throw new Exception("nonce", (nonce == null) ? 0 : nonce.Length, // string.Format("nonce must be {0} bytes in length.", CHACHA20_NONCEBYTES)); byte[] buffer = new byte[message.Length]; fixed(byte *bufferPtr = buffer) { int ret = NativeLibsodium.crypto_stream_chacha20_xor(bufferPtr, message, (ulong)message.Length, nonce, key); if (ret != 0) { throw new Exception("Error encrypting message."); } } return(buffer); }