コード例 #1
0
ファイル: gost28147.py プロジェクト: kalloc/pygost_0_15
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]
コード例 #2
0
ファイル: gost28147.py プロジェクト: kalloc/pygost_0_15
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)
コード例 #3
0
ファイル: gost28147.py プロジェクト: kalloc/pygost_0_15
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)
コード例 #4
0
ファイル: gost28147.py プロジェクト: kalloc/pygost_0_15
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])
コード例 #5
0
ファイル: gost3412.py プロジェクト: kalloc/pygost_0_15
    def __init__(self, key):
        """
        :param key: encryption/decryption key
        :type key: bytes, 32 bytes

        Key scheduling (roundkeys precomputation) is performed here.
        """
        kr0 = bytearray(key[:16])
        kr1 = bytearray(key[16:])
        self.ks = [kr0, kr1]
        for i in range(4):
            for j in range(8):
                k = lp(bytearray(strxor(C[8 * i + j], kr0)))
                kr0, kr1 = [strxor(k, kr1), kr0]
            self.ks.append(kr0)
            self.ks.append(kr1)
コード例 #6
0
ファイル: gost3411_94.py プロジェクト: kalloc/pygost_0_15
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 range(12):
        x = _chi(x)
    x = strxor(x, m)
    x = _chi(x)
    x = strxor(hin, x)
    for _ in range(61):
        x = _chi(x)
    return x
コード例 #7
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
    :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)
    plaintext = []
    data = iv + data
    for i in xrange(BLOCKSIZE, len(data), 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)[:size]
コード例 #8
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,
        ))
コード例 #9
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)
コード例 #10
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)
コード例 #11
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)
コード例 #12
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)
コード例 #13
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)
コード例 #14
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)
コード例 #15
0
ファイル: var1.py プロジェクト: mehakun/Labs
def g(n, hsh, msg, rounds_amount=12):
    res = E(LPS(strxor(hsh[:8], pack("<Q", n)) + hsh[8:]), msg, rounds_amount)
    return strxor(strxor(res, hsh), msg)
コード例 #16
0
def E(k, msg):
    for i in range(12):
        msg = LPS(strxor(k, msg))
        k = LPS(strxor(k, C[i]))
    return strxor(k, msg)
コード例 #17
0
def g(n, hsh, msg):
    res = E(LPS(strxor(hsh[:8], pack("<Q", n)) + hsh[8:]), msg)
    return strxor(strxor(res, hsh), msg)
コード例 #18
0
ファイル: gost3411_12.py プロジェクト: kalloc/pygost_0_15
def E(k, msg):
    for i in range(12):
        msg = LPS(strxor(k, msg))
        k = LPS(strxor(k, C[i]))
    return strxor(k, msg)
コード例 #19
0
ファイル: gost3412.py プロジェクト: kalloc/pygost_0_15
 def encrypt(self, blk):
     blk = bytearray(blk)
     for i in range(9):
         blk = lp(bytearray(strxor(self.ks[i], blk)))
     return bytes(strxor(self.ks[9], blk))
コード例 #20
0
def A(x):
    x4, x3, x2, x1 = x[0:8], x[8:16], x[16:24], x[24:32]
    return b"".join((strxor(x1, x2), x4, x3, x2))
コード例 #21
0
ファイル: gost3412.py プロジェクト: kalloc/pygost_0_15
 def encrypt(self, blk):
     blk = bytearray(blk)
     for i in range(9):
         blk = lp(bytearray(strxor(self.ks[i], blk)))
     return bytes(strxor(self.ks[9], blk))
コード例 #22
0
ファイル: gost3412.py プロジェクト: kalloc/pygost_0_15
 def decrypt(self, blk):
     blk = bytearray(blk)
     for i in range(9, 0, -1):
         blk = [PIinv[v] for v in Linv(bytearray(strxor(self.ks[i], blk)))]
     return bytes(strxor(self.ks[0], blk))
コード例 #23
0
ファイル: var1.py プロジェクト: mehakun/Labs
def E(k, msg, rounds_amount):
    for i in range(rounds_amount):
        msg = LPS(strxor(k, msg))
        k = LPS(strxor(k, C[i]))
    return strxor(k, msg)
コード例 #24
0
ファイル: gost3411_12.py プロジェクト: kalloc/pygost_0_15
def g(n, hsh, msg):
    res = E(LPS(strxor(hsh[:8], pack("<Q", n)) + hsh[8:]), msg)
    return strxor(strxor(res, hsh), msg)
コード例 #25
0
ファイル: gost3412.py プロジェクト: kalloc/pygost_0_15
 def decrypt(self, blk):
     blk = bytearray(blk)
     for i in range(9, 0, -1):
         blk = [PIinv[v] for v in Linv(bytearray(strxor(self.ks[i], blk)))]
     return bytes(strxor(self.ks[0], blk))
コード例 #26
0
ファイル: gost3411_94.py プロジェクト: kalloc/pygost_0_15
def A(x):
    x4, x3, x2, x1 = x[0:8], x[8:16], x[16:24], x[24:32]
    return b''.join((strxor(x1, x2), x4, x3, x2))