zmodpow.c - libzahl - big integer library
(HTM) git clone git://git.suckless.org/libzahl
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
zmodpow.c (1152B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include "internals.h"
3
4 #define tb libzahl_tmp_pow_b
5 #define tc libzahl_tmp_pow_c
6 #define td libzahl_tmp_pow_d
7
8
9 void
10 zmodpow(z_t a, z_t b, z_t c, z_t d)
11 {
12 size_t i, j, n, bits;
13 zahl_char_t x;
14
15 /* TODO use zmodpowu when possible */
16
17 if (unlikely(zsignum(c) <= 0)) {
18 if (zzero(c)) {
19 if (check(zzero(b)))
20 libzahl_failure(-ZERROR_0_POW_0);
21 else if (check(zzero(d)))
22 libzahl_failure(-ZERROR_DIV_0);
23 zsetu(a, 1);
24 } else if (check(zzero1(b, d))) {
25 libzahl_failure(-ZERROR_DIV_0);
26 } else {
27 SET_SIGNUM(a, 0);
28 }
29 return;
30 } else if (check(zzero(d))) {
31 libzahl_failure(-ZERROR_DIV_0);
32 } else if (unlikely(zzero(b))) {
33 SET_SIGNUM(a, 0);
34 return;
35 }
36
37 bits = zbits(c);
38 n = FLOOR_BITS_TO_CHARS(bits);
39
40 zmod(tb, b, d);
41 zset(tc, c);
42 zset(td, d);
43 zsetu(a, 1);
44
45 for (i = 0; i < n; i++) { /* Remember, n is floored. */
46 x = tc->chars[i];
47 for (j = BITS_PER_CHAR; j--; x >>= 1) {
48 if (x & 1)
49 zmodmul(a, a, tb, td);
50 zmodsqr(tb, tb, td);
51 }
52 }
53 x = tc->chars[i];
54 for (; x; x >>= 1) {
55 if (x & 1)
56 zmodmul(a, a, tb, td);
57 zmodsqr(tb, tb, td);
58 }
59 }