// See file LICENSE for more information.

library impl.block_cipher.modes.gctr;

import 'dart:typed_data';

import 'package:pointycastle/api.dart';
import 'package:pointycastle/src/impl/base_block_cipher.dart';
import 'package:pointycastle/src/registry/registry.dart';
import 'package:pointycastle/src/ufixnum.dart';

/// Implementation of GOST 28147 OFB counter mode (GCTR) on top of a [BlockCipher].
class GCTRBlockCipher extends BaseBlockCipher {
  /// Intended for internal use.
  static final FactoryConfig factoryConfig = DynamicFactoryConfig.suffix(
      BlockCipher,
      '/GCTR',
      (_, final Match match) => () {
            var underlying = BlockCipher(match.group(1)!);
            return GCTRBlockCipher(underlying);
          });

  static const C1 = 16843012; //00000001000000010000000100000100
  static const C2 = 16843009; //00000001000000010000000100000001

  final BlockCipher _underlyingCipher;

  late Uint8List _iv;
  Uint8List? _ofbV;
  Uint8List? _ofbOutV;

  bool _firstStep = true;
  late int _n3;
  late int _n4;

  GCTRBlockCipher(this._underlyingCipher) {
    if (blockSize != 8) {
      throw ArgumentError('GCTR can only be used with 64 bit block ciphers');
    }

    _iv = Uint8List(_underlyingCipher.blockSize);
    _ofbV = Uint8List(_underlyingCipher.blockSize);
    _ofbOutV = Uint8List(_underlyingCipher.blockSize);
  }

  @override
  int get blockSize => _underlyingCipher.blockSize;
  @override
  String get algorithmName => '${_underlyingCipher.algorithmName}/GCTR';
  @override
  void reset() {
    _ofbV!.setRange(0, _iv.length, _iv);
    _underlyingCipher.reset();
  }

  /// Initialise the cipher and, possibly, the initialisation vector (IV).
  /// If an IV isn't passed as part of the parameter, the IV will be all zeros.
  /// An IV which is too short is handled in FIPS compliant fashion.
  ///
  /// @param encrypting if true the cipher is initialised for
  ///  encryption, if false for decryption. //ignored by this CTR mode
  /// @param params the key and other data required by the cipher.
  /// @exception IllegalArgumentException if the params argument is
  /// inappropriate.
  @override
  void init(bool encrypting, CipherParameters? params) {
    _firstStep = true;
    _n3 = 0;
    _n4 = 0;

    if (params is ParametersWithIV) {
      var ivParam = params;
      var iv = ivParam.iv;

      if (iv.length < _iv.length) {
        // prepend the supplied IV with zeros (per FIPS PUB 81)
        var offset = _iv.length - iv.length;
        _iv.fillRange(0, offset, 0);
        _iv.setRange(offset, _iv.length, iv);
      } else {
        _iv.setRange(0, _iv.length, iv);
      }

      reset();

      // if params is null we reuse the current working key.
      if (ivParam.parameters != null) {
        _underlyingCipher.init(true, ivParam.parameters);
      }
    } else {
      // TODO: make this behave in a standard way (as the other modes of operation)
      reset();

      // if params is null we reuse the current working key.
      if (params != null) {
        _underlyingCipher.init(true, params);
      }
    }
  }

  @override
  int processBlock(Uint8List inp, int inpOff, Uint8List out, int outOff) {
    if ((inpOff + blockSize) > inp.length) {
      throw ArgumentError('Input buffer too short');
    }

    if ((outOff + blockSize) > out.length) {
      throw ArgumentError('Output buffer too short');
    }

    if (_firstStep) {
      _firstStep = false;
      _underlyingCipher.processBlock(_ofbV!, 0, _ofbOutV!, 0);
      _n3 = _bytesToint(_ofbOutV, 0);
      _n4 = _bytesToint(_ofbOutV, 4);
    }
    _n3 += C2;
    _n4 += C1;
    _intTobytes(_n3, _ofbV, 0);
    _intTobytes(_n4, _ofbV, 4);

    _underlyingCipher.processBlock(_ofbV!, 0, _ofbOutV!, 0);

    // XOR the ofbV with the plaintext producing the cipher text (and the next input block).
    for (var i = 0; i < blockSize; i++) {
      out[outOff + i] = _ofbOutV![i] ^ inp[inpOff + i];
    }

    // change over the input block.
    var offset = _ofbV!.length - blockSize;
    _ofbV!.setRange(0, offset, _ofbV!.sublist(blockSize));
    _ofbV!.setRange(offset, _ofbV!.length, _ofbOutV!);

    return blockSize;
  }

  int _bytesToint(Uint8List? inp, int inpOff) {
    return unpack32(inp, inpOff, Endian.little);
  }

  void _intTobytes(int num, Uint8List? out, int outOff) {
    pack32(num, out, outOff, Endian.little);
  }
}
