@@ -196,16 +196,21 @@ mp_err mp_root_n(const mp_int *a, int b, mp_int *c)
196196 }
197197 /* log2(a), fixed point */
198198 if ((err = s_mp_fp_log (& a_ , & t2 )) != MP_OKAY ) goto LBL_ERR ;
199+
200+ /* This algorithm is sensitive to start-values that are too low. */
201+ mp_set (& t1 , 1 );
202+ if ((err = mp_mul_2d (& t1 ,MP_PRECISION_FIXED_LOG - 1 , & t1 )) != MP_OKAY ) goto LBL_ERR ;
203+ if ((err = mp_add (& t2 , & t1 , & t2 )) != MP_OKAY ) goto LBL_ERR ;
204+
199205 /* k = log2(a) / b, fixed point */
200206 mp_set_i64 (& t1 , b );
201207 if ((err = mp_mul_2d (& t1 ,MP_PRECISION_FIXED_LOG , & t1 )) != MP_OKAY ) goto LBL_ERR ;
202208 if ((err = mp_mul_2d (& t2 ,MP_PRECISION_FIXED_LOG , & t2 )) != MP_OKAY ) goto LBL_ERR ;
203209 if ((err = mp_div (& t2 , & t1 , & t2 ,NULL )) != MP_OKAY ) goto LBL_ERR ;
210+
211+
204212 /* 2^k, the start-value */
205213 if ((err = s_mp_fp_exp2 (& t2 , & t2 )) != MP_OKAY ) goto LBL_ERR ;
206-
207- /* This algorithm is sensitive to start-values that are too low. */
208- if ((err = mp_add_d (& t2 , 2 , & t2 )) != MP_OKAY ) goto LBL_ERR ;
209214 do {
210215
211216 /* t1 = t2 */
@@ -240,7 +245,6 @@ mp_err mp_root_n(const mp_int *a, int b, mp_int *c)
240245 break ;
241246 }
242247 } while (mp_cmp (& t1 , & t2 ) != MP_EQ );
243-
244248 /* result can be off by a few so check */
245249 /* Loop beneath can overshoot by one if root we found is smaller than the actual root */
246250 for (;;) {
@@ -249,7 +253,8 @@ mp_err mp_root_n(const mp_int *a, int b, mp_int *c)
249253 cmp = mp_cmp (& t2 , & a_ );
250254 if (cmp == MP_EQ ) {
251255 err = MP_OKAY ;
252- goto LBL_ERR ;
256+ /* On point, skip overshoot */
257+ goto LBL_SET ;
253258 }
254259 if (cmp == MP_LT ) {
255260 if ((err = mp_add_d (& t1 , 1uL , & t1 )) != MP_OKAY ) goto LBL_ERR ;
@@ -266,7 +271,7 @@ mp_err mp_root_n(const mp_int *a, int b, mp_int *c)
266271 break ;
267272 }
268273 }
269-
274+ LBL_SET :
270275 /* set the result */
271276 mp_exch (& t1 , c );
272277
0 commit comments