summaryrefslogtreecommitdiff
path: root/sys/src/libmp/port/mpexp.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2015-12-16 21:18:20 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2015-12-16 21:18:20 +0100
commitefd3ac8a2328d1baf55c296a00807052473d549e (patch)
tree3e0851312267fee156a3cfb67aea5b4faebbfb76 /sys/src/libmp/port/mpexp.c
parentb6f04b77e3d11699d664d0ca7d0ba991f9599acc (diff)
libmp: add mpfield() function for fast field arithmetic
instead of testing for special field primes each time in mpmod(), make it explicit with a mpfiled() function that tests a modulus N to be of some special form that can be reduced more efficiently with some precalculation, and replaces N with a Mfield* when it can. the Mfield*'s are recognized by mpmod() as they have the MPfield flag set and provide a function pointer that executes the fast reduction.
Diffstat (limited to 'sys/src/libmp/port/mpexp.c')
-rw-r--r--sys/src/libmp/port/mpexp.c20
1 files changed, 9 insertions, 11 deletions
diff --git a/sys/src/libmp/port/mpexp.c b/sys/src/libmp/port/mpexp.c
index 534fb33a9..f5d7ac94d 100644
--- a/sys/src/libmp/port/mpexp.c
+++ b/sys/src/libmp/port/mpexp.c
@@ -61,25 +61,23 @@ mpexp(mpint *b, mpint *e, mpint *m, mpint *res)
j = 0;
for(;;){
for(; bit != 0; bit >>= 1){
- mpmul(t[j], t[j], t[j^1]);
- if(bit & d)
- mpmul(t[j^1], b, t[j]);
+ if(m != nil)
+ mpmodmul(t[j], t[j], m, t[j^1]);
else
+ mpmul(t[j], t[j], t[j^1]);
+ if(bit & d) {
+ if(m != nil)
+ mpmodmul(t[j^1], b, m, t[j]);
+ else
+ mpmul(t[j^1], b, t[j]);
+ } else
j ^= 1;
- if(m != nil && t[j]->top > m->top){
- mpmod(t[j], m, t[j^1]);
- j ^= 1;
- }
}
if(--i < 0)
break;
bit = mpdighi;
d = e->p[i];
}
- if(m != nil){
- mpmod(t[j], m, t[j^1]);
- j ^= 1;
- }
if(t[j] == res){
mpfree(t[j^1]);
} else {