aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--pyecsca/codegen/bn/bn.c134
-rw-r--r--pyecsca/codegen/bn/bn.h10
-rw-r--r--test/Makefile3
-rw-r--r--test/test_bn.c56
4 files changed, 203 insertions, 0 deletions
diff --git a/pyecsca/codegen/bn/bn.c b/pyecsca/codegen/bn/bn.c
index 53777db..77df5ab 100644
--- a/pyecsca/codegen/bn/bn.c
+++ b/pyecsca/codegen/bn/bn.c
@@ -71,6 +71,10 @@ size_t bn_to_bin_size(const bn_t *one) {
return mp_ubin_size(one);
}
+unsigned int bn_to_int(const bn_t *one) {
+ return mp_get_mag_ul(one);
+}
+
bn_err bn_rand_mod_sample(bn_t *out, const bn_t *mod) {
int mod_len = bn_bit_length(mod);
@@ -448,4 +452,134 @@ exit_full_width:
wnaf_t *bn_bnaf(const bn_t *bn) {
return bn_wnaf(bn, 2);
+}
+
+wsliding_t *bn_wsliding_ltr(const bn_t *bn, int w) {
+ if (w > 8 || w < 2) {
+ return NULL;
+ }
+
+ wsliding_t *result = NULL;
+
+ int blen = bn_bit_length(bn);
+ uint8_t arr[blen];
+
+ int b = blen - 1;
+ int u = 0;
+ int c = 0;
+ bn_t mask;
+ if (mp_init(&mask) != BN_OKAY) {
+ goto exit_mask;
+ }
+
+ int i = 0;
+ while (b >= 0) {
+ if (!bn_get_bit(bn, b)) {
+ arr[i++] = 0; // result.append(0)
+ b--; // b -= 1
+ } else {
+ u = 0; // u = 0
+ for (int v = 1; v <= w; v++) { // for v in range(1, w + 1):
+ if (b + 1 < v) { // if b + 1 < v:
+ break;
+ }
+ 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_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
+ }
+ }
+ c = u;
+ while (u) { // k = u.bit_length()
+ arr[i++] = 0; // result.extend([0] * (k - 1))
+ b--; // b -= k
+ u >>= 1;
+ }
+ arr[i - 1] = c; // result.append(u)
+ }
+ }
+ bn_clear(&mask);
+
+ result = malloc(sizeof(wsliding_t));
+ result->w = w;
+ result->length = 0;
+ result->data = NULL;
+ // Strip the repr and return.
+ for (int j = 0; j < i; j++) {
+ if (result->data == NULL) {
+ if (arr[j]) {
+ result->length = i - j;
+ result->data = calloc(result->length, sizeof(uint8_t));
+ result->data[0] = arr[j];
+ }
+ } else {
+ result->data[j - (i - result->length)] = arr[j];
+ }
+ }
+exit_mask:
+ return result;
+}
+
+wsliding_t *bn_wsliding_rtl(const bn_t *bn, int w) {
+ if (w > 8 || w < 2) {
+ return NULL;
+ }
+
+ wsliding_t *result = NULL;
+
+ int blen = bn_bit_length(bn);
+ uint8_t arr[blen];
+
+ bn_t k;
+ if (mp_init(&k) != BN_OKAY) {
+ goto exit_k;
+ }
+ bn_copy(bn, &k);
+
+ bn_t mask;
+ if (mp_init(&mask) != BN_OKAY) {
+ goto exit_mask;
+ }
+
+ int u = 0;
+ int i = 0;
+ while (!bn_is_0(&k) && !(bn_get_sign(&k) == BN_NEG)) {
+ if (!bn_get_bit(&k, 0)) {
+ arr[i++] = 0;
+ bn_rsh(&k, 1, &k);
+ } else {
+ bn_from_int((1 << w) - 1, &mask); // mask = ((2**w) - 1)
+ mp_and(&mask, &k, &mask);
+ arr[i++] = bn_to_int(&mask);
+ for (int j = 0; j < w - 1; j++) {
+ arr[i++] = 0;
+ }
+ bn_rsh(&k, w, &k);
+ }
+ }
+ bn_clear(&mask);
+
+ result = malloc(sizeof(wsliding_t));
+ result->w = w;
+ result->length = 0;
+ result->data = NULL;
+ // Revert, strip the repr and return.
+ for (int j = i - 1; j >= 0; j--) {
+ if (result->data == NULL) {
+ if (arr[j]) {
+ result->length = j + 1;
+ result->data = calloc(result->length, sizeof(uint8_t));
+ result->data[0] = arr[j];
+ }
+ } else {
+ result->data[result->length - j - 1] = arr[j];
+ }
+ }
+
+exit_mask:
+ 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 ed29970..0732fb1 100644
--- a/pyecsca/codegen/bn/bn.h
+++ b/pyecsca/codegen/bn/bn.h
@@ -58,6 +58,12 @@ typedef struct {
int w;
} wnaf_t;
+typedef struct {
+ uint8_t *data;
+ size_t length;
+ int w;
+} wsliding_t;
+
void math_init(void);
bn_err bn_init(bn_t *bn);
@@ -73,6 +79,7 @@ bn_err bn_from_int(unsigned int value, bn_t *out);
bn_err bn_to_binpad(const bn_t *one, uint8_t *data, size_t size);
bn_err bn_to_bin(const bn_t *one, uint8_t *data);
size_t bn_to_bin_size(const bn_t *one);
+unsigned int bn_to_int(const bn_t *one);
bn_err bn_rand_mod_sample(bn_t *out, const bn_t *mod);
bn_err bn_rand_mod_reduce(bn_t *out, const bn_t *mod);
@@ -115,4 +122,7 @@ int bn_bit_length(const bn_t *bn);
wnaf_t *bn_wnaf(const bn_t *bn, int w);
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);
+
#endif //BN_H_ \ No newline at end of file
diff --git a/test/Makefile b/test/Makefile
new file mode 100644
index 0000000..4b8fc78
--- /dev/null
+++ b/test/Makefile
@@ -0,0 +1,3 @@
+
+test_bn: test_bn.c ../pyecsca/codegen/bn/bn.c
+ gcc -o $@ $^ -I ../pyecsca/codegen/ -I ../pyecsca/codegen/tommath/ -L ../pyecsca/codegen/tommath/ -l:libtommath-HOST.a \ No newline at end of file
diff --git a/test/test_bn.c b/test/test_bn.c
new file mode 100644
index 0000000..a77fe9a
--- /dev/null
+++ b/test/test_bn.c
@@ -0,0 +1,56 @@
+#include <stdio.h>
+#include "bn/bn.h"
+
+int test_wsliding_ltr() {
+ printf("test_wsliding_ltr: ");
+ bn_t bn;
+ bn_init(&bn);
+ bn_from_int(181, &bn);
+ wsliding_t *ws = bn_wsliding_ltr(&bn, 3);
+ if (ws == NULL) {
+ printf("NULL\n");
+ return 1;
+ }
+ if (ws->length != 6) {
+ printf("Bad length (%li instead of 6)\n", ws->length);
+ return 1;
+ }
+ uint8_t expected[6] = {5, 0, 0, 5, 0, 1};
+ for (int i = 0; i < 6; i++) {
+ if (ws->data[i] != expected[i]) {
+ printf("Bad data (%i instead of %i)\n", ws->data[i], expected[i]);
+ return 1;
+ }
+ }
+ printf("OK\n");
+ return 0;
+}
+
+int test_wsliding_rtl() {
+ printf("test_wsliding_rtl: ");
+ bn_t bn;
+ bn_init(&bn);
+ bn_from_int(181, &bn);
+ wsliding_t *ws = bn_wsliding_rtl(&bn, 3);
+ if (ws == NULL) {
+ printf("NULL\n");
+ return 1;
+ }
+ if (ws->length != 8) {
+ printf("Bad length (%li instead of 8)\n", ws->length);
+ return 1;
+ }
+ uint8_t expected[8] = {1, 0, 0, 3, 0, 0, 0, 5};
+ for (int i = 0; i < 8; i++) {
+ if (ws->data[i] != expected[i]) {
+ printf("Bad data (%i instead of %i)\n", ws->data[i], expected[i]);
+ return 1;
+ }
+ }
+ printf("OK\n");
+ return 0;
+}
+
+int main(void) {
+ return test_wsliding_ltr() + test_wsliding_rtl();
+} \ No newline at end of file