X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/6e522441172d5b1c2a2fa4d0f6bbe905ce6b647a..c82bda5269af866d4d6390cbe795a01fd3f9dc75:/sshbn.c diff --git a/sshbn.c b/sshbn.c index 693b4ac7..8dfaa298 100644 --- a/sshbn.c +++ b/sshbn.c @@ -11,6 +11,20 @@ unsigned short bnZero[1] = { 0 }; unsigned short bnOne[2] = { 1, 1 }; +/* + * The Bignum format is an array of `unsigned short'. The first + * element of the array counts the remaining elements. The + * remaining elements express the actual number, base 2^16, _least_ + * significant digit first. (So it's trivial to extract the bit + * with value 2^n for any n.) + * + * All Bignums in this module are positive. Negative numbers must + * be dealt with outside it. + * + * INVARIANT: the most significant word of any Bignum must be + * nonzero. + */ + Bignum Zero = bnZero, One = bnOne; Bignum newbn(int length) { @@ -170,11 +184,12 @@ static void internal_mod(unsigned short *a, int alen, * The most significant word of mod MUST be non-zero. * We assume that the result array is the same size as the mod array. */ -void modpow(Bignum base, Bignum exp, Bignum mod, Bignum result) +Bignum modpow(Bignum base, Bignum exp, Bignum mod) { unsigned short *a, *b, *n, *m; int mshift; int mlen, i, j; + Bignum result; /* Allocate m of size mlen, copy mod to m */ /* We use big endian internally */ @@ -238,14 +253,18 @@ void modpow(Bignum base, Bignum exp, Bignum mod, Bignum result) } /* Copy result to buffer */ + result = newbn(mod[0]); for (i = 0; i < mlen; i++) result[result[0] - i] = a[i+mlen]; + while (result[0] > 1 && result[result[0]] == 0) result[0]--; /* Free temporary arrays */ for (i = 0; i < 2*mlen; i++) a[i] = 0; free(a); for (i = 0; i < 2*mlen; i++) b[i] = 0; free(b); for (i = 0; i < mlen; i++) m[i] = 0; free(m); for (i = 0; i < mlen; i++) n[i] = 0; free(n); + + return result; } /* @@ -253,11 +272,12 @@ void modpow(Bignum base, Bignum exp, Bignum mod, Bignum result) * The most significant word of mod MUST be non-zero. * We assume that the result array is the same size as the mod array. */ -void modmul(Bignum p, Bignum q, Bignum mod, Bignum result) +Bignum modmul(Bignum p, Bignum q, Bignum mod) { unsigned short *a, *n, *m, *o; int mshift; int pqlen, mlen, i, j; + Bignum result; /* Allocate m of size mlen, copy mod to m */ /* We use big endian internally */ @@ -306,14 +326,18 @@ void modmul(Bignum p, Bignum q, Bignum mod, Bignum result) } /* Copy result to buffer */ + result = newbn(mod[0]); for (i = 0; i < mlen; i++) result[result[0] - i] = a[i+2*pqlen-mlen]; + while (result[0] > 1 && result[result[0]] == 0) result[0]--; /* Free temporary arrays */ for (i = 0; i < 2*pqlen; i++) a[i] = 0; free(a); for (i = 0; i < mlen; i++) m[i] = 0; free(m); for (i = 0; i < pqlen; i++) n[i] = 0; free(n); for (i = 0; i < pqlen; i++) o[i] = 0; free(o); + + return result; } /*