예제 #1
0
def _sdes_s(bs: BitString) -> BitString:
    bs_l = BitString(bs[:_sdes_block_length // 2])
    bs_r = BitString(bs[_sdes_block_length // 2:])

    result_l = _sdes_s_single_box(bs_l, 0)
    result_r = _sdes_s_single_box(bs_r, 1)

    return operator.add(result_l, result_r)
예제 #2
0
def _sdes_s_single_box(bs: BitString, i: int) -> BitString:
    bs_l = BitString(bs[0] + bs[3])
    bs_r = BitString(bs[1] + bs[2])

    result = _sdes_s_table[i][_sdes_s_row_determination_table[bs_l]][
        _sdes_s_row_determination_table[bs_r]]

    return bit_string.small_int_to_bit_string(result,
                                              _sdes_s_input_length // 2)
예제 #3
0
파일: des.py 프로젝트: a-l-r1/cryptography
def _des_s_single_block(bs: BitString, group_number: int) -> BitString:
    curr_row = _des_s_row_determination_table[BitString(''.join(
        map(lambda x: bs[x], _des_s_row_determination_bit_index_table)))]
    curr_column = _des_s_column_determination_table[BitString(''.join(
        map(lambda x: bs[x], _des_s_column_determination_bit_index_table)))]
    curr_result_block = _des_s_table[group_number][curr_row][curr_column]

    return bit_string.small_int_to_bit_string(curr_result_block,
                                              _des_s_output_group_length)
예제 #4
0
파일: des.py 프로젝트: a-l-r1/cryptography
def _des_s(bs: BitString) -> BitString:
    result_list = []

    for group_number in range(_des_s_group_count):
        curr_slice = bs[group_number * _des_s_group_length:group_number *
                        _des_s_group_length + _des_s_group_length]
        curr_slice = BitString(curr_slice)

        result_list.append(_des_s_single_block(curr_slice, group_number))

    result = BitString(''.join(result_list))
    return result
예제 #5
0
def _sdes(bs: BitString, key_list: List[BitString]) -> BitString:
    result = _sdes_ip(bs)

    result_l = BitString(result[:_sdes_block_length // 2])
    result_r = BitString(result[_sdes_block_length // 2:])

    result_l = bit_string.xor(result_l, _sdes_f(result_r, key_list[0]))
    result_l, result_r = result_r, result_l
    result_l = bit_string.xor(result_l, _sdes_f(result_r, key_list[1]))
    result = operator.add(result_l, result_r)

    result = _sdes_ip_inv(result)
    return result
예제 #6
0
def feistel_round(s: BitString, k: BitString, f: Callable[[BitString, BitString], BitString]) -> BitString:
    length = len(s)

    if length % 2 != 0:
        raise ValueError("feistel_round: s not of even length")

    l = BitString(s[0:length // 2])
    r = BitString(s[length // 2:])

    l_new = r
    r_new = bit_string.xor(l, f(r, k))

    result = BitString(l_new + r_new)

    return result
예제 #7
0
class BitPermutation(object):

    @slot_supporter('bitstring')
    def __init__(self, permutation_list):
        if permutation_list is not None:
            self._permutation_list = permutation_list
        else:
            self._permutation_list = None

        self._input_bitstring = None
        self._output_bitstring = None


    def permute(self, permutation_list=None):
        """
        Permute according to permutation list
        """
        if permutation_list is not None:
            return self._bitstring.permute(permutation_list)
        else:
            if self._permutation_list is not None:
                return self._bitstring.permute(self._permutation_list)
        raise ValueError("Permutation list is not given nor initialized.")

    def bitstring_handler(self, **kwargs):
        self._input_bitstring = BitString(bitstring=kwargs['bitstring'])
        self.apply()

    def apply(self):
        self._output_bitstring = self._input_bitstring.permute(self._permutation_list)
예제 #8
0
def decrypt(c: int, sk: Tuple[List[int], int, int]) -> BitString:
    result = ''
    w = sk[0]
    q = sk[1]
    r = sk[2]

    if gcd.gcd(q, r) != 1:
        raise ValueError("decrypt(): q and r not coprime")

    c_real = (c * gcd.get_modular_inverse(r, q)) % q

    for w_i in reversed(w):
        if c_real >= w_i:
            c_real -= w_i
            result += '1'
        else:
            result += '0'

        if c_real < 0:
            raise ValueError("decrypt(): decrypt error")

    if c_real != 0:
        raise ValueError("decrypt(): decrypt error")

    return BitString(result)
예제 #9
0
파일: des.py 프로젝트: a-l-r1/cryptography
def _des_3round_iter_possible_keys(possible_key_chunks: List[Set[BitString]]):
    mid = _des_actual_key_length // 2
    total_left_rshift_rounds = sum(
        _des_gen_key_shift_count_table[0:_des_3round_round_count])

    for known_bits in itertools.product(*possible_key_chunks):
        for unknown_bits in itertools.product(
                *itertools.repeat(bit_string.all_bits, _des_s_group_count)):
            # 从 DES 轮密钥结构推出
            curr_k_3 = BitString(''.join(known_bits) + ''.join(unknown_bits))

            curr_k_0 = _des_gen_key_pc_2_inv(curr_k_3)
            # XXX: why curr_k_0[:mid] and curr_k_0_l + curr_k_0_r still return a str?
            curr_k_0_l = bit_string.right_rshift(BitString(curr_k_0[:mid]),
                                                 total_left_rshift_rounds)
            curr_k_0_r = bit_string.right_rshift(BitString(curr_k_0[mid:]),
                                                 total_left_rshift_rounds)
            curr_k_0 = operator.add(curr_k_0_l, curr_k_0_r)

            curr_k = _des_gen_key_pc_1_inv(curr_k_0)

            yield curr_k

    return
예제 #10
0
파일: des.py 프로젝트: a-l-r1/cryptography
def _des_gen_key_pc_1_inv(bs: BitString) -> BitString:
    result = bit_string.permutation_by_table_with_completion(
        bs, _des_gen_key_pc_1_inv_table)

    _des_gen_key_pc_2_inv_block_length = 8

    parity_bit_list = []

    result_block_list = [
        result[i:i + _des_gen_key_pc_2_inv_block_length - 1] for i in range(
            0, des_orig_key_length, _des_gen_key_pc_2_inv_block_length)
    ]

    for block in result_block_list:
        one_count = len(
            list(filter(lambda x: ord(x) == bit_string.ord_1, block)))

        parity_bit_list.append(
            BitString('1') if one_count % 2 == 0 else BitString('0'))

    result = BitString(''.join(
        map(operator.add, result_block_list, parity_bit_list)))

    return result
예제 #11
0
파일: des.py 프로젝트: a-l-r1/cryptography
def _des_gen_key_list(k: bytes) -> List[BitString]:
    k_str = _des_gen_key_pc_1(bit_string.bytes_to_bit_string(k))
    c = k_str[0:_des_actual_key_length // 2]
    d = k_str[_des_actual_key_length // 2:]

    result = []

    for round_number in range(_des_gen_key_rounds):
        c = bit_string.left_rshift(
            c, _des_gen_key_shift_count_table[round_number])
        d = bit_string.left_rshift(
            d, _des_gen_key_shift_count_table[round_number])

        k = _des_gen_key_pc_2(BitString(c + d))
        result.append(k)

    return result
예제 #12
0
파일: des.py 프로젝트: a-l-r1/cryptography
def _des_3round_cryptanalysis_differential_two_pairs(
        p1: BitString, c1: BitString, p2: BitString,
        c2: BitString) -> List[Set[BitString]]:
    mid = des_block_length // 2

    r_3_1 = BitString(c1[mid:])
    r_3_2 = BitString(c2[mid:])
    r_3_diff = bit_string.xor(r_3_1, r_3_2)

    l_0_1 = BitString(p1[:mid])
    l_0_2 = BitString(p2[:mid])
    l_0_diff = bit_string.xor(l_0_1, l_0_2)

    c_diff = _des_p_inv(bit_string.xor(r_3_diff, l_0_diff))

    l_3_1 = BitString(c1[:mid])
    l_3_2 = BitString(c2[:mid])
    e_1 = _des_e(l_3_1)
    e_2 = _des_e(l_3_2)

    c_diff_list = list(
        map(lambda x: BitString(c_diff[x:x + _des_s_output_group_length]),
            range(0, des_block_length, _des_s_output_group_length)))
    e_1_list = list(
        map(lambda x: BitString(e_1[x:x + _des_s_group_length]),
            range(0, _des_s_input_length, _des_s_group_length)))
    e_2_list = list(
        map(lambda x: BitString(e_2[x:x + _des_s_group_length]),
            range(0, _des_s_input_length, _des_s_group_length)))

    result = []

    for i in range(_des_s_group_count):
        result.append(
            _des_3round_cryptanalysis_differential_gen_test_set(
                e_1_list[i], e_2_list[i], c_diff_list[i], i))

    return result
예제 #13
0
def cryptanalysis_lll(c: int, pk: List[int]) -> BitString:
    delta = 0.75

    if len(pk) <= 1:
        raise ValueError("cryptanalysis_lll(): pk too short")

    n = len(pk) + 1

    m = [[0 for _ in range(n)] for _ in range(n)]

    # fill in identity matrix
    for i in range(n - 1):
        m[i][i] = 1

    # fill in public key
    for i in range(n - 1):
        m[i][n - 1] = pk[i]

    m[n - 1][n - 1] = -c

    m_lll = lll.lll(m, delta)
    print(m_lll)

    valid_row = None

    for row in m_lll:
        is_valid = True

        for elem in row[:-1]:
            if elem != 0 and elem != 1:
                is_valid = False

        if row[-1] != 0:
            is_valid = False

        if is_valid:
            valid_row = row

    if valid_row is None:
        raise ValueError("cryptanalysis_lll(): cryptanalysis failed")

    return BitString(''.join(map(str, valid_row[:-1])))
예제 #14
0
from knapsack import *
from bit_string import BitString

key_length = 5
key = gen_key(key_length)
print(key)
sk, pk = key

m = BitString('10101')
c = encrypt(m, pk)
print(c)
m_recovered = decrypt(c, sk)
print(m_recovered)
print(m_recovered == m)

w = [2, 3, 7, 14, 30, 57, 120, 251]
q = 491
r = 41
sk = (w, q, r)

pk = [82, 123, 287, 83, 248, 373, 10, 471]

m = BitString('00101111')
c = encrypt(m, pk)
print(c)

m_recovered = cryptanalysis_lll(c, pk)
print(m_recovered)
print(m == m_recovered)
예제 #15
0
_sdes_gen_key_lshift_count_table = [1, 2]

_sdes_gen_key_p8_table = [6, 3, 7, 4, 8, 5, 10, 9]

_sdes_rounds = 2
_sdes_block_length = 8

_sdes_ip_table = [2, 6, 3, 1, 4, 8, 5, 7]

_sdes_e_table = [4, 1, 2, 3, 2, 3, 4, 1]

_sdes_s_input_length = 4

_sdes_s_row_determination_table = {
    BitString('00'): 0,
    BitString('01'): 1,
    BitString('10'): 2,
    BitString('11'): 3
}

_sdes_s_table = [[[1, 0, 3, 2], [3, 2, 1, 0], [0, 2, 1, 3], [3, 1, 3, 2]],
                 [[0, 1, 2, 3], [2, 0, 1, 3], [3, 0, 1, 0], [2, 1, 0, 3]]]

_sdes_p4_table = [2, 4, 3, 1]

_sdes_ip_inv_table = [4, 1, 3, 5, 7, 2, 8, 6]


def _sdes_gen_key(k: BitString) -> List[BitString]:
    actual_key = bit_string.permutation_by_table(k, _sdes_gen_key_p10_table)
예제 #16
0
 def bitstring_handler(self, **kwargs):
     self._input_bitstring = BitString(bitstring=kwargs['bitstring'])
     self.apply()
예제 #17
0
파일: des.py 프로젝트: a-l-r1/cryptography
_des_e_table = [
    32, 1, 2, 3, 4, 5, 4, 5, 6, 7, 8, 9, 8, 9, 10, 11, 12, 13, 12, 13, 14, 15,
    16, 17, 16, 17, 18, 19, 20, 21, 20, 21, 22, 23, 24, 25, 24, 25, 26, 27, 28,
    29, 28, 29, 30, 31, 32, 1
]

_des_s_input_length = 48
_des_s_group_count = 8
_des_s_group_length = 6
_des_s_output_group_length = 4
_des_s_output_length = 32

_des_s_row_determination_bit_index_table = [0, 5]

_des_s_row_determination_table = {
    BitString('00'): 0,
    BitString('01'): 1,
    BitString('10'): 2,
    BitString('11'): 3
}

_des_s_column_determination_bit_index_table = [1, 2, 3, 4]

_des_s_column_determination_table = {
    BitString('0000'): 0,
    BitString('0001'): 1,
    BitString('0010'): 2,
    BitString('0011'): 3,
    BitString('0100'): 4,
    BitString('0101'): 5,
    BitString('0110'): 6,