diff options
| author | Ján Jančár | 2023-10-05 22:04:19 +0200 |
|---|---|---|
| committer | GitHub | 2023-10-05 22:04:19 +0200 |
| commit | 444a6b5c5da6a24a4dd3979dd38f26f2ad58ecc8 (patch) | |
| tree | eb80dc6946a3b168699413303e0ef24d879aaee9 | |
| parent | 509ffef3df7a98cc8cceccbb7d1ca3e8440ea4f5 (diff) | |
| parent | e9b73fd3f476eaf003940aac1f1a1324c02e9ecc (diff) | |
| download | pyecsca-444a6b5c5da6a24a4dd3979dd38f26f2ad58ecc8.tar.gz pyecsca-444a6b5c5da6a24a4dd3979dd38f26f2ad58ecc8.tar.zst pyecsca-444a6b5c5da6a24a4dd3979dd38f26f2ad58ecc8.zip | |
Merge branch 'master' into CPA_pyecsca
| -rw-r--r-- | pyecsca/sca/attack/DPA.py | 11 | ||||
| -rw-r--r-- | pyecsca/sca/target/emulator.py | 47 |
2 files changed, 39 insertions, 19 deletions
diff --git a/pyecsca/sca/attack/DPA.py b/pyecsca/sca/attack/DPA.py index 99e6472..b6be49c 100644 --- a/pyecsca/sca/attack/DPA.py +++ b/pyecsca/sca/attack/DPA.py @@ -7,6 +7,7 @@ from pyecsca.sca.trace.plot import plot_trace from typing import Tuple, Dict from public import public + @public class DPA(): @@ -30,7 +31,7 @@ class DPA(): self.doms = {'guess_one' : [], 'guess_zero' : []} def compute_split_point(self, guessed_scalar: int, target_bit: int, point: Point) -> Point: - with(local(DefaultContext())) as ctx: + with local(DefaultContext()) as ctx: self.mult.init(self.params, point) self.mult.multiply(guessed_scalar) action_index = -1 @@ -46,8 +47,8 @@ class DPA(): one_traces = [] zero_traces = [] for i in range(len(self.points)): - #TODO: works only if the computed split point has "X" coordinate - split_value = self.compute_split_point(guessed_scalar, target_bit, self.points[i]).X + # TODO: works only if the computed split point has "X" coordinate + split_value = self.compute_split_point(guessed_scalar, target_bit, self.points[i]).X if int(split_value) & 1 == 1: one_traces.append(self.traces[i]) elif int(split_value) & 1 == 0: @@ -57,7 +58,7 @@ class DPA(): def calculate_difference_of_means(self, one_traces: list[Trace], zero_traces: list[Trace]) -> Trace: avg_ones = average(*one_traces) avg_zeros = average(*zero_traces) - return subtract(avg_ones, avg_zeros) + return subtract(avg_ones, avg_zeros) # type: ignore def plot_difference_of_means(self, dom): return plot_trace(dom).opts(width=950, height=600) @@ -85,4 +86,4 @@ class DPA(): recovered_scalar = 1 << (scalar_bit_length - 1) for target_bit in range(1, scalar_bit_length): recovered_scalar = self.recover_bit(recovered_scalar, target_bit, scalar_bit_length, real_pub_key) - return recovered_scalar
\ No newline at end of file + return recovered_scalar diff --git a/pyecsca/sca/target/emulator.py b/pyecsca/sca/target/emulator.py index 8d74bf6..bca27cf 100644 --- a/pyecsca/sca/target/emulator.py +++ b/pyecsca/sca/target/emulator.py @@ -16,38 +16,41 @@ from public import public from .base import Target import numpy as np + @public class EmulatorTarget(Target): - + model: CurveModel coords: CoordinateModel mult: ScalarMultiplier + leakage_model: LeakageModel params: Optional[DomainParameters] - leakage_model: Optional[LeakageModel] privkey: Optional[Mod] pubkey: Optional[Point] - def __init__(self, model: CurveModel, coords: CoordinateModel, mult: ScalarMultiplier): + def __init__(self, model: CurveModel, coords: CoordinateModel, mult: ScalarMultiplier, leakage_model: LeakageModel): super().__init__() self.model = model self.coords = coords self.mult = mult + self.leakage_model = leakage_model self.params = None - self.leakage_model = None self.privkey = None self.pubkey = None - + def get_trace(self, context: DefaultContext) -> Trace: def callback(action): if isinstance(action, FormulaAction): for intermediate in action.op_results: leak = self.leakage_model(intermediate.value) temp_trace.append(leak) - temp_trace = [] + temp_trace: list[int] = [] context.actions.walk(callback) return Trace(np.array(temp_trace)) - + def emulate_scalar_mult_traces(self, num_of_traces: int, scalar: int) -> Tuple[list[Point], list[Trace]]: + if self.params is None: + raise ValueError("Missing DomainParameters") points = [self.params.curve.affine_random().to_model(self.coords, self.params.curve) for _ in range(num_of_traces)] traces = [] for point in points: @@ -56,13 +59,15 @@ class EmulatorTarget(Target): return points, traces def emulate_ecdh_traces(self, num_of_traces: int) -> Tuple[list[Point], list[Trace]]: + if self.params is None: + raise ValueError("Missing DomainParameters") other_pubs = [self.params.curve.affine_random().to_model(self.coords, self.params.curve) for _ in range(num_of_traces)] traces = [] for pub in other_pubs: _, trace = self.ecdh(pub, None) traces.append(trace) return other_pubs, traces - + def set_params(self, params: DomainParameters) -> None: self.params = params @@ -70,15 +75,19 @@ class EmulatorTarget(Target): self.leakage_model = leakage_model def scalar_mult(self, scalar: int, point: Point) -> Tuple[Point, Trace]: + if self.params is None: + raise ValueError("Missing DomainParameters") with local(DefaultContext()) as ctx: self.mult.init(self.params, point) res_point = self.mult.multiply(scalar) return res_point, self.get_trace(ctx) def generate(self) -> Tuple[Tuple[Mod, Point], Trace]: + if self.params is None: + raise ValueError("Missing DomainParameters") with local(DefaultContext()) as ctx: keygen = KeyGeneration(self.mult, self.params, False) - priv, pub = keygen.generate() + priv, pub = keygen.generate() return (priv, pub), self.get_trace(ctx) def set_privkey(self, privkey: Mod) -> None: @@ -88,20 +97,32 @@ class EmulatorTarget(Target): self.pubkey = pubkey def ecdh(self, other_pubkey: Point, hash_algo=None) -> Tuple[bytes, Trace]: + if self.params is None: + raise ValueError("Missing DomainParameters") + if self.privkey is None: + raise ValueError("Missing privkey") with local(DefaultContext()) as ctx: ecdh = KeyAgreement(self.mult, self.params, other_pubkey, self.privkey, hash_algo) shared_secret = ecdh.perform() return shared_secret, self.get_trace(ctx) def ecdsa_sign(self, data: bytes, hash_algo=None) -> Tuple[SignatureResult, Trace]: + if self.params is None: + raise ValueError("Missing DomainParameters") + if self.privkey is None: + raise ValueError("Missing privkey") with local(DefaultContext()) as ctx: - ecdsa = Signature(self.mult, self.params, self.mult.formulas["add"], self.pubkey, self.privkey, hash_algo) + ecdsa = Signature(self.mult, self.params, self.mult.formulas["add"], self.pubkey, self.privkey, hash_algo) # type: ignore signed_data = ecdsa.sign_data(data) return signed_data, self.get_trace(ctx) def ecdsa_verify(self, data: bytes, signature: SignatureResult, hash_algo=None) -> Tuple[bool, Trace]: + if self.params is None: + raise ValueError + if self.pubkey is None: + raise ValueError("Missing pubkey") with local(DefaultContext()) as ctx: - ecdsa = Signature(self.mult, self.params, self.mult.formulas["add"], self.pubkey, hash_algo) + ecdsa = Signature(self.mult, self.params, self.mult.formulas["add"], self.pubkey, hash_algo) # type: ignore verified = ecdsa.verify_data(signature, data) return verified, self.get_trace(ctx) @@ -113,11 +134,9 @@ class EmulatorTarget(Target): def disconnect(self): pass - + def set_trigger(self): pass def quit(self): pass - - |
