From c049b56db6af94feccdacb976ca4ed1710e00d0e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Niels=20M=C3=B6ller?= <nisse@lysator.liu.se>
Date: Mon, 18 Feb 2013 15:29:00 +0100
Subject: [PATCH] New functions in gmp-glue.c.

---
 ChangeLog  |  6 ++++++
 gmp-glue.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 gmp-glue.h | 22 ++++++++++++++++++++
 3 files changed, 88 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index e62d748d..e58e810d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
 2013-02-18  Niels Möller  <nisse@lysator.liu.se>
 
+	* gmp-glue.c (_mpz_set_mpn): New convenience function.
+	(_mpn_set_base256): New function.
+	(_gmp_alloc_limbs): New function.
+	(_gmp_free_limbs): New function.
+	* gmp-glue.h: Corresponding declarations. Include nettle-stdinh.h.
+
 	* examples/Makefile.in (HOGWEED_TARGETS): Renamed, was
 	RSA_TARGETS. Added ecc-benchmark$(EXEEXT).
 	(SOURCES): Added ecc-benchmark.c.
diff --git a/gmp-glue.c b/gmp-glue.c
index d483d7c4..ee0b28dc 100644
--- a/gmp-glue.c
+++ b/gmp-glue.c
@@ -25,6 +25,7 @@
 #endif
 
 #include <assert.h>
+#include <stdlib.h>
 
 #include "gmp-glue.h"
 
@@ -135,6 +136,13 @@ _mpz_done_limbs (mpz_ptr x, mp_size_t n)
   SIZ (x) = n;
 }
 
+void
+_mpz_set_mpn (mpz_t r, const mp_limb_t *xp, mp_size_t xn)
+{
+  mpn_copyi (_mpz_write_limbs (r, xn), xp, xn);
+  _mpz_done_limbs (r, xn);
+}
+
 /* Needs some ugly casts. */
 mpz_srcptr
 _mpz_init_mpn (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs)
@@ -148,3 +156,55 @@ _mpz_init_mpn (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs)
   x->_mp_d = (mp_limb_t *) xp;
   return x;
 }
+
+void
+_mpn_set_base256 (mp_limb_t *rp, mp_size_t rn,
+		 const uint8_t *xp, size_t xn)
+{
+  size_t xi;
+  mp_limb_t out;
+  unsigned bits;
+  for (xi = xn, out = bits = 0; xi > 0 && rn > 0; )
+    {
+      mp_limb_t in = xp[--xi];
+      out |= (in << bits) & GMP_NUMB_MASK;
+      bits += 8;
+      if (bits >= GMP_NUMB_BITS)
+	{
+	  *rp++ = out;
+	  rn--;
+
+	  bits -= GMP_NUMB_BITS;
+	  out = in >> (8 - bits);
+	}
+    }
+  if (rn > 0)
+    {
+      *rp++ = out;
+      if (--rn > 0)
+	mpn_zero (rp, rn);
+    }
+}
+
+mp_limb_t *
+_gmp_alloc_limbs (mp_size_t n)
+{
+
+  void *(*alloc_func)(size_t);
+
+  assert (n > 0);
+
+  mp_get_memory_functions (&alloc_func, NULL, NULL);
+  return (mp_limb_t *) alloc_func ( (size_t) n * sizeof(mp_limb_t));
+}
+
+void
+_gmp_free_limbs (mp_limb_t *p, mp_size_t n)
+{
+  void (*free_func)(void *, size_t);
+  assert (n > 0);
+  assert (p != 0);
+  mp_get_memory_functions (NULL, NULL, &free_func);
+
+  free_func (p, (size_t) n * sizeof(mp_limb_t));
+}
diff --git a/gmp-glue.h b/gmp-glue.h
index cddd534f..4d0f00d1 100644
--- a/gmp-glue.h
+++ b/gmp-glue.h
@@ -25,6 +25,8 @@
 
 #include <gmp.h>
 
+#include "nettle-stdint.h"
+
 /* Name mangling. */
 #define _mpz_cmp_limbs _nettle_mpz_cmp_limbs
 #define _mpz_read_limbs _nettle_mpz_read_limbs
@@ -33,7 +35,11 @@
 #define _mpz_write_limbs _nettle_mpz_write_limbs
 #define _mpz_modify_limbs _nettle_mpz_modify_limbs
 #define _mpz_done_limbs _nettle_mpz_done_limbs
+#define _mpz_set_mpn _nettle_mpz_set_mpn
 #define _mpz_init_mpn _nettle_mpz_init_mpn
+#define _mpn_set_base256 _nettle_mpn_set_base256
+#define _gmp_alloc_limbs _nettle_gmp_alloc_limbs
+#define _gmp_free_limbs _nettle_gmp_free_limbs
 
 /* Some functions for interfacing between mpz and mpn code. Signs of
    the mpz numbers are generally ignored. */
@@ -76,10 +82,26 @@ _mpz_modify_limbs (mpz_ptr x, mp_size_t n);
 void
 _mpz_done_limbs (mpz_ptr x, mp_size_t n);
 
+void
+_mpz_set_mpn (mpz_t r, const mp_limb_t *xp, mp_size_t xn);
 
 /* Using an mpn number as an mpz. Can be used for read-only access
    only. x must not be cleared or reallocated. */
 mpz_srcptr
 _mpz_init_mpn (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs);
 
+/* Like mpn_set_str, but always writes rn limbs. If input is larger,
+   higher bits are ignored. */
+void
+_mpn_set_base256 (mp_limb_t *rp, mp_size_t rn,
+		  const uint8_t *xp, size_t xn);
+
+
+mp_limb_t *
+_gmp_alloc_limbs (mp_size_t n);
+
+void
+_gmp_free_limbs (mp_limb_t *p, mp_size_t n);
+
+
 #endif /* NETTLE_GMP_GLUE_H_INCLUDED */
-- 
GitLab