aboutsummaryrefslogtreecommitdiffhomepage
path: root/pyecsca/codegen/__init__.py
diff options
context:
space:
mode:
Diffstat (limited to 'pyecsca/codegen/__init__.py')
-rw-r--r--pyecsca/codegen/__init__.py103
1 files changed, 93 insertions, 10 deletions
diff --git a/pyecsca/codegen/__init__.py b/pyecsca/codegen/__init__.py
index 104b43f..06c85c2 100644
--- a/pyecsca/codegen/__init__.py
+++ b/pyecsca/codegen/__init__.py
@@ -1,7 +1,12 @@
+import os
+import tempfile
from ast import operator, Add, Sub, Mult, Div, Pow
+from enum import Enum
+from os import path
from typing import List, Set, Mapping
from jinja2 import Environment, PackageLoader
+from pkg_resources import resource_filename
from pyecsca.ec.coordinates import CoordinateModel
from pyecsca.ec.formula import (Formula, AdditionFormula, DoublingFormula, TriplingFormula,
NegationFormula, ScalingFormula, DifferentialAdditionFormula,
@@ -25,21 +30,53 @@ def render_op(op: operator, result: str, left: str, right: str, mod: str):
return "bn_mod_div(&{}, &{}, &{}, &{});".format(left, right, mod, result)
elif isinstance(op, Pow) and right == 2:
return "bn_mod_sqr(&{}, &{}, &{});".format(left, mod, result)
+ elif isinstance(op, Pow):
+ return "bn_mod_pow(&{}, &{}, &{}, &{});".format(left, right, mod, result)
+ else:
+ print(op, result, left, right, mod)
env.globals["render_op"] = render_op
-def render_curve_definition(model: CurveModel):
- return env.get_template("curve.h").render(params=model.parameter_names)
+class EnumDefine(Enum):
+ def __str__(self):
+ return self.value
-def render_curve_impl(model: CurveModel):
- return env.get_template("curve.c").render(params=model.parameter_names)
+class Platform(EnumDefine):
+ HOST = "HOST"
+ XMEGA = "CW308_XMEGA"
+ STM32F0 = "CW308_STM32F0"
+ STM32F3 = "CW308_STM32F3"
+
+
+class HashType(EnumDefine):
+ NONE = "HASH_NONE"
+ SHA1 = "HASH_SHA1"
+ SHA224 = "HASH_SHA224"
+ SHA256 = "HASH_SHA256"
+ SHA384 = "HASH_SHA384"
+ SHA512 = "HASH_SHA512"
-def render_coords_definition(coords: CoordinateModel):
- return env.get_template("coords.h").render(variables=coords.variables)
+class MultAlgo(EnumDefine):
+ NONE = "MULT_NONE"
+ DOUBLE_AND_ADD = "MULT_DOUBLE_AND_ADD"
+
+
+class RandomMod(EnumDefine):
+ SAMPLE = "MOD_RAND_SAMPLE"
+ REDUCE = "MOD_RAND_REDUCE"
+
+
+def render_defs(model: CurveModel, coords: CoordinateModel):
+ return env.get_template("defs.h").render(params=model.parameter_names,
+ variables=coords.variables)
+
+
+def render_curve_impl(model: CurveModel):
+ return env.get_template("curve.c").render(params=model.parameter_names)
def transform_ops(ops: List[CodeOp], parameters: List[str], outputs: Set[str],
@@ -69,6 +106,15 @@ def transform_ops(ops: List[CodeOp], parameters: List[str], outputs: Set[str],
const_mapping[const] = name
frees.append(name)
operations.append((op.operator, op.result, rename(op.left), rename(op.right)))
+ mapped = []
+ for op in operations:
+ o2 = op[2]
+ if o2 in const_mapping:
+ o2 = const_mapping[o2]
+ o3 = op[3]
+ if o3 in const_mapping and not (isinstance(op[0], Pow) and o3 == 2):
+ o3 = const_mapping[o3]
+ mapped.append((op[0], op[1], o2, o3))
returns = {}
if renames:
for r_from, r_to in renames.items():
@@ -77,7 +123,7 @@ def transform_ops(ops: List[CodeOp], parameters: List[str], outputs: Set[str],
return dict(allocations=allocations,
initializations=initializations,
- const_mapping=const_mapping, operations=operations,
+ const_mapping=const_mapping, operations=mapped,
frees=frees, returns=returns)
@@ -97,6 +143,8 @@ def render_coords_impl(coords: CoordinateModel):
renames = {"x": "out_x", "y": "out_y"}
for variable in coords.variables:
renames[variable] = "point->{}".format(variable)
+ for param in coords.curve_model.parameter_names:
+ renames[param] = "curve->{}".format(param)
namespace = transform_ops(ops, coords.curve_model.parameter_names,
coords.curve_model.coordinate_names, renames)
returns = namespace["returns"]
@@ -104,8 +152,8 @@ def render_coords_impl(coords: CoordinateModel):
frees = namespace["frees"]
namespace["frees"] = {}
- return env.get_template("coords.c").render(variables=coords.variables, **namespace,
- to_affine_rets=returns, to_affine_frees=frees)
+ return env.get_template("point.c").render(variables=coords.variables, **namespace,
+ to_affine_rets=returns, to_affine_frees=frees)
def render_formula_impl(formula: Formula):
@@ -133,6 +181,8 @@ def render_formula_impl(formula: Formula):
var = input[0]
num = int(input[1:]) - formula.input_index
renames[input] = "{}->{}".format(inputs[num], var)
+ for param in formula.coordinate_model.curve_model.parameter_names:
+ renames[param] = "curve->{}".format(param)
for output in formula.outputs:
var = output[0]
num = int(output[1:]) - formula.output_index
@@ -147,7 +197,40 @@ def render_main(model: CurveModel, coords: CoordinateModel):
curve_parameters=model.parameter_names)
+def render_makefile(platform: Platform, hash_type: HashType, mult_algo: MultAlgo,
+ mod_rand: RandomMod):
+ return env.get_template("Makefile").render(platform=str(platform), hash_type=str(hash_type),
+ mult_algo=str(mult_algo), mod_rand=str(mod_rand))
+
+
+def save_render(dir: str, fname: str, render: str):
+ with open(path.join(dir, fname), "w") as f:
+ f.write(render)
+
+
+def build(platform: Platform, hash_type: HashType, mult_algo: MultAlgo, mod_rand: RandomMod,
+ model: CurveModel, coords: CoordinateModel, *formulas: Formula):
+ temp = tempfile.mkdtemp()
+ symlinks = ["asn1", "bn", "hal", "hash", "mult", "prng", "simpleserial", "tommath", "fat.h",
+ "point.h", "curve.h", "Makefile.inc"]
+ for sym in symlinks:
+ os.symlink(resource_filename("pyecsca.codegen", sym), path.join(temp, sym))
+ gen_dir = path.join(temp, "gen")
+ os.mkdir(gen_dir)
+ save_render(temp, "Makefile", render_makefile(platform, hash_type, mult_algo, mod_rand))
+ save_render(temp, "main.c", render_main(model, coords))
+ save_render(gen_dir, "defs.h", render_defs(model, coords))
+ point_render = render_coords_impl(coords)
+ for formula in formulas:
+ point_render += "\n"
+ point_render += render_formula_impl(formula)
+ save_render(gen_dir, "point.c", point_render)
+ save_render(gen_dir, "curve.c", render_curve_impl(model))
+ print(temp)
+
+
if __name__ == "__main__":
model = ShortWeierstrassModel()
coords = model.coordinates["projective"]
- print(render_coords_impl(coords))
+ build(Platform.HOST, HashType.SHA1, MultAlgo.DOUBLE_AND_ADD, RandomMod.SAMPLE, model, coords,
+ coords.formulas["add-1998-cmo"], coords.formulas["dbl-1998-cmo"])