def QR_chacha(X: tuple) -> tuple:
    """ChaCha QR function."""
    a, b, c, d = X
    a = Binary(a)
    b = Binary(b)
    c = Binary(c)
    d = Binary(d)

    # 1
    a = a % b
    d = d ^ a
    d = d // 16

    # 2
    c = c % d
    b = b ^ c
    b = b // 12

    # 3
    a = a % b
    d = d ^ a
    d = d // 8

    # 4
    c = c % d
    b = b ^ c
    b = b // 7

    return (a.bits, b.bits, c.bits, d.bits)
def random_bits(X):
    Y = list(X)
    for i in range(len(X)):
        tmp_bin = Binary()
        tmp_bin.gen_random(word_size=len(X[i]))
        Y[i] = tmp_bin
    return tuple(Y)
Example #3
0
    def __init__(self, test_mode:bool=False):
        self.test_mode = test_mode
        
        self.a_vects = []
        self.b_vects = []

        for i in range(4):
            a_n = ''
            b_n = ''
            for j in range(4):
                a_n += Binary(PRG.A_VECTOR[i][j]).get_bin(8)
                b_n += Binary(PRG.B_VECTOR[i][j]).get_bin(8)
                #A_bin_n = A_vec_n.get_bin(8)
                #B_bin_n = B_vec_n.get_bin(8)
                #a_n += A_vec_n
                #b_n += B_vec_n

                #a_n += self.to_binary(PRG.A_VECTOR[i][j])
                #b_n += self.to_binary(PRG.B_VECTOR[i][j])
            self.a_vects.append(a_n)
            self.b_vects.append(b_n)
        
        # Log
        self.single_xor     = 0
        self.XORs           = 0
        self.mod_adds       = 0
        self.shifts         = 0
        self.shift_length   = 0
        self.QRs            = 0
        self.total_runs     = 0
        self.QR_x           = []
        self.QR_y           = []
        self.DRF_in         = []
def generate_incr_space(word_size:int):
    """Return a list of all word_size bit binary numbers."""
    space = []
    for i in range(2**word_size):
        a = Binary(i) % word_size
        a = a.split_string()
        space.append(a)
    return space
def get_ints(X:list):
    """Convert list of ints from
    list of bytes."""
    X_ints = []
    for value in X:
        X_bin = Binary().combine_string(value)
        X_ints.append(X_bin.get_dec())
    return X_ints
Example #6
0
def HW(word: Binary) -> int:
    """Returns the hamming weight of input word."""
    if type(word) is tuple:
        word = Binary().combine_string(word)
    if type(word) is Binary:
        word = word.bits

    weight = word.count('1')
    return weight
def get_freq_dist(lst:list, word_size:int):
    freqs = [0] * 2**word_size
    ints = []

    for i in range(len(lst)):
        X_bin = Binary().combine_string(lst[i])
        X_int = X_bin.get_dec()
        freqs[X_int] += 1
        ints.append(X_int)
    
    return freqs, ints
Example #8
0
def test_get_hex():
    a = Binary(3)
    b = Binary(10)
    c = Binary(8)

    assert a.get_hex() == '3'
    assert b.get_hex() == 'a'
    assert c.get_hex() == '8'
Example #9
0
def test_get_dec():
    a = Binary(3)
    b = Binary(10)
    c = Binary(8)

    assert a.get_dec() == 3
    assert b.get_dec() == 10
    assert c.get_dec() == 8
Example #10
0
def HD(word_1: Binary, word_2: Binary) -> int:
    """Returns the hamming distance between
    two input words."""
    if type(word_1) is tuple:
        word_1 = Binary().combine_string(word_1)
    if type(word_2) is tuple:
        word_2 = Binary().combine_string(word_2)
    distance = 0
    for i in range(len(word_1)):
        if word_1[i] != word_2[i]:
            distance += 1
    return distance
