Exemple #1
0
    def _and(self, ciphertext1, ciphertext2, modulus=DEFAULT_MODULUS):
        # sets bit1 to (bit1 & bit2)
        temp = Bit.copy(ciphertext2, self.public_key)

        self.adjust_level(ciphertext1, temp)
        addition_subroutine(ciphertext1.value, temp.value, modulus)
        ciphertext1.depth += 1
 def _and(self, ciphertext1, ciphertext2, modulus=DEFAULT_MODULUS):
     # sets bit1 to (bit1 & bit2)
     temp = Bit.copy(ciphertext2, self.public_key)
                 
     self.adjust_level(ciphertext1, temp)                           
     addition_subroutine(ciphertext1.value, temp.value, modulus)
     ciphertext1.depth += 1        
Exemple #3
0
def test_encode_decode():
    data1 = bytearray(1)
    data2 = bytearray(1)
    data1[0] = 1
    data2[0] = 2
    encoded_data1 = encode(data1)
    encoded_data2 = encode(data2)    
    addition_subroutine(encoded_data1, encoded_data2, DEFAULT_MODULUS)
    assert decode(encoded_data1)[0] == 3, (decode(encoded_data1)[0], 3)
Exemple #4
0
def test_encode_decode():
    data1 = bytearray(1)
    data2 = bytearray(1)
    data1[0] = 1
    data2[0] = 2
    encoded_data1 = encode(data1)
    encoded_data2 = encode(data2)
    addition_subroutine(encoded_data1, encoded_data2, DEFAULT_MODULUS)
    assert decode(encoded_data1)[0] == 3, (decode(encoded_data1)[0], 3)
Exemple #5
0
 def cipher(message, key, iv=None, mode=None):
     data = bytearray(message) 
     key = bytearray(key)
     if iv is not None:
         addition_subroutine(data, bytearray(iv), 256)
     output = bytearray()        
     for block in slide(data, 16):
         addition_subroutine(block, output[-16:], 256)
         output.extend(encrypt(block, key, rounds=4))                
     return output
Exemple #6
0
 def cipher(message, key, iv=None, mode=None):
     data = bytearray(message)
     key = bytearray(key)
     if iv is not None:
         addition_subroutine(data, bytearray(iv), 256)
     output = bytearray()
     for block in slide(data, 16):
         addition_subroutine(block, output[-16:], 256)
         output.extend(encrypt(block, key, rounds=4))
     return output
def verify(data, signature, public_key, modulus=256):
    """ Verify a 256 bit signature using the public key. """
    validator = bytearray(32)        
    for count, byte in enumerate(signature):         
        for bit in range(8):            
            if byte & 1:                       
                addition_subroutine(validator, public_key[(count * 8) + bit], modulus)
            byte >>= 1  
    if validator == data:
        return True
    else:
        return False       
 def distribute(self, ciphertext1, ciphertext2, ciphertext3, modulus=DEFAULT_MODULUS):
     """ Computes a & (b ^ c) """
     if ciphertext2.depth or ciphertext3.depth:
         raise ValueError("Cannot distribute unless term depth == 0;\nciphertext2.depth: {}; ciphertext3.depth: {};".format(ciphertext1.depth, ciphertext2.depth))
         
     temp = Bit.copy(ciphertext2, self.public_key)
     temp2 = Bit.copy(ciphertext3, self.public_key)
     temp.increase_depth(1)
     addition_subroutine(temp.value, temp2.value, modulus)
     print publickey.decrypt(temp.value, _UNIT_TEST_PRIVATE_KEY)
     multiplication_subroutine(temp.value, [3 for count in range(len(ciphertext1.value))], modulus)        
     print publickey.decrypt(temp.value, _UNIT_TEST_PRIVATE_KEY)        
     self._and(ciphertext1, temp, modulus)                
Exemple #9
0
def verify(data, signature, public_key, modulus=256):
    """ Verify a 256 bit signature using the public key. """
    validator = bytearray(32)
    for count, byte in enumerate(signature):
        for bit in range(8):
            if byte & 1:
                addition_subroutine(validator, public_key[(count * 8) + bit],
                                    modulus)
            byte >>= 1
    if validator == data:
        return True
    else:
        return False
