ecDecrypt function

Uint8List ecDecrypt(
  1. dynamic cipherText,
  2. dynamic privateKey
)

Decrypt a ciphertext for a given private key using ECIES algorithm @param {String | Uint8List} ciphertext Ciphertext to decrypt @param {String | Uint8List} privateKey Private key for the shared secret encryption

Implementation

Uint8List ecDecrypt(dynamic cipherText, dynamic privateKey) {
  if (cipherText is! Uint8List && cipherText is! String) {
    throw "'cipherText' must be a string or Uint8List";
  }

  if (privateKey is! Uint8List && privateKey is! String) {
    throw "'publicKey' must be a string or Uint8List";
  }

  if (cipherText is String) {
    if (isHex(cipherText)) {
      cipherText = Uint8List.fromList(hexToUint8List(cipherText));
    } else {
      cipherText = Uint8List.fromList(utf8.encode(cipherText));
    }
  }

  if (privateKey is String) {
    if (isHex(privateKey)) {
      privateKey = Uint8List.fromList(hexToUint8List(privateKey));
    } else {
      throw "'privateKey' must be an hexadecimal string";
    }
  }

  final Uint8List curveBuf = privateKey.sublist(0, 1);
  final Uint8List pvBuf = privateKey.sublist(2, privateKey.length);

  switch (curveBuf[0]) {
    case 0:
      final Uint8List ephemeralPubKey = cipherText.sublist(0, 32);
      final Uint8List tag = cipherText.sublist(32, 32 + 16);
      final Uint8List encrypted =
          cipherText.sublist(32 + 16, cipherText.length);

      final Uint8List curve25519pv = Uint8List(32);
      tweetnacl.TweetNaClExt.crypto_sign_ed25519_sk_to_x25519_sk(
          curve25519pv, pvBuf);

      final Uint8List sharedKey = x25519.X25519(curve25519pv, ephemeralPubKey);
      final Secret secret = deriveSecret(sharedKey);

      return aesAuthDecrypt(encrypted, secret.aesKey, secret.iv, tag);
    case 1:
      final Uint8List ephemeralPubKey = cipherText.sublist(0, 65);
      final Uint8List tag = cipherText.sublist(65, 65 + 16);
      final Uint8List encrypted =
          cipherText.sublist(65 + 16, cipherText.length);
      final elliptic.EllipticCurve ec = elliptic.getP256();
      final elliptic.PrivateKey privateKey =
          elliptic.PrivateKey.fromBytes(ec, pvBuf);
      final elliptic.PublicKey publicKey =
          elliptic.PublicKey.fromHex(ec, uint8ListToHex(ephemeralPubKey));
      final Uint8List sharedKey =
          Uint8List.fromList(ecdh.computeSecret(privateKey, publicKey));
      final Secret secret = deriveSecret(sharedKey);

      return aesAuthDecrypt(encrypted, secret.aesKey, secret.iv, tag);

    case 2:
      final Uint8List ephemeralPubKey = cipherText.sublist(0, 65);
      final Uint8List tag = cipherText.sublist(65, 65 + 16);
      final Uint8List encrypted =
          cipherText.sublist(65 + 16, cipherText.length);

      final elliptic.Curve ec = elliptic.getSecp256k1();
      final elliptic.PrivateKey privateKey =
          elliptic.PrivateKey.fromBytes(ec, pvBuf);
      final elliptic.PublicKey publicKey =
          elliptic.PublicKey.fromHex(ec, uint8ListToHex(ephemeralPubKey));
      final Uint8List sharedKey =
          Uint8List.fromList(ecdh.computeSecret(privateKey, publicKey));
      final Secret secret = deriveSecret(sharedKey);

      return aesAuthDecrypt(encrypted, secret.aesKey, secret.iv, tag);

    default:
      throw 'Curve not supported';
  }
}