ecEncrypt function

Uint8List ecEncrypt(
  1. dynamic data,
  2. dynamic publicKey
)

Encrypt a data for a given public key using ECIES algorithm @param {String | Uint8List} data Data to encrypt @param {String | Uint8List} publicKey Public key for the shared secret encryption

Implementation

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

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

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

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

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

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

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

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

      final Secret secret = deriveSecret(sharedKey);
      final AesAuthEncryptInfos aesAuthEncryptInfos =
          aesAuthEncrypt(data, secret.aesKey, secret.iv);

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

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

    default:
      throw 'Curve not supported';
  }
}