Commit 43152353 by Niels Möller

### (nettle_mpz_sizeinbase_256_s): New function.

```(nettle_mpz_sizeinbase_256_u): New name, was
nettle_mpz_sizeinbase_256.
(nettle_mpz_to_octets): New function.
(nettle_mpz_get_str_256): Handle negative numbers.
(nettle_mpz_from_octets): New function.
(nettle_mpz_set_str_256_u): New name, was nettle_mpz_set_str_256.
(nettle_mpz_init_set_str_256_u): New name, was
nettle_mpz_init_set_str_256.
(nettle_mpz_set_str_256_s): New function, handling negative two's
complement numbers.
(nettle_mpz_init_set_str_256_s): And an init variant.

Rev: src/nettle/bignum.c:1.5
Rev: src/nettle/bignum.h:1.6```
parent 52c695ff
 ... @@ -34,29 +34,54 @@ ... @@ -34,29 +34,54 @@ #include #include #include #include /* Two's complement negation means that -x = ~x + 1, ~x = -(x+1), * and we use that x = ~~x = ~(-x-1). * * Examples: * * x ~x = -x+1 ~~x = x * -1 0 ff * -2 1 fe * -7f 7e 81 * -80 7f 80 * -81 80 ff7f */ /* Including extra sign bit, if needed. Also one byte for zero. */ unsigned unsigned nettle_mpz_sizeinbase_256(const mpz_t x) nettle_mpz_sizeinbase_256_s(const mpz_t x) { { return (mpz_sizeinbase(x, 2) + 7) / 8; if (mpz_sgn(x) >= 0) return 1 + mpz_sizeinbase(x, 2) / 8; else { /* We'll output ~~x, so we need as many bits as for ~x */ unsigned size; mpz_t c; mpz_init(c); mpz_com(c, x); /* Same as c = - x - 1 = |x| + 1 */ size = 1 + mpz_sizeinbase(c,2) / 8; mpz_clear(c); return size; } } } void unsigned nettle_mpz_get_str_256(unsigned length, uint8_t *s, const mpz_t x) nettle_mpz_sizeinbase_256_u(const mpz_t x) { return (mpz_sizeinbase(x,2) + 7) / 8; } static void nettle_mpz_to_octets(unsigned length, uint8_t *s, const mpz_t x, uint8_t sign) { { uint8_t *dst = s + length - 1; uint8_t *dst = s + length - 1; unsigned size = mpz_size(x); unsigned size = mpz_size(x); unsigned i; unsigned i; if (!length) { /* x must be zero */ assert(!mpz_sgn(x)); return; } assert(mpz_sgn(x) >= 0); assert(nettle_mpz_sizeinbase_256(x) <= length); for (i = 0; i>= 8; limb >>= 8; length--; length--; } } } } if (length) if (length) memset(s, 0, length); memset(s, sign, length); } } void void nettle_mpz_set_str_256(mpz_t x, nettle_mpz_get_str_256(unsigned length, uint8_t *s, const mpz_t x) unsigned length, const uint8_t *s) { if (!length) { /* x must be zero */ assert(!mpz_sgn(x)); return; } if (mpz_sgn(x) >= 0) { assert(nettle_mpz_sizeinbase_256_u(x) <= length); nettle_mpz_to_octets(length, s, x, 0); } else { mpz_t c; mpz_init(c); mpz_com(c, x); assert(nettle_mpz_sizeinbase_256_u(c) <= length); nettle_mpz_to_octets(length, s, c, 0xff); mpz_clear(c); } } /* Converting from strings */ static void nettle_mpz_from_octets(mpz_t x, unsigned length, const uint8_t *s, uint8_t sign) { { size_t i; unsigned i; mpz_t digit; mpz_t digit; mpz_init(digit); mpz_init(digit); mpz_set_ui(x, 0); for (i = 0; i < length; i++) for (i = 0; i < length; i++) { { mpz_set_ui(digit, s[i]); mpz_set_ui(digit, sign ^ s[i]); mpz_mul_2exp(digit, digit, (length - i - 1) * 8); mpz_mul_2exp(digit, digit, (length - i - 1) * 8); mpz_ior(x, x, digit); mpz_ior(x, x, digit); } } ... @@ -93,11 +148,45 @@ nettle_mpz_set_str_256(mpz_t x, ... @@ -93,11 +148,45 @@ nettle_mpz_set_str_256(mpz_t x, } } void void nettle_mpz_init_set_str_256(mpz_t x, nettle_mpz_set_str_256_u(mpz_t x, unsigned length, const uint8_t *s) unsigned length, const uint8_t *s) { mpz_set_ui(x, 0); nettle_mpz_from_octets(x, length, s, 0); } void nettle_mpz_init_set_str_256_u(mpz_t x, unsigned length, const uint8_t *s) { mpz_init_set_ui(x, 0); nettle_mpz_from_octets(x, length, s, 0); } void nettle_mpz_set_str_256_s(mpz_t x, unsigned length, const uint8_t *s) { mpz_set_ui(x, 0); if (!length) return; if (s[0] & 0x80) { nettle_mpz_from_octets(x, length, s, 0xff); mpz_com(x, x); } else nettle_mpz_from_octets(x, length, s, 0); } void nettle_mpz_init_set_str_256_s(mpz_t x, unsigned length, const uint8_t *s) { { mpz_init(x); mpz_init(x); nettle_mpz_set_str_256(x, length, s); nettle_mpz_set_str_256_s(x, length, s); } } #endif /* HAVE_LIBGMP */ #endif /* HAVE_LIBGMP */
 ... @@ -31,21 +31,39 @@ ... @@ -31,21 +31,39 @@ #include #include #include #include /* Size needed for signed encoding, including extra sign byte if * necessary. */ unsigned unsigned nettle_mpz_sizeinbase_256(const mpz_t x); nettle_mpz_sizeinbase_256_s(const mpz_t x); /* Writes an unsigned integer as length octets, using big endian byte /* Size needed for unsigned encoding */ * order. */ unsigned nettle_mpz_sizeinbase_256_u(const mpz_t x); /* Writes an integer as length octets, using big endian byte order, * and two's complement for negative numbers. */ /* FIXME: Change order of arguments, putting the mpz_t first? */ void void nettle_mpz_get_str_256(unsigned length, uint8_t *s, const mpz_t x); nettle_mpz_get_str_256(unsigned length, uint8_t *s, const mpz_t x); /* Reads a big endian, two's complement, integer. */ void nettle_mpz_set_str_256_s(mpz_t x, unsigned length, const uint8_t *s); void nettle_mpz_init_set_str_256_s(mpz_t x, unsigned length, const uint8_t *s); /* Similar, but for unsigned format. These function don't interpret * the most significant bit as the sign. */ void void nettle_mpz_set_str_256(mpz_t x, nettle_mpz_set_str_256_u(mpz_t x, unsigned length, const uint8_t *s); unsigned length, const uint8_t *s); void void nettle_mpz_init_set_str_256(mpz_t x, nettle_mpz_init_set_str_256_u(mpz_t x, unsigned length, const uint8_t *s); unsigned length, const uint8_t *s); /* Returns a uniformly distributed random number 0 <= x < 2^n */ /* Returns a uniformly distributed random number 0 <= x < 2^n */ void void ... ...
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!