/// Encrypt and decrypt using AES

/// Note: this example use Pointy Castle WITHOUT the registry.

import 'dart:convert';
import 'dart:math';
import 'dart:typed_data';

import 'package:pointycastle/export.dart';
import 'package:pointycastle/src/platform_check/platform_check.dart';

// Code convention: variable names starting with underscores are examples only,
// and should be implementated according to the needs of the program.

//----------------------------------------------------------------

Uint8List aesCbcEncrypt(
    Uint8List key, Uint8List iv, Uint8List paddedPlaintext) {
  if (![128, 192, 256].contains(key.length * 8)) {
    throw ArgumentError.value(key, 'key', 'invalid key length for AES');
  }
  if (iv.length * 8 != 128) {
    throw ArgumentError.value(iv, 'iv', 'invalid IV length for AES');
  }
  if (paddedPlaintext.length * 8 % 128 != 0) {
    throw ArgumentError.value(
        paddedPlaintext, 'paddedPlaintext', 'invalid length for AES');
  }

  // Create a CBC block cipher with AES, and initialize with key and IV

  final cbc = CBCBlockCipher(AESFastEngine())
    ..init(true, ParametersWithIV(KeyParameter(key), iv)); // true=encrypt

  // Encrypt the plaintext block-by-block

  final cipherText = Uint8List(paddedPlaintext.length); // allocate space

  var offset = 0;
  while (offset < paddedPlaintext.length) {
    offset += cbc.processBlock(paddedPlaintext, offset, cipherText, offset);
  }
  assert(offset == paddedPlaintext.length);

  return cipherText;
}
//----------------------------------------------------------------

Uint8List aesCbcDecrypt(Uint8List key, Uint8List iv, Uint8List cipherText) {
  if (![128, 192, 256].contains(key.length * 8)) {
    throw ArgumentError.value(key, 'key', 'invalid key length for AES');
  }
  if (iv.length * 8 != 128) {
    throw ArgumentError.value(iv, 'iv', 'invalid IV length for AES');
  }
  if (cipherText.length * 8 % 128 != 0) {
    throw ArgumentError.value(
        cipherText, 'cipherText', 'invalid length for AES');
  }

  // Create a CBC block cipher with AES, and initialize with key and IV

  final cbc = CBCBlockCipher(AESFastEngine())
    ..init(false, ParametersWithIV(KeyParameter(key), iv)); // false=decrypt

  // Decrypt the cipherText block-by-block

  final paddedPlainText = Uint8List(cipherText.length); // allocate space

  var offset = 0;
  while (offset < cipherText.length) {
    offset += cbc.processBlock(cipherText, offset, paddedPlainText, offset);
  }
  assert(offset == cipherText.length);

  return paddedPlainText;
}

//================================================================
// Supporting functions
//
// These are not a part of AES, so different standards may do these
// things differently.

//----------------------------------------------------------------
/// Represent bytes in hexadecimal
///
/// If a [separator] is provided, it is placed the hexadecimal characters
/// representing each byte. Otherwise, all the hexadecimal characters are
/// simply concatenated together.

String bin2hex(Uint8List bytes, {String? separator, int? wrap}) {
  var len = 0;
  final buf = StringBuffer();
  for (final b in bytes) {
    final s = b.toRadixString(16);
    if (buf.isNotEmpty && separator != null) {
      buf.write(separator);
      len += separator.length;
    }

    if (wrap != null && wrap < len + 2) {
      buf.write('\n');
      len = 0;
    }

    buf.write('${(s.length == 1) ? '0' : ''}$s');
    len += 2;
  }
  return buf.toString();
}

//----------------------------------------------------------------
// Decode a hexadecimal string into a sequence of bytes.

Uint8List hex2bin(String hexStr) {
  if (hexStr.length % 2 != 0) {
    throw const FormatException('not an even number of hexadecimal characters');
  }
  final result = Uint8List(hexStr.length ~/ 2);
  for (var i = 0; i < result.length; i++) {
    result[i] = int.parse(hexStr.substring(2 * i, 2 * (i + 1)), radix: 16);
  }
  return result;
}

//----------------------------------------------------------------
/// Added padding

