Example #1
0
def cbc_decrypt(key, data, pad=True, sbox=DEFAULT_SBOX, mesh=False):
    """ CBC decryption mode of operation

    :param bytes key: encryption key
    :param bytes data: ciphertext
    :type bool pad: perform ISO/IEC 7816-4 unpadding after decryption
    :param sbox: S-box parameters to use
    :type sbox: str, SBOXES'es key
    :param bool mesh: enable key meshing
    :returns: plaintext
    :rtype: bytes
    """
    validate_key(key)
    validate_sbox(sbox)
    if not data or len(data) % BLOCKSIZE != 0:
        raise ValueError("Data is not blocksize aligned")
    if len(data) < 2 * BLOCKSIZE:
        raise ValueError("There is no either data, or IV in ciphertext")
    iv = data[:BLOCKSIZE]
    plaintext = []
    for i in xrange(BLOCKSIZE, len(data), BLOCKSIZE):
        if (
                mesh and
                (i - BLOCKSIZE) >= MESH_MAX_DATA and
                (i - BLOCKSIZE) % MESH_MAX_DATA == 0
        ):
            key, _ = meshing(key, iv, sbox=sbox)
        plaintext.append(strxor(
            ns2block(decrypt(sbox, key, block2ns(data[i:i + BLOCKSIZE]))),
            data[i - BLOCKSIZE:i],
        ))
    if pad:
        plaintext[-1] = unpad2(plaintext[-1], BLOCKSIZE)
    return b"".join(plaintext)
Example #2
0
def cnt(key, data, iv=8 * b'\x00', sbox=DEFAULT_SBOX):
    """ Counter mode of operation

    :param bytes key: encryption key
    :param bytes data: plaintext
    :param iv: initialization vector
    :type iv: bytes, BLOCKSIZE length
    :param sbox: S-box parameters to use
    :type sbox: str, SBOXES'es key
    :return: ciphertext
    :rtype: bytes

    For decryption you use the same function again.
    """
    validate_key(key)
    validate_iv(iv)
    validate_sbox(sbox)
    if not data:
        raise ValueError("No data supplied")
    n2, n1 = encrypt(sbox, key, block2ns(iv))
    size, data = _pad(data)
    gamma = []
    for _ in xrange(0, len(data), BLOCKSIZE):
        n1 = addmod(n1, C2, 2 ** 32)
        n2 = addmod(n2, C1, 2 ** 32 - 1)
        gamma.append(ns2block(encrypt(sbox, key, (n1, n2))))
    return strxor(b''.join(gamma), data[:size])
