diff --git a/src/poly.c b/src/poly.c index 01b03ff..2a999dd 100644 --- a/src/poly.c +++ b/src/poly.c @@ -146,6 +146,60 @@ void delete_polynom(pb_poly *poly) free(poly); } +/** + * Starmultiplication, as follows: + * c = a * b mod x^(N − 1) + * + * @param a polynom to multiply + * @param b polynom to multiply + * @param c polynom [out] + * @param ctx NTRU context + * @param modulus whether we use p or q + */ +void pb_starmultiply(pb_poly *a, + pb_poly *b, + pb_poly *c, + ntru_context *ctx, + unsigned int modulus) +{ + for (int k = ctx->N - 1; k >= 0; k--) { + int j; + j = k + 1; + + for (int i = ctx->N - 1; i >= 0; i--) { + if (j == (int)(ctx->N)) + j = 0; + if (mp_cmp_d(&(a->terms[i]), (mp_digit)0) != MP_EQ && + mp_cmp_d(&(b->terms[j]), (mp_digit)0) != MP_EQ) { + int result; + mp_int mp_modulus; + mp_int mp_tmp; + + init_integer(&mp_tmp); + init_integer(&mp_modulus); + mp_set_int(&mp_modulus, (unsigned long)(modulus)); + + if ((result = mp_mul(&(a->terms[i]), + &(b->terms[j]), &mp_tmp)) != MP_OKAY) + NTRU_ABORT("Error multiplying terms. %s", + mp_error_to_string(result)); + if ((result = mp_add(&(c->terms[k]), + &mp_tmp, &(c->terms[k]))) != MP_OKAY) + NTRU_ABORT("Error multiplying terms. %s", + mp_error_to_string(result)); + if ((result = mp_mod(&(c->terms[k]), + &mp_modulus, &(c->terms[k]))) != MP_OKAY) + NTRU_ABORT("Error multiplying terms. %s", + mp_error_to_string(result)); + + mp_clear(&mp_modulus); + mp_clear(&mp_tmp); + } + j++; + } + } +} + /** * Print the polynomial in a human readable format to stdout. * diff --git a/src/poly.h b/src/poly.h index 37cf639..ef9700d 100644 --- a/src/poly.h +++ b/src/poly.h @@ -41,6 +41,12 @@ pb_poly *build_polynom(int const * const c, void delete_polynom(pb_poly *new_poly); +void pb_starmultiply(pb_poly *a, + pb_poly *b, + pb_poly *c, + ntru_context *ctx, + unsigned int modulus); + void draw_polynom(pb_poly * const poly); #endif /* NTRU_POLY_H */