aboutsummaryrefslogtreecommitdiffhomepage
path: root/pyecsca/codegen/client.py
diff options
context:
space:
mode:
Diffstat (limited to 'pyecsca/codegen/client.py')
-rw-r--r--pyecsca/codegen/client.py85
1 files changed, 74 insertions, 11 deletions
diff --git a/pyecsca/codegen/client.py b/pyecsca/codegen/client.py
index dca9aee..8893a5c 100644
--- a/pyecsca/codegen/client.py
+++ b/pyecsca/codegen/client.py
@@ -1,16 +1,26 @@
#!/usr/bin/env python3
from binascii import hexlify
-from typing import Mapping, Union, Optional
+from typing import Mapping, Union, Optional, Any
+from os import path
import click
-from pyecsca.ec.coordinates import AffineCoordinateModel
-from pyecsca.ec.curve import EllipticCurve
-from pyecsca.ec.group import AbelianGroup
+from pyecsca.ec.params import DomainParameters
from pyecsca.ec.mod import Mod
-from pyecsca.ec.model import ShortWeierstrassModel
-from pyecsca.ec.mult import LTRMultiplier
from pyecsca.ec.point import Point
+from .common import EnumDefine, wrap_enum
+
+try:
+ import chipwhisperer as cw
+except ImportError:
+ cw = None
+
+
+class Target(EnumDefine):
+ HOST = "HOST"
+ SIMPLESERIAL = "CWLITE_SIMPLESERIAL"
+ JCARD = "CWLITE_JCARD"
+
def encode_scalar(val: Union[int, Mod]) -> bytes:
if isinstance(val, int):
@@ -55,7 +65,7 @@ def cmd_init_prng(seed: bytes) -> str:
return "i" + hexlify(seed).decode()
-def cmd_set_curve(group: AbelianGroup) -> str:
+def cmd_set_curve(group: DomainParameters) -> str:
data = {
"p": encode_scalar(group.curve.prime),
"n": encode_scalar(group.order),
@@ -96,11 +106,49 @@ def cmd_ecdsa_verify(data: bytes, sig: bytes) -> str:
return "v" + hexlify(encode_data(None, {"d": data, "s": sig})).decode()
-@click.command()
+def setup_scope(target_type: Target):
+ if target_type in (Target.SIMPLESERIAL, Target.JCARD):
+ scope = cw.scope()
+ scope.default_setup()
+ return scope
+ return None
+
+
+def connect(target_type: Target, scope, **kwargs) -> Any:
+ if target_type == Target.HOST:
+ return kwargs["binary"]
+ elif target_type == Target.SIMPLESERIAL:
+ return cw.target(scope, cw.targets.SimpleSerial)
+ elif target_type == Target.JCARD:
+ return None # TODO: this
+
+
+def send_command(target_type: Target, target: Any, command: str) -> str:
+ if target_type == Target.SIMPLESERIAL:
+ target.write(command + "\n")
+ result = target.read()
+ target.simpleserial_wait_ack()
+ return result
+ return None # TODO: this
+
+
+@click.group(context_settings={"help_option_names": ["-h", "--help"]})
+@click.option("--target", envvar="TARGET", required=True,
+ type=click.Choice(Target.names()),
+ callback=wrap_enum(Target),
+ help="The target to use.")
+@click.option("--binary", help="For HOST target only. The binary to run.")
@click.version_option()
-def main():
- import chipwhisperer
- pass
+def main(target, binary):
+ """
+ A tool for communicating with built and flashed ECC implementations.
+ """
+ if target in (Target.SIMPLESERIAL, Target.JCARD) and cw is None:
+ click.secho("ChipWhisperer not installed, SIMPLESERIAL and JCARD targets require it.", fg="red", err=True)
+ raise click.Abort
+ if target == Target.HOST and (binary is None or not path.isfile(binary)):
+ click.secho("Binary is required if the target is the host.", fg="red", err=True)
+ raise click.Abort
# model = ShortWeierstrassModel()
# coords = model.coordinates["projective"]
# p = 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff
@@ -136,5 +184,20 @@ def main():
# print(ot == res)
+@main.command("gen")
+def generate():
+ pass
+
+
+@main.command("ecdh")
+def ecdh():
+ pass
+
+
+@main.command("ecdsa")
+def ecdsa():
+ pass
+
+
if __name__ == "__main__":
main()