aboutsummaryrefslogtreecommitdiffhomepage
path: root/pyecsca/codegen
diff options
context:
space:
mode:
authorJ08nY2023-10-03 23:29:18 +0200
committerJ08nY2023-10-03 23:29:18 +0200
commit07026a90ba04e164fadeb40dc2ba80e7743abf00 (patch)
treeb7011593d35684a2bf3191f44b068e5ac8574f3d /pyecsca/codegen
parent7889941ce0c198113509738c1f0e84bb7826080f (diff)
downloadpyecsca-codegen-07026a90ba04e164fadeb40dc2ba80e7743abf00.tar.gz
pyecsca-codegen-07026a90ba04e164fadeb40dc2ba80e7743abf00.tar.zst
pyecsca-codegen-07026a90ba04e164fadeb40dc2ba80e7743abf00.zip
Add fixed width scalarmult.
Diffstat (limited to 'pyecsca/codegen')
-rw-r--r--pyecsca/codegen/bn/bn.c46
-rw-r--r--pyecsca/codegen/bn/bn.h9
-rw-r--r--pyecsca/codegen/common.py5
-rw-r--r--pyecsca/codegen/render.py3
-rw-r--r--pyecsca/codegen/templates/mult_fixed_w.c63
-rw-r--r--pyecsca/codegen/templates/point.c4
6 files changed, 123 insertions, 7 deletions
diff --git a/pyecsca/codegen/bn/bn.c b/pyecsca/codegen/bn/bn.c
index e0c4bcb..13d7134 100644
--- a/pyecsca/codegen/bn/bn.c
+++ b/pyecsca/codegen/bn/bn.c
@@ -53,7 +53,7 @@ bn_err bn_from_int(unsigned int value, bn_t *out) {
} else {
mp_set_u32(out, value);
}
- return MP_OKAY;
+ return BN_OKAY;
}
bn_err bn_to_binpad(const bn_t *one, uint8_t *data, size_t size) {
@@ -350,6 +350,10 @@ bn_err bn_rsh(const bn_t *one, int amount, bn_t *out) {
return mp_div_2d(one, amount, out, NULL);
}
+bn_err bn_and(const bn_t *one, const bn_t *other, bn_t *out) {
+ return mp_and(one, other, out);
+}
+
bool bn_eq(const bn_t *one, const bn_t *other) {
return mp_cmp_mag(one, other) == MP_EQ;
}
@@ -485,7 +489,7 @@ wsliding_t *bn_wsliding_ltr(const bn_t *bn, int w) {
}
bn_from_int((1 << v) - 1, &mask); // mask = ((2**v) - 1) << (b - v + 1)
bn_lsh(&mask, b - v + 1, &mask);
- mp_and(&mask, bn, &mask); // mask = (i & mask)
+ bn_and(&mask, bn, &mask); // mask = (i & mask)
bn_rsh(&mask, b - v + 1, &mask); // mask = mask >> (b - v + 1)
if (bn_get_bit(&mask, 0)) { // if c & 1:
u = (int) bn_to_int(&mask); // u = c
@@ -550,7 +554,7 @@ wsliding_t *bn_wsliding_rtl(const bn_t *bn, int w) {
bn_rsh(&k, 1, &k);
} else {
bn_from_int((1 << w) - 1, &mask); // mask = ((2**w) - 1)
- mp_and(&mask, &k, &mask);
+ bn_and(&mask, &k, &mask);
arr[i++] = bn_to_int(&mask);
for (int j = 0; j < w - 1; j++) {
arr[i++] = 0;
@@ -581,4 +585,40 @@ exit_mask:
bn_clear(&k);
exit_k:
return result;
+}
+
+base_t *bn_convert_base(const bn_t *bn, int m) {
+ base_t *result = NULL;
+
+ bn_t k;
+ if (mp_init(&k) != BN_OKAY) {
+ goto exit_k;
+ }
+ bn_copy(bn, &k);
+
+ int len = 0;
+ if (mp_log_n(&k, m, &len) != BN_OKAY) {
+ goto exit_len;
+ }
+
+ result = malloc(sizeof(base_t));
+ result->length = len + 1;
+ result->data = calloc(result->length, sizeof(uint8_t));
+ result->m = m;
+
+ int i = 0;
+ mp_digit val = 0;
+ while (!bn_is_0(&k) && !(bn_get_sign(&k) == BN_NEG)) {
+ if (mp_div_d(&k, m, &k, &val) != BN_OKAY) {
+ free(result->data);
+ free(result);
+ goto exit_len;
+ }
+ result->data[i++] = (uint8_t) val;
+ }
+
+exit_len:
+ bn_clear(&k);
+exit_k:
+ return result;
} \ No newline at end of file
diff --git a/pyecsca/codegen/bn/bn.h b/pyecsca/codegen/bn/bn.h
index 0732fb1..d5d1e0c 100644
--- a/pyecsca/codegen/bn/bn.h
+++ b/pyecsca/codegen/bn/bn.h
@@ -64,6 +64,12 @@ typedef struct {
int w;
} wsliding_t;
+typedef struct {
+ uint8_t *data;
+ size_t length;
+ int m;
+} base_t;
+
void math_init(void);
bn_err bn_init(bn_t *bn);
@@ -111,6 +117,7 @@ void bn_red_clear(red_t *out);
bn_err bn_lsh(const bn_t *one, int amount, bn_t *out);
bn_err bn_rsh(const bn_t *one, int amount, bn_t *out);
+bn_err bn_and(const bn_t *one, const bn_t *other, bn_t *out);
bool bn_eq(const bn_t *one, const bn_t *other);
bool bn_is_0(const bn_t *one);
@@ -125,4 +132,6 @@ wnaf_t *bn_bnaf(const bn_t *bn);
wsliding_t *bn_wsliding_ltr(const bn_t *bn, int w);
wsliding_t *bn_wsliding_rtl(const bn_t *bn, int w);
+base_t *bn_convert_base(const bn_t *bn, int m);
+
#endif //BN_H_ \ No newline at end of file
diff --git a/pyecsca/codegen/common.py b/pyecsca/codegen/common.py
index 2f3dfbd..b970039 100644
--- a/pyecsca/codegen/common.py
+++ b/pyecsca/codegen/common.py
@@ -17,6 +17,7 @@ from pyecsca.ec.mult import (
WindowNAFMultiplier,
BinaryNAFMultiplier,
SlidingWindowMultiplier,
+ FixedWindowLTRMultiplier,
)
@@ -77,6 +78,10 @@ MULTIPLIERS = [
{
"name": ("sliding", "SlidingWindowMultiplier"),
"class": SlidingWindowMultiplier
+ },
+ {
+ "name": ("fixed", "FixedWindowLTRMultiplier"),
+ "class": FixedWindowLTRMultiplier
}
]
diff --git a/pyecsca/codegen/render.py b/pyecsca/codegen/render.py
index 0358472..ba06a72 100644
--- a/pyecsca/codegen/render.py
+++ b/pyecsca/codegen/render.py
@@ -37,6 +37,7 @@ env = Environment(
)
env.globals["isinstance"] = isinstance
+env.globals["bin"] = bin
env.globals["AccumulationOrder"] = AccumulationOrder
env.globals["ProcessingDirection"] = ProcessingDirection
@@ -181,8 +182,6 @@ def render_coords_impl(coords: CoordinateModel, accumulation_order: Optional[Acc
frees = namespace["frees"]
namespace["frees"] = {}
- accumulation_order = getattr(accumulation_order, "name", None)
-
return env.get_template("point.c").render(variables=coords.variables, **namespace,
to_affine_rets=returns, to_affine_frees=frees,
accumulation_order=accumulation_order)
diff --git a/pyecsca/codegen/templates/mult_fixed_w.c b/pyecsca/codegen/templates/mult_fixed_w.c
new file mode 100644
index 0000000..aa95ebd
--- /dev/null
+++ b/pyecsca/codegen/templates/mult_fixed_w.c
@@ -0,0 +1,63 @@
+#include "mult.h"
+#include "point.h"
+
+void scalar_mult_by_m_pow2(point_t *point, curve_t *curve) {
+ unsigned int m = {{ scalarmult.m }} >> 1;
+ while (m) {
+ point_dbl(point, curve, point);
+ m >>= 1;
+ }
+}
+
+void scalar_mult_by_m_base(point_t *point, curve_t *curve) {
+ point_t *orig = point_copy(point);
+ point_dbl(orig, curve, point);
+ for (int i = 0; i < {{ scalarmult.m - 2}}; i++) {
+ point_add(point, orig, curve, point);
+ }
+ point_free(orig);
+}
+
+static void scalar_mult_inner(bn_t *scalar, point_t *point, curve_t *curve, point_t *out) {
+ point_t *q = point_copy(curve->neutral);
+ point_t *points[{{ scalarmult.m }}];
+
+ point_t *current = point_copy(point);
+ point_t *dbl = point_new();
+ point_dbl(current, curve, dbl);
+ points[0] = point_copy(current);
+ points[1] = point_copy(dbl);
+ point_set(dbl, current);
+ for (long i = 2; i < {{ scalarmult.m }}; i++) {
+ point_add(current, point, curve, current);
+ points[i] = point_copy(current);
+ }
+ point_free(current);
+ point_free(dbl);
+
+ base_t *bs = bn_convert_base(scalar, {{ scalarmult.m }});
+
+ for (long i = bs->length - 1; i >= 0; i--) {
+ {%- if bin(scalarmult.m).count("1") == 1 %}
+ scalar_mult_by_m_pow2(q, curve);
+ {%- else %}
+ scalar_mult_by_m_base(q, curve);
+ {%- endif %}
+
+ uint8_t val = bs->data[i];
+ if (val) {
+ point_accumulate(q, points[val-1], curve, q);
+ }
+ }
+ free(bs->data);
+ free(bs);
+
+ {%- if "scl" in scalarmult.formulas %}
+ point_scl(q, curve, q);
+ {%- endif %}
+ point_set(q, out);
+ for (long i = 0; i < {{ scalarmult.m }}; i++) {
+ point_free(points[i]);
+ }
+ point_free(q);
+} \ No newline at end of file
diff --git a/pyecsca/codegen/templates/point.c b/pyecsca/codegen/templates/point.c
index b4d6e94..bad232a 100644
--- a/pyecsca/codegen/templates/point.c
+++ b/pyecsca/codegen/templates/point.c
@@ -139,9 +139,9 @@ void point_from_affine(bn_t *x, bn_t *y, const curve_t *curve, point_t *out) {
}
void point_accumulate(const point_t *one, const point_t *other, const curve_t *curve, point_t *out_one) {
- {% if accumulation_order == "PeqPR" %}
+ {% if accumulation_order == AccumulationOrder.PeqPR %}
point_add(one, other, curve, out_one);
- {% elif accumulation_order == "PeqRP" %}
+ {% elif accumulation_order == AccumulationOrder.PeqRP %}
point_add(other, one, curve, out_one);
{% endif %}
} \ No newline at end of file