pow_1.c revision 1.1.1.1 1 1.1 mrg /* mpn_pow_1 -- Compute powers R = U^exp.
2 1.1 mrg
3 1.1 mrg THE FUNCTIONS IN THIS FILE ARE FOR INTERNAL USE ONLY. THEY'RE ALMOST
4 1.1 mrg CERTAIN TO BE SUBJECT TO INCOMPATIBLE CHANGES OR DISAPPEAR COMPLETELY IN
5 1.1 mrg FUTURE GNU MP RELEASES.
6 1.1 mrg
7 1.1 mrg Copyright 2002 Free Software Foundation, Inc.
8 1.1 mrg
9 1.1 mrg This file is part of the GNU MP Library.
10 1.1 mrg
11 1.1 mrg The GNU MP Library is free software; you can redistribute it and/or modify it
12 1.1 mrg under the terms of the GNU Lesser General Public License as published by the
13 1.1 mrg Free Software Foundation; either version 3 of the License, or (at your
14 1.1 mrg option) any later version.
15 1.1 mrg
16 1.1 mrg The GNU MP Library is distributed in the hope that it will be useful, but
17 1.1 mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
19 1.1 mrg for more details.
20 1.1 mrg
21 1.1 mrg You should have received a copy of the GNU Lesser General Public License along
22 1.1 mrg with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
23 1.1 mrg
24 1.1 mrg
25 1.1 mrg #include "gmp.h"
26 1.1 mrg #include "gmp-impl.h"
27 1.1 mrg #include "longlong.h"
28 1.1 mrg
29 1.1 mrg mp_size_t
30 1.1 mrg mpn_pow_1 (mp_ptr rp, mp_srcptr bp, mp_size_t bn, mp_limb_t exp, mp_ptr tp)
31 1.1 mrg {
32 1.1 mrg mp_limb_t x;
33 1.1 mrg int cnt, i;
34 1.1 mrg mp_size_t rn;
35 1.1 mrg int par;
36 1.1 mrg
37 1.1 mrg ASSERT (bn >= 1);
38 1.1 mrg /* FIXME: Add operand overlap criteria */
39 1.1 mrg
40 1.1 mrg if (exp <= 1)
41 1.1 mrg {
42 1.1 mrg if (exp == 0)
43 1.1 mrg {
44 1.1 mrg rp[0] = 1;
45 1.1 mrg return 1;
46 1.1 mrg }
47 1.1 mrg else
48 1.1 mrg {
49 1.1 mrg MPN_COPY (rp, bp, bn);
50 1.1 mrg return bn;
51 1.1 mrg }
52 1.1 mrg }
53 1.1 mrg
54 1.1 mrg /* Count number of bits in exp, and compute where to put initial square in
55 1.1 mrg order to magically get results in the entry rp. Use simple code,
56 1.1 mrg optimized for small exp. For large exp, the bignum operations will take
57 1.1 mrg so much time that the slowness of this code will be negligible. */
58 1.1 mrg par = 0;
59 1.1 mrg cnt = GMP_LIMB_BITS;
60 1.1 mrg for (x = exp; x != 0; x >>= 1)
61 1.1 mrg {
62 1.1 mrg par ^= x & 1;
63 1.1 mrg cnt--;
64 1.1 mrg }
65 1.1 mrg exp <<= cnt;
66 1.1 mrg
67 1.1 mrg if (bn == 1)
68 1.1 mrg {
69 1.1 mrg mp_limb_t bl = bp[0];
70 1.1 mrg
71 1.1 mrg if ((cnt & 1) != 0)
72 1.1 mrg MP_PTR_SWAP (rp, tp);
73 1.1 mrg
74 1.1 mrg mpn_sqr (rp, bp, bn);
75 1.1 mrg rn = 2 * bn; rn -= rp[rn - 1] == 0;
76 1.1 mrg
77 1.1 mrg for (i = GMP_LIMB_BITS - cnt - 1;;)
78 1.1 mrg {
79 1.1 mrg exp <<= 1;
80 1.1 mrg if ((exp & GMP_LIMB_HIGHBIT) != 0)
81 1.1 mrg {
82 1.1 mrg rp[rn] = mpn_mul_1 (rp, rp, rn, bl);
83 1.1 mrg rn += rp[rn] != 0;
84 1.1 mrg }
85 1.1 mrg
86 1.1 mrg if (--i == 0)
87 1.1 mrg break;
88 1.1 mrg
89 1.1 mrg mpn_sqr (tp, rp, rn);
90 1.1 mrg rn = 2 * rn; rn -= tp[rn - 1] == 0;
91 1.1 mrg MP_PTR_SWAP (rp, tp);
92 1.1 mrg }
93 1.1 mrg }
94 1.1 mrg else
95 1.1 mrg {
96 1.1 mrg if (((par ^ cnt) & 1) == 0)
97 1.1 mrg MP_PTR_SWAP (rp, tp);
98 1.1 mrg
99 1.1 mrg mpn_sqr (rp, bp, bn);
100 1.1 mrg rn = 2 * bn; rn -= rp[rn - 1] == 0;
101 1.1 mrg
102 1.1 mrg for (i = GMP_LIMB_BITS - cnt - 1;;)
103 1.1 mrg {
104 1.1 mrg exp <<= 1;
105 1.1 mrg if ((exp & GMP_LIMB_HIGHBIT) != 0)
106 1.1 mrg {
107 1.1 mrg rn = rn + bn - (mpn_mul (tp, rp, rn, bp, bn) == 0);
108 1.1 mrg MP_PTR_SWAP (rp, tp);
109 1.1 mrg }
110 1.1 mrg
111 1.1 mrg if (--i == 0)
112 1.1 mrg break;
113 1.1 mrg
114 1.1 mrg mpn_sqr (tp, rp, rn);
115 1.1 mrg rn = 2 * rn; rn -= tp[rn - 1] == 0;
116 1.1 mrg MP_PTR_SWAP (rp, tp);
117 1.1 mrg }
118 1.1 mrg }
119 1.1 mrg
120 1.1 mrg return rn;
121 1.1 mrg }
122