Uint8List pad(Uint8List bytes, int blockSize) {
  // The PKCS #7 padding just fills the extra bytes with the same value.
  // That value is the number of bytes of padding there is.
  //
  // For example, something that requires 3 bytes of padding with append
  // [0x03, 0x03, 0x03] to the bytes. If the bytes is already a multiple of the
  // block size, a full block of padding is added.

  final padLength = blockSize - (bytes.length % blockSize);

  final padded = Uint8List(bytes.length + padLength)..setAll(0, bytes);
  PKCS7Padding().addPadding(padded, bytes.length);

  return padded;
}

//----------------------------------------------------------------
/// Remove padding

Uint8List unpad(Uint8List padded) =>
    padded.sublist(0, padded.length - PKCS7Padding().padCount(padded));

//----------------------------------------------------------------
/// Derive a key from a passphrase.
///
/// The [passPhrase] is an arbitrary length secret string.
///
/// The [bitLength] is the length of key produced. It determines whether
/// AES-128, AES-192, or AES-256 will be used. It must be one of those values.

Uint8List passphraseToKey(String passPhrase,
    {String salt = '', int iterations = 30000, required int bitLength}) {
  if (![128, 192, 256].contains(bitLength)) {
    throw ArgumentError.value(bitLength, 'bitLength', 'invalid for AES');
  }
  final numBytes = bitLength ~/ 8;

  final kd = PBKDF2KeyDerivator(HMac(SHA256Digest(), 64)) // 64 for SHA-256
    ..init(
        Pbkdf2Parameters(utf8.encode(salt) as Uint8List, iterations, numBytes));

  return kd.process(utf8.encode(passPhrase) as Uint8List);
}

//----------------------------------------------------------------
/// Generate random bytes to use as the Initialization Vector (IV).

Uint8List? generateRandomBytes(int numBytes) {
  if (_secureRandom == null) {
    // First invocation: create _secureRandom and seed it

    _secureRandom = FortunaRandom();
    _secureRandom!.seed(
        KeyParameter(Platform.instance.platformEntropySource().getBytes(32)));
  }

  // Use it to generate the random bytes

  final iv = _secureRandom!.nextBytes(numBytes);
  return iv;
}

FortunaRandom? _secureRandom;

//----------------------------------------------------------------
/// Run some of the test vectors from the NIST reference test vectors in the
/// AES Known Answer Test (KAT).
///
/// http://csrc.nist.gov/groups/STM/cavp/documents/aes/KAT_AES.zip

