Exemplo n.º 1
0
    def decrypt(self, ciphertext: bytes) -> Bytes:
        """
        Decrypts `ciphertext`.

        Parameters:
            ciphertext (bytes): Bytes-like object to be decrypted.
        
        Returns:
            Bytes: Resulting plaintext.
        """
        ciphertext = Bytes.wrap(ciphertext).zfill(self.block_size // 4)

        A = ciphertext[:self.block_size // 8].int()
        B = ciphertext[self.block_size // 8:].int()

        for i in range(self.num_rounds, 0, -1):
            B = right_rotate((B - self.S[2 * i + 1]) % self.mod,
                             A % self.block_size,
                             bits=self.block_size) ^ A
            A = right_rotate((A - self.S[2 * i]) % self.mod,
                             B % self.block_size,
                             bits=self.block_size) ^ B

        A = (A - self.S[0]) % self.mod
        B = (B - self.S[1]) % self.mod

        return Bytes(
            (Bytes(A, 'little').zfill(self.block_size // 8) +
             Bytes(B, 'little').zfill(self.block_size // 8)).int()).zfill(
                 self.block_size // 4)
Exemplo n.º 2
0
def Q_PERMUTE(x, Q):
    a_0, b_0 = x // 16, x % 16
    a_1 = a_0 ^ b_0
    b_1 = (a_0 ^ right_rotate(b_0, 1, bits=4) ^ (a_0 * 8)) % 16

    a_2, b_2 = Q[0][a_1], Q[1][b_1]
    a_3 = a_2 ^ b_2
    b_3 = (a_2 ^ right_rotate(b_2, 1, bits=4) ^ (a_2 * 8)) % 16

    a_4, b_4 = Q[2][a_3], Q[3][b_3]
    return (b_4 * 16) + a_4
Exemplo n.º 3
0
    def compression_func(self, block: bytes, state: bytes) -> Bytes:
        """
        SHA-2 compression function.

        Parameters:
            block (bytes): Block being digested.
            state (bytes): Current digest state.
        
        Returns:
            Bytes: Hash output.
        """
        bit_mask = 0xFFFFFFFF if self.state_size == 4 else 0xFFFFFFFFFFFFFFFF
        bit_size = self.state_size * 8

        state = [int.from_bytes(chunk, 'big') for chunk in state.chunk(self.state_size)]
        w = [int.from_bytes(b, 'big') for b in get_blocks(block, self.state_size)] + ([None] * (self.rounds - 16))

        for i in range(16, self.rounds):
            s0 = right_rotate(w[i-15], self.rot[0], bit_size) ^ right_rotate(w[i-15], self.rot[1], bit_size) ^ (w[i-15] >> self.rot[2])
            s1 = right_rotate(w[i-2], self.rot[3], bit_size) ^ right_rotate(w[i-2], self.rot[4], bit_size) ^ (w[i-2] >> self.rot[5])
            w[i] = (w[i-16] + s0 + w[i-7] + s1) & bit_mask


        a = state[0]
        b = state[1]
        c = state[2]
        d = state[3]
        e = state[4]
        f = state[5]
        g = state[6]
        h = state[7]

        for i in range(self.rounds):
            S1 = right_rotate(e,  self.rot[6], bit_size) ^ right_rotate(e, self.rot[7], bit_size) ^ right_rotate(e, self.rot[8], bit_size)
            ch = g ^ (e & (f ^ g))
            temp1 = (h + S1 + ch + self.k[i] + w[i])
            S0 = right_rotate(a, self.rot[9], bit_size) ^ right_rotate(a, self.rot[10], bit_size) ^ right_rotate(a, self.rot[11], bit_size)
            maj = (a & b) ^ (a & c) ^ (b & c)
            temp2 = (S0 + maj)

            h = g
            g = f
            f = e
            e = (d + temp1) & bit_mask
            d = c
            c = b
            b = a
            a = (temp1 + temp2) & bit_mask


        state[0] += a
        state[1] += b
        state[2] += c
        state[3] += d
        state[4] += e
        state[5] += f
        state[6] += g
        state[7] += h

        return Bytes(b''.join([int.to_bytes(h_i & bit_mask, self.state_size, 'big') for h_i in state]))
Exemplo n.º 4
0
    def mix(self, V_a, V_b, V_c, V_d, x, y):
        V_a = (V_a + V_b + x) & self.MASKBITS
        V_d = right_rotate(V_d ^ V_a, self.ROTATIONS[0], bits=self.WORD_SIZE)

        V_c = (V_c + V_d) & self.MASKBITS
        V_b = right_rotate(V_b ^ V_c, self.ROTATIONS[1], bits=self.WORD_SIZE)

        V_a = (V_a + V_b + y) & self.MASKBITS
        V_d = right_rotate(V_d ^ V_a, self.ROTATIONS[2], bits=self.WORD_SIZE)

        V_c = (V_c + V_d) & self.MASKBITS
        V_b = right_rotate(V_b ^ V_c, self.ROTATIONS[3], bits=self.WORD_SIZE)

        return V_a, V_b, V_c, V_d
Exemplo n.º 5
0
    def decrypt(self, ciphertext: bytes) -> Bytes:
        """
        Decrypts `ciphertext`.

        Parameters:
            ciphertext (bytes): Bytes-like object to be decrypted.
        
        Returns:
            Bytes: Resulting plaintext.
        """
        ciphertext = Bytes.wrap(ciphertext)
        ct_chunks = [
            chunk.zfill(4)[::-1].int() for chunk in ciphertext.chunk(4)
        ]

        # Dewhitening
        R = [ct_chunks[i] ^ self.K[i + 4] for i in range(len(ct_chunks))]

        for i in range(ROUNDS - 1, -1, -1):
            FR_0, FR_1 = self.F(R[0], R[1], i)
            R = [
                R[0], R[1],
                left_rotate(R[2], 1) ^ FR_0,
                right_rotate(R[3] ^ FR_1, 1)
            ]

            R[0], R[2] = R[2], R[0]
            R[1], R[3] = R[3], R[1]

        R = [R[(i + 2) % 4] ^ self.K[i] for i in range(len(ct_chunks))]

        return Bytes(b''.join([int.to_bytes(r, 4, 'little') for r in R]),
                     'little')[::-1]
Exemplo n.º 6
0
    def encrypt(self, plaintext: bytes) -> Bytes:
        """
        Encrypts `plaintext`.

        Parameters:
            plaintext (bytes): Bytes-like object to be encrypted.
        
        Returns:
            Bytes: Resulting ciphertext.
        """
        plaintext = Bytes.wrap(plaintext)[::-1]
        pt_chunks = [chunk.zfill(4).int() for chunk in plaintext.chunk(4)]

        # Whitening
        R = [pt_chunks[i] ^ self.K[i] for i in range(len(pt_chunks))]

        for i in range(ROUNDS):
            FR_0, FR_1 = self.F(R[0], R[1], i)
            R = [
                R[0], R[1],
                right_rotate(R[2] ^ FR_0, 1),
                left_rotate(R[3], 1) ^ FR_1
            ]

            R[0], R[2] = R[2], R[0]
            R[1], R[3] = R[3], R[1]

        R = [R[(i + 2) % 4] ^ self.K[i + 4] for i in range(len(pt_chunks))]

        return Bytes(b''.join([int.to_bytes(r, 4, 'little') for r in R]))
Exemplo n.º 7
0
    def rrot(self, amount: int, bits: int=None):
        """
        Performs a right-rotate.

        Parameters:
            amount (int): Amount to rotate by.
            bits   (int): Bitspace to rotate over.
        
        Returns:
            Bytes: A new instance of Bytes with the transformation applied.
        """
        if not bits:
            bits = len(self) * 8

        back_to_bytes = int.to_bytes(right_rotate(self.to_int(), amount % bits, bits), bits // 8, self.byteorder)
        return Bytes(back_to_bytes, self.byteorder)
Exemplo n.º 8
0
def V32_64_XSH_RR(x, mult, inc):
    count = x >> 59
    state = (x * mult + inc) & 0xFFFFFFFFFFFFFFFF
    x ^= x >> 18
    return state, right_rotate((x >> 27) & 0xFFFFFFFF, count)