def ta(traces_file: str, keys_file: str, plain_file: str, points_of_interest: int, pooled: bool, spacing: int,
       subkey: int, num_traces: int, gpu: bool, leakage_model: bool, debug_mode: bool, num_attack_traces: int,
       feature_select: int):
    """
    Performs (pooled) template attack.

    :param traces_file: the traces file to use.
    :param keys_file: the keys file to use.
    :param plain_file: the plaintexts file to use.
    :param points_of_interest: the number of points of interest to extract.
    :param pooled: whether to use pooled attack.
    :param spacing: spacing between the points of interest.
    :param subkey: the subkey index to analyze. Must be in the range [0-16], 16 signaling the whole key to be found out.
    :param num_traces: the amount of traces to analyze starting from trace 0
    :param gpu: whether or not to use gpu for this attack
    :param leakage_model: the leakage model to use
    :param debug_mode: whether to enable debug mode
    :param num_attack_traces: the number of attack traces.
    :param feature_select: which feature select to use, default is none.
    """
    traces, keys, plain = FileLoader.main(traces_file, keys_file, plain_file)

    profiling_traces, profiling_keys, profiling_plaintext, attack_traces, attack_keys, attack_plaintext = \
        DataPartitioner.get_traces(traces, keys, plain, num_traces, subkey,
                                   0, num_attack_traces, 0, 1, 0, leakage_model)

    if not pooled and profiling_traces.shape[0] < profiling_traces.shape[1]:
        print("ERROR: profiling traces are smaller than features, please run Pooled Template Attack instead of"
              " normal Template attack for a more accurate result.")
        exit(1)

    TA.run(profiling_traces, profiling_keys, profiling_plaintext, attack_traces, attack_keys, attack_plaintext,
           pooled, points_of_interest, spacing, subkey, gpu, leakage_model, debug_mode, feature_select)
def cpa(traces_file: str, keys_file: str, plain_file: str, subkey: int, leakage_model: bool,
        num_traces: int, num_attack_traces: int, num_features: int, feature_select: int, round_: int,
        operation: int, debug_mode: bool, version: int):
    """
    Performs different CPA attacks.

    :param traces_file: the traces file to use
    :param keys_file: the keys file to use
    :param plain_file: the plaintexts file to use
    :param subkey: the subkey index to analyze. Must be in the range [0-15]
    :param leakage_model: the leakage model to use.
    :param round_: the AES round to attack.
    :param num_traces: the amount of traces to analyze starting from trace 0.
    :param num_attack_traces: the amount of attack traces to analyze starting from trace 0.
    :param num_features: the number of features
    :param operation: the AES operation to 'attack', represented as an integer from 0 to 3.
    :param feature_select: which feature select to use
    :param debug_mode: whether to enable debug mode
    :param version: pick which version of CPA you want, the default is offline CPA.
    """

    online, conditional_averaging = False, False
    if version == 1:
        online = True
    elif version == 2:
        conditional_averaging = True

    traces, keys, plain = FileLoader.main(traces_file, keys_file, plain_file)
    profiling_traces, profiling_keys, profiling_plaintext, attack_traces, attack_keys, attack_plaintext = \
        DataPartitioner.get_traces(traces, keys, plain, num_traces, subkey,
                                   0, num_attack_traces, num_features, round_, operation, leakage_model)
    CPA.run(profiling_traces, profiling_keys, profiling_plaintext, attack_traces, attack_keys, attack_plaintext,
            round_, operation, subkey, feature_select, num_features, leakage_model,
            debug_mode_enabled=debug_mode, online=online, conditional_averaging=conditional_averaging)
def sa(traces_file: str, keys_file: str, plain_file: str, round_: int, operation: int, num_traces: int,
       num_attack_traces: int, subkey: int, gpu: bool, leakage_model: bool, num_features: int, feature_select: int,
       debug_mode: bool):
    """
    Performs stochastic attack.

    :param traces_file: the traces file to use.
    :param keys_file: the keys file to use.
    :param plain_file: the plaintexts file to use.
    :param round_: the AES round to attack.
    :param operation: the AES operation to 'attack', represented as an integer from 0 to 3.
    :param num_traces: the amount of traces to analyze starting from trace 0.
    :param num_attack_traces: the amount of attack traces to analyze starting from trace 0.
    :param subkey: the subkey index to analyze. Must be in the range [0-16], 16 signaling the whole key to be found out.
    :param gpu: enables gpu acceleration if set to true.
    :param num_features: number of features to select for.
    :param feature_select: which feature select to use, default is pearson.
    :param leakage_model: the leakage model to use.
    :param debug_mode: whether to enable debug mode
    """

    traces, keys, plain = FileLoader.main(traces_file, keys_file, plain_file)
    profiling_traces, profiling_keys, profiling_plaintext, attack_traces, attack_keys, attack_plaintext = \
        DataPartitioner.get_traces(traces, keys, plain, num_traces, subkey,
                                   0, num_attack_traces, num_features, round_, operation, leakage_model)
    SA.run(profiling_traces, profiling_keys, profiling_plaintext, attack_traces, attack_keys, attack_plaintext,
           round_, operation, len(profiling_traces), num_attack_traces, subkey, feature_select, num_features, gpu,
           leakage_model, debug_mode_enabled=debug_mode)
