aboutsummaryrefslogtreecommitdiffhomepage
path: root/pyecsca/codegen/__init__.py
diff options
context:
space:
mode:
authorJ08nY2019-11-26 18:34:59 +0100
committerJ08nY2019-11-26 18:34:59 +0100
commit6784477dfc8f34f8d1a262517fe83ae70a59b325 (patch)
treed935d6263005066967735d2956bb333657fd52de /pyecsca/codegen/__init__.py
parent2ff2dd72400d38d69096c507c8e72899169ec83f (diff)
downloadpyecsca-codegen-6784477dfc8f34f8d1a262517fe83ae70a59b325.tar.gz
pyecsca-codegen-6784477dfc8f34f8d1a262517fe83ae70a59b325.tar.zst
pyecsca-codegen-6784477dfc8f34f8d1a262517fe83ae70a59b325.zip
Add rendering of formulas.
Diffstat (limited to 'pyecsca/codegen/__init__.py')
-rw-r--r--pyecsca/codegen/__init__.py87
1 files changed, 64 insertions, 23 deletions
diff --git a/pyecsca/codegen/__init__.py b/pyecsca/codegen/__init__.py
index 7848a60..33320ac 100644
--- a/pyecsca/codegen/__init__.py
+++ b/pyecsca/codegen/__init__.py
@@ -1,15 +1,19 @@
from ast import operator, Add, Sub, Mult, Div, Pow
-from typing import List
+from typing import List, Set, Mapping
from jinja2 import Environment, PackageLoader
from pyecsca.ec.coordinates import CoordinateModel
-from pyecsca.ec.model import CurveModel, ShortWeierstrassModel, MontgomeryModel
+from pyecsca.ec.formula import (Formula, AdditionFormula, DoublingFormula, TriplingFormula,
+ NegationFormula, ScalingFormula, DifferentialAdditionFormula,
+ LadderFormula)
+from pyecsca.ec.model import CurveModel, MontgomeryModel
from pyecsca.ec.op import CodeOp
env = Environment(
loader=PackageLoader("pyecsca.codegen")
)
+
def render_op(op: operator, result: str, left: str, right: str, mod: str):
if isinstance(op, Add):
return "bn_mod_add(&{}, &{}, &{}, &{});".format(left, right, mod, result)
@@ -22,22 +26,29 @@ def render_op(op: operator, result: str, left: str, right: str, mod: str):
elif isinstance(op, Pow) and right == 2:
return "bn_mod_sqr(&{}, &{}, &{});".format(left, mod, result)
+
env.globals["render_op"] = render_op
-def get_curve_definition(model: CurveModel):
+def render_curve_definition(model: CurveModel):
return env.get_template("curve.h").render(params=model.parameter_names)
-def get_curve_impl(model: CurveModel):
+def render_curve_impl(model: CurveModel):
return env.get_template("curve.c").render(params=model.parameter_names)
-def get_coords_definition(coords: CoordinateModel):
+def render_coords_definition(coords: CoordinateModel):
return env.get_template("coords.h").render(variables=coords.variables)
-def transform_ops(ops: List[CodeOp], parameters: List[str], outputs: List[str]):
+def transform_ops(ops: List[CodeOp], parameters: List[str], outputs: Set[str],
+ renames: Mapping[str, str] = None):
+ def rename(name: str):
+ if renames is not None:
+ return renames.get(name, name)
+ return name
+
allocations = []
initializations = {}
const_mapping = {}
@@ -57,14 +68,21 @@ def transform_ops(ops: List[CodeOp], parameters: List[str], outputs: List[str]):
initializations[name] = const
const_mapping[const] = name
frees.append(name)
- operations.append((op.operator, op.result, op.left, op.right))
- return env.get_template("ops.c").render(allocations=allocations,
- initializations=initializations,
- const_mapping=const_mapping, operations=operations,
- frees=frees)
+ operations.append((op.operator, op.result, rename(op.left), rename(op.right)))
+
+ return dict(allocations=allocations,
+ initializations=initializations,
+ const_mapping=const_mapping, operations=operations,
+ frees=frees)
+
+
+def render_ops(ops: List[CodeOp], parameters: List[str], outputs: Set[str],
+ renames: Mapping[str, str] = None):
+ namespace = transform_ops(ops, parameters, outputs, renames)
+ return env.get_template("ops.c").render(namespace)
-def get_coords_impl(coords: CoordinateModel):
+def render_coords_impl(coords: CoordinateModel):
ops = []
for s in coords.satisfying:
try:
@@ -72,23 +90,46 @@ def get_coords_impl(coords: CoordinateModel):
except:
pass
transform_ops(ops, coords.curve_model.parameter_names, coords.curve_model.coordinate_names)
+ # TODO: do point_from_affine, and point_to_affine
return env.get_template("coords.c").render(variables=coords.variables)
-if __name__ == "__main__":
- model = ShortWeierstrassModel()
- s = get_curve_definition(model)
-
- s = get_curve_impl(model)
-
- coords = model.coordinates["projective"]
+def render_formula_impl(formula: Formula):
+ if isinstance(formula, AdditionFormula):
+ tname = "formula_add.c"
+ elif isinstance(formula, DoublingFormula):
+ tname = "formula_dbl.c"
+ elif isinstance(formula, TriplingFormula):
+ tname = "formula_tpl.c"
+ elif isinstance(formula, NegationFormula):
+ tname = "formula_neg.c"
+ elif isinstance(formula, ScalingFormula):
+ tname = "formula_scl.c"
+ elif isinstance(formula, DifferentialAdditionFormula):
+ tname = "formula_dadd.c"
+ elif isinstance(formula, LadderFormula):
+ tname = "formula_ladd.c"
+ else:
+ raise ValueError
+ template = env.get_template(tname)
+ inputs = ["one", "other", "diff"]
+ outputs = ["out_one", "out_other"]
+ renames = {}
+ for input in formula.inputs:
+ var = input[0]
+ num = int(input[1:]) - formula.input_index
+ renames[input] = "{}->{}".format(inputs[num], var)
+ for output in formula.outputs:
+ var = output[0]
+ num = int(output[1:]) - formula.output_index
+ renames[output] = "{}->{}".format(outputs[num], var)
+ namespace = transform_ops(formula.code, formula.coordinate_model.curve_model.parameter_names, formula.outputs, renames)
+ return template.render(namespace)
- s = get_coords_definition(coords)
-
- s = get_coords_impl(coords)
+if __name__ == "__main__":
mont = MontgomeryModel()
mcoords = mont.coordinates["xz"]
dbl = mcoords.formulas["dbl-1987-m"]
t = transform_ops(dbl.code, mont.parameter_names, dbl.outputs)
- print(t)
+ print(render_formula_impl(dbl))