Signed-off-by: Dmitry Eremin-Solenikov <[email protected]>
---
 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 9afcd299f8ed..87dd2d12dc3f 100644
--- a/bignum.h
+++ b/bignum.h
@@ -67,11 +67,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,
@@ -91,6 +99,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();
-- 
2.14.1

_______________________________________________
nettle-bugs mailing list
[email protected]
http://lists.lysator.liu.se/mailman/listinfo/nettle-bugs

Reply via email to