decryptMessage function

String decryptMessage(
  1. String key,
  2. String data
)

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));
}