Beispiel #1
0
def test_4bit_sbox(_zeros=[0 for count in range(15)]):
    from crypto.analysis.cryptanalysis import summarize_sbox  
    ddt = dict((bit, {}) for bit in range(32))
    
    for word1 in range(256):
        print("{}%...".format((word1 / 256.0) * 100))
        for difference in range(1, 256):            
            state1 = _zeros + [word1]
            state2 = _zeros + [word1 ^ difference]
            output1 = bytes_to_longs(round(round(state1)))
            output2 = bytes_to_longs(round(round(state2)))
            state1, state2 = bytes_to_longs(state1), bytes_to_longs(state2)
            input_difference = [state1[index] ^ state2[index] for index in range(4)]
            difference = [output1[index] ^ output2[index] for index in range(4)]
            mask = 1                        
            for bit in range(32):               
                _input_difference = (input_difference[0] & mask) | ((input_difference[1] & mask) << 1) | ((input_difference[2] & mask) << 2) | ((input_difference[3] & mask) << 3)
                _output_difference = (difference[0] & mask) | ((difference[1] & mask) << 1) | ((difference[2] & mask) << 2) | ((difference[3] & mask) << 3)
                try:
                    ddt[bit][(_input_difference, _output_difference)] += 1
                except KeyError:
                    ddt[bit][(_input_difference, _output_difference)] = 1
                mask <<= 1                                          

    pprint.pprint(ddt)
Beispiel #2
0
def encrypt(data, key, rounds=2):
    k1, k2, k3, k4 = bytes_to_longs(key)
    s1, s2, s3, s4 = bytes_to_longs(data)

    for round in range(1, rounds + 1):

        s1, s2, s3, s4 = nonlinear_mixing(round ^ s1 ^ k1, round ^ s2 ^ k2,
                                          round ^ s3 ^ k3, round ^ s4 ^ k4)

        k1, k2, k3, k4 = nonlinear_mixing(k1, k2, k3, k4)

    return longs_to_bytes(s1 ^ k1, s2 ^ k2, s3 ^ k3, s4 ^ k4)
Beispiel #3
0
def encrypt(data, key, rounds=2):    
    k1, k2, k3, k4 = bytes_to_longs(key)
    s1, s2, s3, s4 = bytes_to_longs(data)
        
    for round in range(1, rounds + 1):              
        
        s1, s2, s3, s4 = nonlinear_mixing(round ^ s1 ^ k1, 
                                          round ^ s2 ^ k2, 
                                          round ^ s3 ^ k3, 
                                          round ^ s4 ^ k4)
    
        k1, k2, k3, k4 = nonlinear_mixing(k1, k2, k3, k4)            
        
    return longs_to_bytes(s1 ^ k1, s2 ^ k2, s3 ^ k3, s4 ^ k4)    
Beispiel #4
0
def find_duplicate_via_prng():    
    import random
    import itertools
    from crypto.utilities import slide, bytes_to_longs
    from crypto.designs.nonlinear.ciphercomponents import optimized_bit_byte_transposition_words as prng_of_hamming_weight
    sample_size = 16
    weight = 64
    test_sample = list(('1' * weight).zfill(128))
    target_sample = bytearray(16)
    while sum(format(byte, 'b').zfill(8).count('1') for byte in target_sample) != weight:
        target_sample[:] = urandom(16)
    
    random.shuffle(test_sample)
    test_sample = tuple(int(word, 2) for word in slide(''.join(test_sample), 32))
    target_sample = bytes_to_longs(target_sample)
    failed = True
    outputs = set()
    for counter in itertools.count():
        if test_sample == target_sample:
            break
        if test_sample in outputs:
            print "Entered cycle after {} without finding target".format(counter)
            outputs.remove(test_sample)
            failed = True
            #break
        else:
            outputs.add(test_sample)
        test_sample = prng_of_hamming_weight(*test_sample)
        
    else:
        print "Failed to find identical sample after 2 ** {}".format(log(counter, 2))
        failed = True
    if not failed:
        print "Regenerated identical samples after: {} (2 ** {})".format(counter, log(counter, 2))
Beispiel #5
0
def decrypt(data, key, rounds=2):
    k1, k2, k3, k4 = bytes_to_longs(key)
    s1, s2, s3, s4 = bytes_to_longs(data)

    keys = []
    for round in range(1, rounds + 1):
        keys.append((k1, k2, k3, k4))
        k1, k2, k3, k4 = nonlinear_mixing(k1, k2, k3, k4)

    s1 ^= k1
    s2 ^= k2
    s3 ^= k3
    s4 ^= k4

    for round in reversed(range(1, rounds + 1)):
        k1, k2, k3, k4 = keys.pop(-1)

        s1, s2, s3, s4 = invert_nonlinear_mixing(s1, s2, s3, s4)
        s1 ^= k1 ^ round
        s2 ^= k2 ^ round
        s3 ^= k3 ^ round
        s4 ^= k4 ^ round
    return longs_to_bytes(s1, s2, s3, s4)
