ecEncrypt function

Uint8List ecEncrypt(
  1. dynamic data,
  2. dynamic publicKey, {
  3. bool isDataHexa = true,
  4. bool isPublicKeyHexa = true,
})

Encrypt a data for a given public key using ECIES algorithm

Implementation

Uint8List ecEncrypt(
  dynamic data,
  dynamic publicKey, {
  bool isDataHexa = true,
  bool isPublicKeyHexa = true,
}) {
  if (data is! Uint8List && data is! String) {
    throw "'data' must be a string or Uint8List";
  }

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

  if (data is String) {
    if (isDataHexa && !isHex(data)) {
      throw const FormatException("'data' must be an hexadecimal string");
    }

    if (isDataHexa) {
      data = Uint8List.fromList(hexToUint8List(data));
    } else {
      data = Uint8List.fromList(utf8.encode(data));
    }
  }

  if (publicKey is String) {
    if (isPublicKeyHexa && !isHex(publicKey)) {
      throw const FormatException("'publicKey' must be an hexadecimal string");
    }

    if (isPublicKeyHexa) {
      publicKey = Uint8List.fromList(hexToUint8List(publicKey));
    } else {
      throw "'publicKey' must be an hexadecimal string";
    }
  }

  final curveBuf = Uint8List.fromList(publicKey.sublist(0, 1));
  final pubBuf = Uint8List.fromList(publicKey.sublist(2, publicKey.length));

  switch (curveBuf[0]) {
    case 0:
      final keyPair = x25519.generateKeyPair();
      final ephemeralPrivateKey = Uint8List.fromList(keyPair.privateKey);
      final ephemeralPublicKey = Uint8List.fromList(keyPair.publicKey);

      final curve25519Pub = Uint8List(32);
      tweetnacl.TweetNaClExt.crypto_sign_ed25519_pk_to_x25519_pk(
        curve25519Pub,
        pubBuf,
      );

      final sharedKey = x25519.X25519(ephemeralPrivateKey, curve25519Pub);

      final secret = deriveSecret(sharedKey);
      final aesAuthEncryptInfos = aesAuthEncrypt(
        data,
        Uint8List.fromList(secret.aesKey!),
        Uint8List.fromList(secret.iv!),
      );

      return concatUint8List(<Uint8List>[
        ephemeralPublicKey,
        Uint8List.fromList(aesAuthEncryptInfos.tag!),
        Uint8List.fromList(aesAuthEncryptInfos.encrypted!),
      ]);
    case 1:
      final ec = elliptic.getP256();
      final privateKey = ec.generatePrivateKey();
      final publicKey = elliptic.PublicKey.fromHex(ec, uint8ListToHex(pubBuf));
      final sharedKey =
          Uint8List.fromList(ecdh.computeSecret(privateKey, publicKey));
      final secret = deriveSecret(sharedKey);
      final aesAuthEncryptInfos = aesAuthEncrypt(
        data,
        Uint8List.fromList(secret.aesKey!),
        Uint8List.fromList(secret.iv!),
      );
      return concatUint8List(<Uint8List>[
        Uint8List.fromList(hexToUint8List(privateKey.publicKey.toHex())),
        Uint8List.fromList(aesAuthEncryptInfos.tag!),
        Uint8List.fromList(aesAuthEncryptInfos.encrypted!),
      ]);

    case 2:
      final ec = elliptic.getSecp256k1();
      final privateKey = ec.generatePrivateKey();
      final publicKey = elliptic.PublicKey.fromHex(ec, uint8ListToHex(pubBuf));
      final sharedKey =
          Uint8List.fromList(ecdh.computeSecret(privateKey, publicKey));
      final secret = deriveSecret(sharedKey);
      final aesAuthEncryptInfos = aesAuthEncrypt(
        data,
        Uint8List.fromList(secret.aesKey!),
        Uint8List.fromList(
          secret.iv!,
        ),
      );
      return concatUint8List(<Uint8List>[
        Uint8List.fromList(hexToUint8List(privateKey.publicKey.toHex())),
        Uint8List.fromList(
          aesAuthEncryptInfos.tag!,
        ),
        Uint8List.fromList(aesAuthEncryptInfos.encrypted!),
      ]);

    default:
      throw 'Curve not supported';
  }
}