   'use strict'
 
   # libraries
-  Forge = require 'forge'
+  forge = require 'forge'
 
   # kryptnostic
   AbstractCryptoService = require 'kryptnostic.abstract-crypto-service'


  # constants
  BITS_PER_BYTE = 8

  logger = Logger.get('AesCryptoService')

  class AesCryptoService



      if not @key
        logger.info('no key passed! generating a key.')
        @key = forge.random.getBytesSync(@cypher.keySize / BITS_PER_BYTE) 
      @abstractCryptoService = new AbstractCryptoService(@cypher)

    encrypt: (plaintext) ->

      iv         = forge.random.getBytesSync(AesCryptoService.BLOCK_CIPHER_KEY_SIZE)
      salt       = forge.random.getBytesSync(0)
      ciphertext = @abstractCryptoService.encrypt(@key, iv, plaintext)
      props = {
        iv       : btoa(iv)
        salt     : btoa(salt)
        contents : btoa(ciphertext)
      }

      hmacHash = computeHMAC(@key, iv, salt, ciphertext)
      if hmacHash?
        props.tag = btoa(hmacHash)

      return new BlockCiphertext(props)

    encryptUint8Array: (uint8) ->

      iv         = forge.random.getBytesSync(AesCryptoService.BLOCK_CIPHER_KEY_SIZE)
      salt       = forge.random.getBytesSync(0)
      buffer     = forge.util.createBuffer(uint8)
      ciphertext = @abstractCryptoService.encryptBuffer(@key, iv, buffer)
      props = {
        iv       : btoa(iv)
        salt     : btoa(salt)
        contents : btoa(ciphertext)
      }

      hmacHash = computeHMAC(@key, iv, salt, ciphertext)
      if hmacHash?
        props.tag = btoa(hmacHash)

      return new BlockCiphertext(props)

    decrypt: (blockCipherText) ->

      Validator.validate(blockCipherText, BlockCiphertext, BLOCK_CIPHERTEXT_SCHEMA)

      iv         = atob(blockCipherText.iv)
      salt       = atob(blockCipherText.salt)
      ciphertext = atob(blockCipherText.contents)

      if _.isEmpty(blockCipherText.tag)
        logger.warn('BlockCipherText tag missing')
      else
        tag = atob(blockCipherText.tag)
        isValid = checkDataIntegrity(@key, iv, salt, ciphertext, tag)
        if not isValid
          throw new Error('BlockCipherText data integrity check failed')

      return @abstractCryptoService.decrypt(@key, iv, ciphertext)

    decryptToUint8Array: (blockCipherText) ->

