#include <stdlib.h>
#include <string.h>
#include <limits.h>
+#include <ctype.h>
#include "misc.h"
BignumInt bnZero[1] = { 0 };
BignumInt bnOne[2] = { 1, 1 };
+BignumInt bnTen[2] = { 1, 10 };
/*
* The Bignum format is an array of `BignumInt'. The first
* nonzero.
*/
-Bignum Zero = bnZero, One = bnOne;
+Bignum Zero = bnZero, One = bnOne, Ten = bnTen;
static Bignum newbn(int length)
{
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();
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;
}