AESEncrypt method

List<int> AESEncrypt(
  1. List<int> messageBuffer,
  2. SVPrivateKey senderPrivateKey,
  3. SVPublicKey recipientPublicKey
)

Perform an ECIES encryption using AES for the symmetric cipher.

messageBuffer - The buffer to encrypt. Note that the buffer in this instance has a very specific encoding format called "BIE1" or "Electrum ECIES". It is in essence a serialization format with a built-in checksum.

  • bytes 0 - 4 : Magic value. Literally "BIE1".
  • bytes 4 - 37 : Compressed Public Key
  • bytes 37 - (length - 32) : Actual cipherText
  • bytes length - 32 : (last 32 bytes) Checksum value

senderPrivateKey - Private Key of the sending party

recipientPublicKey - Public Key of the party who can decrypt the message

Implementation

List<int> AESEncrypt(List<int> messageBuffer, SVPrivateKey senderPrivateKey, SVPublicKey recipientPublicKey){

  //Encryption requires derivation of a cipher using the other party's Public Key
  // Bob is sender, Alice is recipient of encrypted message
  // Qb = k o Qa, where
  //     Qb = Bob's Public Key;
  //     k = Bob's private key;
  //     Qa = Alice's public key;

  final ECPoint S = (recipientPublicKey.point * senderPrivateKey.privateKey)!; //point multiplication
  final pubkeyS = SVPublicKey.fromXY(S.x!.toBigInteger()!, S.y!.toBigInteger()!);
  final pubkeyBuffer = HEX.decode(pubkeyS.getEncoded(true));
  final pubkeyHash = SHA512Digest().process(pubkeyBuffer as Uint8List);

  //initialization vector parameters
  final iv = pubkeyHash.sublist(0, 16);
  final kE = pubkeyHash.sublist(16, 32);
  final kM = pubkeyHash.sublist(32, 64);

  CipherParameters params = PaddedBlockCipherParameters(ParametersWithIV(KeyParameter(kE), iv), null);
  BlockCipher encryptionCipher = PaddedBlockCipher('AES/CBC/PKCS7');
  encryptionCipher.init(true, params);

  final cipherText = encryptionCipher.process(messageBuffer as Uint8List);
  final magic = utf8.encode('BIE1');

  final encodedBuffer = Uint8List.fromList(magic + HEX.decode(senderPrivateKey.publicKey.toHex()) + cipherText);

  //calc checksum
  final hmac = _calculateHmac(kM, encodedBuffer);

  return encodedBuffer + hmac;
}