aboutsummaryrefslogtreecommitdiffhomepage
path: root/pyecsca/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'pyecsca/codegen')
-rw-r--r--pyecsca/codegen/builder.py225
-rw-r--r--pyecsca/codegen/client.py85
-rw-r--r--pyecsca/codegen/common.py145
-rw-r--r--pyecsca/codegen/templates/main.c14
-rw-r--r--pyecsca/codegen/templates/mult_ldr.c6
5 files changed, 296 insertions, 179 deletions
diff --git a/pyecsca/codegen/builder.py b/pyecsca/codegen/builder.py
index 3970d21..d65eb2b 100644
--- a/pyecsca/codegen/builder.py
+++ b/pyecsca/codegen/builder.py
@@ -4,12 +4,10 @@ import re
import shutil
import subprocess
import tempfile
-from ast import operator, Add, Sub, Mult, Div, Pow
+from ast import Pow
from copy import copy
-from dataclasses import dataclass
-from enum import Enum
from os import path
-from typing import List, Set, Mapping, Any, Optional, Type, Tuple, MutableMapping
+from typing import List, Set, Mapping, Any, Optional, Tuple, MutableMapping
import click
from jinja2 import Environment, PackageLoader
@@ -23,152 +21,41 @@ from pyecsca.ec.model import (CurveModel, ShortWeierstrassModel, MontgomeryModel
TwistedEdwardsModel)
from pyecsca.ec.mult import (ScalarMultiplier, LTRMultiplier, RTLMultiplier, CoronMultiplier,
LadderMultiplier, SimpleLadderMultiplier, DifferentialLadderMultiplier,
- WindowNAFMultiplier, BinaryNAFMultiplier)
-from pyecsca.ec.op import CodeOp
+ BinaryNAFMultiplier)
+from pyecsca.ec.op import CodeOp, OpType
+
+from .common import (Platform, Multiplication, Squaring, Reduction, HashType, RandomMod,
+ Configuration, MULTIPLIERS, wrap_enum)
env = Environment(
loader=PackageLoader("pyecsca.codegen")
)
-def render_op(op: operator, result: str, left: str, right: str, mod: str) -> Optional[str]:
- if isinstance(op, Add):
+def render_op(op: OpType, result: str, left: str, right: str, mod: str) -> Optional[str]:
+ if op == OpType.Add:
return "bn_mod_add(&{}, &{}, &{}, &{});".format(left, right, mod, result)
- elif isinstance(op, Sub):
+ elif op == OpType.Sub:
return "bn_mod_sub(&{}, &{}, &{}, &{});".format(left, right, mod, result)
- elif isinstance(op, Mult):
+ elif op == OpType.Mult:
return "bn_mod_mul(&{}, &{}, &{}, &{});".format(left, right, mod, result)
- elif isinstance(op, Div):
+ elif op == OpType.Div or op == OpType.Inv:
return "bn_mod_div(&{}, &{}, &{}, &{});".format(left, right, mod, result)
- elif isinstance(op, Pow) and right == 2:
+ elif op == OpType.Sqr:
return "bn_mod_sqr(&{}, &{}, &{});".format(left, mod, result)
- elif isinstance(op, Pow):
+ elif op == OpType.Pow:
return "bn_mod_pow(&{}, &{}, &{}, &{});".format(left, right, mod, result)
- elif op is None:
+ elif op == OpType.Id:
return "bn_copy(&{}, &{});".format(left, result)
else:
print(op, result, left, right, mod)
+ return None
env.globals["render_op"] = render_op
env.globals["isinstance"] = isinstance
-class EnumDefine(Enum):
- def __str__(self):
- return self.value
-
- def __repr__(self):
- return self.value
-
- @classmethod
- def names(cls):
- return list(e.name for e in cls)
-
-
-@public
-class Platform(EnumDefine):
- """Platform to build for."""
- HOST = "HOST"
- XMEGA = "CW308_XMEGA"
- STM32F0 = "CW308_STM32F0"
- STM32F3 = "CW308_STM32F3"
-
-
-@public
-class Multiplication(EnumDefine):
- """Base multiplication algorithm to use."""
- TOOM_COOK = "MUL_TOOM_COOK"
- KARATSUBA = "MUL_KARATSUBA"
- COMBA = "MUL_COMBA"
- BASE = "MUL_BASE"
-
-
-@public
-class Squaring(EnumDefine):
- """Base squaring algorithm to use."""
- TOOM_COOK = "SQR_TOOM_COOK"
- KARATSUBA = "SQR_KARATSUBA"
- COMBA = "SQR_COMBA"
- BASE = "SQR_BASE"
-
-
-@public
-class Reduction(EnumDefine):
- """Modular reduction method used."""
- BARRETT = "RED_BARRETT"
- MONTGOMERY = "RED_MONTGOMERY"
- BASE = "RED_BASE"
-
-
-@public
-class HashType(EnumDefine):
- """Hash algorithm used in ECDH and ECDSA."""
- NONE = "HASH_NONE"
- SHA1 = "HASH_SHA1"
- SHA224 = "HASH_SHA224"
- SHA256 = "HASH_SHA256"
- SHA384 = "HASH_SHA384"
- SHA512 = "HASH_SHA512"
-
-
-@public
-class RandomMod(EnumDefine):
- """Method of sampling a uniform integer modulo order."""
- SAMPLE = "MOD_RAND_SAMPLE"
- REDUCE = "MOD_RAND_REDUCE"
-
-
-@public
-@dataclass
-class Configuration(object):
- platform: Platform
- hash_type: HashType
- mod_rand: RandomMod
- mult: Multiplication # TODO: Use this
- sqr: Squaring # TODO: Use this
- red: Reduction # TODO: Use this
- model: CurveModel
- coords: CoordinateModel
- formulas: List[Formula]
- scalarmult: ScalarMultiplier
-
-MULTIPLIERS = [
- {
- "name": ("rtl", "RTLMultiplier"),
- "class": LTRMultiplier
- },
- {
- "name": ("rtl", "RTLMultiplier"),
- "class": RTLMultiplier
- },
- {
- "name": ("coron", "CoronMultiplier"),
- "class": CoronMultiplier
- },
- {
- "name":("ldr", "LadderMultiplier"),
- "class": LadderMultiplier
- },
- {
- "name": ("simple-ldr", "SimpleLadderMultiplier"),
- "class": SimpleLadderMultiplier
- },
- {
- "name": ("diff-ldr", "DifferentialLadderMultiplier"),
- "class": DifferentialLadderMultiplier
- },
- {
- "name": ("naf", "bnaf", "BinaryNAFMultiplier"),
- "class": BinaryNAFMultiplier
- },
- {
- "name": ("wnaf", "WindowNAFMultiplier"),
- "class": WindowNAFMultiplier
- }
-]
-
-
def render_defs(model: CurveModel, coords: CoordinateModel) -> str:
return env.get_template("defs.h").render(params=model.parameter_names,
variables=coords.variables)
@@ -185,7 +72,7 @@ def transform_ops(ops: List[CodeOp], parameters: List[str], outputs: Set[str],
return renames.get(name, name)
return name
- allocations = []
+ allocations: List[str] = []
initializations = {}
const_mapping = {}
operations = []
@@ -302,9 +189,10 @@ def render_scalarmult_impl(scalarmult: ScalarMultiplier) -> str:
BinaryNAFMultiplier=BinaryNAFMultiplier)
-def render_main(model: CurveModel, coords: CoordinateModel) -> str:
+def render_main(model: CurveModel, coords: CoordinateModel, keygen: bool, ecdh: bool, ecdsa: bool) -> str:
return env.get_template("main.c").render(curve_variables=coords.variables,
- curve_parameters=model.parameter_names)
+ curve_parameters=model.parameter_names,
+ keygen=keygen, ecdh=ecdh, ecdsa=ecdsa)
def render_makefile(platform: Platform, hash_type: HashType, mod_rand: RandomMod) -> str:
@@ -328,7 +216,7 @@ def render(config: Configuration) -> Tuple[str, str, str]:
os.mkdir(gen_dir)
save_render(temp, "Makefile",
render_makefile(config.platform, config.hash_type, config.mod_rand))
- save_render(temp, "main.c", render_main(config.model, config.coords))
+ save_render(temp, "main.c", render_main(config.model, config.coords, config.keygen, config.ecdh, config.ecdsa))
save_render(gen_dir, "defs.h", render_defs(config.model, config.coords))
point_render = render_coords_impl(config.coords)
for formula in config.formulas:
@@ -337,7 +225,8 @@ def render(config: Configuration) -> Tuple[str, str, str]:
save_render(gen_dir, "point.c", point_render)
save_render(gen_dir, "curve.c", render_curve_impl(config.model))
save_render(gen_dir, "mult.c", render_scalarmult_impl(config.scalarmult))
- return temp, "pyecsca-codegen-{}.elf".format(str(config.platform)), "pyecsca-codegen-{}.hex".format(str(config.platform))
+ return temp, "pyecsca-codegen-{}.elf".format(
+ str(config.platform)), "pyecsca-codegen-{}.hex".format(str(config.platform))
@public
@@ -439,23 +328,21 @@ def get_multiplier(ctx: click.Context, param, value: Optional[str]) -> Optional[
return mult
-def wrap_enum(enum_class: Type[EnumDefine]):
- def callback(ctx, param, value):
- try:
- res = getattr(enum_class, value)
- return res
- except Exception:
- raise click.BadParameter(
- "Cannot create {} enum from {}.".format(enum_class.__name__, value))
-
- return callback
-
+def get_ecdsa(ctx: click.Context, param, value: bool) -> bool:
+ if not value:
+ return False
+ formulas = ctx.meta["formulas"]
+ if not any(isinstance(formula, AdditionFormula) for formula in formulas):
+ raise click.BadParameter("ECDSA needs an addition formula. None was supplied.")
@click.group(context_settings={"help_option_names": ["-h", "--help"]})
@click.version_option()
@public
def main():
+ """
+ A tool for building, querying and flashing ECC implementations on devices.
+ """
pass
@@ -484,6 +371,10 @@ def main():
type=click.Choice(Reduction.names()),
callback=wrap_enum(Reduction),
help="Modular reduction algorithm to use.")
+@click.option("--keygen/--no-keygen", help="Whether to disable keygen.", is_flag=True, default=True)
+@click.option("--ecdh/--no-ecdh", help="Whether to disable ECDH.", is_flag=True, default=True)
+@click.option("--ecdsa/--no-ecdsa", help="Whether to disable ECDSA.", is_flag=True, default=True,
+ callback=get_ecdsa)
@click.option("--strip", help="Whether to strip the binary or not.", is_flag=True)
@click.option("--remove/--no-remove", help="Whether to remove the dir.", is_flag=True, default=True)
@click.option("-v", "--verbose", count=True)
@@ -498,8 +389,8 @@ def main():
callback=get_multiplier)
@click.argument("outdir")
@public
-def build_impl(platform, hash, rand, mul, sqr, red, strip, remove, verbose, model, coords, formulas, scalarmult,
- outdir):
+def build_impl(platform, hash, rand, mul, sqr, red, keygen, ecdh, ecdsa, strip, remove,
+ verbose, model, coords, formulas, scalarmult, outdir):
"""This command builds an ECC implementation.
\b
@@ -510,10 +401,10 @@ def build_impl(platform, hash, rand, mul, sqr, red, strip, remove, verbose, mode
OUTDIR: The output directory for files with the built impl.
"""
- config = Configuration(platform, hash, rand, mul, sqr, red, model, coords, formulas, scalarmult)
+ config = Configuration(platform, hash, rand, mul, sqr, red, model, coords, formulas, scalarmult,
+ keygen, ecdh, ecdsa)
dir, elf_file, hex_file = render(config)
-
res = subprocess.run(["make"], cwd=dir, capture_output=True)
if verbose >= 1:
click.echo(res.stdout.decode())
@@ -540,7 +431,7 @@ def build_impl(platform, hash, rand, mul, sqr, red, strip, remove, verbose, mode
callback=get_formula)
@public
def list_impl(model: Optional[CurveModel], coords: Optional[CoordinateModel],
- formulas: Optional[Tuple[Formula]]):
+ formulas: Optional[Tuple[Formula]]):
"""This command lists possible choices for an ECC implementation.
If no arguments are provided the argument lists other implementation options,
such as modular reduction algorithms, build platforms and so on.
@@ -575,14 +466,24 @@ def list_impl(model: Optional[CurveModel], coords: Optional[CoordinateModel],
"{}: {}, [{}]".format(coord.name, coord.full_name, ",".join(coord.variables)))
return
if not model:
- click.echo(click.wrap_text("Platform:\n\t" + ", ".join(Platform.names()),subsequent_indent="\t"))
- click.echo(click.wrap_text("Hash type:\n\t" + ", ".join(HashType.names()),subsequent_indent="\t"))
- click.echo(click.wrap_text("Modular Random:\n\t" + ", ".join(RandomMod.names()),subsequent_indent="\t"))
- click.echo(click.wrap_text("Multiplication:\n\t" + ", ".join(Multiplication.names()),subsequent_indent="\t"))
- click.echo(click.wrap_text("Squaring:\n\t" + ", ".join(Squaring.names()),subsequent_indent="\t"))
- click.echo(click.wrap_text("Modular Reduction:\n\t" + ", ".join(Reduction.names()),subsequent_indent="\t"))
- click.echo(click.wrap_text("Scalar multplier:\n\t" + ", ".join(map(lambda m: m["name"][-1], MULTIPLIERS)),
+ click.echo(
+ click.wrap_text("Platform:\n\t" + ", ".join(Platform.names()),
+ subsequent_indent="\t"))
+ click.echo(
+ click.wrap_text("Hash type:\n\t" + ", ".join(HashType.names()),
+ subsequent_indent="\t"))
+ click.echo(click.wrap_text("Modular Random:\n\t" + ", ".join(RandomMod.names()),
+ subsequent_indent="\t"))
+ click.echo(click.wrap_text("Multiplication:\n\t" + ", ".join(Multiplication.names()),
+ subsequent_indent="\t"))
+ click.echo(
+ click.wrap_text("Squaring:\n\t" + ", ".join(Squaring.names()),
+ subsequent_indent="\t"))
+ click.echo(click.wrap_text("Modular Reduction:\n\t" + ", ".join(Reduction.names()),
subsequent_indent="\t"))
+ click.echo(click.wrap_text(
+ "Scalar multplier:\n\t" + ", ".join(map(lambda m: m["name"][-1], MULTIPLIERS)),
+ subsequent_indent="\t"))
@main.command()
@@ -592,7 +493,7 @@ def list_impl(model: Optional[CurveModel], coords: Optional[CoordinateModel],
help="The platform to flash.")
@click.argument("dir")
@public
-def flash(platform, dir):
+def flash(platform, dir): # pragma: no cover
"""This command flashes a chip through the ChipWhisperer framework with the built implementation.
\b
@@ -602,14 +503,16 @@ def flash(platform, dir):
import chipwhisperer as cw
except ImportError:
click.secho("ChipWhisperer not installed, flashing requires it.", fg="red", err=True)
- return
+ raise click.Abort
if platform in (Platform.STM32F0, Platform.STM32F3):
prog = cw.programmers.STM32FProgrammer
elif platform == Platform.XMEGA:
prog = cw.programmers.XMEGAProgrammer
else:
- click.secho("Flashing the HOST is not required, just run the ELF and communicate with it via the standard IO.", fg="red", err=True)
- return
+ click.secho(
+ "Flashing the HOST is not required, just run the ELF and communicate with it via the standard IO.",
+ fg="red", err=True)
+ raise click.Abort
fw_path = path.join(dir, "pyecsca-codegen-{}.hex".format(platform))
scope = cw.scope()
scope.default_setup()
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()
diff --git a/pyecsca/codegen/common.py b/pyecsca/codegen/common.py
new file mode 100644
index 0000000..e29fa00
--- /dev/null
+++ b/pyecsca/codegen/common.py
@@ -0,0 +1,145 @@
+from dataclasses import dataclass
+from enum import Enum
+from typing import List, Type
+import click
+
+from public import public
+from pyecsca.ec.coordinates import CoordinateModel
+from pyecsca.ec.formula import Formula
+from pyecsca.ec.model import CurveModel
+from pyecsca.ec.mult import (ScalarMultiplier, LTRMultiplier, RTLMultiplier, CoronMultiplier,
+ LadderMultiplier, SimpleLadderMultiplier, DifferentialLadderMultiplier,
+ WindowNAFMultiplier, BinaryNAFMultiplier)
+
+
+@public
+class EnumDefine(Enum):
+ def __str__(self):
+ return self.value
+
+ def __repr__(self):
+ return self.value
+
+ @classmethod
+ def names(cls):
+ return list(e.name for e in cls)
+
+
+@public
+class Platform(EnumDefine):
+ """Platform to build for."""
+ HOST = "HOST"
+ XMEGA = "CW308_XMEGA"
+ STM32F0 = "CW308_STM32F0"
+ STM32F3 = "CW308_STM32F3"
+
+
+@public
+class Multiplication(EnumDefine):
+ """Base multiplication algorithm to use."""
+ TOOM_COOK = "MUL_TOOM_COOK"
+ KARATSUBA = "MUL_KARATSUBA"
+ COMBA = "MUL_COMBA"
+ BASE = "MUL_BASE"
+
+
+@public
+class Squaring(EnumDefine):
+ """Base squaring algorithm to use."""
+ TOOM_COOK = "SQR_TOOM_COOK"
+ KARATSUBA = "SQR_KARATSUBA"
+ COMBA = "SQR_COMBA"
+ BASE = "SQR_BASE"
+
+
+@public
+class Reduction(EnumDefine):
+ """Modular reduction method used."""
+ BARRETT = "RED_BARRETT"
+ MONTGOMERY = "RED_MONTGOMERY"
+ BASE = "RED_BASE"
+
+
+@public
+class HashType(EnumDefine):
+ """Hash algorithm used in ECDH and ECDSA."""
+ NONE = "HASH_NONE"
+ SHA1 = "HASH_SHA1"
+ SHA224 = "HASH_SHA224"
+ SHA256 = "HASH_SHA256"
+ SHA384 = "HASH_SHA384"
+ SHA512 = "HASH_SHA512"
+
+
+@public
+class RandomMod(EnumDefine):
+ """Method of sampling a uniform integer modulo order."""
+ SAMPLE = "MOD_RAND_SAMPLE"
+ REDUCE = "MOD_RAND_REDUCE"
+
+
+@public
+@dataclass
+class Configuration(object):
+ platform: Platform
+ hash_type: HashType
+ mod_rand: RandomMod
+ mult: Multiplication # TODO: Use this
+ sqr: Squaring # TODO: Use this
+ red: Reduction # TODO: Use this
+ model: CurveModel
+ coords: CoordinateModel
+ formulas: List[Formula]
+ scalarmult: ScalarMultiplier
+ keygen: bool
+ ecdh: bool
+ ecdsa: bool
+
+
+MULTIPLIERS = [
+ {
+ "name": ("ltr", "LTRMultiplier"),
+ "class": LTRMultiplier
+ },
+ {
+ "name": ("rtl", "RTLMultiplier"),
+ "class": RTLMultiplier
+ },
+ {
+ "name": ("coron", "CoronMultiplier"),
+ "class": CoronMultiplier
+ },
+ {
+ "name": ("ldr", "LadderMultiplier"),
+ "class": LadderMultiplier
+ },
+ {
+ "name": ("simple-ldr", "SimpleLadderMultiplier"),
+ "class": SimpleLadderMultiplier
+ },
+ {
+ "name": ("diff-ldr", "DifferentialLadderMultiplier"),
+ "class": DifferentialLadderMultiplier
+ },
+ {
+ "name": ("naf", "bnaf", "BinaryNAFMultiplier"),
+ "class": BinaryNAFMultiplier
+ },
+ {
+ "name": ("wnaf", "WindowNAFMultiplier"),
+ "class": WindowNAFMultiplier
+ }
+]
+
+
+@public
+def wrap_enum(enum_class: Type[EnumDefine]):
+ def callback(ctx, param, value):
+ try:
+ res = getattr(enum_class, value)
+ return res
+ except Exception:
+ raise click.BadParameter(
+ "Cannot create {} enum from {}.".format(enum_class.__name__, value))
+
+ return callback
diff --git a/pyecsca/codegen/templates/main.c b/pyecsca/codegen/templates/main.c
index 1c9491b..e39af07 100644
--- a/pyecsca/codegen/templates/main.c
+++ b/pyecsca/codegen/templates/main.c
@@ -352,13 +352,19 @@ int main(void) {
simpleserial_init();
simpleserial_addcmd('i', MAX_SS_LEN, cmd_init_prng);
simpleserial_addcmd('c', MAX_SS_LEN, cmd_set_curve);
- simpleserial_addcmd('g', 0, cmd_generate);
+ {%- if keygen %}
+ simpleserial_addcmd('g', 0, cmd_generate);
+ {%- endif %}
simpleserial_addcmd('s', MAX_SS_LEN, cmd_set_privkey);
simpleserial_addcmd('w', MAX_SS_LEN, cmd_set_pubkey);
simpleserial_addcmd('m', MAX_SS_LEN, cmd_scalar_mult);
- simpleserial_addcmd('e', MAX_SS_LEN, cmd_ecdh);
- simpleserial_addcmd('a', MAX_SS_LEN, cmd_ecdsa_sign);
- simpleserial_addcmd('v', MAX_SS_LEN, cmd_ecdsa_verify);
+ {%- if ecdh %}
+ simpleserial_addcmd('e', MAX_SS_LEN, cmd_ecdh);
+ {%- endif %}
+ {%- if ecdsa %}
+ simpleserial_addcmd('a', MAX_SS_LEN, cmd_ecdsa_sign);
+ simpleserial_addcmd('v', MAX_SS_LEN, cmd_ecdsa_verify);
+ {%- endif %}
while(simpleserial_get());
return 0;
} \ No newline at end of file
diff --git a/pyecsca/codegen/templates/mult_ldr.c b/pyecsca/codegen/templates/mult_ldr.c
index cabab0b..c7c5246 100644
--- a/pyecsca/codegen/templates/mult_ldr.c
+++ b/pyecsca/codegen/templates/mult_ldr.c
@@ -3,7 +3,7 @@
void scalar_mult(bn_t *scalar, point_t *point, curve_t *curve, point_t *out) {
{%- if scalarmult.complete %}
- point_t *p0 = point_copy(&curve->neutral);
+ point_t *p0 = point_copy(curve->neutral);
point_t *p1 = point_copy(point);
int nbits = bn_bit_length(&curve->n) - 1;
{%- else %}
@@ -15,9 +15,9 @@ void scalar_mult(bn_t *scalar, point_t *point, curve_t *curve, point_t *out) {
for (int i = nbits; i >= 0; i--) {
if (bn_get_bit(scalar, i) == 0) {
- point_ladd(p0, p1, curve, p0, p1);
+ point_ladd(p0, p1, point, curve, p0, p1);
} else {
- point_ladd(p1, p0, curve, p1, p0);
+ point_ladd(p1, p0, point, curve, p1, p0);
}
}