예제 #1
0
class Test(unittest.TestCase):

    def setUp(self):
        self.keygen = KeyGenerator()
        logging.basicConfig(filename="log.txt", 
                            level=logging.INFO, 
                            filemode="w",
                            format="%(message)s")

    def test_factorize(self):
        p = get_random_prime(32)
        factorization = factorize(p - 1)
        q = 1
        for factor in factorization.items():
            q *= factor[0]**factor[1]

        self.assertEqual(q + 1, p)

    def test_gelfond(self):
        gelfond = GelfondAttack(2)
        y, g, p = self.keygen.get_key(16)
        x = gelfond.attack((y, g, p))
        self.assertEqual(pow(g, x, p), y)

    def test_pohlig_hellman(self):
        pohlig_hellman = PohligHellmanAttack()
        y, g, p = self.keygen.get_vulnerable_pohlig_hellman_key(128)
        x = pohlig_hellman.attack((y, g, p))
        self.assertEqual(pow(g, x, p), y)

    def test_rho_pollard(self):
        rho_pollard = RhoPollardAttack()
        y, g, p = self.keygen.get_key(16)
        x = rho_pollard.attack((y, g, p))
        self.assertEqual(pow(g, x, p), y)        
예제 #2
0
    def __init__(self, key, ROUNDS=8):
        self.BLOCK_SIZE = 128
        self.ROUNDS = ROUNDS

        self.key = key
        self.keygen = KeyGenerator(key)
        self._gen_keys()
        self.debug = False
예제 #3
0
 def reduce_subkey(self, rmatrix, subkey):
     _subkey = []
     for i in range(8):
         seedkey = rmatrix[(i * 8):((i + 1) * 8)].tolist()
         sbox = KeyGenerator.get_sbox(sum(seedkey))
         matkey = subkey[(i * 12):((i + 1) * 12)]
         matkey_str = ''.join([str(x) for x in matkey])
         row, col = int(matkey_str[6], 2), int(matkey_str[6:12], 2)
         _subkey.append('{:08b}'.format(sbox[row][col]))
     return [int(c) for x in _subkey for c in x]
예제 #4
0
class PEA():
    def __init__(self, key):
        self.key_gen = KeyGenerator(key)
        self.matrix_permute = MatrixPermute(self.key_gen.seed)
        self.subkeys = self.key_gen.get_subkeys()

    def encrypt(self, bits, decrypt=False):
        '''
            bits: list of 0s and 1s
        '''
        if len(bits) != 256:
            raise Exception('Length of bits must be 256')
        b1, b2, b3, b4 = bits[:64], bits[64:128], bits[128:192], bits[192:256]
        m1 = self.matrix_permute.permute(b1)
        m2 = self.matrix_permute.permute(b2)
        m3 = self.matrix_permute.permute(b3)
        m4 = self.matrix_permute.permute(b4)

        subkeys_1 = self.subkeys[:16]
        f1 = Feistel(m1, m2, subkeys_1)
        if decrypt:
            f1.decipher()
        else:
            f1.encipher()

        subkeys_2 = self.subkeys[16:32]
        f2 = Feistel(m3, m4, subkeys_2)
        if decrypt:
            f2.decipher()
        else:
            f2.encipher()

        m1 = self.matrix_permute.permute(f1.lmatrix, True)
        m2 = self.matrix_permute.permute(f1.rmatrix, True)
        m3 = self.matrix_permute.permute(f2.lmatrix, True)
        m4 = self.matrix_permute.permute(f2.rmatrix, True)

        return m1.tolist() + m2.tolist() + m3.tolist() + m4.tolist()
예제 #5
0
 def setUp(self):
     self.keygen = KeyGenerator()
     logging.basicConfig(filename="log.txt", 
                         level=logging.INFO, 
                         filemode="w",
                         format="%(message)s")
예제 #6
0
            self.lmatrix = self.round_function(self.rmatrix, self.lmatrix,
                                               inv_subkeys[i])
            self.rmatrix = temp


def xor_bit(bits1, bits2):
    bits1_str = ''.join([str(x) for x in bits1])
    bits2_str = ''.join([str(x) for x in bits2])
    res_xor = '{:064b}'.format(int(bits1_str, 2) ^ int(bits2_str, 2))
    return np.asarray([int(x) for x in res_xor])


if __name__ == '__main__':
    import random

    k = KeyGenerator('hello adelle')
    matrix_permute = MatrixPermute(k.seed)
    m0 = [random.randint(0, 1) for i in range(64)]
    m0 = matrix_permute.permute(m0)

    m1 = [random.randint(0, 1) for i in range(64)]
    m1 = matrix_permute.permute(m1)
    f = Feistel(m0, m1, k.get_subkeys()[:16])
    subkey = f.reduce_subkey(f.rmatrix, f.subkeys[0])
    print(subkey)
    print(xor_bit(subkey, [0] * 64))
    f.encipher()
    f.decipher()
    print(f.lmatrix.tolist() == m0.tolist())
    print(f.rmatrix.tolist() == m1.tolist())
예제 #7
0
 def __init__(self, key):
     self.key_gen = KeyGenerator(key)
     self.matrix_permute = MatrixPermute(self.key_gen.seed)
     self.subkeys = self.key_gen.get_subkeys()
