diff options
| -rw-r--r-- | pyecsca/codegen/bn/bn.c | 134 | ||||
| -rw-r--r-- | pyecsca/codegen/bn/bn.h | 10 | ||||
| -rw-r--r-- | test/Makefile | 3 | ||||
| -rw-r--r-- | test/test_bn.c | 56 |
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 |
