aboutsummaryrefslogtreecommitdiffhomepage
path: root/pyecsca/codegen
diff options
context:
space:
mode:
authorandrr3j2023-04-08 16:12:12 +0200
committerandrr3j2023-04-08 16:12:12 +0200
commite2acae5b7e0d5ff0a0c35189ddb67d404ca6716d (patch)
treeb7ee7b05748ff94fd05230da8902fd915d3b4f98 /pyecsca/codegen
parent3790770c2bc6ca618df8a95f0f5efc15ce9eba21 (diff)
downloadpyecsca-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.py123
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.