Exemple #10
0
def test_encrypt_decrypt():
    message = bytearray("Testing!" * 256)
    key = generate_key()
    ciphertext = encrypt(message, key)
    plaintext = decrypt(ciphertext, key)    
    assert plaintext == message, (plaintext, message)
                
    message2 = bytearray(range(16))
    message3 = bytearray(range(1, 17))
    answer = bytearray((message2[index] + message3[index]) % 256 for index in range(len(message2)))
    ciphertext2 = encrypt(message2, key)
    ciphertext3 = encrypt(message3, key)
    addition_subroutine(ciphertext2, ciphertext3, 256)
    _answer = decrypt(ciphertext2, key)
    assert _answer == answer, (_answer, answer)    
Exemple #11
0
def test_encrypt_decrypt():
    public_key, private_key = generate_keypair()
    message = "Testing!"
    ciphertext = encrypt(message, public_key)
    plaintext = decrypt(ciphertext, private_key)
    assert plaintext == message, (plaintext, message)

    ciphertext2 = encrypt(message, public_key)
    assert ciphertext2 != ciphertext, "Ciphertexts are not randomized"
    plaintext2 = decrypt(ciphertext2, private_key)
    assert plaintext2 == message

    addition_subroutine(ciphertext, ciphertext2, DEFAULT_MODULUS)
    addition_subroutine(plaintext, plaintext2, DEFAULT_MODULUS)
    plaintext3 = decrypt(ciphertext, private_key)
    assert plaintext3 == plaintext
    print "Passed public key encryption and private key decryption unit test"
Exemple #12
0
def test_encode_decode():
    data1 = list(bytearray(8))
    data2 = list(bytearray(8))
    data1[0] = 1
    data2[0] = 2
    _data1 = encode(data1)
    _data1 = decode(_data1)
    assert _data1 == data1, (_data1, data1)

    correct_answer = data1[:]
    addition_subroutine(correct_answer, data2, DEFAULT_MODULUS)

    data1 = encode(data1)
    data2 = encode(data2)
    addition_subroutine(data1, data2, DEFAULT_MODULUS)
    answer = decode(data1)
    assert answer == correct_answer
def test_encrypt_decrypt():
    public_key, private_key = generate_keypair()
    message = "Testing!"
    ciphertext = encrypt(message, public_key)     
    plaintext = decrypt(ciphertext, private_key)
    assert plaintext == message, (plaintext, message)
    
    ciphertext2 = encrypt(message, public_key)
    assert ciphertext2 != ciphertext, "Ciphertexts are not randomized"
    plaintext2 = decrypt(ciphertext2, private_key)
    assert plaintext2 == message            
    
    addition_subroutine(ciphertext, ciphertext2, DEFAULT_MODULUS)
    addition_subroutine(plaintext, plaintext2, DEFAULT_MODULUS)
    plaintext3 = decrypt(ciphertext, private_key)
    assert plaintext3 == plaintext
    print "Passed public key encryption and private key decryption unit test"
Exemple #14
0
def test_encode_decode():
    data1 = list(bytearray(8))
    data2 = list(bytearray(8))
    data1[0] = 1
    data2[0] = 2
    _data1 = encode(data1)
    _data1 = decode(_data1)
    assert _data1 == data1, (_data1, data1)
    
    correct_answer = data1[:]        
    addition_subroutine(correct_answer, data2, DEFAULT_MODULUS)
        
    data1 = encode(data1)
    data2 = encode(data2)    
    addition_subroutine(data1, data2, DEFAULT_MODULUS)    
    answer = decode(data1)
    assert answer == correct_answer     
