Ejemplo n.º 1
0
def slow_hash(seed, tweak, rounds=1, output_size=32, tables=256):
    seed = bytearray(null_pad(seed, 256))
    state = seed[0]
    _rows = [rotate(tweak, amount) for amount in xrange(tables)]
    
    for round in range(rounds):    
        for i in reversed(range(1, 256)):    
            for rows in slide(_rows, 256):
                for row in rows:                
                    j = state & (i - 1)                
                    row[i], row[j] = row[j], row[i]           
                    random_row = rows[j]
                    row[j], random_row[j] = random_row[j], row[j]
                    
                    seed[i] ^= random_row[row[j]] ^ row[random_row[j]]
                    state ^= seed[i] ^ seed[j] ^ row[i] ^ random_row[i]
        i = 0
        for rows in slide(_rows, 256):
            for row in rows:        
                seed[i] ^= random_row[row[j]] ^ row[random_row[j]]
                state ^= seed[i] ^ seed[j] ^ row[i] ^ random_row[i]
    
    output = []
    for index in range(output_size):
        output.append(seed[rows[index][index]])    
    return bytearray(output)
Ejemplo n.º 2
0
def one_way_function_base_conversion(old_value, tweak=ASCII_CONSTANT):
    new_base = tweak           
    old_base_mapping = {}
    old_value = ''.join(reversed(bytes(old_value)))
    for index, symbol in enumerate(slide(old_value, 2)):
        old_base_mapping[symbol] = index
   
    _old_value = bytearray(old_value)    
    
    xor_key = xor_sum(_old_value)    
    old_base_size = len(old_base_mapping)    
    decimal_value = (xor_key +
                     sum(((xor_key ^ old_base_mapping[value_representation]) * (old_base_size ** power) for
                           power, value_representation in enumerate(slide(old_value, 2)))))
    #decimal_value = xor_key
    #for power, value_representation in enumerate(slide(old_value, 2)):
    #    decimal_value += (xor_key ^ old_base_mapping[value_representation]) * (old_base_size ** power)                                
        
    new_value = ''    
    new_base_size = len(new_base)    
    new_value = ''
    while decimal_value > 0 or not new_value: # divmod = divide and modulo in one action 
        decimal_value, digit = divmod(decimal_value, new_base_size)
        new_value += new_base[digit]
    return ''.join(reversed(new_value))
Ejemplo n.º 3
0
    def _test_random_data():
        import os
        outputs = []
        for key_count, key in enumerate(slide(os.urandom(16 * 256), 16)):
            ciphertext = os.urandom(16 * 65535)        
            pride.utilities.print_in_place(str(key_count / 256.0) + '% complete; Current bias: {}'.format(float(outputs.count(1)) / (outputs.count(0) or 1)))
            for index, block in enumerate(slide(os.urandom(16 * 65535), 16)):
                outputs.append(1 if xor_parity(block) ^ xor_parity(ciphertext[index * 16:(index + 1) * 16]) else 0)

        zero_bits = outputs.count(0)
        one_bits = outputs.count(1)
        print float(one_bits) / zero_bits, one_bits, zero_bits                
Ejemplo n.º 4
0
 def test_hash(data):
     output = bytearray(16)        
     key = xor_sum(bytearray(data[:16]))
     for block in slide(bytearray(data), 16):            
         prf(block, xor_sum(block))            
         xor_subroutine(output, block)        
     return bytes(output)
Ejemplo n.º 5
0
def sponge_function(hash_input, key='', output_size=32, capacity=32, rate=32, 
                    mixing_subroutine=None,
                    mode_of_operation=variable_length_hash,
                    absorb_mode=xor_subroutine): 
    assert mixing_subroutine is not None
    #print "Hashing: ", [byte for byte in hash_input]
    if isinstance(rate, int):
        rate = slice(0, rate)
    if isinstance(capacity, int):
        end_of_rate = rate.stop
        capacity = slice(end_of_rate, end_of_rate + capacity)
    state_size = capacity.stop
    state = bytearray(state_size)
    if key:
        absorb(key, state, rate, mixing_subroutine, absorb_mode)      
    
    rate_in_bytes = rate.stop - rate.start
    hash_input = pad_input(bytearray(hash_input), rate_in_bytes)
        
    #print "\nBeginning absorption", [byte for byte in hash_input]
    for _bytes in slide(hash_input, rate_in_bytes):
        #print "Absorbing: ", [byte for byte in _bytes]
        absorb(_bytes, state, rate, mixing_subroutine, absorb_mode)
    
    #print "\nBeginning final mix before mode of operation: ", [byte for byte in state]
    mixing_subroutine(state)
    return mode_of_operation(state, rate, output_size, mixing_subroutine, absorb_mode)                
