@@ -53,9 +53,14 @@ namespace electionguard
5353 // / </summary>
5454 std::vector<uint64_t > pow_mod_p (uint64_t (&exponent)[MAX_Q_LEN]) const
5555 {
56- uint64_t result[MAX_P_LEN] = {1UL };
56+ uint64_t montgomery_result[MAX_P_LEN] = {};
57+ uint64_t result[MAX_P_LEN] = {};
5758 uint8_t exponentBytes[MAX_Q_SIZE] = {};
5859
60+ // copy the 1 in montgomery form into montgomery_result to start
61+ copy ((uint64_t *)one_in_montgomery_form, (uint64_t *)one_in_montgomery_form + MAX_P_LEN,
62+ montgomery_result);
63+
5964 // convert the bignum to byte array
6065 // which aligns with the k window size
6166 Bignum256::toBytes (static_cast <uint64_t *>(exponent),
@@ -73,9 +78,13 @@ namespace electionguard
7378 continue ;
7479 }
7580
76- mul_mod_p (result, const_cast <uint64_t *>(_lookupTable[i][slice]), result);
81+ mul_mod_p_mont (montgomery_result, const_cast <uint64_t *>(_lookupTable[i][slice]),
82+ montgomery_result);
7783 }
7884
85+ // convert from montogomery form
86+ CONTEXT_P ().from_montgomery_form (montgomery_result, result);
87+
7988 // wrap in a vector for convenience
8089 std::vector<uint64_t > vec (begin (result), end (result));
8190 return vec;
@@ -91,31 +100,38 @@ namespace electionguard
91100
92101 uint64_t row_base[MAX_P_LEN] = {};
93102 uint64_t running_base[MAX_P_LEN] = {};
103+ uint64_t one[MAX_P_LEN] = {1UL };
104+
105+
106+ // convert base to montgomery form
107+ CONTEXT_P ().to_montgomery_form (base, row_base);
94108
95109 // assign initial values
96- copy (base, base + len, row_base);
97- copy (base, base + len, running_base);
110+ copy (row_base, row_base + len, running_base);
98111
99112 // iterate over each m-row in the table
100113 for (uint64_t i = 0 ; i < TableLength; i++) {
101114 // iterate over each b-bit and compute the table values
102115 for (uint64_t j = 1 ; j < OrderBits; j++) {
103116 copy (begin (running_base), end (running_base), begin (_lookupTable[i][j]));
104- mul_mod_p (running_base, row_base, running_base);
117+ mul_mod_p_mont (running_base, row_base, running_base);
105118 }
106119 copy (begin (running_base), end (running_base), begin (row_base));
107120 }
121+
122+ // also convert 1 to montgomery form and store it because we use it to
123+ // start every table based exponentiation and there is no point in
124+ // computing it each time
125+ CONTEXT_P ().to_montgomery_form (one, one_in_montgomery_form);
108126 }
109127
110- void mul_mod_p (uint64_t *lhs, uint64_t *rhs, uint64_t *res) const
128+ void mul_mod_p_mont (uint64_t *lhs, uint64_t *rhs, uint64_t *res) const
111129 {
112- uint64_t mulResult[MAX_P_LEN_DOUBLE] = {};
113- Bignum4096::mul (lhs, rhs, static_cast <uint64_t *>(mulResult));
114- CONTEXT_P ().mod (static_cast <uint64_t *>(mulResult), res);
130+ CONTEXT_P ().montgomery_mod_mul_stay_in_mont_form (lhs, rhs, res);
115131 }
116-
117132 private:
118133 FixedBaseTable _lookupTable = {};
134+ uint64_t one_in_montgomery_form[MAX_P_LEN] = {};
119135 };
120136
121137 typedef LookupTable<LUT_WINDOW_SIZE, LUT_ORDER_BITS, LUT_TABLE_LENGTH> LookupTableType;
0 commit comments