コード例 #1
0
ファイル: rc5.py プロジェクト: gcdeshpande/samson
    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).zfill(self.block_size // 4)

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

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

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

        return (Bytes(A, 'little').zfill(self.block_size // 8) +
                Bytes(B, 'little').zfill(self.block_size // 8))
コード例 #2
0
ファイル: keccak.py プロジェクト: gcdeshpande/samson
    def round_func(self, A, rc):
        C = [0] * 5
        for x in range(5):
            C[x] = A[x][0] ^ A[x][1] ^ A[x][2] ^ A[x][3] ^ A[x][4]

        D = [0] * 5
        for x in range(5):
            D[x] = C[x - 1] ^ left_rotate(C[(x + 1) % 5], 1, 64)

        for x in range(5):
            for y in range(5):
                A[x][y] = A[x][y] ^ D[x]

        B = [[0] * 5 for _ in range(5)]
        for x in range(5):
            for y in range(5):
                B[y][(2 * x + 3 * y) % 5] = left_rotate(A[x][y], R[y][x], 64)

        for x in range(5):
            for y in range(5):
                A[x][y] = B[x][y] ^ ((~B[(x + 1) % 5][y]) & B[(x + 2) % 5][y])

        A[0][0] ^= rc

        return A
コード例 #3
0
def EXPAND_KEY(M_e, M_o, k):
    K = []
    for i in range(ROUNDS + 4):
        A_i = G(2 * i * RHO, M_e, k)
        B_i = G((2 * i + 1) * RHO, M_o, k)
        B_i = left_rotate(B_i, 8)

        K.append((A_i + B_i) & 0xFFFFFFFF)
        K.append(left_rotate((A_i + 2 * B_i) & 0xFFFFFFFF, 9))

    return K
コード例 #4
0
def compression_func(chunk, state):
    """Process a chunk of data and return the new digest variables."""
    assert len(chunk) == 64

    w = [0] * 80

    # Break chunk into sixteen 4-byte big-endian words w[i]
    for i in range(16):
        w[i] = struct.unpack(b'>I', chunk[i * 4:i * 4 + 4])[0]

    # Extend the sixteen 4-byte words into eighty 4-byte words
    for i in range(16, 80):
        w[i] = left_rotate(w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16], 1)

    # Initialize hash value for this chunk
    h0, h1, h2, h3, h4 = bytes_to_state(state)

    a = h0
    b = h1
    c = h2
    d = h3
    e = h4

    for i in range(80):
        if 0 <= i <= 19:
            # Use alternative 1 for f from FIPS PB 180-1 to avoid bitwise not
            f = d ^ (b & (c ^ d))
            k = 0x5A827999
        elif 20 <= i <= 39:
            f = b ^ c ^ d
            k = 0x6ED9EBA1
        elif 40 <= i <= 59:
            f = (b & c) | (b & d) | (c & d)
            k = 0x8F1BBCDC
        elif 60 <= i <= 79:
            f = b ^ c ^ d
            k = 0xCA62C1D6

        a, b, c, d, e = ((left_rotate(a, 5) + f + e + k + w[i]) & 0xffffffff,
                         a, left_rotate(b, 30), c, d)

    # Add this chunk's hash to result so far
    h0 = (h0 + a) & 0xffffffff
    h1 = (h1 + b) & 0xffffffff
    h2 = (h2 + c) & 0xffffffff
    h3 = (h3 + d) & 0xffffffff
    h4 = (h4 + e) & 0xffffffff

    state = [h0, h1, h2, h3, h4]

    return Bytes(state_to_bytes(state))
コード例 #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]
コード例 #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]))
コード例 #7
0
ファイル: camellia.py プロジェクト: gcdeshpande/samson
def FL(FL_IN, KE):
    x1 = (FL_IN >> 32) & MASK32
    x2 = FL_IN & MASK32
    k1 = (KE >> 32) & MASK32
    k2 = KE & MASK32

    x2 = x2 ^ left_rotate((x1 & k1), 1, bits=32)
    x1 = x1 ^ (x2 | k2)
    return (x1 << 32) | x2
コード例 #8
0
def QUARTER_ROUND(a: int, b: int, c: int, d: int) -> (int, int, int, int):
    """
    Performs a quarter round of ChaCha.

    Parameters:
        a (int): ChaCha state variable.
        b (int): ChaCha state variable.
        c (int): ChaCha state variable.
        d (int): ChaCha state variable.
    
    Returns:
        (int, int, int, int): New values for (a, b, c, d).
    """
    a = (a + b) & 0xFFFFFFFF; d ^= a; d = left_rotate(d, 16)
    c = (c + d) & 0xFFFFFFFF; b ^= c; b = left_rotate(b, 12)
    a = (a + b) & 0xFFFFFFFF; d ^= a; d = left_rotate(d, 8)
    c = (c + d) & 0xFFFFFFFF; b ^= c; b = left_rotate(b, 7)
    return a, b, c, d
コード例 #9
0
ファイル: camellia.py プロジェクト: gcdeshpande/samson
def FLINV(FLINV_IN, KE):
    y1 = (FLINV_IN) >> 32 & MASK32
    y2 = FLINV_IN & MASK32
    k1 = (KE >> 32) & MASK32
    k2 = KE & MASK32

    y1 = y1 ^ (y2 | k2)
    y2 = y2 ^ left_rotate((y1 & k1), 1, bits=32)
    return (y1 << 32) | y2
コード例 #10
0
def COMPRESS(message, state):
    # The authors of RIPEMD160 couldn't decide on whether to use big or little endian, so they used both!
    # RIPEMD160 takes in bytes as big endian but operates and outputs bytes of little endian. Man, was this 'fun.'

    h = [chunk.to_int() for chunk in state.chunk(4)]
    msg_chunks = [
        chunk[::-1].to_int()
        for chunk in Bytes.wrap(message, byteorder='big').chunk(4)
    ]

    AL = AR = h[0]
    BL = BR = h[1]
    CL = CR = h[2]
    DL = DR = h[3]
    EL = ER = h[4]

    for curr_round in range(5):
        for w in range(16):
            T = left_rotate(
                AL + FL[curr_round](BL, CL, DL) + msg_chunks[RL[curr_round][w]]
                + KL[curr_round], SL[curr_round][w]) + EL
            AL = EL & 0xFFFFFFFF
            EL = DL & 0xFFFFFFFF
            DL = left_rotate(CL, 10)
            CL = BL & 0xFFFFFFFF
            BL = T & 0xFFFFFFFF

            T = left_rotate(
                AR + FR[curr_round](BR, CR, DR) + msg_chunks[RR[curr_round][w]]
                + KR[curr_round], SR[curr_round][w]) + ER
            AR = ER & 0xFFFFFFFF
            ER = DR & 0xFFFFFFFF
            DR = left_rotate(CR, 10)
            CR = BR & 0xFFFFFFFF
            BR = T & 0xFFFFFFFF

    T = (h[1] + CL + DR) & 0xFFFFFFFF
    h[1] = (h[2] + DL + ER) & 0xFFFFFFFF
    h[2] = (h[3] + EL + AR) & 0xFFFFFFFF
    h[3] = (h[4] + AL + BR) & 0xFFFFFFFF
    h[4] = (h[0] + BL + CR) & 0xFFFFFFFF
    h[0] = T

    return sum([Bytes(state, 'little').zfill(4) for state in h])
コード例 #11
0
    def F(self, R_0, R_1, i):
        R_0_little = int.from_bytes(int.to_bytes(R_0, 4, 'big'), 'little')
        R_1_little = int.from_bytes(
            int.to_bytes(left_rotate(R_1, 8), 4, 'big'), 'little')

        T_0 = G(R_0_little, self.S, self.k)
        T_1 = G(R_1_little, self.S, self.k)

        F_0 = (T_0 + T_1 + self.K[2 * i + 8]) & 0xFFFFFFFF
        F_1 = (T_0 + 2 * T_1 + self.K[2 * i + 9]) & 0xFFFFFFFF

        return F_0, F_1
コード例 #12
0
ファイル: des.py プロジェクト: gcdeshpande/samson
def key_schedule(key):
    key_bits = bytes_to_bitstring(key)

    left_key = ''.join([key_bits[PC_1_left[i] - 1] for i in range(28)])
    right_key = ''.join([key_bits[PC_1_right[i] - 1] for i in range(28)])

    for i in range(16):
        # Rotate
        rotation = rotation_round_map[i]

        left_key = bin(left_rotate(int(left_key, 2), rotation,
                                   bits=28))[2:].zfill(28)
        right_key = bin(left_rotate(int(right_key, 2), rotation,
                                    bits=28))[2:].zfill(28)

        # Permutate
        combined_keys = left_key + right_key
        sub_key = int.to_bytes(
            int(''.join([combined_keys[PC_2[j] - 1] for j in range(48)]), 2),
            7, 'big')

        yield sub_key
コード例 #13
0
ファイル: rc5.py プロジェクト: gcdeshpande/samson
    def _key_expansion(self):
        b = len(self.key)
        u = self.block_size // 8
        t = 2 * (self.num_rounds + 1)

        if b == 0:
            c = 1
        elif b % u:
            self.key = self.key.zfill(u - b % u + b)
            b = len(self.key)
            c = b // u
        else:
            c = b // u

        const_idx = int(math.log(self.block_size, 2) - 4)

        if b == 0:
            L = [0]
        else:
            L = self.key.chunk(b // c)

        for i in range(b - 1, -1, -1):
            L[i // u] = Bytes.wrap(L[i // u] << 8).int() + self.key[i]

        S = [(P_w[const_idx] + (Q_w[const_idx] * i)) % self.mod
             for i in range(t)]

        i = j = 0
        A = B = 0

        for _ in range(3 * max(t, c)):
            A = S[i] = left_rotate((S[i] + A + B), 3, bits=self.block_size)
            B = L[j] = left_rotate((L[j] + A + B), (A + B) % self.block_size,
                                   bits=self.block_size)
            i = (i + 1) % t
            j = (j + 1) % c

        return S
コード例 #14
0
ファイル: md4.py プロジェクト: gcdeshpande/samson
def compression_func(message, state):
    X = list(struct.unpack("<16I", message) + (None, ) * (80 - 16))
    h = bytes_to_state(state)
    last_state = [x for x in h]

    # Round 1
    s = (3, 7, 11, 19)
    for r in range(16):
        i = (16 - r) % 4
        k = r
        h[i] = left_rotate(
            (h[i] + F(h[(i + 1) % 4], h[(i + 2) % 4], h[(i + 3) % 4]) + X[k]) %
            2**32, s[r % 4])

    # Round 2
    s = (3, 5, 9, 13)
    for r in range(16):
        i = (16 - r) % 4
        k = 4 * (r % 4) + r // 4
        h[i] = left_rotate(
            (h[i] + G(h[(i + 1) % 4], h[(i + 2) % 4], h[(i + 3) % 4]) + X[k] +
             0x5a827999) % 2**32, s[r % 4])

    # Round 3
    s = (3, 9, 11, 15)
    k = (0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11, 7, 15)
    for r in range(16):
        i = (16 - r) % 4
        h[i] = left_rotate(
            (h[i] + H(h[(i + 1) % 4], h[(i + 2) % 4], h[(i + 3) % 4]) +
             X[k[r]] + 0x6ed9eba1) % 2**32, s[r % 4])

    new_state = []
    for i, v in enumerate(h):
        new_state.append((v + last_state[i]) % 2**32)

    return Bytes(state_to_bytes(new_state))
コード例 #15
0
ファイル: zuc.py プロジェクト: gcdeshpande/samson
    def run_lfsr(self, u: int = None):
        """
        Used internally. Runs the LFSR one iteration.
        """
        f = self.lfsr_states[0]

        rotations = [(0, 8), (4, 20), (10, 21), (13, 17), (15, 15)]

        for state_idx, rot_amount in rotations:
            v = left_rotate(self.lfsr_states[state_idx], rot_amount, bits=31)
            f = ADD_M(f, v)

        if u:
            f = ADD_M(f, u)

        self.shift_states(f)
コード例 #16
0
    def lrot(self, amount: int, bits: int=None):
        """
        Performs a left-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(left_rotate(self.to_int(), amount % bits, bits), bits // 8, self.byteorder)
        return Bytes(back_to_bytes, self.byteorder)
コード例 #17
0
ファイル: xoroshiro.py プロジェクト: gcdeshpande/samson
    def gen_func(
        sym_s0,
        sym_s1,
        SHFT_L=lambda x, n: (x << n) & MASK64,
        SHFT_R=DEFAULT_SHFT_R,
        RotateLeft=lambda x, n: left_rotate(x, n, bits=64)
    ) -> (list, int):
        """
        Internal function compatible with Python and symbolic execution.
        """
        s0, s1 = sym_s0, sym_s1
        result = (s0 + s1) & MASK64

        s1 ^= s0
        sym_s0 = RotateLeft(s0, 24) ^ s1 ^ SHFT_L(s1, 16)
        sym_s1 = RotateLeft(s1, 37)
        return [sym_s0, sym_s1], result
コード例 #18
0
ファイル: serpent.py プロジェクト: gcdeshpande/samson
    def make_subkeys(self):
        w = {}

        for i, chunk in enumerate(self.key.chunk(4)[::-1]):
            w[i - 8] = chunk[::-1].int()

        for i in range(132):
            w[i] = (left_rotate(
                w[i - 8] ^ w[i - 5] ^ w[i - 3] ^ w[i - 1] ^ PHI ^ i, 11))

        w = {
            i: Bitstring(val, 'little', auto_fill=False)[::-1]
            for i, val in w.items()
        }

        k = {}
        for i in range(ROUNDS + 1):
            sbox = (ROUNDS + 3 - i) % ROUNDS
            for h in range(4):
                k[h + 4 * i] = Bitstring("", 'little', auto_fill=False)

            for j in range(ROUNDS):
                s_in = ''.join([
                    str(
                        Bitstring(w[h + 4 * i], 'little',
                                  auto_fill=False).zfill(32)[j])
                    for h in range(4)
                ])
                s_out = Bitstring(SBOX[sbox % len(SBOX)][s_in],
                                  'little',
                                  auto_fill=False)

                for h in range(4):
                    k[h + 4 * i] += s_out[h]

        K = []
        for i in range(ROUNDS + 1):
            K.append(k[4 * i] + k[4 * i + 1] + k[4 * i + 2] + k[4 * i + 3])

        K_hat = []
        for i in range(ROUNDS + 1):
            K_hat.append(self.IP(K[i]))

        return K, K_hat
コード例 #19
0
def compression_func(message, state):
    new_state = bytes_to_state(state)

    for chunk_ofst in range(0, len(message), 64):
        a, b, c, d = new_state
        chunk = message[chunk_ofst:chunk_ofst+64]

        for i in range(64):
            f = functions[i](b, c, d)
            g = index_functions[i](i)
            to_rotate = a + f + constants[i] + int.from_bytes(chunk[4*g:4*g+4], byteorder='little')
            new_b = (b + left_rotate(to_rotate, rotate_amounts[i])) & 0xFFFFFFFF
            a, b, c, d = d, new_b, b, c

        for i, val in enumerate([a, b, c, d]):
            new_state[i] += val
            new_state[i] &= 0xFFFFFFFF

    return Bytes(state_to_bytes(new_state))
コード例 #20
0
ファイル: zuc.py プロジェクト: gcdeshpande/samson
def L2(X):
    return (X ^ left_rotate(X, 8) ^ left_rotate(X, 14) ^ left_rotate(X, 22)
            ^ left_rotate(X, 30)) & 0xFFFFFFFF
コード例 #21
0
ファイル: zuc.py プロジェクト: gcdeshpande/samson
def L1(X):
    return (X ^ left_rotate(X, 2) ^ left_rotate(X, 10) ^ left_rotate(X, 18)
            ^ left_rotate(X, 24)) & 0xFFFFFFFF
コード例 #22
0
ファイル: camellia.py プロジェクト: gcdeshpande/samson
def ROTL128(x, amount):
    return left_rotate(x, amount, bits=128)