aboutsummaryrefslogtreecommitdiffhomepage
path: root/pyecsca/codegen/__init__.py
diff options
context:
space:
mode:
authorJ08nY2019-11-26 15:10:38 +0100
committerJ08nY2019-11-26 15:10:38 +0100
commit2ff2dd72400d38d69096c507c8e72899169ec83f (patch)
treecfd403fd5f22aac5b9aee92817423565070c3178 /pyecsca/codegen/__init__.py
parentde491a6191b465edb7bd9a01a5177ac9bf836747 (diff)
downloadpyecsca-codegen-2ff2dd72400d38d69096c507c8e72899169ec83f.tar.gz
pyecsca-codegen-2ff2dd72400d38d69096c507c8e72899169ec83f.tar.zst
pyecsca-codegen-2ff2dd72400d38d69096c507c8e72899169ec83f.zip
Add rendering of CodeOps.
Diffstat (limited to 'pyecsca/codegen/__init__.py')
-rw-r--r--pyecsca/codegen/__init__.py67
1 files changed, 64 insertions, 3 deletions
diff --git a/pyecsca/codegen/__init__.py b/pyecsca/codegen/__init__.py
index 894c843..7848a60 100644
--- a/pyecsca/codegen/__init__.py
+++ b/pyecsca/codegen/__init__.py
@@ -1,25 +1,80 @@
+from ast import operator, Add, Sub, Mult, Div, Pow
+from typing import List
+
from jinja2 import Environment, PackageLoader
-from pyecsca.ec.model import CurveModel, ShortWeierstrassModel
from pyecsca.ec.coordinates import CoordinateModel
+from pyecsca.ec.model import CurveModel, ShortWeierstrassModel, 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)
+ elif isinstance(op, Sub):
+ return "bn_mod_sub(&{}, &{}, &{}, &{});".format(left, right, mod, result)
+ elif isinstance(op, Mult):
+ return "bn_mod_mul(&{}, &{}, &{}, &{});".format(left, right, mod, result)
+ elif isinstance(op, Div):
+ return "bn_mod_div(&{}, &{}, &{}, &{});".format(left, right, mod, result)
+ 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):
return env.get_template("curve.h").render(params=model.parameter_names)
+
def get_curve_impl(model: CurveModel):
return env.get_template("curve.c").render(params=model.parameter_names)
+
def get_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]):
+ allocations = []
+ initializations = {}
+ const_mapping = {}
+ operations = []
+ frees = []
+ for op in ops:
+ if op.result not in allocations and op.result not in outputs:
+ allocations.append(op.result)
+ frees.append(op.result)
+ for param in op.parameters:
+ if param not in allocations and param not in parameters:
+ raise ValueError("Should be allocated or parameter: {}".format(param))
+ for const in op.constants:
+ name = "c" + str(const)
+ if name not in allocations:
+ allocations.append(name)
+ 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)
+
+
def get_coords_impl(coords: CoordinateModel):
- print(coords.satisfying)
+ ops = []
+ for s in coords.satisfying:
+ try:
+ ops.append(CodeOp(s))
+ except:
+ pass
+ transform_ops(ops, coords.curve_model.parameter_names, coords.curve_model.coordinate_names)
return env.get_template("coords.c").render(variables=coords.variables)
+
if __name__ == "__main__":
model = ShortWeierstrassModel()
s = get_curve_definition(model)
@@ -30,4 +85,10 @@ if __name__ == "__main__":
s = get_coords_definition(coords)
- s = get_coords_impl(coords) \ No newline at end of file
+ s = get_coords_impl(coords)
+
+ mont = MontgomeryModel()
+ mcoords = mont.coordinates["xz"]
+ dbl = mcoords.formulas["dbl-1987-m"]
+ t = transform_ops(dbl.code, mont.parameter_names, dbl.outputs)
+ print(t)