in src/fpx.c [1322:1378]
static inline void Montgomery_inversion_mod_order_bingcd_partial(const digit_t* a, digit_t* x1, unsigned int* k, const digit_t* order)
{ // Partial Montgomery inversion modulo order.
digit_t u[NWORDS_ORDER], v[NWORDS_ORDER], x2[NWORDS_ORDER] = {0};
unsigned int cwords; // number of words necessary for x1, x2
copy_words(a, u, NWORDS_ORDER);
copy_words(order, v, NWORDS_ORDER);
copy_words(x2, x1, NWORDS_ORDER);
x1[0] = 1;
*k = 0;
while (!is_zero_mod_order(v)) {
cwords = ((*k + 1) / RADIX) + 1;
if ((cwords < NWORDS_ORDER)) {
if (is_even_mod_order(v)) {
mp_shiftr1(v, NWORDS_ORDER);
mp_shiftl1(x1, cwords);
} else if (is_even_mod_order(u)) {
mp_shiftr1(u, NWORDS_ORDER);
mp_shiftl1(x2, cwords);
} else if (!is_lt_mod_order(v, u)) {
mp_sub(v, u, v, NWORDS_ORDER);
mp_shiftr1(v, NWORDS_ORDER);
mp_add(x1, x2, x2, cwords);
mp_shiftl1(x1, cwords);
} else {
mp_sub(u, v, u, NWORDS_ORDER);
mp_shiftr1(u, NWORDS_ORDER);
mp_add(x1, x2, x1, cwords);
mp_shiftl1(x2, cwords);
}
} else {
if (is_even_mod_order(v)) {
mp_shiftr1(v, NWORDS_ORDER);
mp_shiftl1(x1, NWORDS_ORDER);
} else if (is_even_mod_order(u)) {
mp_shiftr1(u, NWORDS_ORDER);
mp_shiftl1(x2, NWORDS_ORDER);
} else if (!is_lt_mod_order(v, u)) {
mp_sub(v, u, v, NWORDS_ORDER);
mp_shiftr1(v, NWORDS_ORDER);
mp_add(x1, x2, x2, NWORDS_ORDER);
mp_shiftl1(x1, NWORDS_ORDER);
} else {
mp_sub(u, v, u, NWORDS_ORDER);
mp_shiftr1(u, NWORDS_ORDER);
mp_add(x1, x2, x1, NWORDS_ORDER);
mp_shiftl1(x2, NWORDS_ORDER);
}
}
*k += 1;
}
if (is_lt_mod_order(order, x1)) {
mp_sub(x1, order, x1, NWORDS_ORDER);
}
}