Esempio n. 1
0
    def linear_layer(self, x_in, x_out):
        x_in = [
            x_in[(8 * shift_rows[i // 8]) + (i % 8)] for i in range(128)
        ]  # variables after ShiftRows and before MixColumns

        for col, bit in itp(range(4), range(8)):
            bit_list = [x_in[(32 * row) + (8 * col) + bit] for row in range(4)] + [
                x_out[(32 * row) + (8 * col) + bit] for row in range(4)
            ]

            self.add_bin_matrix_constr(
                self.mixcol, bit_list, 0, mode="integer",
            )
Esempio n. 2
0
    def run(self, T=1000, gamma=1, n_iter=100):
        self.gamma = gamma
        self.update_time = []
        self.n_iter = n_iter
        while self.t < T:
            print("iteration", self.t)
            # choose next action
            a = self.policy[self.state]
            self.arm_sequence.append(a)
            # Observe reward
            r = self.reward(ast.literal_eval(self.state), a)
            self.reward_sequence.append(r)
            # update
            self.N.loc[self.state, a] += 1
            self.R[self.state, a] += r
            self.state = self.transition(self.state, a)  # next state
            update_policy = False
            _conf = np.log(2 * (self.t + 1**self.alpha) * self.cardS *
                           self.cardA)
            new_conf = deepcopy(self.conf)

            for s_a in itp(*[self.states, self.actions]):
                s, a = s_a
                new_conf[s][a] = self.conf_r(self.t + 1, s, a, _conf)
                if new_conf[s][a] < self.conf[s][a] / 2:
                    update_policy = True
                if self.N[s][a] > 0:
                    self.r_hat[s][a] = self.R[s][a] / self.N[s][a]

            # update policy ?
            if update_policy:
                self.round += 1
                self.update_time.append(self.t + 1)
                print('update policy, round=', self.round)
                self.conf = deepcopy(new_conf)
                self.policyUpdate(self.r_hat)

            self.t += 1
Astate = list(np.repeat(0, window))
Bstate = list(np.repeat(1, window))
mnA = data.loc[str(
    Astate
), 'mn_rewardA']  #0.09166072904895288 # computed from user that have a frequency of A of 1
mnB = data.loc[
    str(Bstate),
    'mn_rewardB']  # computed from user that have a frequency of A of 0
K = 2

gamma = .99
n_iter = 200

for repeat_ in range(nRepeat):

    S = list(itp(range(K), repeat=window))  # all possibles states
    S = list(map(lambda s: str(list(s)), S))

    def next_state_(x, a):
        # x[j] contains the arm that have been played j+1 timesteps ago
        y = deepcopy(x)
        y = y[:-1]
        y = [a] + y
        return y

    def Bellman_a(a, gamma, state):
        # update for one state at random
        if a == 0:
            r = deepcopy(data.loc[state, 'mn_rewardA'])
        else:
            r = deepcopy(data.loc[state, 'mn_rewardB'])
Esempio n. 4
0
    def differential_trail_search(self, active_sboxes):
        """
        Computes a differential trail with the highest possible probability given a class of
        truncated differential characteristics
        """
        local_constraints = []
        y = dict()
        idx = 0

        for r, i in itp(range(self.nb_rounds), range(self.nb_nibbles)):
            y[r, i] = self.model.addVar(name="active_({}, {})".format(r, i),
                                        vtype=GRB.BINARY)
            bits = [
                self.in_sbox[r, (self.nibble_size * i) + j]
                for j in range(self.nibble_size)
            ] + [
                self.out_sbox[r, (self.nibble_size * i) + j]
                for j in range(self.nibble_size)
            ]

            lc = self.model.addGenConstrOr(y[r, i], bits)
            local_constraints.append(lc)

            lc = self.model.addConstr(y[r, i] == quicksum([
                self.Q64[r, i], self.Q48[r, i], self.Q40[r, i], self.Q32[r, i],
                self.Q28[r, i], self.Q24[r, i], self.Q20[r, i], self.Q16[r, i],
                self.Q12[r, i], self.Q8[r,
                                        i], self.Q6[r,
                                                    i], self.Q4[r,
                                                                i], self.Q2[r,
                                                                            i]
            ]))
            local_constraints.append(lc)

            lc = self.model.addConstr(y[r, i] == int(active_sboxes[idx]))
            local_constraints.append(lc)

            idx += 1

        # We fix at least one active input cell
        lc = self.model.addConstr(
            quicksum(y[0, i] for i in range(self.nb_nibbles)) >= 1)
        local_constraints.append(lc)

        # Additional constraint to indicate the minimum number of active S-boxes
        idx = {
            2: 2.0,
            3: 5.0,
            4: 8.0,
            5: 12.0,
            6: 16.0,
            7: 26.0,
            8: 36.0,
            9: 41.0,
            10: 46.0,
            11: 51.0,
            12: 55.0,
            13: 58.0,
            14: 61.0
        }
        lc = self.model.addConstr(
            quicksum(
                y[r, i]
                for r, i in itp(range(self.nb_rounds), range(self.nb_nibbles)))
            >= idx[self.nb_rounds])
        local_constraints.append(lc)

        self.model.optimize()

        # Parsing results
        output = ""
        file = open("SKINNY128_DDT.txt", "r")
        diff = file.readlines()
        file.close()
        probability_index = []
        diff = diff[2:]
        for i in range(len(diff)):
            temp = diff[i][23:]
            assert temp[1] == '/' or temp[2] == '/'
            if temp[1] == '/':
                probability_index.append(int(temp[0]))
            else:
                probability_index.append(int(temp[:2]))
            diff[i] = diff[i][:8] + diff[i][13:21]

        output += "Skinny-128, %s rounds\n" % self.nb_rounds
        output += "Truncated differential characteristics : %s\n" % active_sboxes

        all_status = {2: "OPTIMAL", 6: "CUTOFF", 9: "TIME_LIMIT"}
        if self.model.status in all_status and self.model.SolCount > 0:
            output += "Model status : %s\n" % all_status[self.model.status]

            total = 0
            for r, i in itp(range(self.nb_rounds), range(self.nb_nibbles)):
                total += y[r, i].x
            output += "Best probability found : 2^(-%s) | Number of active S-boxes : %s\n" % (
                self.model.getObjective().getValue(), total)

            for r in range(self.nb_rounds):
                temp = ""
                temp2 = ""
                transition_probability = ""
                for i in range(self.nb_nibbles):
                    if y[r, i].x >= 0.5:
                        current_diff = ""
                        a = [
                            self.in_sbox[r, (self.nibble_size * i) + j].x
                            for j in range(self.nibble_size)
                        ]
                        for x in a:
                            if x >= 0.5:
                                current_diff = current_diff + "1"
                            else:
                                current_diff = current_diff + "0"

                        temp = temp + "{:02x}".format(int(current_diff, 2))

                        current_diff2 = ""
                        b = [
                            self.out_sbox[r, (self.nibble_size * i) + j].x
                            for j in range(self.nibble_size)
                        ]

                        for x in b:
                            if x >= 0.5:
                                current_diff = current_diff + "1"
                                current_diff2 = current_diff2 + "1"
                            else:
                                current_diff = current_diff + "0"
                                current_diff2 = current_diff2 + "0"

                        temp2 = temp2 + "{:02x}".format(int(current_diff2, 2))
                        transition_probability = transition_probability + str(
                            probability_index[diff.index(
                                current_diff)]) + "/256."

                    else:
                        temp = temp + "00"
                        temp2 = temp2 + "00"

                output += "Round : %s | Before SB : %s | After SB : %s  | Probability : %s\n" \
                          % (r + 1, utilities.parse_space(temp), utilities.parse_space(temp2), transition_probability)

            output += "-----------------\n"

        else:
            output += "Failure, model status %s\n" % self.model.status

        # Removing local constraints and variables
        for lc in local_constraints:
            self.model.remove(lc)
        for r, i in itp(range(self.nb_rounds), range(self.nb_nibbles)):
            self.model.remove(y[r, i])

        return output
Esempio n. 5
0
    def __init__(self, state_size, nb_rounds, sbox_file):

        Primitive.__init__(self, state_size, state_size)

        self.nb_rounds = nb_rounds
        self.sbox_name = sbox_file

        with open(sbox_file, "rb") as f:
            (in_nibble_size, out_nibble_size, _, _, _, _, _, _, _, _, _, _, _,
             _, _, _, _) = pickle.load(f)

        assert in_nibble_size == out_nibble_size
        nibble_size = in_nibble_size

        assert state_size % nibble_size == 0
        nb_nibbles = state_size // nibble_size

        self.add_sbox_modeling(sbox_file)

        self.state_size = state_size  # equal to 128
        self.nibble_size = nibble_size
        self.nb_nibbles = nb_nibbles

        in_sbox = {}  # in_sbox for sbox input
        out_sbox = {}  # out_sbox for sbox output
        Q64 = {}
        Q48 = {}
        Q40 = {}
        Q32 = {}
        Q28 = {}
        Q24 = {}
        Q20 = {}
        Q16 = {}
        Q12 = {}
        Q8 = {}
        Q6 = {}
        Q4 = {}
        Q2 = {}

        for i, j in itp(range(nb_rounds), range(state_size)):
            in_sbox[i, j] = self.model.addVar(name="in_sbox_({}, {})".format(
                i, j),
                                              vtype=GRB.BINARY)
        for i, j in itp(range(nb_rounds), range(state_size)):
            out_sbox[i, j] = self.model.addVar(name="out_sbox_({}, {})".format(
                i, j),
                                               vtype=GRB.BINARY)
        for r, i in itp(range(nb_rounds), range(nb_nibbles)):
            Q64[r, i] = self.model.addVar(
                name="Q64_({}, {})".format(r, i),
                vtype=GRB.BINARY,
                obj=2.00,
            )
            Q48[r, i] = self.model.addVar(
                name="Q48_({}, {})".format(r, i),
                vtype=GRB.BINARY,
                obj=2.42,
            )
            Q40[r, i] = self.model.addVar(
                name="Q40_({}, {})".format(r, i),
                vtype=GRB.BINARY,
                obj=2.68,
            )
            Q32[r, i] = self.model.addVar(
                name="Q32_({}, {})".format(r, i),
                vtype=GRB.BINARY,
                obj=3.00,
            )
            Q28[r, i] = self.model.addVar(
                name="Q28_({}, {})".format(r, i),
                vtype=GRB.BINARY,
                obj=3.20,
            )
            Q24[r, i] = self.model.addVar(
                name="Q24_({}, {})".format(r, i),
                vtype=GRB.BINARY,
                obj=3.42,
            )
            Q20[r, i] = self.model.addVar(
                name="Q20_({}, {})".format(r, i),
                vtype=GRB.BINARY,
                obj=3.68,
            )
            Q16[r, i] = self.model.addVar(
                name="Q16_({}, {})".format(r, i),
                vtype=GRB.BINARY,
                obj=4.00,
            )
            Q12[r, i] = self.model.addVar(
                name="Q12_({}, {})".format(r, i),
                vtype=GRB.BINARY,
                obj=4.42,
            )
            Q8[r, i] = self.model.addVar(
                name="Q8_({}, {})".format(r, i),
                vtype=GRB.BINARY,
                obj=5.00,
            )
            Q6[r, i] = self.model.addVar(
                name="Q6_({}, {})".format(r, i),
                vtype=GRB.BINARY,
                obj=5.42,
            )
            Q4[r, i] = self.model.addVar(
                name="Q4_({}, {})".format(r, i),
                vtype=GRB.BINARY,
                obj=6.00,
            )
            Q2[r, i] = self.model.addVar(
                name="Q2_({}, {})".format(r, i),
                vtype=GRB.BINARY,
                obj=7.00,
            )

        self.Q64 = Q64
        self.Q48 = Q48
        self.Q40 = Q40
        self.Q32 = Q32
        self.Q28 = Q28
        self.Q24 = Q24
        self.Q20 = Q20
        self.Q16 = Q16
        self.Q12 = Q12
        self.Q8 = Q8
        self.Q6 = Q6
        self.Q4 = Q4
        self.Q2 = Q2

        for i in range(state_size):
            self.in_var[i] = in_sbox[0, i]
            self.out_var[i] = out_sbox[nb_rounds - 1, i]

        for i in range(nb_rounds):
            self.subcell(
                [in_sbox[i, j] for j in range(state_size)],
                [out_sbox[i, j] for j in range(state_size)],
                i,
            )

        for i in range(nb_rounds - 1):
            self.linear_layer(
                [out_sbox[i, j] for j in range(state_size)],
                [in_sbox[i + 1, j] for j in range(state_size)],
            )

        self.in_sbox = in_sbox
        self.out_sbox = out_sbox
Esempio n. 6
0
    K = len(phi)
    M = K**window
    print('Space state size:', M)

    description = ["Decaying arms with :"]
    description.append("- " + str(K) + " arms ")
    description.append("- a window of length " + str(window))
    for a in range(K):
        description.append("- arm " + str(a) + ": " + str(phi[a]))

    mydir = 'README_param' + str(_it) + '.txt'
    np.savetxt(path + mydir, tuple(description), fmt="%s")

    V = {}
    S = itp(range(K), repeat=window)  # all possibles states
    for state in S:
        state = list(state)
        V[str(state)] = 0
    stops = [1000]  #,1000]
    gamma = 0.99
    n_iter = max(stops)
    policies = dict.fromkeys(stops)
    for it in range(n_iter):
        mem = deepcopy(V)  # copy old value
        S = itp(range(K), repeat=window)  # all possibles states
        S = list(S)
        shuffle(S)
        for state in S:
            state = list(state)
            V[str(state)] = max(