aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJ08nY2023-03-29 23:30:12 +0200
committerJ08nY2023-03-29 23:30:12 +0200
commit68a4698448f0d5c6b8d8af022c870b47dab8f1af (patch)
tree7270a186adf9299d7906ad888a4b89d90c0c432d
parent3790770c2bc6ca618df8a95f0f5efc15ce9eba21 (diff)
downloadpyecsca-codegen-68a4698448f0d5c6b8d8af022c870b47dab8f1af.tar.gz
pyecsca-codegen-68a4698448f0d5c6b8d8af022c870b47dab8f1af.tar.zst
pyecsca-codegen-68a4698448f0d5c6b8d8af022c870b47dab8f1af.zip
Fix montgomery multiplication.
Fixes pyecsca#33.
-rw-r--r--pyecsca/codegen/render.py28
-rw-r--r--pyecsca/codegen/templates/action.c6
-rw-r--r--pyecsca/codegen/templates/main.c3
-rw-r--r--pyecsca/codegen/templates/ops.c6
-rw-r--r--pyecsca/codegen/templates/point.c6
-rw-r--r--test/test_impl.py9
6 files changed, 44 insertions, 14 deletions
diff --git a/pyecsca/codegen/render.py b/pyecsca/codegen/render.py
index d4d1d7f..984a25c 100644
--- a/pyecsca/codegen/render.py
+++ b/pyecsca/codegen/render.py
@@ -2,7 +2,6 @@ import os
import shutil
import subprocess
import tempfile
-from _ast import Pow
from os import path
from os import makedirs
from typing import Optional, List, Set, Mapping, MutableMapping, Any, Tuple
@@ -82,6 +81,13 @@ def render_curve_impl(model: CurveModel) -> str:
def transform_ops(ops: List[CodeOp], parameters: List[str], outputs: Set[str],
renames: Mapping[str, str] = None) -> MutableMapping[Any, Any]:
+ """
+ Transform a list of CodeOps, parameters, outputs and renames into a mapping
+ that will be used by the ops template macros to render the ops.
+
+ This tracks allocations and frees, also creates a mapping of constants
+ to variable names
+ """
def rename(name: str):
if renames is not None and name not in outputs:
return renames.get(name, name)
@@ -100,21 +106,27 @@ def transform_ops(ops: List[CodeOp], parameters: List[str], outputs: Set[str],
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 op.operator == OpType.Pow:
+ name = "cu" + str(const)
+ encode = False
+ else:
+ name = "c" + str(const)
+ encode = True
if name not in allocations:
allocations.append(name)
- initializations[name] = const
- const_mapping[const] = name
+ initializations[name] = (const, encode)
+ const_mapping[(const, encode)] = 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]
+ if (o2, True) in const_mapping:
+ o2 = const_mapping[(o2, True)]
o3 = op[3]
- if o3 in const_mapping and not (isinstance(op[0], Pow) and o3 == 2):
- o3 = const_mapping[o3]
+ o3_enc = op[0] != OpType.Pow
+ if (o3, o3_enc) in const_mapping:
+ o3 = const_mapping[(o3, o3_enc)]
mapped.append((op[0], op[1], o2, o3))
returns = {}
if renames:
diff --git a/pyecsca/codegen/templates/action.c b/pyecsca/codegen/templates/action.c
index 939c6a0..75f3f7a 100644
--- a/pyecsca/codegen/templates/action.c
+++ b/pyecsca/codegen/templates/action.c
@@ -1,4 +1,7 @@
{% macro start_action(action) %}
+ {# // Macro for starting a given "action".
+ // If the trigger is setup to fire on that action
+ // then this will toggle the trigger value. #}
{% if action == "add" %}
action_start((uint32_t) (1 << 0));
{% elif action == "dadd" %}
@@ -31,6 +34,9 @@
{%- endmacro %}
{% macro end_action(action) %}
+ {# // Macro for ending a given "action".
+ // If the trigger is setup to fire on that action
+ // then this will toggle the trigger value. #}
{% if action == "add" %}
action_end((uint32_t) (1 << 0));
{% elif action == "dadd" %}
diff --git a/pyecsca/codegen/templates/main.c b/pyecsca/codegen/templates/main.c
index 9014c9a..af82603 100644
--- a/pyecsca/codegen/templates/main.c
+++ b/pyecsca/codegen/templates/main.c
@@ -125,6 +125,9 @@ static uint8_t cmd_set_params(uint8_t *data, uint16_t len) {
if (!curve->neutral->infinity) {
point_red_encode(curve->neutral, curve);
}
+ {%- for param in curve_parameters %}
+ bn_red_encode(&curve->{{ param }}, &curve->p, &curve->p_red);
+ {%- endfor %}
bn_t x; bn_init(&x);
bn_t y; bn_init(&y);
diff --git a/pyecsca/codegen/templates/ops.c b/pyecsca/codegen/templates/ops.c
index 12b126f..ee322a8 100644
--- a/pyecsca/codegen/templates/ops.c
+++ b/pyecsca/codegen/templates/ops.c
@@ -16,9 +16,11 @@
{%- endmacro %}
{% macro render_initializations(initializations) -%}
- {%- for init, value in initializations.items() %}
+ {%- for init, (value, encode) in initializations.items() %}
bn_from_int({{ value }}, &{{ init }});
- bn_red_encode(&{{ init }}, &curve->p, &curve->p_red);
+ {%- if encode %}
+ bn_red_encode(&{{ init }}, &curve->p, &curve->p_red);
+ {%- endif %}
{%- endfor %}
{%- endmacro %}
diff --git a/pyecsca/codegen/templates/point.c b/pyecsca/codegen/templates/point.c
index 8b7b07e..e87ae36 100644
--- a/pyecsca/codegen/templates/point.c
+++ b/pyecsca/codegen/templates/point.c
@@ -4,6 +4,9 @@
{% import "ops.c" as ops %}
{% from "action.c" import start_action, end_action %}
+/**
+ * Constructs (allocates) a new point.
+ */
point_t *point_new(void) {
point_t *result = malloc(sizeof(point_t));
{%- for variable in variables %}
@@ -13,6 +16,9 @@ point_t *point_new(void) {
return result;
}
+/**
+ * Creates a copy of a point.
+ */
point_t *point_copy(const point_t *from) {
point_t *result = point_new();
point_set(from, result);
diff --git a/test/test_impl.py b/test/test_impl.py
index a061a74..ea92f8a 100644
--- a/test/test_impl.py
+++ b/test/test_impl.py
@@ -1,4 +1,3 @@
-from binascii import hexlify
from copy import copy
from os.path import join
from unittest import TestCase
@@ -7,7 +6,6 @@ from click.testing import CliRunner
from pyecsca.ec.params import get_params
from pyecsca.ec.key_agreement import ECDH_SHA1
from pyecsca.ec.mult import LTRMultiplier, RTLMultiplier, CoronMultiplier, BinaryNAFMultiplier
-from pyecsca.ec.point import Point
from pyecsca.ec.signature import ECDSA_SHA1, SignatureResult
from pyecsca.codegen.builder import build_impl
@@ -30,7 +28,8 @@ class ImplTests(TestCase):
other_args = [
("--mul", "KARATSUBA", "--sqr", "KARATSUBA"),
("--mul", "TOOM_COOK", "--sqr", "TOOM_COOK"),
- ("--red", "BARRETT")
+ ("--red", "BARRETT"),
+ ("--red", "MONTGOMERY")
]
for additional in other_args:
with runner.isolated_filesystem() as tmpdir:
@@ -83,13 +82,16 @@ class SetupTests(ImplTests):
def test_debug(self):
runner = CliRunner()
+
def callback(target, mult, params):
model, coords = target.debug()
self.assertEqual(model, params.curve.model.shortname)
self.assertEqual(coords, params.curve.coordinate_model.name)
+
self.do_basic_test(callback, runner, self.secp128r1, LTRMultiplier,
["add-1998-cmo", "dbl-1998-cmo"], "ltr", False, False, complete=False)
+
class KeyGenerationTests(ImplTests):
def do_keygen_test(self, runner, params, mult_class, formulas, mult_name, **mult_kwargs):
@@ -234,7 +236,6 @@ class ECDSATests(ImplTests):
ecdsa = ECDSA_SHA1(copy(mult), params, mult.formulas["add"],
pub.to_model(params.curve.coordinate_model, params.curve), priv)
-
signature_data = target.ecdsa_sign(data)
result = SignatureResult.from_DER(signature_data)
self.assertTrue(ecdsa.verify_data(result, data))