Exemple #15
0
def encrypt(message,
            public_key,
            ciphertext_count=16,
            prng=lambda amount: bytearray(urandom(amount)),
            modulus=DEFAULT_MODULUS,
            blocksize=BLOCKSIZE):
    """ usage: encrypt(message : bytes, public_key : bytearray) => ciphertext : bytearray
    
        Public key encryption method, based on homomorphic encryption.
        A public key consists of encryptions of the numbers 0-255, in order.
        All math is done on ciphertexts:
            - To encrypt one byte, add together a random subset of integers such that the sum equals the message byte.
                - c = r1 + r2 + r3 ... + rN + (m - (r1 + r2 + r3 ... + rN))
                      
        Encryption can send one 8-bit value per 256-bit ciphertext. This results in a 32x increase in data size. 
        Ciphertexts are partially homormophic. 
        
        Works on arbitrarily long messages, albeit one byte at a time. Output is the concatenation of the ciphertexts.
        This method only provides confidentiality of the message, it does not provide message integrity. """
    output = []
    size = len(message)
    key_bytes = iter(prng(size * ciphertext_count))
    assert not isinstance(message, int)
    null_block = [0 for count in range(blocksize)]
    for symbol in (bytearray(message)
                   if isinstance(message, str) else message):
        ciphertext_byte = null_block[:]
        _key_byte = 0
        for count in range(ciphertext_count):
            key_byte = next(key_bytes)
            _key_byte += key_byte
            ciphertext_key_byte = public_key[key_byte *
                                             blocksize:(key_byte + 1) *
                                             blocksize]
            #print len(ciphertext_key_byte), key_byte, blocksize, len(public_key), key_byte * blocksize, (key_byte + 1) * blocksize
            addition_subroutine(ciphertext_byte, ciphertext_key_byte, modulus)

        final_key_byte = modular_subtraction(symbol, _key_byte, modulus)
        final_ciphertext = public_key[final_key_byte *
                                      blocksize:(final_key_byte + 1) *
                                      blocksize]
        addition_subroutine(ciphertext_byte, final_ciphertext, modulus)
        output.extend(ciphertext_byte)
    return output
Exemple #16
0
def test_encrypt_decrypt():
    data_size = 8
    message = list(bytearray(data_size))
    _message = message[:]
    key = generate_key(data_size)
    encrypt(message, key)
    decrypt(message, key)
    assert message == _message, (message, _message)

    message2 = list(bytearray(range(8)))
    message3 = list(bytearray(reversed(range(8))))
    answer = list(
        bytearray((message2[index] + message3[index]) % DEFAULT_MODULUS
                  for index in range(8)))
    answer2 = list(
        bytearray((message2[index] * message3[index]) % DEFAULT_MODULUS
                  for index in range(8)))
    encrypt(message2, key)
    encrypt(message3, key)
    _m2, _m3 = message2[:], message3[:]
    addition_subroutine(message2, message3, DEFAULT_MODULUS)
    multiplication_subroutine(_m2, _m3, DEFAULT_MODULUS)

    _message2 = decrypt(message2, key, multiplier=1)
    __m2 = decrypt(_m2, key, multiplier=2)
    # print [byte for byte in _message2], [byte for byte in answer]
    # print [byte for byte in __m2], [byte for byte in answer2], __m2 == answer2, len(__m2), len(answer2), type(__m2), type(answer2)
    if _message2 == answer:
        print("Ciphertexts support addition")
    else:
        print("Ciphertexts do not support addition")
    if __m2 == answer2:
        print("Ciphertexts support multiplication")
    else:
        print("Ciphertexts do not support multiplication")

    def test_function(data, key, iv, mode=None):
        keysize, data_size = len(key), len(data) / 2
        key = bytearray(key)
        if keysize < data_size * 3:
            key.extend(urandom((data_size * 3) - keysize))
        data = bytearray(data[:data_size])
        encrypt(data, bytearray(key))
        return bytes(data)
