diff options
| author | andrr3j | 2023-04-08 16:12:12 +0200 |
|---|---|---|
| committer | andrr3j | 2023-04-08 16:12:12 +0200 |
| commit | e2acae5b7e0d5ff0a0c35189ddb67d404ca6716d (patch) | |
| tree | b7ee7b05748ff94fd05230da8902fd915d3b4f98 /pyecsca/codegen | |
| parent | 3790770c2bc6ca618df8a95f0f5efc15ce9eba21 (diff) | |
| download | pyecsca-codegen-e2acae5b7e0d5ff0a0c35189ddb67d404ca6716d.tar.gz pyecsca-codegen-e2acae5b7e0d5ff0a0c35189ddb67d404ca6716d.tar.zst pyecsca-codegen-e2acae5b7e0d5ff0a0c35189ddb67d404ca6716d.zip | |
SimulatorTarget added to client.py
Diffstat (limited to 'pyecsca/codegen')
| -rw-r--r-- | pyecsca/codegen/client.py | 123 |
1 files changed, 122 insertions, 1 deletions
diff --git a/pyecsca/codegen/client.py b/pyecsca/codegen/client.py index 22e6634..6caa85c 100644 --- a/pyecsca/codegen/client.py +++ b/pyecsca/codegen/client.py @@ -16,11 +16,14 @@ from pyecsca.ec.mod import Mod from pyecsca.ec.model import CurveModel from pyecsca.ec.params import DomainParameters, get_params from pyecsca.ec.point import Point, InfinityPoint -from pyecsca.sca.target import (SimpleSerialTarget, ChipWhispererTarget, BinaryTarget, Flashable, +from pyecsca.sca.target import (Target, SimpleSerialTarget, ChipWhispererTarget, BinaryTarget, Flashable, SimpleSerialMessage as SMessage) from .common import wrap_enum, Platform, get_model, get_coords +from rainbow.devices import rainbow_stm32f215 +from rainbow import TraceConfig, HammingWeight + class Triggers(IntFlag): """ @@ -186,6 +189,124 @@ def cmd_debug() -> str: return "d" +class SimulatorTarget(Target): + + simulator: rainbow_stm32f215 + result: list + model: CurveModel + coords: CoordinateModel + seed: Optional[bytes] + params: Optional[DomainParameters] + privkey: Optional[int] + pubkey: Optional[Point] + + def __init__(self, model: CurveModel, coords: CoordinateModel): + super().__init__() + self.simulator = rainbow_stm32f215(allow_stubs=True) + self.result = [] + self.model = model + self.coords = coords + self.seed = None + self.params = None + self.privkey = None + self.pubkey = None + + def __simulate(self, command: str, function: str) -> None: + data = unhexlify(command[1:]) + length = len(data) + data_adress = 0xDEAD0000 + self.simulator[data_adress] = data + self.simulator['r0'] = data_adress + self.simulator['r1'] = length + self.simulator.start(self.simulator.functions[function] | 1, 0) + self.simulator.reset() + + def hook_result(self, simulator) -> None: + self.result.append(simulator['r0']) + self.result.append(simulator['r1']) + self.result.append(simulator['r2']) + + def connect(self, **kwargs) -> None: + self.simulator.load(kwargs["binary"]) + self.simulator.setup() + self.simulator.hook_bypass("simpleserial_put", self.hook_result) + self.simulator.start(self.simulator.functions['main'] | 1, 0) + self.simulator.reset() + + def set_params(self, params: DomainParameters) -> None: + command = cmd_set_params(params) + self.__simulate(command, 'cmd_set_params') + self.params = params + + def scalar_mult(self, scalar: int, point: Point) -> Point: + command = cmd_scalar_mult(scalar, point) + self.__simulate(command, 'cmd_scalar_mult') + res_adress = self.result[2] + res_length = self.result[1] // 3 + x = int.from_bytes(self.simulator[res_adress: res_adress + res_length], 'big') + y = int.from_bytes(self.simulator[res_adress + res_length: res_adress + 2 * res_length], 'big') + res_point = Point(AffineCoordinateModel(self.model), x = Mod(x, self.params.curve.prime), + y = Mod(y, self.params.curve.prime)) + self.result = [] + return res_point + + def init_prng(self, seed: bytes) -> None: + command = cmd_init_prng(seed) + self.__simulate(command, 'cmd_init_prng') + self.seed = seed + + def generate(self) -> Tuple[int, Point]: + command = cmd_generate() + self.__simulate(command, 'cmd_generate') + priv = int(hexlify(self.simulator[self.result[2]:self.result[2] + self.result[1]]) ,16) + pub_x = int(hexlify(self.simulator[self.result[5]:self.result[5] + self.result[4] // 2]), 16) + pub_y = int(hexlify(self.simulator[self.result[5] + self.result[4] // 2:self.result[5] + self.result[4]]) ,16) + self.result = [] + return priv, Point(AffineCoordinateModel(self.model), x = Mod(pub_x, self.params.curve.prime), + y = Mod(pub_y, self.params.curve.prime)) + + def set_privkey(self, privkey: int) -> None: + command = cmd_set_privkey(privkey) + self.__simulate(command, 'cmd_set_privkey') + self.privkey = privkey + + def set_pubkey(self, pubkey: Point) -> None: + command = cmd_set_pubkey(pubkey) + self.__simulate(command, 'cmd_set_pubkey') + self.pubkey = pubkey + + def ecdh(self, other_pubkey: Point) -> bytes: + command = cmd_ecdh(other_pubkey) + self.__simulate(command, 'cmd_ecdh') + shared_secret = self.simulator[self.result[2]:self.result[2] + self.result[1]] + self.result = [] + return shared_secret + + def ecdsa_sign(self, data: bytes) -> bytes: + command = cmd_ecdsa_sign(data) + self.__simulate(command, 'cmd_ecdsa_sign') + signature = self.simulator[self.result[2]:self.result[2] + self.result[1]] + self.result = [] + return signature + + def ecdsa_verify(self, data: bytes, signature: bytes) -> bool: + command = cmd_ecdsa_verify(data, signature) + self.__simulate(command, 'cmd_ecdsa_verify') + res = self.simulator[self.result[2]:self.result[2] + self.result[1]] + self.result = [] + return bool(int.from_bytes(res, 'big')) + + def set_strigger(self): + pass + + def debug(self): + pass + + def disconnect(self): + pass + + + class ImplTarget(SimpleSerialTarget): """ A target that is based on an implementation built by pyecsca-codegen. |
