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
|
from functools import lru_cache
from typing import Type, Callable
from copy import deepcopy
from pyecsca.ec.formula import (
AdditionFormula,
DifferentialAdditionFormula,
DoublingFormula,
LadderFormula,
NegationFormula,
ScalingFormula,
)
from pyecsca.ec.formula.fake import (
FakeAdditionFormula,
FakeDifferentialAdditionFormula,
FakeDoublingFormula,
FakeLadderFormula,
FakeNegationFormula,
FakeScalingFormula,
)
from pyecsca.ec.mult import ScalarMultiplier
from pyecsca.ec.params import DomainParameters
fake_map = {
AdditionFormula: FakeAdditionFormula,
DifferentialAdditionFormula: FakeDifferentialAdditionFormula,
DoublingFormula: FakeDoublingFormula,
LadderFormula: FakeLadderFormula,
NegationFormula: FakeNegationFormula,
ScalingFormula: FakeScalingFormula,
}
def fake_mult(
mult_class: Type[ScalarMultiplier], mult_factory: Callable, params: DomainParameters
) -> ScalarMultiplier:
"""
Get a multiplier with `FakeFormula`s.
:param mult_class: The class of the scalar multiplier to use.
:param mult_factory: A callable that takes the formulas and instantiates the multiplier.
:param params: The domain parameters to use.
:return: The multiplier.
"""
formulas = []
for formula, fake_formula in fake_map.items():
if formula in mult_class.requires:
formulas.append(fake_formula(params.curve.coordinate_model))
mult = mult_factory(*formulas, short_circuit=False)
return mult
def turn_fake(mult: ScalarMultiplier) -> ScalarMultiplier:
"""
Turn a multiplier into a fake multiplier.
:param mult: The multiplier to turn into a fake multiplier.
:return: The multiplier with fake formulas.
"""
copy = deepcopy(mult)
copy.short_circuit = False
formulas = {}
for key, formula in copy.formulas.items():
for real, fake in fake_map.items():
if isinstance(formula, real):
formulas[key] = fake(formula.coordinate_model)
copy.formulas = formulas
return copy
@lru_cache(maxsize=256, typed=True)
def cached_fake_mult(
mult_class: Type[ScalarMultiplier], mult_factory: Callable, params: DomainParameters
) -> ScalarMultiplier:
fm = fake_mult(mult_class, mult_factory, params)
if getattr(fm, "short_circuit", False):
raise ValueError("The multiplier must not short-circuit.")
return fm
|