def mia(traces_file: str, keys_file: str, plain_file: str, subkey: int, leakage_model: bool,
        num_traces: int, num_attack_traces: int, num_features: int, feature_select: int, round_: int,
        operation: int, debug_mode: bool):
    """Performs MIA (Mutual Information Analysis) attack.

    :param traces_file: the traces file to use
    :param keys_file: the keys file to use
    :param plain_file: the plaintexts file to use
    :param subkey: the subkey index to analyze. Must be in the range [0-15]
    :param leakage_model: the leakage model to use.
    :param round_: the AES round to attack.
    :param num_traces: the amount of traces to analyze starting from trace 0.
    :param num_attack_traces: the amount of attack traces to analyze starting from trace 0.
    :param num_features: the number of features
    :param operation: the AES operation to 'attack', represented as an integer from 0 to 3.
    :param feature_select: which feature select to use
    :param debug_mode: whether to enable debug mode
    """
    traces, keys, plain = FileLoader.main(traces_file, keys_file, plain_file)
    profiling_traces, profiling_keys, profiling_plaintext, attack_traces, attack_keys, attack_plaintext = \
        DataPartitioner.get_traces(traces, keys, plain, num_traces, subkey,
                                   0, num_attack_traces, num_features, round_, operation, leakage_model)
    Mia.run(profiling_traces, profiling_keys, profiling_plaintext, attack_traces, attack_keys, attack_plaintext,
            round_, operation, subkey, feature_select,
            num_features, leakage_model, debug_mode_enabled=debug_mode)
    def test_run_nicv_without_hamming_weight(self):
        """"This tests if a probable point is contained in the result set not using hamming weights"""

        traces, keys, plain = FileLoader.main(CONST_DEFAULT_TRACES_FILE,
                                              CONST_DEFAULT_KEYS_FILE,
                                              CONST_DEFAULT_PLAIN_FILE)

        result = NICV.run(traces, keys, plain, hamming_weight=False)
        self.assertTrue(1350 in result)
def align(aligned: str, unaligned: str, algorithm: int, output: str, debug_mode: bool):
    """Aligns traces with specified algorithm and outputs an aligned file.

    :param aligned: File of 1 or more aligned traces.
    :param unaligned: File of unaligned traces
    :param algorithm: algorithm to use
    :param output: filename to output to.
    :param debug_mode: debug mode flag.
    :return:
    """

    unaligned_file = FileLoader.load_traces(unaligned)
    if aligned == 'none':
        aligned_file = np.zeros((1, len(unaligned[0])))
        aligned_file[0] = unaligned[0]
    else:
        aligned_file = FileLoader.load_traces(aligned)
    Aligner.run(aligned_file, unaligned_file, algorithm, output, debug_mode)
    def test_run_nicv(self):
        """"This tests if the most probable point is contained in the result set"""

        traces, keys, plain = FileLoader.main(CONST_DEFAULT_TRACES_FILE,
                                              CONST_DEFAULT_KEYS_FILE,
                                              CONST_DEFAULT_PLAIN_FILE)

        result = NICV.run(traces, keys, plain)

        self.assertTrue(1398 in result)
def snr(traces_file: str, num_features: int):
    """
    Performs SNR

    :param traces_file: the file from which to load the traces
    :param num_features: the number of points of interest to extract.
    :return: the signal to noise ratio of the traces
    """

    traces = FileLoader.load_traces(traces_file)
    SNR.run(traces, num_features)