Ejemplo n.º 6
0
def decrypt(ciphertexts, key, rounds=1, modulus=256, blocksize=16):
    output = bytearray()    
    key = [modular_inverse(item | 1, modulus) for item in key]
    for index, block in enumerate(slide(ciphertexts, 2)):
        block[1] = (block[1] * key[1]) % modulus
        block[0] = (block[0] * key[0]) % modulus
        block[0] = modular_subtraction(block[0], block[1], modulus)        
        output.append(block[0])
    return output
Ejemplo n.º 7
0
def decrypt(ciphertexts, private_key, blocksize=BLOCKSIZE, decryption_function=secretkey.decrypt):
    """ usage: decrypt(ciphertexts : bytearray, private_key : bytearray,
                       blocksize=BLOCKSIZE, 
                       decryption_function=secretkey.decrypt) => plaintext : bytearray
                       
        Private key decryption function based on homomorphic encryption/decryption. """
    message = []#bytearray()
    for ciphertext_byte in slide(ciphertexts, blocksize):           
        plaintext_byte = decryption_function(ciphertext_byte, private_key)                       
        message.append(plaintext_byte[0])
    return message
Ejemplo n.º 8
0
def decrypt(ciphertexts, key, rounds=5, modulus=DEFAULT_MODULUS):  
    """ usage: decrypt(ciphertexts, key, 
                       rounds=5, modulus=DEFAULT_MODULUS) => plaintext
                       
        Given ciphertexts and key, return plaintexts. """        
    output = [] 
    for ciphertext in slide(ciphertexts, 2 ** rounds):        
        multiplication_subroutine(ciphertext, [modular_inverse(item | 1, modulus) for item in key], modulus)            
        for round in range(rounds):    
            ciphertext[:] = decode(ciphertext, modulus)          
        output.append(ciphertext[0])   
    return output
Ejemplo n.º 9
0
 def test_hash(data):   
     size = len(data)
     data = data + ("\x00" * (16 - size))
     if size == 16:            
         output = bytearray(data)
         for round in range(1):
             prp(output, xor_sum(output))            
     else:
         output = bytearray(16)
         for block in slide(bytearray(data), 16):            
             prp(block, xor_sum(block))
             xor_subroutine(output, block)        
     return bytes(output)
Ejemplo n.º 10
0
def decrypt(data, cipher, iv, tag=None, tweak=None):#key, iv, cipher, mode_of_operation, tweak=None):    
    mode = cipher.mode    
    #if mode != "ella":
    #    assert not tag, (mode, data, cipher, iv, tag)
    if mode in ("cbc", "ella", "ecb"):
        crypt_block = cipher.decrypt_block
        if mode == "ella":                    
            data = ''.join(reversed([block for block in slide(bytes(data), cipher.blocksize)]))
    else:
        crypt_block = cipher.encrypt_block  
    
    #data = bytearray(data)        
    crypt(data, cipher.key, iv, crypt_block, DECRYPTION_MODES[mode], cipher.blocksize, tag, tweak)  
    if mode == "ella":
        if tag != cipher.mac_key:
            raise InvalidTag()
        return ''.join(reversed([block for block in slide(bytes(data), cipher.blocksize)]))
    elif mode in ("cbc", "ecb"):
        padding_amount = data[-1]                  
        return bytes(data)[:-(padding_amount or cipher.blocksize)]
    else:
        return bytes(data)
Ejemplo n.º 11
0
def decrypt_then_mac(ciphertexts, private_key, blocksize=32, tag_size=64, 
                     integrity_key_size=32, decryption_function=secret_key_decrypt):
    tag = bytearray(ciphertext[-tag_size:])
    ciphertexts = ciphertext[:-tag_size]
    _ciphertexts = [load_ciphertext(ciphertext) for ciphertext in slide(ciphertexts, blocksize)] # is this right?    
    message = decryption_function(_ciphertexts[0], private_key)
    integrity_key = decryption_function(_ciphertexts[-1], private_key)
    
    _tag = hmac(integrity_key, ciphertexts)
    if compare_digest(_tag, tag):
        return message
    else:
        return None    
