ecDecrypt function
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';
}
}