def nicv(traces_file, keys_file, plain_file, leakage_model):
    """
    Performs Normalized Inter-Class Variance for feature selection.

    :param traces_file: the traces file to use
    :param keys_file: the keys file to use
    :param plain_file: the plaintexts file to use
    :param leakage_model: the leakage model to use.
    """
    traces, keys, plain = FileLoader.main(traces_file, keys_file, plain_file)
    NICV.run(traces, keys, plain, leakage_model)
    def test_mia_run(self):
        """"This tests the run method of MIA with a reduced data set"""
        traces, keys, plain = FileLoader.main(CONST_DEFAULT_TRACES_FILE,
                                              CONST_DEFAULT_KEYS_FILE,
                                              CONST_DEFAULT_PLAIN_FILE)

        profiling_traces, profiling_keys, profiling_plaintext, attack_traces, attack_keys, attack_plaintext = \
            DataPartitioner.get_traces(traces, keys, plain, 1000, 0,
                                       0, 1000, 10, 1, 0, False)

        expected = np.array([43, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
        self.assertTrue(np.array_equal(Mia.run(profiling_traces, profiling_keys, profiling_plaintext, attack_traces,
                        attack_keys, attack_plaintext, 1, 0, 0, 1, 10, True), expected))
def sosd(traces_file: str, keys_file: str, plain_file: str, num_features: int, round_: int,
         operation: int, save_traces: bool, subkey: int, leakage_model: bool):
    """
    Performs SOSD. By default, the indices of the specified number of points of
    interest (features) are saved to `out/sosd_selected_indices`. When
    `--save-traces` is passed, the corresponding traces are saved instead.

    :param traces_file: the traces file to use.
    :param keys_file: the keys file to use.
    :param plain_file: the plaintexts file to use.
    :param num_features: the number of points of interest to extract.
    :param round_: the AES round to attack.
    :param operation: the AES operation to 'attack', represented as an integer from 0 to 3.
    :param save_traces: whether to save the traces to a file.
    :param subkey: the subkey index to analyze. Must be in the range [0-15].
    :param leakage_model: the leakage model to use.
    """
    traces, keys, plain = FileLoader.main(traces_file, keys_file, plain_file)
    SOSTD.run(traces, keys, plain, num_features, save_traces, subkey, round_, operation, leakage_model, False)
def lra(traces_file: str, keys_file: str, plain_file: str, num_traces: int, subkey: int, num_features: int,
        feature_select: int):
    """
    Performs non-linear regression analysis.

    :param traces_file: the traces file to use.
    :param keys_file: the keys file to use.
    :param plain_file: the plaintexts file to use.
    :param num_traces: the amount of traces to use
    :param subkey: the subkey index to analyze. Must be in the range [0-16], 16 signaling the whole key to be found out.
    :param num_features: number of features to select for.
    :param feature_select: which feature select to use, default is pearson.
    """

    traces, keys, plain = FileLoader.main(traces_file, keys_file, plain_file)
    traces = traces[:num_traces, :]
    keys = keys[:num_traces, :]
    plain = plain[:num_traces, :]

    lra_obj = LRA(traces, plain)
    lra_obj.run(traces, keys, plain, subkey, num_features, feature_select)
def pia(traces_file: str, keys_file: str, plain_file: str, subkey: int, num_traces: int, num_attack_traces: int,
        round_: int,
        debug_mode: bool):
    """Performs PIA (Perceived Information Analysis).

    :param traces_file: the traces file to use
    :param keys_file: the keys file to use
    :param plain_file: the plaintexts file to use
    :param subkey: the subkey index to analyze. Must be in the range [0-15]
    :param round_: the AES round to attack.
    :param num_traces: the amount of traces to analyze starting from trace 0.
    :param num_attack_traces: the amount of attack traces to analyze starting from trace 0.
    :param num_features: the number of features
    :param feature_select: which feature select to use
    :param debug_mode: whether to enable debug mode
    """
    traces, keys, plain = FileLoader.main(traces_file, keys_file, plain_file)
    profiling_traces, profiling_keys, profiling_plaintext, attack_traces, attack_keys, attack_plaintext = \
        DataPartitioner.get_traces(traces, keys, plain, num_traces, subkey,
                                   0, num_attack_traces, 5000, round_, 0, False)

    Pia.run(profiling_traces, profiling_plaintext, profiling_keys, attack_traces, subkey, debug_mode_enabled=debug_mode)
def dpa(traces_file: str, keys_file: str, plain_file: str, subkey: int, num_attack_traces: int,
        round_: int, operation: int, debug_mode: bool, bit: int, offset: int, single_order: bool):
    """Performs different DPA attacks.

    :param traces_file: the traces file to use
    :param keys_file: the keys file to use
    :param plain_file: the plaintexts file to use
    :param subkey: the subkey index to analyze. Must be in the range [0-15]
    :param round_: the AES round to attack.
    :param num_attack_traces: the amount of attack traces to analyze starting from trace 0.
    :param operation: the AES operation to 'attack', represented as an integer from 0 to 3.
    :param debug_mode: whether to enable debug mode
    :param bit: which bit to attack
    :param offset: the offset to use
    :param single_order: enables single order DPA
    """
    traces, keys, plain = FileLoader.main(traces_file, keys_file, plain_file)
    profiling_traces, profiling_keys, profiling_plaintext, attack_traces, attack_keys, attack_plaintext = \
        DataPartitioner.get_traces(traces, keys, plain, 0, subkey,
                                   0, num_attack_traces, 0, round_, operation, False)
    DPA.run(attack_traces, attack_keys, attack_plaintext,
            round_, operation, subkey, offset=offset, single_order=single_order,
            debug_mode_enabled=debug_mode, bit=bit)
def tvla(traces_file, output_file, threshold) -> None:
    """
    Performs TVLA
    """
    traces = FileLoader.load_traces(traces_file)
    TVLA.run(traces, output_file=output_file, threshold=threshold)