Example #3
0
    def digest(self):
        """ Get hash of the provided data
        """
        hsh = BLOCKSIZE * (b'\x01' if self.digest_size == 256 else b'\x00')
        chk = BLOCKSIZE * b'\x00'
        n = 0
        data = self.data
        for i in xrange(0, len(data) // BLOCKSIZE * BLOCKSIZE, BLOCKSIZE):
            block = data[i:i + BLOCKSIZE]
            hsh = g(n, hsh, block)
            chk = add512bit(chk, block)
            n += 512

        # Padding
        padblock_size = len(data) * 8 - n
        data += b'\x01'
        padlen = BLOCKSIZE - len(data) % BLOCKSIZE
        if padlen != BLOCKSIZE:
            data += b'\x00' * padlen

        hsh = g(n, hsh, data[-BLOCKSIZE:])
        n += padblock_size
        chk = add512bit(chk, data[-BLOCKSIZE:])
        hsh = g(0, hsh, pack("<Q", n) + 56 * b'\x00')
        hsh = g(0, hsh, chk)
        if self.digest_size == 256:
            return hsh[32:]
        return hsh
Example #4
0
def cbc_encrypt(key, data, iv=8 * b"\x00", pad=True, sbox=DEFAULT_SBOX, mesh=False):
    """ CBC encryption mode of operation

    :param bytes key: encryption key
    :param bytes data: plaintext
    :param iv: initialization vector
    :type iv: bytes, BLOCKSIZE length
    :type bool pad: perform ISO/IEC 7816-4 padding
    :param sbox: S-box parameters to use
    :type sbox: str, SBOXES'es key
    :param bool mesh: enable key meshing
    :returns: ciphertext
    :rtype: bytes

    34.13-2015 padding method 2 is used.
    """
    validate_key(key)
    validate_iv(iv)
    validate_sbox(sbox)
    if not data:
        raise ValueError("No data supplied")
    if pad:
        data = pad2(data, BLOCKSIZE)
    if len(data) % BLOCKSIZE != 0:
        raise ValueError("Data is not blocksize aligned")
    ciphertext = [iv]
    for i in xrange(0, len(data), BLOCKSIZE):
        if mesh and i >= MESH_MAX_DATA and i % MESH_MAX_DATA == 0:
            key, _ = meshing(key, iv, sbox=sbox)
        ciphertext.append(ns2block(encrypt(sbox, key, block2ns(
            strxor(ciphertext[-1], data[i:i + BLOCKSIZE])
        ))))
    return b"".join(ciphertext)
Example #5
0
def cbc_encrypt(key, data, iv=8 * b'\x00', pad=True, sbox=DEFAULT_SBOX):
    """ CBC encryption mode of operation

    :param bytes key: encryption key
    :param bytes data: plaintext
    :param iv: initialization vector
    :type iv: bytes, BLOCKSIZE length
    :type bool pad: perform ISO/IEC 7816-4 padding
    :param sbox: S-box parameters to use
    :type sbox: str, SBOXES'es key
    :return: ciphertext
    :rtype: bytes

    Padding is following: append 0x80 and then necessary number of zeros.
    """
    validate_key(key)
    validate_iv(iv)
    validate_sbox(sbox)
    if not data:
        raise ValueError("No data supplied")
    if pad:
        _, data = _pad(data + b'\x80')
    if len(data) % BLOCKSIZE != 0:
        raise ValueError("Data is not blocksize aligned")
    ciphertext = [iv]
    for i in xrange(0, len(data), BLOCKSIZE):
        ciphertext.append(ns2block(encrypt(sbox, key, block2ns(
            strxor(ciphertext[-1], data[i:i + BLOCKSIZE])
        ))))
    return b''.join(ciphertext)
Example #6
0
    def S(self, A):
        Pi = ( \
            252, 238, 221,  17, 207, 110,  49,  22, 251, 196, 250, \
            218,  35, 197,   4,  77, 233, 119, 240, 219, 147,  46, \
            153, 186,  23,  54, 241, 187,  20, 205,  95, 193, 249, \
             24, 101,  90, 226,  92, 239,  33, 129,  28,  60,  66, \
            139,   1, 142,  79,   5, 132,   2, 174, 227, 106, 143, \
            160,   6,  11, 237, 152, 127, 212, 211,  31, 235,  52, \
             44,  81, 234, 200,  72, 171, 242,  42, 104, 162, 253, \
             58, 206, 204, 181, 112,  14,  86,   8,  12, 118,  18, \
            191, 114,  19,  71, 156, 183,  93, 135,  21, 161, 150, \
             41,  16, 123, 154, 199, 243, 145, 120, 111, 157, 158, \
            178, 177,  50, 117,  25,  61, 255,  53, 138, 126, 109, \
             84, 198, 128, 195, 189,  13,  87, 223, 245,  36, 169, \
             62, 168,  67, 201, 215, 121, 214, 246, 124,  34, 185, \
              3, 224,  15, 236, 222, 122, 148, 176, 188, 220, 232, \
             40,  80,  78,  51,  10,  74, 167, 151,  96, 115,  30, \
              0,  98,  68,  26, 184,  56, 130, 100, 159,  38,  65, \
            173,  69,  70, 146,  39,  94,  85,  47, 140, 163, 165, \
            125, 105, 213, 149,  59,   7,  88, 179,  64, 134, 172, \
             29, 247,  48,  55, 107, 228, 136, 217, 231, 137, 225, \
             27, 131,  73,  76,  63, 248, 254, 141,  83, 170, 144, \
            202, 216, 133,  97,  32, 113, 103, 164,  45,  43,   9, \
             91, 203, 155,  37, 208, 190, 229, 108,  82,  89, 166, \
            116, 210, 230, 244, 180, 192, 209, 102, 175, 194,  57, \
            75,  99, 182)

        result = [0] * 64
        for i in xrange(0, 64):
            result[i] = Pi[A[i]]

        return result
Example #7
0
def pbkdf2(hasher, password, salt, iterations, dklen):
    """PBKDF2 implementation suitable for GOST R 34.11-94/34.11-2012
    """
    inner = hasher()
    outer = hasher()
    password = password + b"\x00" * (inner.block_size - len(password))
    inner.update(strxor(password, len(password) * b"\x36"))
    outer.update(strxor(password, len(password) * b"\x5C"))

    def prf(msg):
        icpy = inner.copy()
        ocpy = outer.copy()
        icpy.update(msg)
        ocpy.update(icpy.digest())
        return ocpy.digest()

    dkey = b''
    loop = 1
    while len(dkey) < dklen:
        prev = prf(salt + long2bytes(loop, 4))
        rkey = bytes2long(prev)
        for _ in xrange(iterations - 1):
            prev = prf(prev)
            rkey ^= bytes2long(prev)
        loop += 1
        dkey += long2bytes(rkey, inner.digest_size)
    return dkey[:dklen]
Example #8
0
    def digest(self):
        """ Get hash of the provided data
        """
        hsh = BLOCKSIZE * (b"\x01" if self.digest_size == 32 else b"\x00")
        chk = bytearray(BLOCKSIZE * b"\x00")
        n = 0
        data = self.data
        for i in xrange(0, len(data) // BLOCKSIZE * BLOCKSIZE, BLOCKSIZE):
            block = data[i:i + BLOCKSIZE]
            hsh = g(n, hsh, block)
            chk = add512bit(chk, block)
            n += 512

        # Padding
        padblock_size = len(data) * 8 - n
        data += b"\x01"
        padlen = BLOCKSIZE - len(data) % BLOCKSIZE
        if padlen != BLOCKSIZE:
            data += b"\x00" * padlen

        hsh = g(n, hsh, data[-BLOCKSIZE:])
        n += padblock_size
        chk = add512bit(chk, data[-BLOCKSIZE:])
        hsh = g(0, hsh, pack("<Q", n) + 56 * b"\x00")
        hsh = g(0, hsh, chk)
        return hsh[-self._digest_size:]
Example #9
0
def cbc_decrypt(key, data, pad=True, sbox=DEFAULT_SBOX):
    """ CBC decryption mode of operation

    :param bytes key: encryption key
    :param bytes data: ciphertext
    :param iv: initialization vector
    :type iv: bytes, BLOCKSIZE length
    :type bool pad: perform ISO/IEC 7816-4 unpadding after decryption
    :param sbox: S-box parameters to use
    :type sbox: str, SBOXES'es key
    :return: plaintext
    :rtype: bytes
    """
    validate_key(key)
    validate_sbox(sbox)
    if not data or len(data) % BLOCKSIZE != 0:
        raise ValueError("Data is not blocksize aligned")
    if len(data) < 2 * BLOCKSIZE:
        raise ValueError("There is no either data, or IV in ciphertext")
    plaintext = []
    for i in xrange(BLOCKSIZE, len(data), BLOCKSIZE):
        plaintext.append(strxor(
            ns2block(decrypt(sbox, key, block2ns(data[i:i + BLOCKSIZE]))),
            data[i - BLOCKSIZE:i],
        ))
    if pad:
        last_block = bytearray(plaintext[-1])
        pad_index = last_block.rfind(b'\x80')
        if pad_index == -1:
            raise ValueError("Invalid padding")
        for c in last_block[pad_index + 1:]:
            if c != 0:
                raise ValueError("Invalid padding")
        plaintext[-1] = bytes(last_block[:pad_index])
    return b''.join(plaintext)
Example #10
0
def cfb_encrypt(key, data, iv=8 * b'\x00', sbox=DEFAULT_SBOX, mesh=False):
    """ CFB encryption mode of operation

    :param bytes key: encryption key
    :param bytes data: plaintext
    :param iv: initialization vector
    :type iv: bytes, BLOCKSIZE length
    :param sbox: S-box parameters to use
    :type sbox: str, SBOXES'es key
    :param bool mesh: enable key meshing
    :return: ciphertext
    :rtype: bytes
    """
    validate_key(key)
    validate_iv(iv)
    validate_sbox(sbox)
    if not data:
        raise ValueError("No data supplied")
    size, data = _pad(data)
    ciphertext = [iv]
    for i in xrange(0, len(data), BLOCKSIZE):
        if mesh and i >= MESH_MAX_DATA and i % MESH_MAX_DATA == 0:
            key, iv = meshing(key, ciphertext[-1], sbox=sbox)
            ciphertext.append(strxor(
                data[i:i + BLOCKSIZE],
                ns2block(encrypt(sbox, key, block2ns(iv))),
            ))
            continue
        ciphertext.append(strxor(
            data[i:i + BLOCKSIZE],
            ns2block(encrypt(sbox, key, block2ns(ciphertext[-1]))),
        ))
    return b''.join(ciphertext[1:])[:size]
Example #11
0
def _step(hin, m, sbox):
    """ Step function

    H_out = f(H_in, m)
    """
    # Generate keys
    u = hin
    v = m
    w = strxor(hin, m)
    k1 = P(w)

    u = strxor(A(u), C2)
    v = A(A(v))
    w = strxor(u, v)
    k2 = P(w)

    u = strxor(A(u), C3)
    v = A(A(v))
    w = strxor(u, v)
    k3 = P(w)

    u = strxor(A(u), C4)
    v = A(A(v))
    w = strxor(u, v)
    k4 = P(w)

    # Encipher
    h4, h3, h2, h1 = hin[0:8], hin[8:16], hin[16:24], hin[24:32]
    s1 = ns2block(encrypt(sbox, k1[::-1], block2ns(h1[::-1])))[::-1]
    s2 = ns2block(encrypt(sbox, k2[::-1], block2ns(h2[::-1])))[::-1]
    s3 = ns2block(encrypt(sbox, k3[::-1], block2ns(h3[::-1])))[::-1]
    s4 = ns2block(encrypt(sbox, k4[::-1], block2ns(h4[::-1])))[::-1]
    s = b"".join((s4, s3, s2, s1))

    # Permute
    # H_out = chi^61(H_in XOR chi(m XOR chi^12(S)))
    x = s
    for _ in xrange(12):
        x = _chi(x)
    x = strxor(x, m)
    x = _chi(x)
    x = strxor(hin, x)
    for _ in xrange(61):
        x = _chi(x)
    return x
Example #12
0
    def FromString(self, string, hashtype):

        h = [1 if hashtype == 256 else 0] * 64

        e = [0] * 64
        N = [0] * 64
        Z = [0] * 64
        m = [0] * 64

        start = 0
        while start + 64 <= len(string):
            for i in xrange(0, 64):
                m[63 - i] = ord(string[start + i])

            h = self.g(N, h, m)

            e[62] = (512 >> 8)
            e[63] = (512 & 0xFF)
            N = self.plus(N, e)

            Z = self.plus(Z, m)

            start += 64

        sz = len(string) - start
        m = [0] * 64
        for i in xrange(0, sz):
            m[63 - i] = ord(string[start + i])
        m[64 - sz - 1] = 1

        h = self.g(N, h, m)
        e[62] = (sz * 8) >> 8
        e[63] = (sz * 8) & 0xFF
        N = self.plus(N, e)
        Z = self.plus(Z, m)

        e[62] = 0
        e[63] = 0
        h = self.g(e, h, N)

        h = self.g(e, h, Z)

        return ''.join(
            reversed([('%0.2X' % a)
                      for a in h][:(32 if hashtype == 256 else 64)]))
Example #13
0
def ecb_encrypt(encrypter, bs, pt):
    """ECB encryption mode of operation

    :param encrypter: Encrypting function, that takes block as an input
    :param int bs: cipher's blocksize
    :param bytes pt: already padded plaintext
    """
    if not pt or len(pt) % bs != 0:
        raise ValueError("Plaintext is not blocksize aligned")
    ct = []
    for i in xrange(0, len(pt), bs):
        ct.append(encrypter(pt[i:i + bs]))
    return b"".join(ct)
Example #14
0
def ecb_decrypt(decrypter, bs, ct):
    """ECB decryption mode of operation

    :param decrypter: Decrypting function, that takes block as an input
    :param int bs: cipher's blocksize
    :param bytes ct: ciphertext
    """
    if not ct or len(ct) % bs != 0:
        raise ValueError("Ciphertext is not blocksize aligned")
    pt = []
    for i in xrange(0, len(ct), bs):
        pt.append(decrypter(ct[i:i + bs]))
    return b"".join(pt)
Example #15
0
def cfb_encrypt(encrypter, bs, pt, iv):
    """CFB encryption mode of operation

    :param encrypter: Encrypting function, that takes block as an input
    :param int bs: cipher's blocksize
    :param bytes pt: plaintext
    :param bytes iv: blocksize-sized initialization vector
    """
    if len(iv) < bs or len(iv) % bs != 0:
        raise ValueError("Invalid IV size")
    r = [iv[i:i + bs] for i in range(0, len(iv), bs)]
    ct = []
    for i in xrange(0, len(pt) + pad_size(len(pt), bs), bs):
        ct.append(strxor(encrypter(r[0]), pt[i:i + bs]))
        r = r[1:] + [ct[-1]]
    return b"".join(ct)
Example #16
0
    def P(self, A):

        tau = ( \
            0,  8, 16, 24, 32, 40, 48, 56, \
            1,  9, 17, 25, 33, 41, 49, 57, \
            2, 10, 18, 26, 34, 42, 50, 58, \
            3, 11, 19, 27, 35, 43, 51, 59, \
            4, 12, 20, 28, 36, 44, 52, 60, \
            5, 13, 21, 29, 37, 45, 53, 61, \
            6, 14, 22, 30, 38, 46, 54, 62, \
            7, 15, 23, 31, 39, 47, 55, 63)

        result = [0] * 64
        for i in xrange(0, 64):
            result[i] = A[tau[i]]

        return result
Example #17
0
def ofb(encrypter, bs, data, iv):
    """OFB mode of operation

    :param encrypter: Encrypting function, that takes block as an input
    :param int bs: cipher's blocksize
    :param bytes data: plaintext/ciphertext
    :param bytes iv: blocksize-sized initialization vector

    For decryption you use the same function again.
    """
    if len(iv) < bs or len(iv) % bs != 0:
        raise ValueError("Invalid IV size")
    r = [iv[i:i + bs] for i in range(0, len(iv), bs)]
    result = []
    for i in xrange(0, len(data) + pad_size(len(data), bs), bs):
        r = r[1:] + [encrypter(r[0])]
        result.append(strxor(r[-1], data[i:i + bs]))
    return b"".join(result)
Example #18
0
def ctr(encrypter, bs, data, iv):
    """Counter mode of operation

    :param encrypter: Encrypting function, that takes block as an input
    :param int bs: cipher's blocksize
    :param bytes data: plaintext/ciphertext
    :param bytes iv: half blocksize-sized initialization vector

    For decryption you use the same function again.
    """
    if len(iv) != bs // 2:
        raise ValueError("Invalid IV size")
    stream = []
    ctr_value = 0
    for _ in xrange(0, len(data) + pad_size(len(data), bs), bs):
        stream.append(encrypter(iv + long2bytes(ctr_value, bs // 2)))
        ctr_value += 1
    return strxor(b"".join(stream), data)
Example #19
0
def cbc_decrypt(decrypter, bs, ct, iv):
    """CBC decryption mode of operation

    :param decrypter: Decrypting function, that takes block as an input
    :param int bs: cipher's blocksize
    :param bytes ct: ciphertext
    :param bytes iv: blocksize-sized initialization vector
    """
    if not ct or len(ct) % bs != 0:
        raise ValueError("Ciphertext is not blocksize aligned")
    if len(iv) < bs or len(iv) % bs != 0:
        raise ValueError("Invalid IV size")
    r = [iv[i:i + bs] for i in range(0, len(iv), bs)]
    pt = []
    for i in xrange(0, len(ct), bs):
        blk = ct[i:i + bs]
        pt.append(strxor(r[0], decrypter(blk)))
        r = r[1:] + [blk]
    return b"".join(pt)
Example #20
0
    def digest(self):
        """ Get MAC tag of supplied data

        You have to provide at least single byte of data.
        If you want to produce tag length of 3 bytes, then
        ``digest()[:3]``.
        """
        if not self.data:
            raise ValueError("No data processed")
        _, data = _pad(self.data)
        prev = block2ns(self.iv)[::-1]
        for i in xrange(0, len(data), BLOCKSIZE):
            prev = xcrypt(
                SEQ_MAC, self.sbox, self.key, block2ns(strxor(
                    data[i:i + BLOCKSIZE],
                    ns2block(prev),
                )),
            )[::-1]
        return ns2block(prev)
Example #21
0
def ecb(key, data, action, sbox=DEFAULT_SBOX):
    """ ECB mode of operation

    :param bytes key: encryption key
    :param data: plaintext
    :type data: bytes, multiple of BLOCKSIZE
    :param func action: encrypt/decrypt
    :param sbox: S-box parameters to use
    :type sbox: str, SBOXES'es key
    :return: ciphertext
    :rtype: bytes
    """
    validate_key(key)
    validate_sbox(sbox)
    if not data or len(data) % BLOCKSIZE != 0:
        raise ValueError("Data is not blocksize aligned")
    result = []
    for i in xrange(0, len(data), BLOCKSIZE):
        result.append(
            ns2block(action(sbox, key, block2ns(data[i:i + BLOCKSIZE]))))
    return b''.join(result)
Example #22
0
def ecb(key, data, action, sbox=DEFAULT_SBOX):
    """ ECB mode of operation

    :param bytes key: encryption key
    :param data: plaintext
    :type data: bytes, multiple of BLOCKSIZE
    :param func action: encrypt/decrypt
    :param sbox: S-box parameters to use
    :type sbox: str, SBOXES'es key
    :return: ciphertext
    :rtype: bytes
    """
    validate_key(key)
    validate_sbox(sbox)
    if not data or len(data) % BLOCKSIZE != 0:
        raise ValueError("Data is not blocksize aligned")
    result = []
    for i in xrange(0, len(data), BLOCKSIZE):
        result.append(ns2block(action(
            sbox, key, block2ns(data[i:i + BLOCKSIZE])
        )))
    return b''.join(result)
Example #23
0
def mac(encrypter, bs, data):
    """MAC (known here as CMAC, OMAC1) mode of operation

    :param encrypter: Encrypting function, that takes block as an input
    :param int bs: cipher's blocksize
    :param bytes data: data to authenticate

    Implementation is based on PyCrypto's CMAC one, that is in public domain.
    """
    k1, k2 = _mac_ks(encrypter, bs)
    if len(data) % bs == 0:
        tail_offset = len(data) - bs
    else:
        tail_offset = len(data) - (len(data) % bs)
    prev = bs * b'\x00'
    for i in xrange(0, tail_offset, bs):
        prev = encrypter(strxor(data[i:i + bs], prev))
    tail = data[tail_offset:]
    return encrypter(strxor(
        strxor(pad3(tail, bs), prev),
        k1 if len(tail) == bs else k2,
    ))
Example #24
0
    def digest(self):
        """ Get hash of the provided data
        """
        l = 0
        checksum = 0
        h = 32 * b'\x00'
        m = self.data
        for i in xrange(0, len(m), BLOCKSIZE):
            part = m[i:i + BLOCKSIZE][::-1]
            l += len(part) * 8
            checksum = addmod(checksum, int(hexenc(part), 16), 2 ** 256)
            if len(part) < BLOCKSIZE:
                part = b'\x00' * (BLOCKSIZE - len(part)) + part
            h = _step(h, part, self.sbox)
        h = _step(h, 24 * b'\x00' + pack(">Q", l), self.sbox)

        checksum = hex(checksum)[2:].rstrip("L")
        if len(checksum) % 2 != 0:
            checksum = "0" + checksum
        checksum = hexdec(checksum)
        checksum = b'\x00' * (BLOCKSIZE - len(checksum)) + checksum
        h = _step(h, checksum, self.sbox)
        return h
Example #25
0
    def digest(self):
        """ Get hash of the provided data
        """
        _len = 0
        checksum = 0
        h = 32 * b"\x00"
        m = self.data
        for i in xrange(0, len(m), BLOCKSIZE):
            part = m[i:i + BLOCKSIZE][::-1]
            _len += len(part) * 8
            checksum = addmod(checksum, int(hexenc(part), 16), 2 ** 256)
            if len(part) < BLOCKSIZE:
                part = b"\x00" * (BLOCKSIZE - len(part)) + part
            h = _step(h, part, self.sbox)
        h = _step(h, 24 * b"\x00" + pack(">Q", _len), self.sbox)

        checksum = hex(checksum)[2:].rstrip("L")
        if len(checksum) % 2 != 0:
            checksum = "0" + checksum
        checksum = hexdec(checksum)
        checksum = b"\x00" * (BLOCKSIZE - len(checksum)) + checksum
        h = _step(h, checksum, self.sbox)
        return h[::-1]
Example #26
0
def cfb_decrypt(key, data, iv=8 * b"\x00", sbox=DEFAULT_SBOX, mesh=False):
    """ CFB decryption mode of operation

    :param bytes key: encryption key
    :param bytes data: plaintext
    :param iv: initialization vector
    :type iv: bytes, BLOCKSIZE length
    :param sbox: S-box parameters to use
    :type sbox: str, SBOXES'es key
    :param bool mesh: enable key meshing
    :returns: ciphertext
    :rtype: bytes
    """
    validate_key(key)
    validate_iv(iv)
    validate_sbox(sbox)
    if not data:
        raise ValueError("No data supplied")
    plaintext = []
    data = iv + data
    for i in xrange(BLOCKSIZE, len(data) + pad_size(len(data), BLOCKSIZE), BLOCKSIZE):
        if (
                mesh and
                (i - BLOCKSIZE) >= MESH_MAX_DATA and
                (i - BLOCKSIZE) % MESH_MAX_DATA == 0
        ):
            key, iv = meshing(key, data[i - BLOCKSIZE:i], sbox=sbox)
            plaintext.append(strxor(
                data[i:i + BLOCKSIZE],
                ns2block(encrypt(sbox, key, block2ns(iv))),
            ))
            continue
        plaintext.append(strxor(
            data[i:i + BLOCKSIZE],
            ns2block(encrypt(sbox, key, block2ns(data[i - BLOCKSIZE:i]))),
        ))
    return b"".join(plaintext)
Example #27
0
    36, 169, 62, 168, 67, 201, 215, 121, 214, 246, 124, 34, 185, 3, 224, 15,
    236, 222, 122, 148, 176, 188, 220, 232, 40, 80, 78, 51, 10, 74, 167, 151,
    96, 115, 30, 0, 98, 68, 26, 184, 56, 130, 100, 159, 38, 65, 173, 69, 70,
    146, 39, 94, 85, 47, 140, 163, 165, 125, 105, 213, 149, 59, 7, 88, 179, 64,
    134, 172, 29, 247, 48, 55, 107, 228, 136, 217, 231, 137, 225, 27, 131, 73,
    76, 63, 248, 254, 141, 83, 170, 144, 202, 216, 133, 97, 32, 113, 103, 164,
    45, 43, 9, 91, 203, 155, 37, 208, 190, 229, 108, 82, 89, 166, 116, 210, 230,
    244, 180, 192, 209, 102, 175, 194, 57, 75, 99, 182,
))

########################################################################
# Precalculate inverted PI value as a performance optimization.
# Actually it can be computed only once and saved on the disk.
########################################################################
PIinv = bytearray(256)
for x in xrange(256):
    PIinv[PI[x]] = x


def gf(a, b):
    c = 0
    while b:
        if b & 1:
            c ^= a
        if a & 0x80:
            a = (a << 1) ^ 0x1C3
        else:
            a <<= 1
        b >>= 1
    return c
Example #28
0
    209,
    102,
    175,
    194,
    57,
    75,
    99,
    182,
))

########################################################################
# Precalculate inverted PI value as a performance optimization.
# Actually it can be computed only once and saved on the disk.
########################################################################
PIinv = bytearray(256)
for x in xrange(256):
    PIinv[PI[x]] = x


def gf(a, b):
    c = 0
    while b:
        if b & 1:
            c ^= a
        if a & 0x80:
            a = (a << 1) ^ 0x1C3
        else:
            a <<= 1
        b >>= 1
    return c