Esempio n. 1
0
    def feistel_round(self, L, R, i):
        """
            Runs one round of the Feistel System on the given chunk

            Example:

            >>> cipher = ToyDesCipher(0b010011001)
            >>> cipher.feistel_round((0, 1, 1, 1, 0, 0), (1, 0, 0, 1, 1, 0), 4)
            ((1, 0, 0, 1, 1, 0), (0, 1, 1, 0, 0, 0))
        """
        K = self.rotate(self.key, i)
        return R, tuple(xor_streams(L, self.f(R, K)))
Esempio n. 2
0
    def f(cls, R, K):
        """
            The encryption function `f` in the DES algorithm

            Example:

            >>> ToyDesCipher.f([1, 0, 0, 1, 1, 0], [0, 1, 1, 0, 0, 1, 0, 1])
            (0, 0, 0, 1, 0, 0)
        """
        bits = tuple(xor_streams(cls.expand_bits(R), K))
        # Concatenate the output of the S-boxes.
        return cls.S1(bits[:4]) + cls.S2(bits[4:])
Esempio n. 3
0
    def feistel_round(self, L, R, i):
        """
            Runs the ith round of the Feistel System on the given chunk

            Example:
            >>> cipher = DesCipher(0x21347851283645)
            >>> bits = tuple(bits_of(0x178263487126234, 64))
            >>> cipher.feistel_round(bits[:32], bits[32:], 4)  # Run the fourth feitsel round
            ((0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0), (1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1))
        """
        K = self.keys[i]
        return R, tuple(xor_streams(L, self.f(R, K)))
Esempio n. 4
0
    def analyze(self, input1, input2):
        """
            Analyze the differences in the outputs with respect to the given inputs, when ran
            through the given cipher object.

            Example:

            >>> key = 0b001001101
            >>> cipher = ToyDesCipher(key, 3)
            >>> attack = ThreeRoundDifferentialCryptanalysis(cipher)
            >>> L1, R1 = (0, 0, 0, 1, 1, 1), (0, 1, 1, 0, 1, 1)
            >>> L1S, R1S = (1, 0, 1, 1, 1, 0), (0, 1, 1, 0, 1, 1)
            >>> attack.analyze((L1, R1), (L1S, R1S))
            ({(1, 0, 0, 1), (0, 0, 1, 1)}, {(1, 1, 0, 0), (0, 1, 1, 1)})
            >>> L1, R1 = (0, 1, 0, 1, 1, 1), (0, 1, 1, 0, 1, 1)
            >>> L1S, R1S = (1, 0, 1, 1, 1, 0), (0, 1, 1, 0, 1, 1)
            >>> attack.analyze((L1, R1), (L1S, R1S))
            ({(1, 0, 0, 1), (0, 0, 1, 0)}, {(1, 1, 0, 0), (0, 0, 1, 1)})
        """

        # Fun fact: pylint thinks there are too many local variables here. I say it should have seen
        # the implementation before I simplified it...
        L4, R4 = self.cipher.encrypt_chunk(input1, rounds=[2, 3, 4])
        L4S, R4S = self.cipher.encrypt_chunk(input2, rounds=[2, 3, 4])

        E4 = self.cipher.expand_bits(L4)
        E4S = self.cipher.expand_bits(L4S)

        # Ths S-boxe's input XOR, 4-bits each
        difference = tuple(xor_streams(E4, E4S))
        S1IX = bits_to_integer(difference[:4])
        S2IX = bits_to_integer(difference[4:])

        # The S-box output XOR, 6-bits
        SOX = tuple(
            xor_streams(xor_streams(input1[0], input2[0]),
                        xor_streams(R4, R4S)))

        poss1 = set()
        poss2 = set()
        # Iterate over all pairs a four bit numbers to compare the XOR of the S-box outputs
        for left, right in ThreeRoundDifferentialCryptanalysis.LOOKUP[S1IX]:
            left_bits = tuple(bits_of(left, 4))
            right_bits = tuple(bits_of(right, 4))
            if tuple(
                    xor_streams(self.cipher.S1(left_bits),
                                self.cipher.S1(right_bits))) == SOX[:3]:
                poss1.add(left_bits)

        for left, right in ThreeRoundDifferentialCryptanalysis.LOOKUP[S2IX]:
            left_bits = tuple(bits_of(left, 4))
            right_bits = tuple(bits_of(right, 4))
            if tuple(
                    xor_streams(self.cipher.S2(left_bits),
                                self.cipher.S2(right_bits))) == SOX[3:]:
                poss2.add(left_bits)

        return poss1, poss2
Esempio n. 5
0
    def f(cls, R, K):
        """
            The encryption function `f` in the DES algorithm

            Example:
            >>> R = tuple(bits_of(0x978612348976, 32))
            >>> K = tuple(bits_of(0x234626727892, 48))
            >>> DesCipher.f(R, K)
            [0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1]
        """
        bits = tuple(xor_streams(cls.expand_bits(R), K))
        Bs = nslice(bits, 6)
        Ss = [cls.s_box(i, bits) for i, bits in enumerate(Bs)]
        C = list(itertools.chain.from_iterable(Ss))
        return cls.permute(C, cls._sbox_permutation)
Esempio n. 6
0
    def decrypt(self, ciphertext):
        """
            Decrypts the given ciphertext with a LFSR Cipher.

            Example:

            >>> import numpy
            >>> initial_values = numpy.array([1, 0, 1, 0, 0, 1])
            >>> coeffs = numpy.array([1, 1, 0, 1, 1, 0])
            >>> cipher = LfsrCipher(initial_values, coeffs)
            >>> cipher.decrypt('\x04A\x82')
            'abc'
        """
        cipher_stream = TextBitstream(ciphertext)
        cipher_bits = xor_streams(cipher_stream, self.decode_key_stream)

        return bits_to_string(cipher_bits)
Esempio n. 7
0
    def encrypt(self, message):
        """
            Encrypts the given message with a LFSR Cipher.

            Example:

            >>> import numpy
            >>> initial_values = numpy.array([1, 0, 1, 0, 0, 1])
            >>> coeffs = numpy.array([1, 1, 0, 1, 1, 0])
            >>> cipher = LfsrCipher(initial_values, coeffs)
            >>> cipher.encrypt('abc')
            '\\x04A\\x82'
        """
        message_stream = TextBitstream(preprocess(message))
        cipher_bits = xor_streams(message_stream, self.encode_key_stream)

        return bits_to_string(cipher_bits)