Ejemplo n.º 12
0
def decrypt(ciphertexts, key, rounds=5, modulus=DEFAULT_MODULUS):
    """ usage: decrypt(ciphertexts, key, 
                       rounds=5, modulus=DEFAULT_MODULUS) => plaintext
                       
        Given ciphertexts and key, return plaintexts. """
    output = []
    for ciphertext in slide(ciphertexts, 2**rounds):
        multiplication_subroutine(
            ciphertext, [modular_inverse(item | 1, modulus) for item in key],
            modulus)
        for round in range(rounds):
            ciphertext[:] = decode(ciphertext, modulus)
        output.append(ciphertext[0])
    return output
Ejemplo n.º 13
0
def decrypt(ciphertexts,
            private_key,
            blocksize=BLOCKSIZE,
            decryption_function=secretkey.decrypt):
    """ usage: decrypt(ciphertexts : bytearray, private_key : bytearray,
                       blocksize=BLOCKSIZE, 
                       decryption_function=secretkey.decrypt) => plaintext : bytearray
                       
        Private key decryption function based on homomorphic encryption/decryption. """
    message = []  #bytearray()
    for ciphertext_byte in slide(ciphertexts, blocksize):
        plaintext_byte = decryption_function(ciphertext_byte, private_key)
        message.append(plaintext_byte[0])
    return message
Ejemplo n.º 14
0
def p_box(input_bytes):    
    """ Data concentrating permutation box. Evenly distributes input bits amongst output. """
    bits = cast(bytes(input_bytes), "binary")      
    # if a 64 bit block was acceptable, the operation would be this simple:
    #   for index, byte in enumerate(int(bits[index::8], 2) for index in range(8)):
    #       input_bytes[index] = byte  
    
    bit_count = len(bits)
    word_size = bit_count / 8
    word_size_in_bytes = word_size / 8
    for index in range(8):
        bits_at_index = bits[index::word_size]
        _index = index * word_size_in_bytes    
        
        for offset, _bits in enumerate(slide(bits_at_index, 8)):   
            input_bytes[_index + offset] = int(_bits, 2)
Ejemplo n.º 15
0
def decrypt_then_mac(ciphertexts,
                     private_key,
                     blocksize=32,
                     tag_size=64,
                     integrity_key_size=32,
                     decryption_function=secret_key_decrypt):
    tag = bytearray(ciphertext[-tag_size:])
    ciphertexts = ciphertext[:-tag_size]
    _ciphertexts = [
        load_ciphertext(ciphertext)
        for ciphertext in slide(ciphertexts, blocksize)
    ]  # is this right?
    message = decryption_function(_ciphertexts[0], private_key)
    integrity_key = decryption_function(_ciphertexts[-1], private_key)

    _tag = hmac(integrity_key, ciphertexts)
    if compare_digest(_tag, tag):
        return message
    else:
        return None
Ejemplo n.º 16
0
def decrypt(ciphertext, key, function, input_block_size, 
            mode_of_operation=xor_with_key, key_rotation=all_or_nothing, 
            output_block_size=1):
    """ Decrypt the ciphertext hash chain as produced by encrypt. The amount
        of work and therefore time taken to recover the plaintext increases
        dramatically as output_block_size is incremented. The output_block_size
        argument must be set to the same value used by the server or the
        decryption will fail. """
    test_bytes = [RANGE_256 for count in range(output_block_size)]
    plaintext = plaintext_block = ''

    for ciphertext_block in slide(ciphertext, input_block_size):
        (plaintext_block, ciphertext_block, 
         key, function) = mode_of_operation(plaintext_block, ciphertext_block, 
                                            key, function)
                                          
        plaintext_block = brute_force(ciphertext_block, function, test_bytes, key)
        plaintext += plaintext_block
        
        (plaintext_block, ciphertext_block,
         key, function) = key_rotation(plaintext_block, ciphertext_block, key, function)            
    return plaintext   
