ecEncrypt function
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, {
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';
}
}