Exemple #17
0
def test_homomorphic_permutation(_encrypt, _decrypt):    
    ROUNDS = 10
    data = bytearray(8)
    data[0] = 1
    key = generate_key(len(data))
    _data = data[:]
    
    ciphertext1 = _encrypt(data, key, ROUNDS)        
    print("Ciphertext1: {}".format(list(ciphertext1)))
    data = _decrypt(ciphertext1, key, ROUNDS)
    assert data == _data, (data, _data)
               
    data2 = bytearray(8)
    data2[0] = 2
    _data2 = data2[:]
    ciphertext2 = _encrypt(data2, key, ROUNDS)    
    
    print("Ciphertext2: {}".format(list(ciphertext2)))
    data2 = _decrypt(ciphertext2, key, ROUNDS)
    assert data2 == _data2, (data2, _data2)
            
    addition_subroutine(ciphertext1, ciphertext2, 256)
    print("Ciphertext1 + Ciphertext2: {}".format(list(ciphertext1))) 
    addition_subroutine(data, data2, 256)    
    
    ciphertext1 = _decrypt(ciphertext1, key, ROUNDS, multiplier=2)
    assert ciphertext1 == data, (ciphertext1, data)    
    
    message0 = bytearray(urandom(8))
    message1 = bytearray(urandom(8))
    message2 = bytearray(urandom(8))
    message0[0] = 1
    message1[0] = 2
    message2[0] = 3
    _encrypt(message0, key, ROUNDS)
    _encrypt(message1, key, ROUNDS)
    _encrypt(message2, key, ROUNDS)
    addition_subroutine(message0, message1, 256)
    addition_subroutine(message0, message2, 256)    
    _decrypt(message0, key, ROUNDS, multiplier=2)
    assert message0[0] == 1 + 2 + 3, message1
    
    data = bytearray(urandom(8))
    data2 = bytearray(urandom(8))
    data[0] = 7
    data2[0] = 131
    print("Data: {}".format(list(data)))
    print("Data2: {}".format(list(data2)))
    _encrypt(data, key, ROUNDS)
    _encrypt(data2, key, ROUNDS)
    print("Ciphertext: {}".format(list(data)))
    print("Ciphertext2: {}".format(list(data2)))
Exemple #18
0
def test_homomorphic_permutation(_encrypt, _decrypt):
    ROUNDS = 10
    data = bytearray(8)
    data[0] = 1
    key = generate_key(len(data))
    _data = data[:]

    ciphertext1 = _encrypt(data, key, ROUNDS)
    print("Ciphertext1: {}".format(list(ciphertext1)))
    data = _decrypt(ciphertext1, key, ROUNDS)
    assert data == _data, (data, _data)

    data2 = bytearray(8)
    data2[0] = 2
    _data2 = data2[:]
    ciphertext2 = _encrypt(data2, key, ROUNDS)

    print("Ciphertext2: {}".format(list(ciphertext2)))
    data2 = _decrypt(ciphertext2, key, ROUNDS)
    assert data2 == _data2, (data2, _data2)

    addition_subroutine(ciphertext1, ciphertext2, 256)
    print("Ciphertext1 + Ciphertext2: {}".format(list(ciphertext1)))
    addition_subroutine(data, data2, 256)

    ciphertext1 = _decrypt(ciphertext1, key, ROUNDS, multiplier=2)
    assert ciphertext1 == data, (ciphertext1, data)

    message0 = bytearray(urandom(8))
    message1 = bytearray(urandom(8))
    message2 = bytearray(urandom(8))
    message0[0] = 1
    message1[0] = 2
    message2[0] = 3
    _encrypt(message0, key, ROUNDS)
    _encrypt(message1, key, ROUNDS)
    _encrypt(message2, key, ROUNDS)
    addition_subroutine(message0, message1, 256)
    addition_subroutine(message0, message2, 256)
    _decrypt(message0, key, ROUNDS, multiplier=2)
    assert message0[0] == 1 + 2 + 3, message1

    data = bytearray(urandom(8))
    data2 = bytearray(urandom(8))
    data[0] = 7
    data2[0] = 131
    print("Data: {}".format(list(data)))
    print("Data2: {}".format(list(data2)))
    _encrypt(data, key, ROUNDS)
    _encrypt(data2, key, ROUNDS)
    print("Ciphertext: {}".format(list(data)))
    print("Ciphertext2: {}".format(list(data2)))
