// // helper precomputation routines for the "modexpng" core // #include "modexpng_util.h" // // internal buffers // static uint32_t MOD_FACTOR_N[BUF_NUM_WORDS]; static uint32_t MOD_NN[BUF_NUM_WORDS+1]; static uint32_t MOD_T[BUF_NUM_WORDS+1]; static void _add32(uint32_t, uint32_t, uint32_t, uint32_t *, uint32_t *); static void _sub32(uint32_t, uint32_t, uint32_t, uint32_t *, uint32_t *); static void _mul32(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t *, uint32_t *); // // calculation of the Montgomery factor // void _calc_montgomery_factor(uint32_t num_words, const uint32_t *N, uint32_t *N_FACTOR) { // counters uint32_t i, j; // flag uint32_t flag_keep; // carry and borrow uint32_t cry_in, cry_out; uint32_t brw_in, brw_out; // initially set N_FACTOR = 1 for (i=0; i> (UINT32_BITS - 1); // | N_FACTOR <<= 1 N_FACTOR[j] <<= 1; N_FACTOR[j] |= cry_in; // | _sub32(N_FACTOR[j], N[j], brw_in, &MOD_FACTOR_N[j], &brw_out); // MOD_FACTOR_N = N_FACTOR - N // propagate carry & borrow cry_in = cry_out, brw_in = brw_out; } // obtain flag flag_keep = brw_out && !cry_out; // now select the right value for (j=0; j> UINT32_BITS); // return the higher part of result, ... *c_out &= (uint32_t)1; // ...but truncate it to 1 bit } // // low-level subtraction w/ borrow // static void _sub32(uint32_t a, uint32_t b, uint32_t b_in, uint32_t *d, uint32_t *b_out) { uint64_t t; // intermediate var t = (uint64_t)a - (uint64_t)b; // obtain "wide" difference t -= (uint64_t)(b_in & 1); // take borrow into account *d = (uint32_t)t; // return the lower part of result *b_out = (uint32_t)(t >> UINT32_BITS); // return the higher part of result, ... *b_out &= (uint32_t)1; // ...but truncate it to 1 bit } // // low-level multiplication w/ carry and pre-adder // static void _mul32(uint32_t a, uint32_t b, uint32_t t, uint32_t c_in, uint32_t *p, uint32_t *c_out) { uint64_t r; // intermediate result r = (uint64_t)a * (uint64_t)b; // obtain wide product r += (uint64_t)t; // handle pre-addition r += (uint64_t)c_in; // take carry into account *p = (uint32_t)r; // return the lower part of result *c_out = (uint32_t)(r >> UINT32_BITS); // return the higher part of result, ... } // // end-of-file //