public byte[] DecryptAES256CBC4Msg(byte[] data)
{
//blocksize = OpenSSL.get_cipher(ciphername).get_blocksize()
const int blocksize = 16;
//iv = data[:blocksize]
//i = blocksize
int pos = 0;
var iv = data.ReadBytes(ref pos, blocksize);
//curve, pubkey_x, pubkey_y, i2 = ECC._decode_pubkey(data[i:])
//i += i2
UInt16 curve;
byte[] pubkeyX;
byte[] pubkeyY;
ECC._decode_pubkey(data, out curve, out pubkeyX, out pubkeyY, ref pos);
//ciphertext = data[i:len(data)-32]
//i += len(ciphertext)
var ciphertext = data.ReadBytes(ref pos, data.Length - pos - 32);
//mac = data[i:]
var mac = data.ReadBytes(ref pos, 32);
//key = sha512(self.raw_get_ecdh_key(pubkey_x, pubkey_y)).digest()
byte[] key;
using (var sha512 = new SHA512Managed())
key = sha512.ComputeHash(new ECC(null, null, null, null, Wif2PrivateKey(PrivEncryptionKeyWif), ECC.Secp256K1).raw_get_ecdh_key(pubkeyX, pubkeyY));
//key_e, key_m = key[:32], key[32:]
byte[] key_e = new byte[32];
byte[] key_m = new byte[32];
Buffer.BlockCopy(key, 0, key_e, 0, 32);
Buffer.BlockCopy(key, 32, key_m, 0, 32);
//if hmac_sha256(key_m, ciphertext) != mac:
// raise RuntimeError("Fail to verify data")
if (!new HMACSHA256(key_m).ComputeHash(ciphertext).SequenceEqual(mac))
throw new Exception("Fail to verify data");
var ctx = new Cipher(key_e, iv, false);
return ctx.Ciphering(ciphertext);
}