aboutsummaryrefslogtreecommitdiff
path: root/test/sca/test_tree.py
blob: 897ffd53a60ea96dadaa8567d78a9acae6c8fc06 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import random
from copy import deepcopy

from pyecsca.sca.re.tree import Tree, Map
import pandas as pd


def test_map():
    cfgs = {"a", "b"}
    binary_sets = {"a": {1, 2, 3}, "b": {2, 4}}
    dmap = Map.from_sets(cfgs, binary_sets)
    assert dmap.domain == [1, 2, 3, 4]
    assert dmap.codomain == {True, False}
    assert dmap.mapping.index.tolist() == [0, 1]
    assert set(dmap.cfg_map.index) == cfgs
    assert dmap.cfgs == cfgs
    assert dmap["a", 1]
    assert not dmap["a", 4]

    io_map = {"a": {1: 5, 2: 7}, "b": {1: 3}}
    dmap = Map.from_io_maps(cfgs, io_map)
    assert dmap.domain == [1, 2]
    assert dmap.codomain == {5, 3, 7, None}

    io_map_full = {"a": {1: 5, 2: 7}, "b": {1: 3, 2: 11}}
    dmap = Map.from_io_maps(cfgs, io_map_full)
    assert dmap.domain == [1, 2]
    assert dmap.codomain == {5, 3, 7, 11}


def test_map_merge():
    cfgs = {"a", "b"}
    binary_sets = {"a": {1, 2, 3}, "b": {2, 4}}
    dmap1 = Map.from_sets(cfgs, binary_sets)
    assert len(dmap1.mapping) == 2

    cfgs = {"c", "d"}
    binary_sets = {"c": {1, 2}, "d": {2, 4, 3}}
    dmap2 = Map.from_sets(cfgs, binary_sets)
    assert len(dmap2.mapping) == 2
    merged = deepcopy(dmap1)
    merged.merge(dmap2)
    assert len(merged.mapping) == 4
    assert len(merged.cfg_map) == 4
    assert len(merged.codomain) == 2
    for i in [1, 2, 3, 4]:
        for cfg in "ab":
            assert merged[cfg, i] == dmap1[cfg, i]
        for cfg in "cd":
            assert merged[cfg, i] == dmap2[cfg, i]


def test_map_deduplicate():
    cfgs = {"a", "b", "c", "d"}
    binary_sets = {"a": {1, 2, 3}, "b": {2, 3, 4}, "c": {1, 2, 3}, "d": {4, 2}}
    dmap = Map.from_sets(cfgs, binary_sets)
    original = deepcopy(dmap)
    dmap.deduplicate()
    for cfg in cfgs:
        for i in [1, 2, 3, 4]:
            assert dmap[cfg, i] == original[cfg, i]
    assert len(dmap.mapping) < len(original.mapping)


def test_map_with_callable(secp128r1):
    add = secp128r1.curve.coordinate_model.formulas["add-2007-bl"]
    dbl = secp128r1.curve.coordinate_model.formulas["dbl-2007-bl"]
    mdbl = secp128r1.curve.coordinate_model.formulas["mdbl-2007-bl"]
    cfgs = [(add, dbl), (add, mdbl)]
    binary_sets = {cfgs[0]: {1, 2, 3}, cfgs[1]: {2, 3}}
    dmap = Map.from_sets(set(cfgs), binary_sets)
    assert dmap[cfgs[0], 1]


def test_build_tree():
    cfgs = ["a", "b", "c"]
    cfg_map = pd.DataFrame([0, 1, 2], index=cfgs, columns=["vals"])
    inputs1 = [1, 2, 3, 4]
    codomain1 = {0, 1, 3, 4, 5}
    mapping1 = pd.DataFrame([(0, 4, 5, 0), (0, 3, 0, 0), (1, 4, 0, 0)])
    dmap1 = Map(mapping1, cfg_map, inputs1, codomain1)

    inputs2 = ["f", "e", "d"]
    codomain2 = {0, 1, 2, 3}
    mapping2 = pd.DataFrame([(1, 0, 0), (2, 0, 0), (3, 0, 0)])
    dmap2 = Map(mapping2, cfg_map, inputs2, codomain2)
    tree = Tree.build(set(cfgs), dmap1, dmap2)
    tree.render()
    tree.render_basic()
    tree.describe()


def test_expand_tree():
    cfgs = ["a", "b", "c"]
    cfg_map = pd.DataFrame([0, 1, 2], index=cfgs, columns=["vals"])
    inputs1 = [1, 2]
    codomain1 = {0, 3, 4}
    mapping1 = pd.DataFrame([(0, 4), (0, 3), (0, 4)])
    dmap1 = Map(mapping1, cfg_map, inputs1, codomain1)

    inputs2 = ["f", "e", "d"]
    codomain2 = {0, 1, 2, 3}
    mapping2 = pd.DataFrame([(1, 0, 0), (2, 0, 0), (3, 0, 0)])
    dmap2 = Map(mapping2, cfg_map, inputs2, codomain2)
    tree = Tree.build(set(cfgs), dmap1)
    res = tree.expand(dmap2)
    assert res.height > tree.height


def test_df():
    nrows = 12_000_000
    ncols = 5
    df = pd.DataFrame([random.choices((True, False), k=ncols) for _ in range(nrows)])
    cfg_map = pd.DataFrame(
        [(i,) for i in range(nrows)],
        index=[str(i) for i in range(nrows)],
        columns=["vals"],
    )
    dmap = Map(df, cfg_map, list(range(ncols)), {True, False})
    # start = time.perf_counter()
    dmap.deduplicate()
    # end = time.perf_counter()