decryptMessage function
Implementation
String decryptMessage(String key, String data) {
key = remove0x(key);
data = remove0x(data);
var ephemKeyLength = 65;
var ivLength = 16;
var macLength = 32;
var encrypted = crypto.hexToBytes(data);
int metaLength = ephemKeyLength + ivLength + macLength;
if (encrypted.length < metaLength) {
print('Invalid Ciphertext. Data is too small');
return null;
}
// deserialise
var ephemPublicKey = encrypted.sublist(0, ephemKeyLength);
var cipherTextLength = encrypted.length - metaLength;
var iv = encrypted.sublist(ephemKeyLength, ephemKeyLength + ivLength);
var cipherAndIv = encrypted.sublist(
ephemKeyLength, ephemKeyLength + ivLength + cipherTextLength);
var ciphertext = cipherAndIv.sublist(ivLength);
var msgMac = encrypted.sublist(ephemKeyLength + ivLength + cipherTextLength);
// derive private key
ECDomainParameters curve = ECDomainParameters('secp256k1');
ECPoint s = curve.curve.decodePoint(ephemPublicKey);
var px = (s * BigInt.parse(key, radix: 16)).x.toBigInteger();
var hash = _kdf(px, 32);
var encryptionKey = Uint8List.fromList(hash.sublist(0, 16));
var macKey = sha256.convert(Uint8List.fromList(hash.sublist(16))).bytes;
// check HMAC
var currentHMAC = new Hmac(sha256, macKey);
var digest = currentHMAC.convert(cipherAndIv);
// decrypt message - ok
final encryptedText = Encrypted.fromBase16(hex.encode(ciphertext));
final ctr = pc.CTRStreamCipher(pc.AESFastEngine())
..init(false, pc.ParametersWithIV(pc.KeyParameter(encryptionKey), iv));
Uint8List decrypted = ctr.process(encryptedText.bytes);
//print(HEX.encode(decrypted));
return (HEX.encode(decrypted));
}