void katTest() {
  // Encryption tests

  [
    [
      'CBCGFSbox128.rsp: encrypt 0',
      '00000000000000000000000000000000', // key
      '00000000000000000000000000000000', // IV
      'f34481ec3cc627bacd5dc3fb08f273e6', // plaintext
      '0336763e966d92595a567cc9ce537f5e', // ciphertext
    ],
    [
      'CBCKeySbox128.rsp: encrypt 0',
      '10a58869d74be5a374cf867cfb473859',
      '00000000000000000000000000000000',
      '00000000000000000000000000000000',
      '6d251e6944b051e04eaa6fb4dbf78465',
    ],
    [
      'CBCVarKey128.rsp: encrypt 0',
      '80000000000000000000000000000000', // 8...
      '00000000000000000000000000000000',
      '00000000000000000000000000000000',
      '0edd33d3c621e546455bd8ba1418bec8',
    ],
    [
      'CBCVarTxt128.rsp: encrypt 0',
      '00000000000000000000000000000000',
      '00000000000000000000000000000000',
      '80000000000000000000000000000000', // 8...
      '3ad78e726c1ec02b7ebfe92b23d9ec34',
    ],
    [
      'CBCGFSbox192.rsp: encrypt 0',
      '000000000000000000000000000000000000000000000000',
      '00000000000000000000000000000000',
      '1b077a6af4b7f98229de786d7516b639',
      '275cfc0413d8ccb70513c3859b1d0f72',
    ],
    [
      'CBCGFSbox256.rsp: encrypt 0',
      '0000000000000000000000000000000000000000000000000000000000000000',
      '00000000000000000000000000000000',
      '014730f80ac625fe84f026c60bfd547d',
      '5c9d844ed46f9885085e5d6a4f94c7d7',
    ]
  ].forEach((testCase) {
    final name = testCase[0];
    final key = testCase[1];
    final iv = testCase[2];
    final plaintext = testCase[3];
    final cipherText = testCase[4];

    final cipher = aesCbcEncrypt(hex2bin(key), hex2bin(iv), hex2bin(plaintext));
    if (bin2hex(cipher) != cipherText) {
      print('$name: failed');
      throw AssertionError('$name: failed');
    }
  });

  // Decryption tests

  [
    [
      'CBCGFSbox128.rsp: decrypt 0',
      '00000000000000000000000000000000', // key
      '00000000000000000000000000000000', // IV
      '0336763e966d92595a567cc9ce537f5e', // ciphertext
      'f34481ec3cc627bacd5dc3fb08f273e6', // plaintext
    ],
    [
      'CBCGFSbox192.rsp: decrypt 3',
      '000000000000000000000000000000000000000000000000', // key
      '00000000000000000000000000000000', // IV
      '4f354592ff7c8847d2d0870ca9481b7c', // ciphertext
      '51719783d3185a535bd75adc65071ce1', // plaintext
    ],
    [
      'CBCGFSbox256.rsp: decrypt 4',
      '0000000000000000000000000000000000000000000000000000000000000000', // key
      '00000000000000000000000000000000', // IV
      '1bc704f1bce135ceb810341b216d7abe', // ciphertext
      '91fbef2d15a97816060bee1feaa49afe', // plaintext
    ]
  ].forEach((testCase) {
    final name = testCase[0];
    final key = testCase[1];
    final iv = testCase[2];
    final cipherText = testCase[3];
    final plaintext = testCase[4];

    final plain = aesCbcDecrypt(hex2bin(key), hex2bin(iv), hex2bin(cipherText));
    if (bin2hex(plain) != plaintext) {
      print('$name: failed');
      throw AssertionError('$name: failed');
    }
  });
}

//----------------------------------------------------------------
/// Demonstrates encryption and decryption.
///
/// This uses the custom key derivation, IV generation and padding functions
/// that have been implemented in this program.
///
/// The [aesSize] is either 128, 192 or 256 to use AES-128, AES-192 or AES-256.

void encryptAndDecryptTest(int aesSize) {
  const textToEncrypt = '''
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis
nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore
eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt
in culpa qui officia deserunt mollit anim id est laborum.
''';
  const passphrase = 'p@ssw0rd';

  final randomSalt = latin1.decode(generateRandomBytes(32)!);

  // IV for both encrypt and decrypt (must ALWAYS be 128 bits for AES)
  final iv = generateRandomBytes(128 ~/ 8)!;

  // Encrypt (note must ALWAYS pad to 128-bit block size for AES)

  final cipherText = aesCbcEncrypt(
      passphraseToKey(passphrase, salt: randomSalt, bitLength: aesSize),
      iv,
      pad(utf8.encode(textToEncrypt) as Uint8List, 128));

  // If the encrypted data was to be stored or transmitted to the receiver,
  // it will have to store the cipher-text, Initialization Vector (IV) and
  // all the parameters used to convert the passphrase into a key (in this
  // example, that would be the salt and bit-length).

  // Decrypt

  final paddedDecryptedBytes = aesCbcDecrypt(
      passphraseToKey(passphrase, salt: randomSalt, bitLength: aesSize),
      iv,
      cipherText);
  final decryptedBytes = unpad(paddedDecryptedBytes);
  final decryptedText = utf8.decode(decryptedBytes);

  // Check decryption produced the original plaintext

  if (decryptedText != textToEncrypt) {
    print('decryption did not produce the original plaintext');
    throw AssertionError('encrypt/decrypt failed');
  }
}

//----------------------------------------------------------------

void main(List<String> args) {
  if (args.contains('-h') || args.contains('--help')) {
    print('Usage: aes-cbc-direct');
    return;
  }

  katTest();
  encryptAndDecryptTest(128);
  encryptAndDecryptTest(192);
  encryptAndDecryptTest(256);
  print('Ok');
}