Example #11
0
    def hash_function(self, words:tuple) -> str:
        """The hash function does the following:
        1. Split the 64 byte input into 16 words.
        2. For all words: Update by littleendian function.
        3. Run all words through doubleround^10.
        4. Do the last magic. (See link.)"""
        
        # 1. Split words.
        #words = []
        #for i in range(16):
        #    word = ''
        #    for j in range(4):
        #        word += input_bytes[j + i*4]
        #    words.append(word)
        
        # 2. Run through littleendian function.
        for word in words:
            word = self.littleendian_function(word)
        
        """
        # 2.5 merge words --> x_list.
        x_list = ''
        for word in words:
            x_list += word
        """

        # 3. Run all words though doubleround x10.
        x_list = words + tuple()  # The cool way to do copy for tuples.

        for i in range(10):
            assert len(x_list) == 16
            x_list = self.doubleround_function(x_list)
            assert len(x_list) == 16

        # 4. The final magic
        output_list = []
        for i in range(16):
            input_1 = Binary(x_list[i])
            input_2 = Binary(words[i])
            output_element = input_1 % input_2
            output_element = output_element.bits

            #output_element = self.sum_words(x_list[i], words[i])
            output_element = self.littleendian_function(output_element)
            output_list.append(output_element)
        
        output = ''
        for output_element in output_list:
            output += output_element
        
        return output
Example #12
0
def HD_2(word_1: Binary, word_2: Binary) -> int:
    """Alternative (and slower) version of HD."""
    if type(word_1) is tuple:
        word_1 = Binary().combine_string(word_1)
    if type(word_2) is tuple:
        word_2 = Binary().combine_string(word_2)
    if type(word_1) is str:
        word_1 = Binary(word_1)
    if type(word_2) is str:
        word_2 = Binary(word_2)

    xor = word_1 ^ word_2
    distance = HW(xor)
    return distance
def get_plaintext(number):
    binary = Binary(number)

    # Random chars:
    #string = gen_random_string(length=128)

    # Random binary values:
    #binary.gen_random(word_size=128)
    #string = binary.bits

    # Counting values:
    string = binary.get_bin(word_size=128)

    return string
Example #14
0
def test_init():
    Bin1 = Binary()
    assert type(Bin1) is Binary
    assert type(Bin1.bits) is str
    assert Bin1.bits == '0'

    Bin2 = Binary(5)
    assert type(Bin2) is Binary
    assert type(Bin2.bits) is str
    assert Bin2.bits == '101'

    Bin3 = Binary('1100')
    assert type(Bin3) is Binary
    assert type(Bin3.bits) is str
    assert Bin3.bits == '1100'
Example #15
0
def test_incement():
    a = Binary(30)
    assert a.get_dec() == 30
    assert a.bits == '11110'

    a.incr()
    assert a.get_dec() == 31
    assert a.bits == '11111'

    a.incr(4)
    assert a.get_dec() == 35
    assert a.bits == '100011'
Example #16
0
def test_decrement():
    a = Binary(30)
    assert a.get_dec() == 30
    assert a.bits == '11110'

    a.decr()
    assert a.get_dec() == 29
    assert a.bits == '11101'

    a.decr(4)
    assert a.get_dec() == 25
    assert a.bits == '11001'
Example #17
0
def test_gen_random():
    Bin = Binary()
    assert Bin.bits == '0'
    Bin.gen_random(32)
    assert type(Bin.bits) is str
    assert len(Bin.bits) == 32

    zeros = 0
    ones = 0
    for bit in Bin.bits:
        if bit == '0':
            zeros += 1
        else:
            ones += 1
    assert 4 < zeros < 28
    assert 4 < ones < 28
Example #18
0
def test_set_at():
    a = Binary('10101')
    assert a.bits == '10101'
    a.set_at(2, '0')
    assert a.bits == '10001'
    a.set_at(1, '1')
    assert a.bits == '11001'
    a.set_at(0, '1')
    assert a.bits == '11001'
Example #19
0
def test_flip_bit_at():
    a = Binary('10101')
    assert a.bits == '10101'
    a.flip_bit_at(2)
    assert a.bits == '10001'
    a.flip_bit_at(1)
    assert a.bits == '11001'
    a.flip_bit_at(0)
    assert a.bits == '01001'
Example #20
0
def gen_random_bits(word_size):
    """Return a random set of bits,
    of length word_size, as a Binary object."""
    bits = ''
    for i in range(word_size):
        bits += random.choice(('0', '1'))
    
    return Binary(bits)
Example #21
0
def test_random_index():
    a = Binary('1001101010')
    indexes = [0] * len(a)
    runs = 100
    for i in range(runs):
        index = random.randint(0, len(a.bits) - 1)
        indexes[index] += 1
    for index in indexes:
        assert index > 0
