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 }