Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com --- bignum.c | 35 +++++++++++++++++++++++++++++++++++ bignum.h | 17 +++++++++++++++++ testsuite/bignum-test.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+)
diff --git a/bignum.c b/bignum.c index 335252876544..413a630cb3aa 100644 --- a/bignum.c +++ b/bignum.c @@ -133,12 +133,32 @@ nettle_mpz_get_str_256(size_t length, uint8_t *s, const mpz_t x) } }
+void +nettle_mpz_get_str_256_u_le(size_t length, uint8_t *s, const mpz_t x) +{ + if (!length) + { + /* x must be zero */ + assert(!mpz_sgn(x)); + return; + } + + size_t count; + + assert(nettle_mpz_sizeinbase_256_u(x) <= length); + mpz_export(s, &count, -1, 1, 0, 0, x); + memset(s + count, 0, length - count); +} + /* Converting from strings */
/* mpz_import was introduced in GMP-4.1 */ #define nettle_mpz_from_octets(x, length, s) \ mpz_import((x), (length), 1, 1, 0, 0, (s))
+#define nettle_mpz_from_octets_le(x, length, s) \ + mpz_import((x), (length), -1, 1, 0, 0, (s)) + void nettle_mpz_set_str_256_u(mpz_t x, size_t length, const uint8_t *s) @@ -154,6 +174,21 @@ nettle_mpz_init_set_str_256_u(mpz_t x, nettle_mpz_from_octets(x, length, s); }
+void +nettle_mpz_set_str_256_u_le(mpz_t x, + size_t length, const uint8_t *s) +{ + nettle_mpz_from_octets_le(x, length, s); +} + +void +nettle_mpz_init_set_str_256_u_le(mpz_t x, + size_t length, const uint8_t *s) +{ + mpz_init(x); + nettle_mpz_from_octets_le(x, length, s); +} + void nettle_mpz_set_str_256_s(mpz_t x, size_t length, const uint8_t *s) diff --git a/bignum.h b/bignum.h index 7871d843168c..42a97e63d6b6 100644 --- a/bignum.h +++ b/bignum.h @@ -68,11 +68,19 @@ nettle_mpz_sizeinbase_256_s(const mpz_t x); size_t nettle_mpz_sizeinbase_256_u(const mpz_t x);
+#define nettle_mpz_sizeinbase_256_u_le nettle_mpz_sizeinbase_256_u + /* Writes an integer as length octets, using big endian byte order, * and two's complement for negative numbers. */ void nettle_mpz_get_str_256(size_t length, uint8_t *s, const mpz_t x);
+/* Writes an integer as length octets, using big endian byte order, + * and unsigned number format. */ +void +nettle_mpz_get_str_256_u_le(size_t 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, @@ -92,6 +100,15 @@ void nettle_mpz_init_set_str_256_u(mpz_t x, size_t length, const uint8_t *s);
+/* Similar, but for little endian byte order. */ +void +nettle_mpz_set_str_256_u_le(mpz_t x, + size_t length, const uint8_t *s); + +void +nettle_mpz_init_set_str_256_u_le(mpz_t x, + size_t length, const uint8_t *s); + /* Returns a uniformly distributed random number 0 <= x < 2^n */ void nettle_mpz_random_size(mpz_t x, diff --git a/testsuite/bignum-test.c b/testsuite/bignum-test.c index 602554b53941..79fd92e2d37d 100644 --- a/testsuite/bignum-test.c +++ b/testsuite/bignum-test.c @@ -34,6 +34,30 @@ test_bignum(const char *hex, const struct tstring *base256) free(buf); }
+static void +test_bignum_le(const char *hex, const struct tstring *base256) +{ + mpz_t a; + mpz_t b; + uint8_t *buf; + + mpz_init_set_str(a, hex, 16); + nettle_mpz_init_set_str_256_u_le(b, base256->length, base256->data); + + ASSERT(mpz_cmp(a, b) == 0); + + buf = xalloc(base256->length + 1); + memset(buf, 17, base256->length + 1); + + nettle_mpz_get_str_256_u_le(base256->length, buf, a); + ASSERT(MEMEQ(base256->length, buf, base256->data)); + + ASSERT(buf[base256->length] == 17); + + mpz_clear(a); mpz_clear(b); + free(buf); +} + static void test_size(long x, unsigned size) { @@ -86,6 +110,11 @@ test_main(void) test_bignum("-7fff", SHEX( "8001")); test_bignum("-8000", SHEX( "8000")); test_bignum("-8001", SHEX("ff7fff")); + + test_bignum_le("0", SHEX("00")); + test_bignum_le("010203040506", SHEX("060504030201")); + test_bignum_le("80010203040506", SHEX("06050403020180")); + test_bignum_le("01020304050680", SHEX("80060504030201"));
#else /* !WITH_HOGWEED */ SKIP();
Dmitry Eremin-Solenikov dbaryshkov@gmail.com writes:
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com
bignum.c | 35 +++++++++++++++++++++++++++++++++++ bignum.h | 17 +++++++++++++++++ testsuite/bignum-test.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+)
Hmm, I'm not sure we should add more gmp wrappers to bignum.[hc]. The code dates back to before Nettle was split out of LSH, as can be seen in the _s functions which do formatting according to the ssh binary format.
We also have some related functions in gmp-glue.c (for internal use only),
mpn_set_base256_le mpn_get_base256_le
but those work with the mpn layer, which lacks the general export/import functions.
What use for these functions do you have in mind? Application use, or some code you'd like to add to Nettle?
Regards, /Niels
Hello,
вс, 17 июн. 2018 г. в 20:47, Niels Möller nisse@lysator.liu.se:
Dmitry Eremin-Solenikov dbaryshkov@gmail.com writes:
Signed-off-by: Dmitry Eremin-Solenikov dbaryshkov@gmail.com
bignum.c | 35 +++++++++++++++++++++++++++++++++++ bignum.h | 17 +++++++++++++++++ testsuite/bignum-test.c | 29 +++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+)
Hmm, I'm not sure we should add more gmp wrappers to bignum.[hc]. The code dates back to before Nettle was split out of LSH, as can be seen in the _s functions which do formatting according to the ssh binary format.
We also have some related functions in gmp-glue.c (for internal use only),
mpn_set_base256_le mpn_get_base256_le
but those work with the mpn layer, which lacks the general export/import functions.
What use for these functions do you have in mind? Application use, or some code you'd like to add to Nettle?
Unfortunately Russian crypto standards prefer to use LE representation for MPIs, so I'd like to use native Nettle functions to import/export LE values (to make GnuTLS code more or less symmetrical). Basically I'm using those functions through GnuTLS'es lib/nettle/mpi.c wrappers.
nettle-bugs@lists.lysator.liu.se