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(data, 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 = hexToUint8List(data);
} else {
data = Uint8List.fromList(utf8.encode(data));
}
}
if (publicKey is String) {
if (isHex(publicKey)) {
publicKey = 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 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>[
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>[
hexToUint8List(privateKey.publicKey.toHex()),
aesAuthEncryptInfos.tag,
aesAuthEncryptInfos.encrypted
]);
default:
throw 'Curve not supported';
}
}