# Path: pycoind/util/pyaes/util.py
# def append_PKCS7_padding(data):
#     pad = 16 - (len(data) % 16)
#     return data + pad * chr(pad)
# 
# def strip_PKCS7_padding(data):
#     if len(data) % 16 != 0:
#         raise ValueError("invalid length")
# 
#     pad = ord(data[-1])
# 
#     if pad > 16:
#         raise ValueError("invalid padding byte")
# 
#     return data[:-pad]


from .aes import AESBlockModeOfOperation, AESSegmentModeOfOperation, AESStreamModeOfOperation
from .util import append_PKCS7_padding, strip_PKCS7_padding
#    _can_consume(size)
#       - Given a size, determine how many bytes could be consumed in
#         a single call to either the decrypt or encrypt method
#
#    _final_encrypt(data)
#       - call and return encrypt on this (last) chunk of data,
#         padding as necessary; this will always be at least 16
#         bytes unless the total incoming input was less than 16
#         bytes
#
#    _final_decrypt(data)
#       - same as _final_encrypt except for decrypt, for
#         stripping off padding
#


# ECB and CBC are block-only ciphers

def _block_can_consume(self, size):
    if size >= 16: return 16
    return 0

# After padding, we may have more than one block
def _block_final_encrypt(self, data):
    data = append_PKCS7_padding(data)
    if len(data) == 32:
        return self.encrypt(data[:16]) + self.encrypt(data[16:])
    return self.encrypt(data)

def _block_final_decrypt(self, data):

# Path: pycoind/util/pyaes/util.py
# def append_PKCS7_padding(data):
#     pad = 16 - (len(data) % 16)
#     return data + pad * chr(pad)
# 
# def strip_PKCS7_padding(data):
#     if len(data) % 16 != 0:
#         raise ValueError("invalid length")
# 
#     pad = ord(data[-1])
# 
#     if pad > 16:
#         raise ValueError("invalid padding byte")
# 
#     return data[:-pad]


# Path: pycoind/util/pyaes/blockfeeder.py
from .aes import AESBlockModeOfOperation, AESSegmentModeOfOperation, AESStreamModeOfOperation
from .util import append_PKCS7_padding, strip_PKCS7_padding

#    _can_consume(size)
#       - Given a size, determine how many bytes could be consumed in
#         a single call to either the decrypt or encrypt method
#
#    _final_encrypt(data)
#       - call and return encrypt on this (last) chunk of data,
#         padding as necessary; this will always be at least 16
#         bytes unless the total incoming input was less than 16
#         bytes
#
#    _final_decrypt(data)
#       - same as _final_encrypt except for decrypt, for
#         stripping off padding
#


# ECB and CBC are block-only ciphers

def _block_can_consume(self, size):
    if size >= 16: return 16
    return 0

# After padding, we may have more than one block
def _block_final_encrypt(self, data):
    data = append_PKCS7_padding(data)
    if len(data) == 32:
        return self.encrypt(data[:16]) + self.encrypt(data[16:])
    return self.encrypt(data)

def _block_final_decrypt(self, data):

    return strip_PKCS7_padding(self.decrypt(data))