aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--pyecsca/codegen/bn/bn.c74
-rw-r--r--pyecsca/codegen/bn/bn.h6
-rw-r--r--test/.gitignore2
-rw-r--r--test/test_bn.c60
5 files changed, 134 insertions, 9 deletions
diff --git a/.gitignore b/.gitignore
index 9e55abb..58caf65 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,7 +4,6 @@
htmlcov/
/build/
__pycache__
-/test/test_bn
pyecsca-codegen-*.elf
pyecsca-codegen-*.hex \ No newline at end of file
diff --git a/pyecsca/codegen/bn/bn.c b/pyecsca/codegen/bn/bn.c
index 02371e2..d3b7968 100644
--- a/pyecsca/codegen/bn/bn.c
+++ b/pyecsca/codegen/bn/bn.c
@@ -472,18 +472,80 @@ wnaf_t *bn_bnaf(const bn_t *bn) {
return bn_wnaf(bn, 2);
}
-void bn_naf_extend(wnaf_t *naf, size_t new_length) {
- if (new_length <= naf->length) {
+void bn_naf_pad_left(wnaf_t *naf, int8_t value, size_t amount) {
+ if (amount == 0) {
return;
}
- int8_t *new_data = calloc(new_length, sizeof(int8_t));
- size_t diff = new_length - naf->length;
+ int8_t *new_data = calloc(naf->length + amount, sizeof(int8_t));
for (size_t i = 0; i < naf->length; i++) {
- new_data[i + diff] = naf->data[i];
+ new_data[i + amount] = naf->data[i];
+ }
+ for (size_t i = 0; i < amount; i++) {
+ new_data[i] = value;
}
free(naf->data);
naf->data = new_data;
- naf->length = new_length;
+ naf->length += amount;
+}
+
+void bn_naf_pad_right(wnaf_t *naf, int8_t value, size_t amount) {
+ if (amount == 0) {
+ return;
+ }
+ naf->data = realloc(naf->data, (naf->length + amount) * sizeof(int8_t));
+ for (size_t i = naf->length; i < naf->length + amount; i++) {
+ naf->data[i] = value;
+ }
+ naf->length += amount;
+}
+
+void bn_naf_strip_left(wnaf_t *naf, int8_t value) {
+ size_t i = 0;
+ while (i < naf->length && naf->data[i] == value) {
+ i++;
+ }
+ if (i == 0) {
+ return;
+ }
+ if (i == naf->length) {
+ free(naf->data);
+ naf->data = NULL;
+ naf->length = 0;
+ return;
+ }
+ int8_t *new_data = calloc(naf->length - i, sizeof(int8_t));
+ for (size_t j = 0; j < naf->length - i; j++) {
+ new_data[j] = naf->data[j + i];
+ }
+ free(naf->data);
+ naf->data = new_data;
+ naf->length -= i;
+}
+
+void bn_naf_strip_right(wnaf_t *naf, int8_t value) {
+ size_t i = naf->length;
+ while (i > 0 && naf->data[i - 1] == value) {
+ i--;
+ }
+ if (i == naf->length) {
+ return;
+ }
+ if (i == 0) {
+ free(naf->data);
+ naf->data = NULL;
+ naf->length = 0;
+ return;
+ }
+ naf->data = realloc(naf->data, i * sizeof(int8_t));
+ naf->length = i;
+}
+
+void bn_naf_reverse(wnaf_t *naf) {
+ for (size_t i = 0; i < naf->length / 2; i++) {
+ int8_t temp = naf->data[i];
+ naf->data[i] = naf->data[naf->length - i - 1];
+ naf->data[naf->length - i - 1] = temp;
+ }
}
wsliding_t *bn_wsliding_ltr(const bn_t *bn, int w) {
diff --git a/pyecsca/codegen/bn/bn.h b/pyecsca/codegen/bn/bn.h
index 4e69474..78d2d94 100644
--- a/pyecsca/codegen/bn/bn.h
+++ b/pyecsca/codegen/bn/bn.h
@@ -138,7 +138,11 @@ 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);
-void bn_naf_extend(wnaf_t *naf, size_t new_length);
+void bn_naf_pad_left(wnaf_t *naf, int8_t value, size_t amount);
+void bn_naf_pad_right(wnaf_t *naf, int8_t value, size_t amount);
+void bn_naf_strip_left(wnaf_t *naf, int8_t value);
+void bn_naf_strip_right(wnaf_t *naf, int8_t value);
+void bn_naf_reverse(wnaf_t *naf);
wsliding_t *bn_wsliding_ltr(const bn_t *bn, int w);
wsliding_t *bn_wsliding_rtl(const bn_t *bn, int w);
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644
index 0000000..05cabee
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1,2 @@
+test_bn_val
+test_bn_san
diff --git a/test/test_bn.c b/test/test_bn.c
index 66ce377..2d3461c 100644
--- a/test/test_bn.c
+++ b/test/test_bn.c
@@ -278,6 +278,64 @@ int test_bn_wnaf() {
return failed;
}
+int test_bn_wnaf_manipulation() {
+ printf("test_bn_wnaf_manipulation: ");
+ bn_t bn;
+ bn_init(&bn);
+ bn_from_dec("123456789", &bn);
+ wnaf_t *naf = bn_wnaf(&bn, 3);
+ bn_clear(&bn);
+ if (naf->length != 28) {
+ printf("FAILED (bad length %li instead of 28)\n", naf->length);
+ return 1;
+ }
+ bn_naf_pad_left(naf, 0, 5);
+ if (naf->length != 33) {
+ printf("FAILED (bad length after pad left %li instead of 33)\n", naf->length);
+ return 1;
+ }
+ for (int i = 0; i < 5; i++) {
+ if (naf->data[i] != 0) {
+ printf("FAILED (bad data after pad left at %d (%i instead of 0))\n", i, naf->data[i]);
+ return 1;
+ }
+ }
+ bn_naf_strip_left(naf, 0);
+ if (naf->length != 28) {
+ printf("FAILED (bad length after strip left %li instead of 28)\n", naf->length);
+ return 1;
+ }
+ bn_naf_pad_right(naf, 0, 3);
+ if (naf->length != 31) {
+ printf("FAILED (bad length after pad right %li instead of 31)\n", naf->length);
+ return 1;
+ }
+ for (int i = 28; i < 31; i++) {
+ if (naf->data[i] != 0) {
+ printf("FAILED (bad data after pad right at %d (%i instead of 0))\n", i, naf->data[i]);
+ return 1;
+ }
+ }
+ bn_naf_strip_right(naf, 0);
+ if (naf->length != 28) {
+ printf("FAILED (bad length after strip right %li instead of 28)\n", naf->length);
+ return 1;
+ }
+ int8_t rev[28] = {-3, 0, 0, 3, 0, 0, 0, 0, -3, 0, 0, 0, -3, 0, 0, 0, 0, 0, -1, 0, 0, 3, 0, 0, -1, 0, 0, 1};
+ bn_naf_reverse(naf);
+ for (int i = 0; i < 28; i++) {
+ if (naf->data[i] != rev[i]) {
+ printf("FAILED (bad data after reverse at %d (%i instead of %i))\n", i, naf->data[i], rev[i]);
+ return 1;
+ }
+ }
+
+ free(naf->data);
+ free(naf);
+ printf("OK\n");
+ return 0;
+}
+
int main(void) {
- return test_wsliding_ltr() + test_wsliding_rtl() + test_convert_base_small() + test_convert_base_large() + test_bn_wnaf();
+ return test_wsliding_ltr() + test_wsliding_rtl() + test_convert_base_small() + test_convert_base_large() + test_bn_wnaf() + test_bn_wnaf_manipulation();
}