diff options
| -rw-r--r-- | pyecsca/sca/target/__init__.py | 1 | ||||
| -rw-r--r-- | pyecsca/sca/target/leakage.py | 65 | ||||
| -rw-r--r-- | test/sca/test_target.py | 29 |
3 files changed, 73 insertions, 22 deletions
diff --git a/pyecsca/sca/target/__init__.py b/pyecsca/sca/target/__init__.py index bc9a54d..828632e 100644 --- a/pyecsca/sca/target/__init__.py +++ b/pyecsca/sca/target/__init__.py @@ -6,6 +6,7 @@ from .serial import * from .simpleserial import * from .binary import * from .flash import * +from .leakage import * has_chipwhisperer: bool = False has_pyscard: bool = False diff --git a/pyecsca/sca/target/leakage.py b/pyecsca/sca/target/leakage.py index 8a8acd6..1f6e2b0 100644 --- a/pyecsca/sca/target/leakage.py +++ b/pyecsca/sca/target/leakage.py @@ -1,25 +1,25 @@ -from pyecsca.ec.coordinates import CoordinateModel -from pyecsca.ec.mod import Mod -from pyecsca.ec.model import CurveModel -from pyecsca.ec.params import DomainParameters -from pyecsca.ec.point import Point -from pyecsca.ec.mult import ScalarMultiplier -from pyecsca.ec.key_generation import KeyGeneration -from pyecsca.ec.key_agreement import KeyAgreement -from pyecsca.ec.signature import Signature, SignatureResult -from pyecsca.ec.formula import FormulaAction -from pyecsca.ec.context import DefaultContext, local -from pyecsca.sca.attack import LeakageModel -from pyecsca.sca.trace import Trace +import numpy as np from typing import Optional, Tuple from public import public + +from ...ec.coordinates import CoordinateModel +from ...ec.mod import Mod +from ...ec.model import CurveModel +from ...ec.params import DomainParameters +from ...ec.point import Point +from ...ec.mult import ScalarMultiplier +from ...ec.key_generation import KeyGeneration +from ...ec.key_agreement import KeyAgreement +from ...ec.signature import Signature, SignatureResult +from ...ec.formula import FormulaAction +from ...ec.context import DefaultContext, local +from ..attack import LeakageModel +from ..trace import Trace from .base import Target -import numpy as np @public class LeakageTarget(Target): - model: CurveModel coords: CoordinateModel mult: ScalarMultiplier @@ -28,7 +28,13 @@ class LeakageTarget(Target): privkey: Optional[Mod] pubkey: Optional[Point] - def __init__(self, model: CurveModel, coords: CoordinateModel, mult: ScalarMultiplier, leakage_model: LeakageModel): + def __init__( + self, + model: CurveModel, + coords: CoordinateModel, + mult: ScalarMultiplier, + leakage_model: LeakageModel, + ): super().__init__() self.model = model self.coords = coords @@ -44,24 +50,35 @@ class LeakageTarget(Target): for intermediate in action.op_results: leak = self.leakage_model(intermediate.value) temp_trace.append(leak) + temp_trace: list[int] = [] context.actions.walk(callback) return Trace(np.array(temp_trace)) - def simulate_scalar_mult_traces(self, num_of_traces: int, scalar: int) -> Tuple[list[Point], list[Trace]]: + def simulate_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)] + points = [ + self.params.curve.affine_random().to_model(self.coords, self.params.curve) + for _ in range(num_of_traces) + ] traces = [] for point in points: _, trace = self.scalar_mult(scalar, point) traces.append(trace) return points, traces - def simulate_ecdh_traces(self, num_of_traces: int) -> Tuple[list[Point], list[Trace]]: + def simulate_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)] + 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) @@ -102,7 +119,9 @@ class LeakageTarget(Target): 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) + ecdh = KeyAgreement( + self.mult, self.params, other_pubkey, self.privkey, hash_algo + ) shared_secret = ecdh.perform() return shared_secret, self.get_trace(ctx) @@ -116,7 +135,9 @@ class LeakageTarget(Target): 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]: + 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: diff --git a/test/sca/test_target.py b/test/sca/test_target.py index ac0c8c8..6b8a8c7 100644 --- a/test/sca/test_target.py +++ b/test/sca/test_target.py @@ -1,3 +1,4 @@ +import hashlib import io from contextlib import redirect_stdout from copy import copy @@ -17,7 +18,9 @@ from pyecsca.sca.target import ( SimpleSerialTarget, SimpleSerialMessage, has_pyscard, + LeakageTarget, ) +from pyecsca.sca.attack import HammingWeight from pyecsca.sca.target.ectester import ( KeyAgreementEnum, SignatureEnum, @@ -505,3 +508,29 @@ def test_ecdsa_verify(target, secp256r1_projective): KeypairEnum.KEYPAIR_LOCAL, SignatureEnum.ALG_ECDSA_SHA, sig.to_DER(), data ) assert ecdsa_resp.success + + +def test_leakage_target(secp256r1_projective): + mult = LTRMultiplier( + secp256r1_projective.curve.coordinate_model.formulas["add-2015-rcb"], + secp256r1_projective.curve.coordinate_model.formulas["dbl-2015-rcb"], + ) + lm = HammingWeight() + target = LeakageTarget(secp256r1_projective.curve.model, secp256r1_projective.curve.coordinate_model, mult, lm) + target.set_params(secp256r1_projective) + (priv, pub), trace = target.generate() + assert trace is not None + (other_priv, other_pub), trace = target.generate() + target.set_privkey(priv) + target.set_pubkey(pub) + secret, trace = target.ecdh(other_pub) + target.set_privkey(other_priv) + target.set_pubkey(other_pub) + secret2, trace = target.ecdh(pub) + assert secret == secret2 + res, trace = target.scalar_mult(7, secp256r1_projective.generator) + assert res is not None + + msg = b"data" + signature, trace = target.ecdsa_sign(msg, hashlib.sha1) + assert target.ecdsa_verify(msg, signature, hashlib.sha1) |