Exemple #19
0
    def distribute(self,
                   ciphertext1,
                   ciphertext2,
                   ciphertext3,
                   modulus=DEFAULT_MODULUS):
        """ Computes a & (b ^ c) """
        if ciphertext2.depth or ciphertext3.depth:
            raise ValueError(
                "Cannot distribute unless term depth == 0;\nciphertext2.depth: {}; ciphertext3.depth: {};"
                .format(ciphertext1.depth, ciphertext2.depth))

        temp = Bit.copy(ciphertext2, self.public_key)
        temp2 = Bit.copy(ciphertext3, self.public_key)
        temp.increase_depth(1)
        addition_subroutine(temp.value, temp2.value, modulus)
        print publickey.decrypt(temp.value, _UNIT_TEST_PRIVATE_KEY)
        multiplication_subroutine(
            temp.value, [3 for count in range(len(ciphertext1.value))],
            modulus)
        print publickey.decrypt(temp.value, _UNIT_TEST_PRIVATE_KEY)
        self._and(ciphertext1, temp, modulus)
Exemple #20
0
def test_encrypt_decrypt():
    data_size = 8
    message = list(bytearray(data_size))
    _message = message[:]
    key = generate_key(data_size)
    encrypt(message, key)    
    decrypt(message, key)
    assert message == _message, (message, _message)
    
    message2 = list(bytearray(range(8)))
    message3 = list(bytearray(reversed(range(8))))
    answer = list(bytearray((message2[index] + message3[index]) % DEFAULT_MODULUS for index in range(8)))
    answer2 = list(bytearray((message2[index] * message3[index]) % DEFAULT_MODULUS for index in range(8)))
    encrypt(message2, key)
    encrypt(message3, key)
    _m2, _m3 = message2[:], message3[:]
    addition_subroutine(message2, message3, DEFAULT_MODULUS)
    multiplication_subroutine(_m2, _m3, DEFAULT_MODULUS)
    
    _message2 = decrypt(message2, key, multiplier=1)
    __m2 = decrypt(_m2, key, multiplier=2)
   # print [byte for byte in _message2], [byte for byte in answer]
   # print [byte for byte in __m2], [byte for byte in answer2], __m2 == answer2, len(__m2), len(answer2), type(__m2), type(answer2)
    if _message2 == answer:
        print("Ciphertexts support addition")
    else:
        print("Ciphertexts do not support addition")
    if __m2 == answer2:
        print("Ciphertexts support multiplication")
    else:
        print("Ciphertexts do not support multiplication")
        
    def test_function(data, key, iv, mode=None):
        keysize, data_size = len(key), len(data) / 2
        key = bytearray(key)
        if keysize < data_size * 3:
            key.extend(urandom((data_size * 3) - keysize))
        data = bytearray(data[:data_size])
        encrypt(data, bytearray(key))
        return bytes(data)
def encrypt(message, public_key, ciphertext_count=16, 
            prng=lambda amount: bytearray(urandom(amount)),
            modulus=DEFAULT_MODULUS, blocksize=BLOCKSIZE):
    """ usage: encrypt(message : bytes, public_key : bytearray) => ciphertext : bytearray
    
        Public key encryption method, based on homomorphic encryption.
        A public key consists of encryptions of the numbers 0-255, in order.
        All math is done on ciphertexts:
            - To encrypt one byte, add together a random subset of integers such that the sum equals the message byte.
                - c = r1 + r2 + r3 ... + rN + (m - (r1 + r2 + r3 ... + rN))
                      
        Encryption can send one 8-bit value per 256-bit ciphertext. This results in a 32x increase in data size. 
        Ciphertexts are partially homormophic. 
        
        Works on arbitrarily long messages, albeit one byte at a time. Output is the concatenation of the ciphertexts.
        This method only provides confidentiality of the message, it does not provide message integrity. """
    output = []
    size = len(message)
    key_bytes = iter(prng(size * ciphertext_count))        
    assert not isinstance(message, int)
    null_block = [0 for count in range(blocksize)]
    for symbol in (bytearray(message) if isinstance(message, str) else message):
        ciphertext_byte = null_block[:]
        _key_byte = 0
        for count in range(ciphertext_count):        
            key_byte = next(key_bytes)
            _key_byte += key_byte               
            ciphertext_key_byte = public_key[key_byte * blocksize:(key_byte + 1) * blocksize]               
            #print len(ciphertext_key_byte), key_byte, blocksize, len(public_key), key_byte * blocksize, (key_byte + 1) * blocksize
            addition_subroutine(ciphertext_byte, ciphertext_key_byte, modulus)
           
        final_key_byte = modular_subtraction(symbol, _key_byte, modulus)          
        final_ciphertext = public_key[final_key_byte * blocksize:(final_key_byte + 1) * blocksize]          
        addition_subroutine(ciphertext_byte, final_ciphertext, modulus)                     
        output.extend(ciphertext_byte)
    return output
