3 /* LibTomMath, multiple-precision integer library -- Tom St Denis
5 * LibTomMath is a library that provides multiple-precision
6 * integer arithmetic as well as number theoretic functionality.
8 * The library was designed directly after the MPI library by
9 * Michael Fromberger but has been written from scratch with
10 * additional optimizations in place.
12 * The library is free for all purposes without any express
15 * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
18 /* find the n'th root of an integer
20 * Result found such that (c)**b <= a and (c+1)**b > a
22 * This algorithm uses Newton's approximation
23 * x[i+1] = x[i] - f(x[i])/f'(x[i])
24 * which will find the root in log(N) time where
25 * each step involves a fair bit. This is not meant to
26 * find huge roots [square and cube, etc].
28 int mp_n_root (mp_int
* a
, mp_digit b
, mp_int
* c
)
33 /* input must be positive if b is even */
34 if ((b
& 1) == 0 && a
->sign
== MP_NEG
) {
38 if ((res
= mp_init (&t1
)) != MP_OKAY
) {
42 if ((res
= mp_init (&t2
)) != MP_OKAY
) {
46 if ((res
= mp_init (&t3
)) != MP_OKAY
) {
50 /* if a is negative fudge the sign but keep track */
59 if ((res
= mp_copy (&t2
, &t1
)) != MP_OKAY
) {
63 /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */
66 if ((res
= mp_expt_d (&t1
, b
- 1, &t3
)) != MP_OKAY
) {
72 if ((res
= mp_mul (&t3
, &t1
, &t2
)) != MP_OKAY
) {
77 if ((res
= mp_sub (&t2
, a
, &t2
)) != MP_OKAY
) {
82 /* t3 = t1**(b-1) * b */
83 if ((res
= mp_mul_d (&t3
, b
, &t3
)) != MP_OKAY
) {
87 /* t3 = (t1**b - a)/(b * t1**(b-1)) */
88 if ((res
= mp_div (&t2
, &t3
, &t3
, NULL
)) != MP_OKAY
) {
92 if ((res
= mp_sub (&t1
, &t3
, &t2
)) != MP_OKAY
) {
95 } while (mp_cmp (&t1
, &t2
) != MP_EQ
);
97 /* result can be off by a few so check */
99 if ((res
= mp_expt_d (&t1
, b
, &t2
)) != MP_OKAY
) {
103 if (mp_cmp (&t2
, a
) == MP_GT
) {
104 if ((res
= mp_sub_d (&t1
, 1, &t1
)) != MP_OKAY
) {
112 /* reset the sign of a first */
118 /* set the sign of the result */
123 LBL_T3
:mp_clear (&t3
);
124 LBL_T2
:mp_clear (&t2
);
125 LBL_T1
:mp_clear (&t1
);
130 /* $Source: /cvs/libtom/libtommath/bn_mp_n_root.c,v $ */
131 /* $Revision: 1.3 $ */
132 /* $Date: 2006/03/31 14:18:44 $ */