X-Git-Url: https://asedeno.scripts.mit.edu/gitweb/?a=blobdiff_plain;f=sshbn.c;h=0d64620da5c8728b59adf86e3334148cc76359bb;hb=eef0235a0f79e92f25f34782fc486c101fa703ee;hp=b40781ff2996dc65fe9659e4d15ef8921d1f52f3;hpb=8ab1433caaefef02a19e8e5ea74e5259fa719eae;p=PuTTY.git diff --git a/sshbn.c b/sshbn.c index b40781ff..0d64620d 100644 --- a/sshbn.c +++ b/sshbn.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "misc.h" @@ -102,6 +103,7 @@ typedef BignumInt *Bignum; BignumInt bnZero[1] = { 0 }; BignumInt bnOne[2] = { 1, 1 }; +BignumInt bnTen[2] = { 1, 10 }; /* * The Bignum format is an array of `BignumInt'. The first @@ -117,7 +119,7 @@ BignumInt bnOne[2] = { 1, 1 }; * nonzero. */ -Bignum Zero = bnZero, One = bnOne; +Bignum Zero = bnZero, One = bnOne, Ten = bnTen; static Bignum newbn(int length) { @@ -1233,21 +1235,67 @@ Bignum bignum_from_bytes(const unsigned char *data, int nbytes) return result; } +Bignum bignum_from_bytes_le(const unsigned char *data, int nbytes) +{ + Bignum result; + int w, i; + + assert(nbytes >= 0 && nbytes < INT_MAX/8); + + w = (nbytes + BIGNUM_INT_BYTES - 1) / BIGNUM_INT_BYTES; /* bytes->words */ + + result = newbn(w); + for (i = 1; i <= w; i++) + result[i] = 0; + for (i = 0; i < nbytes; ++i) { + unsigned char byte = *data++; + result[1 + i / BIGNUM_INT_BYTES] |= byte << (8*i % BIGNUM_INT_BITS); + } + + while (result[0] > 1 && result[result[0]] == 0) + result[0]--; + return result; +} + +Bignum bignum_from_decimal(const char *decimal) +{ + Bignum result = copybn(Zero); + + while (*decimal) { + Bignum tmp, tmp2; + + if (!isdigit((unsigned char)*decimal)) { + freebn(result); + return 0; + } + + tmp = bigmul(result, Ten); + tmp2 = bignum_from_long(*decimal - '0'); + result = bigadd(tmp, tmp2); + freebn(tmp); + freebn(tmp2); + + decimal++; + } + + return result; +} + Bignum bignum_random_in_range(const Bignum lower, const Bignum upper) { Bignum ret = NULL; + unsigned char *bytes; int upper_len = bignum_bitcount(upper); int upper_bytes = upper_len / 8; int upper_bits = upper_len % 8; if (upper_bits) ++upper_bytes; + bytes = snewn(upper_bytes, unsigned char); do { - unsigned char *bytes; int i; if (ret) freebn(ret); - bytes = snewn(upper_bytes, unsigned char); for (i = 0; i < upper_bytes; ++i) { bytes[i] = (unsigned char)random_byte(); @@ -1260,6 +1308,8 @@ Bignum bignum_random_in_range(const Bignum lower, const Bignum upper) ret = bignum_from_bytes(bytes, upper_bytes); } while (bignum_cmp(ret, lower) < 0 || bignum_cmp(ret, upper) > 0); + smemclr(bytes, upper_bytes); + sfree(bytes); return ret; }