aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pyecsca/sca/target/__init__.py1
-rw-r--r--pyecsca/sca/target/leakage.py65
-rw-r--r--test/sca/test_target.py29
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)