2014-06-25 Niels Möller <nisse@lysator.liu.se>
+ Support for building with mini-gmp instead of the real GMP.
+ * configure.ac: New command line option --enable-mini-gmp. Also
+ disable all libgmp-related checks when enabled.
+ (NETTLE_USE_MINI_GMP): New substituted variable.
+ (LIBHOGWEED_LIBS): Use $(LIBS) instead of -lgmp.
+ (IF_MINI_GMP): New Makefile conditional.
+ (GMP_NUMB_BITS): Alternative test for the mini-gmp case.
+ Substituted also in bignum.h.
+ (HAVE_MPZ_POWM_SEC): Drop this unused check.
+
+ * bignum.h: Renamed, to...
+ * bignum.h.in: New name.
+ (NETTLE_USE_MINI_GMP): Substituted by configure.
+ (GMP_NUMB_BITS): Substituted by configure, for the mini-gmp case.
+
+ * Makefile.in (OPT_HOGWEED_SOURCES): New variable, value
+ conditional on @IF_MINI_GMP@.
+ (hogweed_SOURCES): Add $(OPT_HOGWEED_SOURCES).
+ (PRE_CPPFLAGS): Add -I$(srcdir).
+ (HEADERS): Delete bignum.h.
+ (INSTALL_HEADERS): Add bignum.h. Also add mini-gmp.h, if mini-gmp
+ is enabled.
+ (DISTFILES): Added bignum.h.in.
+ (bignum.h): New target.
+ (distclean-here): Delete bignum.h.
+
+ * examples/ecc-benchmark.c (modinv_gcd) [NETTLE_USE_MINI_GMP]:
+ Disable this benchmark.
+ (mpn_random) [NETTLE_USE_MINI_GMP]: Provide a simple implementation.
+
+ * testsuite/ecc-mod-test.c [NETTLE_USE_MINI_GMP]: Skip test, it
+ depends on gmp_randstate_t.
+ * testsuite/ecc-modinv-test.c [NETTLE_USE_MINI_GMP]: Likewise.
+ * testsuite/ecc-mul-a-test.c [NETTLE_USE_MINI_GMP]: Likewise.
+ * testsuite/ecc-mul-g-test.c [NETTLE_USE_MINI_GMP]: Likewise.
+ * testsuite/ecc-redc-test.c [NETTLE_USE_MINI_GMP]: Likewise.
+
+ Various preparations for mini-gmp support.
* testsuite/bignum-test.c: Use WITH_HOGWEED instead of HAVE_LIBGMP
for preprocessor conditionals.
* testsuite/testutils.h: Likewise.
OPT_ASM_NETTLE_SOURCES = @OPT_ASM_NETTLE_SOURCES@
OPT_ASM_HOGWEED_SOURCES = @OPT_ASM_HOGWEED_SOURCES@
+OPT_HOGWEED_SOURCES = @IF_MINI_GMP@ mini-gmp.c
+
SUBDIRS = tools testsuite examples
include config.make
-PRE_CPPFLAGS = -I.
+# $(srcdir) is needed for includes in bignum.h.
+PRE_CPPFLAGS = -I. -I$(srcdir)
+
# FIXME: Add configuration of LIBEXT?
LIBTARGETS = @IF_STATIC@ libnettle.a @IF_HOGWEED@ libhogweed.a
SHLIBTARGETS = @IF_SHARED@ $(LIBNETTLE_FORLINK) @IF_HOGWEED@ $(LIBHOGWEED_FORLINK)
ecc-mul-g.c ecc-mul-a.c ecc-hash.c ecc-random.c \
ecc-point.c ecc-scalar.c ecc-point-mul.c ecc-point-mul-g.c \
ecc-ecdsa-sign.c ecdsa-sign.c \
- ecc-ecdsa-verify.c ecdsa-verify.c ecdsa-keygen.c
+ ecc-ecdsa-verify.c ecdsa-verify.c ecdsa-keygen.c \
+ $(OPT_HOGWEED_SOURCES)
-HEADERS = aes.h arcfour.h arctwo.h asn1.h bignum.h blowfish.h \
+HEADERS = aes.h arcfour.h arctwo.h asn1.h blowfish.h \
base16.h base64.h buffer.h camellia.h cast128.h \
cbc.h ccm.h chacha.h chacha-poly1305.h ctr.h \
des.h des-compat.h dsa.h dsa-compat.h eax.h \
serpent.h sha.h sha1.h sha2.h sha3.h twofish.h \
umac.h yarrow.h poly1305.h
-INSTALL_HEADERS = $(HEADERS) nettle-stdint.h
+INSTALL_HEADERS = $(HEADERS) nettle-stdint.h bignum.h @IF_MINI_GMP@ mini-gmp.h
SOURCES = $(nettle_SOURCES) $(hogweed_SOURCES) \
$(getopt_SOURCES) $(internal_SOURCES) \
DISTFILES = $(SOURCES) $(HEADERS) getopt.h getopt_int.h \
.bootstrap run-tests \
aclocal.m4 configure.ac \
- configure stamp-h.in \
+ configure stamp-h.in bignum.h.in \
config.guess config.sub install-sh texinfo.tex \
config.h.in config.m4.in config.make.in Makefile.in \
README AUTHORS COPYING.LESSERv3 COPYINGv2 COPYINGv3 \
./config.status config.h
echo timestamp > stamp-h
+bignum.h: bignum.h.in config.status
+ ./config.status $@
+
Makefile: Makefile.in config.status
./config.status $@
distclean-here: clean-here
-rm -f config.h stamp-h config.log config.status machine.m4 \
- config.make config.m4 Makefile nettle-stdint.h \
+ config.make config.m4 Makefile nettle-stdint.h bignum.h \
nettle.pc hogweed.pc \
*.asm *.d
#include "nettle-meta.h"
-#include <gmp.h>
#include "nettle-types.h"
+#define NETTLE_USE_MINI_GMP @NETTLE_USE_MINI_GMP@
+
+#if NETTLE_USE_MINI_GMP
+# include "mini-gmp.h"
+
+/* We need a preprocessor constant for GMP_NUMB_BITS, simply using
+ sizeof(mp_limb_t) * CHAR_BIT is not good enough. */
+# define GMP_NUMB_BITS @GMP_NUMB_BITS@
+# define GMP_NUMB_MASK (~(mp_limb_t) 0)
+
+/* Functions missing in older gmp versions, and checked for with ifdef */
+# define mpz_limbs_read mpz_limbs_read
+# define mpn_copyd mpn_copyd
+# define mpn_sqr mpn_sqr
+# define mpz_combit mpz_combit
+# define mpz_import mpz_import
+# define mpz_export mpz_export
+#else
+# include <gmp.h>
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
AC_HELP_STRING([--enable-arm-neon], [Enable ARM Neon assembly. (default=auto)]),,
[enable_arm_neon=auto])
+AC_ARG_ENABLE(mini-gmp,
+ AC_HELP_STRING([--enable-mini-gmp], [Enable mini-gmp, used instead of libgmp.]),,
+ [enable_mini_gmp=no])
+
+if test "x$enable_mini_gmp" = xyes ; then
+ NETTLE_USE_MINI_GMP=1
+else
+ NETTLE_USE_MINI_GMP=0
+fi
+AC_SUBST([NETTLE_USE_MINI_GMP])
+
LSH_RPATH_INIT([`echo $with_lib_path | sed 's/:/ /g'` \
`echo $exec_prefix | sed "s@^NONE@$prefix/lib@g" | sed "s@^NONE@$ac_default_prefix/lib@g"` \
/usr/local/lib /sw/local/lib /sw/lib \
LIBHOGWEED_SONAME='libhogweed.$(LIBHOGWEED_MAJOR).dylib'
LIBHOGWEED_FILE='libhogweed.$(LIBHOGWEED_MAJOR).$(LIBHOGWEED_MINOR).dylib'
LIBHOGWEED_LINK='$(CC) $(CFLAGS) -dynamiclib -L. $(LDFLAGS) -install_name ${libdir}/$(LIBHOGWEED_SONAME) -compatibility_version $(LIBHOGWEED_MAJOR) -current_version $(LIBHOGWEED_MAJOR).$(LIBHOGWEED_MINOR)'
- LIBHOGWEED_LIBS='-lnettle -lgmp'
+ LIBHOGWEED_LIBS='-lnettle $(LIBS)'
;;
solaris*)
# Sun's ld uses -h to set the soname, and this option is passed
LIBHOGWEED_SONAME='$(LIBHOGWEED_FORLINK).$(LIBHOGWEED_MAJOR)'
LIBHOGWEED_FILE='$(LIBHOGWEED_SONAME).$(LIBHOGWEED_MINOR)'
LIBHOGWEED_LINK='$(CC) $(CFLAGS) $(LDFLAGS) -G -h $(LIBHOGWEED_SONAME)'
- LIBHOGWEED_LIBS='libnettle.so -lgmp'
+ LIBHOGWEED_LIBS='libnettle.so $(LIBS)'
;;
*)
LIBNETTLE_FORLINK=libnettle.so
# (does not work in general, e.g., with static linking all of
# -lhogweed -lgmp -lnettle are still required). Also makes dlopen
# of libhogweed.so work, without having to use RTLD_GLOBAL.
- LIBHOGWEED_LIBS='libnettle.so -lgmp'
+ LIBHOGWEED_LIBS='libnettle.so $(LIBS)'
;;
esac
# Checks for libraries
if test "x$enable_public_key" = "xyes" ; then
- AC_CHECK_LIB(gmp, __gmpz_getlimbn,,
- [AC_MSG_WARN(
- [GNU MP not found, or not 3.1 or up, see http://gmplib.org/.
- Support for public key algorithms will be unavailable.])]
- enable_public_key=no)
-
- # Add -R flags needed to run programs linked with gmp
- LSH_RPATH_FIX
+ if test "x$enable_mini_gmp" = "xno" ; then
+ AC_CHECK_LIB(gmp, __gmpz_getlimbn,,
+ [AC_MSG_WARN(
+ [GNU MP not found, or not 3.1 or up, see http://gmplib.org/.
+ Support for public key algorithms will be unavailable.])]
+ enable_public_key=no)
+
+ # Add -R flags needed to run programs linked with gmp
+ LSH_RPATH_FIX
+ fi
fi
+nettle_cv_gmp_numb_bits=0
if test "x$enable_public_key" = "xyes" ; then
# Check for gmp limb size
- nettle_cv_gmp_numb_bits=0
- if test "$enable_public_key" = yes; then
+ if test "x$enable_mini_gmp" = "xyes" ; then
+ AC_MSG_CHECKING([for mini-gmp limb size])
+ # With mini-gmp, mp_limb_t is always unsigned long.
+ AC_COMPUTE_INT(nettle_cv_gmp_numb_bits, [(sizeof(unsigned long) * CHAR_BIT)],
+ [#include <limits.h>],
+ [AC_MSG_FAILURE([cannot find value of GMP_NUMB_BITS])])
+
+ AC_MSG_RESULT([$nettle_cv_gmp_numb_bits bits])
+ else
AC_MSG_CHECKING([for GMP limb size])
AC_COMPUTE_INT(nettle_cv_gmp_numb_bits, [GMP_NUMB_BITS],
[#include <gmp.h>],
AC_MSG_RESULT([$nettle_cv_gmp_numb_bits bits])
fi
-
- GMP_NUMB_BITS="$nettle_cv_gmp_numb_bits"
- AC_SUBST([GMP_NUMB_BITS])
-
- AH_TEMPLATE([HAVE_MPZ_POWM_SEC], [Define if mpz_powm_sec is available (appeared in GMP-5)])
- AC_CHECK_FUNC(__gmpz_powm_sec, [AC_DEFINE(HAVE_MPZ_POWM_SEC)])
fi
+GMP_NUMB_BITS="$nettle_cv_gmp_numb_bits"
+AC_SUBST([GMP_NUMB_BITS])
+
AH_TEMPLATE([WITH_HOGWEED], [Defined if public key features are enabled])
if test "x$enable_public_key" = xyes ; then
IF_DOCUMENTATION='#'
fi
+if test "x$enable_mini_gmp" = "xyes" ; then
+ IF_MINI_GMP=''
+else
+ IF_MINI_GMP='#'
+fi
+
AC_SUBST(IF_HOGWEED)
AC_SUBST(IF_STATIC)
AC_SUBST(IF_SHARED)
AC_SUBST(IF_DOCUMENTATION)
AC_SUBST(IF_DLL)
+AC_SUBST(IF_MINI_GMP)
OPENSSL_LIBFLAGS=''
# inttypes.h.
fi
-AC_CONFIG_FILES([config.make config.m4 Makefile])
+AC_CONFIG_FILES([config.make config.m4 Makefile bignum.h])
AC_CONFIG_FILES([tools/Makefile testsuite/Makefile examples/Makefile])
AC_CONFIG_FILES([nettle.pc hogweed.pc])
Static libraries: ${enable_static}
Shared libraries: ${enable_shared}
Public key crypto: ${enable_public_key}
+ Using mini-gmp: ${enable_mini_gmp}
Documentation: ${enable_documentation}
])
return elapsed / ncalls;
}
+#if !NETTLE_USE_MINI_GMP
static int
modinv_gcd (const struct ecc_curve *ecc,
mp_limb_t *rp, mp_limb_t *ap, mp_limb_t *tp)
mpn_copyi (rp, sp, size);
return 1;
}
+#endif
struct ecc_ctx {
const struct ecc_curve *ecc;
ecc_modp_inv (ctx->ecc, ctx->rp, ctx->rp + ctx->ecc->size, ctx->tp);
}
+#if !NETTLE_USE_MINI_GMP
static void
bench_modinv_gcd (void *p)
{
mpn_copyi (ctx->rp + ctx->ecc->size, ctx->ap, ctx->ecc->size);
modinv_gcd (ctx->ecc, ctx->rp, ctx->rp + ctx->ecc->size, ctx->tp);
}
+#endif
#ifdef mpn_sec_powm
static void
ecc_mul_a (ctx->ecc, 1, ctx->rp, ctx->ap, ctx->bp, ctx->tp);
}
+#if NETTLE_USE_MINI_GMP
+static void
+mpn_random (mp_limb_t *xp, mp_size_t n)
+{
+ mp_size_t i;
+ for (i = 0; i < n; i++)
+ xp[i] = rand();
+}
+#endif
+
static void
bench_curve (const struct ecc_curve *ecc)
{
modq = time_function (bench_modq, &ctx);
modinv = time_function (bench_modinv, &ctx);
+#if !NETTLE_USE_MINI_GMP
modinv_gcd = time_function (bench_modinv_gcd, &ctx);
+#else
+ modinv_gcd = 0;
+#endif
#ifdef mpn_sec_powm
modinv_powm = time_function (bench_modinv_powm, &ctx);
#else
#include "testutils.h"
+#if NETTLE_USE_MINI_GMP
+void
+test_main (void)
+{
+ SKIP();
+}
+#else /* ! NETTLE_USE_MINI_GMP */
+
static void
ref_mod (mp_limb_t *rp, const mp_limb_t *ap, const mp_limb_t *mp, mp_size_t mn)
{
mpz_clear (r);
gmp_randclear (state);
}
+#endif /* ! NETTLE_USE_MINI_GMP */
#include "testutils.h"
+#if NETTLE_USE_MINI_GMP
+void
+test_main (void)
+{
+ SKIP();
+}
+#else /* ! NETTLE_USE_MINI_GMP */
+
static int
ref_modinv (mp_limb_t *rp, const mp_limb_t *ap, const mp_limb_t *mp, mp_size_t mn)
{
gmp_randclear (state);
mpz_clear (r);
}
+#endif /* ! NETTLE_USE_MINI_GMP */
#include "testutils.h"
+#if NETTLE_USE_MINI_GMP
+void
+test_main (void)
+{
+ SKIP();
+}
+#else /* ! NETTLE_USE_MINI_GMP */
+
void
test_main (void)
{
mpz_clear (r);
gmp_randclear (state);
}
+#endif /* ! NETTLE_USE_MINI_GMP */
#include "testutils.h"
+#if NETTLE_USE_MINI_GMP
+void
+test_main (void)
+{
+ SKIP();
+}
+#else /* ! NETTLE_USE_MINI_GMP */
+
void
test_main (void)
{
mpz_clear (r);
gmp_randclear (state);
}
+#endif /* ! NETTLE_USE_MINI_GMP */
#include "testutils.h"
+#if NETTLE_USE_MINI_GMP
+void
+test_main (void)
+{
+ SKIP();
+}
+#else /* ! NETTLE_USE_MINI_GMP */
+
static void
ref_redc (mp_limb_t *rp, const mp_limb_t *ap, const mp_limb_t *mp, mp_size_t mn)
{
mpz_clear (r);
gmp_randclear (state);
}
+#endif /* ! NETTLE_USE_MINI_GMP */
fi
if [ -s ../libhogweed.a ] ; then
+ PATTERN='\.?_?_?nettle_|get_pc_thunk'
+ if grep '^#define.*NETTLE_USE_MINI_GMP.*1$' ../bignum.h >/dev/null ; then
+ PATTERN="$PATTERN|mp_|mpz_|mpn_"
+ fi
( $NM -g ../libhogweed.a || $NM ../libhogweed.a ) \
- | grep ' [DRT] ' | egrep -v '( |^)\.?_?_?nettle_|get_pc_thunk' \
+ | grep ' [DRT] ' | egrep -v "( |^)($PATTERN)" \
| sort -k3 > test1.out
if [ -s test1.out ] ; then