예제 #8
0
        for j in range(level, end_idx):
            matrix[level, j] = nums[c]
            c += 1
        for i in range(level + 1, end_idx - 1):
            matrix[i, end_idx - 1] = nums[c]
            c += 1

        for j in range(end_idx - 1, level - 1, -1):
            matrix[end_idx - 1, j] = nums[c]
            c += 1
        for i in range(end_idx - 2, level, -1):
            matrix[i, level] = nums[c]
            c += 1

    def circular_shift(self, bits, n, clockwise):
        if clockwise:
            return bits[n:] + bits[:n]
        return bits[-n:] + bits[:-n]


if __name__ == '__main__':
    from keygen import KeyGenerator
    key_gen = KeyGenerator('whooo hooaa hoooaaawjkzhsejzksehzjskej anymoooree')
    matrix_permute = MatrixPermute(key_gen.seed)
    random.seed(1)

    m0 = [random.randint(0, 1) for i in range(64)]
    m1 = matrix_permute.permute(m0)
    m2 = matrix_permute.permute(m1, True)
    print(m0 == m2)
예제 #9
0
from random import choice
import logging

if __name__ == "__main__":
    print("1. Key analyzer.")
    print("2. Weak Pohlig-Hellman key generator.")

    n = ""
    while n != "1" and n != "2":
        n = input()

    if n == "2":
        print("Enter key length:")
        n = int(input())
        keygen = KeyGenerator()
        y, g, p = keygen.get_vulnerable_pohlig_hellman_key(n)
        print("y =", y)
        print("g =", g)
        print("p =", p)

    elif n == "1":
        logging.basicConfig(filename="log.txt",
                            level=logging.INFO,
                            filemode="w",
                            format="%(message)s")
        print("Enter time limit:")
        n = int(input())
        print("Enter modulo:")
        p = int(input())
        print("Enter primitive root of group:")
예제 #10
0
class Chiper():
    _S_BOX = [0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
              0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
              0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
              0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
              0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
              0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
              0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
              0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
              0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
              0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
              0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
              0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
              0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
              0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
              0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
              0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16]
    _PERMUTATION_TABLE = [0, 7, 2, 5, 3, 1, 4, 6]

    def __init__(self, key, ROUNDS=8):
        self.BLOCK_SIZE = 128
        self.ROUNDS = ROUNDS

        self.key = key
        self.keygen = KeyGenerator(key)
        self._gen_keys()
        self.debug = False
    
    def _transform(self, block, key, n_bit_rearrange):
        """
        Internal transformation function.
        """
        # Xor with key
        if self.debug:
            print("xor with key")
            print("before :", block)
        res1 = xorblock(block, key)
        if self.debug:
            print("after :", res1)
            print()

        # bit rearrange
        temp_bit = BitArray(bytes=res1).bin
        if self.debug:
            print("bit rearrange")
            print("before :", temp_bit)
        temp = ""
        for i in range(n_bit_rearrange):
            temp += temp_bit[i::n_bit_rearrange]
        res2 = int(temp, 2).to_bytes(self.BLOCK_SIZE // 2 // 8, "big")
        if self.debug:
            print("after :", temp)
            print()

        # S-BOX
        if self.debug:
            print("byte substitution")
            print("before :", res2)
        res3 = b""
        for c in res2:
            res3 += bytes([self._S_BOX[c]])
        if self.debug:
            print("after :", res3)
            print()

        # permutation
        if self.debug:
            print("byte permutation")
            print("before :", res3)
        temp = []
        for n in self._PERMUTATION_TABLE:
            temp.append(res3[n])
        block_result = bytes(temp)
        if self.debug:
            print("after :", block_result)
            print()

        return block_result

    def _split(self, block):
        """
        This function is used to split `block` into L and R for feistel network.
        """
        L = block[:self.BLOCK_SIZE // 2 // 8]
        R = block[self.BLOCK_SIZE // 2 // 8:]
        return L, R
    
    def _merge(self, L, R):
        """
        This function is used to merge L and R from feistel network into a block.
        Should reversible from `Chiper.split()`
        """
        block = L + R
        return block
    
    def _gen_keys(self):
        # Generated the keys used for process.
        keygen = self.keygen.gen()
        self.keys = [] 
        for r in range(self.ROUNDS):
            self.keys.append(next(keygen))
    
    def encode_block(self, block):
        next_L, next_R = self._split(block)

        print()
        print("Encrypt")

        for round in range(self.ROUNDS):
            if round == 0:
                self.debug = True
            else:
                self.debug = False
            prev_L, prev_R = next_L, next_R
            current_key = self.keys[round]

            if self.debug:
                print("Left :", prev_L)
                print("Right :", prev_R)
                print()

            next_L = prev_R
            next_R = xorblock(prev_L, self._transform(prev_R, current_key, 2))
        
        return self._merge(next_L, next_R)
    
    def decode_block(self, block):
        prev_L, prev_R = self._split(block)

        print()
        print("Decrypt")

        for round in reversed(range(self.ROUNDS)):
            if round == 0:
                self.debug = True
            else:
                self.debug = False
            next_L, next_R = prev_L, prev_R
            current_key = self.keys[round]

            if self.debug:
                print("Left :", prev_L)
                print("Right :", prev_R)
                print()

            prev_R = next_L
            prev_L = xorblock(next_R, self._transform(next_L, current_key, 2))
        
        return self._merge(prev_L, prev_R)