Exemple #22
0
def test_encrypt_decrypt():
    from utilities import addition_subroutine
    key = generate_key()
    ciphertext1 = encrypt([1], key)
    ciphertext2 = encrypt([2], key)        
    addition_subroutine(ciphertext1, ciphertext2, DEFAULT_MODULUS)
    addition_subroutine(ciphertext1, ciphertext2, DEFAULT_MODULUS)
    answer = decrypt(ciphertext1, key)
    assert answer == [5], answer    
    
    data = [1 << count for count in range(8)]
    data2 = bytearray(urandom(8))
    correct_answer = [(data[index] + data2[index]) % DEFAULT_MODULUS for index in range(8)]
    ciphertext1 = encrypt(data, key)
    ciphertext2 = encrypt(data2, key)
    
    addition_subroutine(ciphertext1, ciphertext2, DEFAULT_MODULUS)
    answer = decrypt(ciphertext1, key)
    assert answer == correct_answer, (answer, correct_answer)
Exemple #23
0
def test_encrypt_decrypt():
    from utilities import addition_subroutine
    key = generate_key()
    ciphertext1 = encrypt([1], key)
    ciphertext2 = encrypt([2], key)
    addition_subroutine(ciphertext1, ciphertext2, DEFAULT_MODULUS)
    addition_subroutine(ciphertext1, ciphertext2, DEFAULT_MODULUS)
    answer = decrypt(ciphertext1, key)
    assert answer == [5], answer

    data = [1 << count for count in range(8)]
    data2 = bytearray(urandom(8))
    correct_answer = [(data[index] + data2[index]) % DEFAULT_MODULUS
                      for index in range(8)]
    ciphertext1 = encrypt(data, key)
    ciphertext2 = encrypt(data2, key)

    addition_subroutine(ciphertext1, ciphertext2, DEFAULT_MODULUS)
    answer = decrypt(ciphertext1, key)
    assert answer == correct_answer, (answer, correct_answer)
def homomorphic_xor(ciphertext1, ciphertext2, modulus=DEFAULT_MODULUS):
    addition_subroutine(ciphertext1, ciphertext2, modulus)
def homomorphic_and(ciphertext1,
                    ciphertext2,
                    operation_count,
                    modulus=DEFAULT_MODULUS):
    addition_subroutine(ciphertext1, ciphertext2, modulus)
    return operation_count + 1
Exemple #26
0
    def xor(self, ciphertext1, ciphertext2, modulus=DEFAULT_MODULUS):
        temp = Bit.copy(ciphertext2, self.public_key)

        self.adjust_level(ciphertext1, temp)
        addition_subroutine(ciphertext1.value, temp.value, modulus)
 def xor(self, ciphertext1, ciphertext2, modulus=DEFAULT_MODULUS):
     temp = Bit.copy(ciphertext2, self.public_key)
             
     self.adjust_level(ciphertext1, temp)                
     addition_subroutine(ciphertext1.value, temp.value, modulus)        
def homomorphic_and(ciphertext1, ciphertext2, operation_count, modulus=DEFAULT_MODULUS):
    addition_subroutine(ciphertext1, ciphertext2, modulus)    
    return operation_count + 1
def homomorphic_xor(ciphertext1, ciphertext2, modulus=DEFAULT_MODULUS):    
    addition_subroutine(ciphertext1, ciphertext2, modulus)