Beispiel #6
0
def decrypt(data, key, rounds=2):
    k1, k2, k3, k4 = bytes_to_longs(key)
    s1, s2, s3, s4 = bytes_to_longs(data)
        
    keys = []
    for round in range(1, rounds + 1):
        keys.append((k1, k2, k3, k4))
        k1, k2, k3, k4 = nonlinear_mixing(k1, k2, k3, k4)
    
    s1 ^= k1
    s2 ^= k2
    s3 ^= k3
    s4 ^= k4
    
    for round in reversed(range(1, rounds + 1)):
        k1, k2, k3, k4 = keys.pop(-1)
        
        s1, s2, s3, s4 = invert_nonlinear_mixing(s1, s2, s3, s4)
        s1 ^= k1 ^ round
        s2 ^= k2 ^ round
        s3 ^= k3 ^ round
        s4 ^= k4 ^ round        
    return longs_to_bytes(s1, s2, s3, s4)
Beispiel #7
0
def permutation_256_32(state, rounds=1):
    (a, b, c, d, e, f, g, h) = bytes_to_longs(state)
    for round in range(rounds):
        a, b, c, d = nonlinear_mixing_step(*branching_step(
            a, b, c, d))  # could be done in parallel in hardware
        e, f, g, h = nonlinear_mixing_step(*branching_step(
            e, f, g, h))  # could be done in parallel in hardware

        a, b, e, f = nonlinear_mixing_step(*branching_step(a, b, e, f))
        c, d, g, h = nonlinear_mixing_step(*branching_step(c, d, g, h))

        a, b, g, h = nonlinear_mixing_step(*branching_step(a, b, g, h))
        c, d, a, b = nonlinear_mixing_step(*branching_step(c, d, a, b))

    state[:] = longs_to_bytes(a, b, c, d, e, f, g, h)
Beispiel #8
0
def find_duplicate_via_prng():
    import random
    import itertools
    from crypto.utilities import slide, bytes_to_longs
    from crypto.designs.nonlinear.ciphercomponents import optimized_bit_byte_transposition_words as prng_of_hamming_weight
    sample_size = 16
    weight = 64
    test_sample = list(('1' * weight).zfill(128))
    target_sample = bytearray(16)
    while sum(format(byte, 'b').zfill(8).count('1')
              for byte in target_sample) != weight:
        target_sample[:] = urandom(16)

    random.shuffle(test_sample)
    test_sample = tuple(
        int(word, 2) for word in slide(''.join(test_sample), 32))
    target_sample = bytes_to_longs(target_sample)
    failed = True
    outputs = set()
    for counter in itertools.count():
        if test_sample == target_sample:
            break
        if test_sample in outputs:
            print "Entered cycle after {} without finding target".format(
                counter)
            outputs.remove(test_sample)
            failed = True
            #break
        else:
            outputs.add(test_sample)
        test_sample = prng_of_hamming_weight(*test_sample)

    else:
        print "Failed to find identical sample after 2 ** {}".format(
            log(counter, 2))
        failed = True
    if not failed:
        print "Regenerated identical samples after: {} (2 ** {})".format(
            counter, log(counter, 2))
Beispiel #9
0
def invert_permutation_subroutine(data, mask=0xFFFFFFFFFFFFFFFF):
    a, b, c, d = bytes_to_longs(bytearray(data))
    a, b, c, d = invert_permutation(a, b, c, d)
    data[:] = bytes(longs_to_bytes(a, b, c, d))  
Beispiel #10
0
def permutation_on_state(data, mask=0xFFFFFFFFFFFFFFFF):
    a, b, c, d = bytes_to_longs(bytearray(data))
    a, b, c, d = permutation(a, b, c, d)
    return bytes(longs_to_bytes(a, b, c, d))    
Beispiel #11
0
def invert_permutation_subroutine(data, mask=0xFFFFFFFFFFFFFFFF):
    a, b, c, d = bytes_to_longs(bytearray(data))
    a, b, c, d = invert_permutation(a, b, c, d)
    data[:] = bytes(longs_to_bytes(a, b, c, d))  
Beispiel #12
0
def permutation_on_state(data, mask=0xFFFFFFFFFFFFFFFF):
    a, b, c, d = bytes_to_longs(bytearray(data))
    a, b, c, d = permutation(a, b, c, d)
    return bytes(longs_to_bytes(a, b, c, d))