Ejemplo n.º 17
0
def encrypt(plaintext, key, function, mode_of_operation=xor_with_key, 
            key_rotation=all_or_nothing, input_block_size=1): 
    """ An encryption function with an associated work factor. Returns a
        ciphertext encrypted under key. 
        
        The input_block_size adjusts two factors: First, by a smaller
        amount, as input_block_size increases, generating the challenge tends
        to take less time. Second, as input_block_size increases, solving the
        challenge tends to take significantly more time.
        
        As an example, consider a server that requires proof of work with
        each request submitted by a client. An overloaded server could 
        increment the bytes per hash to crack. As a result, it would spend 
        less time generating each challenge, while clients would take 
        significantly longer to solve each challenge. The net effect is
        an actual reduction in traffic, as clients cannot effectively make
        additional requests until the current challenge is solved.

        Note that output block size is determined implicitly by the function used,
        and is not otherwise configurable.
        
        As a result, when used with hash functions, ciphertext is necessarily
        significantly larger then the input plaintext."""
    if len(plaintext) % input_block_size:
        raise ValueError("Plaintext length not a multiple of input_block_size")
    ciphertext = ''           
    
    for plaintext_block in slide(plaintext, input_block_size):
        ciphertext_block = function(key, plaintext_block) 
        (plaintext_block, ciphertext_block, 
         key, function) = mode_of_operation(plaintext_block, ciphertext_block, key, function)
        
        ciphertext += ciphertext_block
        
        (plaintext_block, ciphertext_block, 
         key, function) = key_rotation(plaintext_block, ciphertext_block, key, function)
    return ciphertext
Ejemplo n.º 18
0
def crypt(data, key, iv, cipher, mode_of_operation, blocksize, tag, tweak):    
    output = bytearray()    
    for block in slide(data, blocksize):      
        mode_of_operation(block, iv, key, cipher, tag, tweak)        
        output.extend(block)
    replacement_subroutine(data, output)                       
Ejemplo n.º 19
0
def _print_state(state, message):
    print message
    for _bytes in slide(state, 4):
        print ' '.join(format(byte, 'b').zfill(4) for byte in _bytes)
        print
Ejemplo n.º 20
0
def load_ciphertext(saved_ciphertext):
    output = []
    for entry in slide(bytearray(saved_ciphertext), BLOCKSIZE * 2):
        output.extend(bytes_to_words(entry, 2))
    return output
Ejemplo n.º 21
0
def save_ciphertext(ciphertext):
    return ''.join(
        bytes(words_to_bytes(entry, 2))
        for entry in slide(ciphertext, BLOCKSIZE))
Ejemplo n.º 22
0
def load_public_key(saved_key):
    output = []
    for entry in slide(bytearray(saved_key), BLOCKSIZE * 2):
        output.extend(bytes_to_words(entry, 2))
    return output
Ejemplo n.º 23
0
def save_public_key(public_key):
    return ''.join(
        bytes(words_to_bytes(entry, 2))
        for entry in slide(public_key, BLOCKSIZE))
Ejemplo n.º 24
0
def load_ciphertext(saved_ciphertext):
    output = []
    for entry in slide(bytearray(saved_ciphertext), BLOCKSIZE * 2):
        output.extend(bytes_to_words(entry, 2))
    return output  
Ejemplo n.º 25
0
def load_public_key(saved_key):
    public_key = []
    for line in slide(saved_key, 16):
        public_key.append(bytes_to_words(line, 4))
    return public_key
Ejemplo n.º 26
0
def absorb(data, state, rate, mixing_subroutine, replacement_subroutine): 
    for block in slide(bytearray(data), rate.stop - rate.start):
        replacement_subroutine(state, block)
        mixing_subroutine(state)
Ejemplo n.º 27
0
def save_public_key(public_key):      
    return ''.join(bytes(words_to_bytes(entry, 2)) for entry in slide(public_key, BLOCKSIZE))
Ejemplo n.º 28
0
def decrypt(data, key, iv, mixing_subroutine, rate=32, **kwargs):
    decryptor = sponge_function(iv, key, mixing_subroutine=mixing_subroutine,
                                mode_of_operation=decryption_mode,
                                **kwargs)
    next(decryptor)    
    return ''.join(decryptor.send(block) for block in slide(data, rate))                    
Ejemplo n.º 29
0
def load_public_key(saved_key):    
    output = []
    for entry in slide(bytearray(saved_key), BLOCKSIZE * 2):
        output.extend(bytes_to_words(entry, 2))
    return output    
Ejemplo n.º 30
0
def save_ciphertext(ciphertext):
    return ''.join(bytes(words_to_bytes(entry, 2)) for entry in slide(ciphertext, BLOCKSIZE))
Ejemplo n.º 31
0
 def print_state(self, state, message):
     print(message)
     for word in slide(state, 4):
         print(' '.join(format(byte, 'b').zfill(8) for byte in word))
         print('')