Improve robustness in modpow().
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 29 Jul 2004 15:44:35 +0000 (15:44 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Thu, 29 Jul 2004 15:44:35 +0000 (15:44 +0000)
git-svn-id: svn://svn.tartarus.org/sgt/putty@4372 cda61777-01e9-0310-a592-d414129be87e

sshbn.c

diff --git a/sshbn.c b/sshbn.c
index 7fe0309..dc83c40 100644 (file)
--- a/sshbn.c
+++ b/sshbn.c
@@ -3,6 +3,7 @@
  */
 
 #include <stdio.h>
+#include <assert.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -226,16 +227,25 @@ static void internal_mod(BignumInt *a, int alen,
 
 /*
  * Compute (base ^ exp) % mod.
- * The base MUST be smaller than the modulus.
- * The most significant word of mod MUST be non-zero.
- * We assume that the result array is the same size as the mod array.
  */
-Bignum modpow(Bignum base, Bignum exp, Bignum mod)
+Bignum modpow(Bignum base_in, Bignum exp, Bignum mod)
 {
     BignumInt *a, *b, *n, *m;
     int mshift;
     int mlen, i, j;
-    Bignum result;
+    Bignum base, result;
+
+    /*
+     * The most significant word of mod needs to be non-zero. It
+     * should already be, but let's make sure.
+     */
+    assert(mod[mod[0]] != 0);
+
+    /*
+     * Make sure the base is smaller than the modulus, by reducing
+     * it modulo the modulus if not.
+     */
+    base = bigmod(base_in, mod);
 
     /* Allocate m of size mlen, copy mod to m */
     /* We use big endian internally */
@@ -331,6 +341,8 @@ Bignum modpow(Bignum base, Bignum exp, Bignum mod)
        n[i] = 0;
     sfree(n);
 
+    freebn(base);
+
     return result;
 }