Example #22
0
def test_set_bin():
    Bin = Binary()

    Bin.set_bin(3)
    assert Bin == '11'

    Bin.set_bin(10)
    assert Bin == '1010'

    Bin.set_bin(8)
    assert Bin == '1000'
Example #23
0
def test_is_binary():
    Bin = Binary()

    assert Bin.is_binary('10101')
    assert Bin.is_binary('0')
    assert not Bin.is_binary('102')
    assert not Bin.is_binary('1af0')
    assert not Bin.is_binary(10)
def random_flips(function=QR, word_size:int=12):
    X = Binary()#'0000000000000000')
    X.gen_random(word_size)
    X = X.split_string()
    Y = function(X)

    HD_lists = []
    for i in range(100):
        Xs = generate_random_flipped_space(X, runs=100)
        #Ys = QR_on_list(Xs)
        Ys = []
        for X_i in Xs:
            Ys.append(function(X_i))
        

        Y_base = [Y] * len(Ys)
        HDs = HDs_of_lists(Y_base, Ys)
        HD_lists.append(HDs)
    
    return HD_lists
Example #25
0
def HW_2(word: Binary) -> int:
    """Alternative (and slower) version of HW."""
    if type(word) is tuple:
        word = Binary().combine_string(word)
    if type(word) is Binary:
        word = word.bits

    weight = 0
    for bit in word:
        if bit == '1':
            weight += 1
    return weight
Example #26
0
def test_add():
    a = Binary(123)
    b = Binary(345)
    c = Binary(468)
    assert a + b == c
    assert a.is_binary(a)
    assert a.is_binary(a + b)
def test_while_bits():
    a = '0100101'
    b = Binary('01010111')
    c = ('010', '101', '110', '100')
    d = [Binary('1010'), Binary('001'), '100010101010']

    A = whipe_bits(a)
    B = whipe_bits(b, default='1')
    C = whipe_bits(c)
    D = whipe_bits(d)

    assert type(A) is str
    assert len(A) == len(a)
    assert A == '0000000'

    assert type(B) is Binary
    assert len(B) == len(b)
    assert B == Binary('11111111')

    assert type(C) is tuple
    assert len(C) == len(c)
    assert C == ('000', '000', '000', '000')
    assert type(C[0]) == type(C[1]) == type(C[2]) == type(C[3]) == str

    assert type(d) is list
    assert len(D) == len(d)
    assert D == [Binary('0000'), Binary('000'), '000000000000']
    assert type(D[0]) == type(D[1]) == Binary
    assert type(D[2]) == str
def xor_0(X, bit='0'):
    X = list(X)
    for i in range(len(X)):
        new_word = ''
        for j in range(len(X[i])):
            if X[i][j] == bit:
                new_word += '0'
            else:
                new_word += '1'

        X[i] = Binary(new_word)

    return tuple(X)
def incremental_space(function=QR, word_size:int = 12):
    X = Binary()#'0000000000000000')
    X.gen_random(word_size)
    X = X.split_string()
    Y = function(X)

    Xs = generate_incr_space(word_size)
    #Ys = QR_on_list(Xs)
    Ys = []
    for X in Xs:
        Ys.append(function(X))
    

    Y_base = [Y] * len(Ys)
    HDs = HDs_of_lists(Y_base, Ys)

    multi_line_chart(
        lines=[HDs],
        title='HDs of incremental outputs',
        x_label='bits',
        y_label='Hamming distance and weight'
    )
def QR(X: tuple) -> tuple:
    """Salsa QR function."""
    #print('X:', X)
    x0, x1, x2, x3 = X

    word_size = len(x0)

    x0 = Binary(x0)
    x1 = Binary(x1)
    x2 = Binary(x2)
    x3 = Binary(x3)

    y1 = x1 ^ ((x0 % x3) // 7)
    y2 = x2 ^ ((y1 % x0) // 9)
    y3 = x3 ^ ((y2 % y1) // 13)
    y0 = x0 ^ ((y3 % y2) // 18)

    y0_ = y0.get_bin(word_size)
    y1_ = y1.get_bin(word_size)
    y2_ = y2.get_bin(word_size)
    y3_ = y3.get_bin(word_size)

    Y = (y0_, y1_, y2_, y3_)
    return Y