OPT_ASM_SOURCES is already included via hogweed_OBJS.
This avoids build errors about duplicate symbols in the shared library. --- Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile.in b/Makefile.in index 1ec807b..2db76c5 100644 --- a/Makefile.in +++ b/Makefile.in @@ -180,7 +180,7 @@ nettle_OBJS = $(nettle_SOURCES:.c=.$(OBJEXT)) $(LIBOBJS) nettle_PURE_OBJS = $(nettle_OBJS:.$(OBJEXT)=.p$(OBJEXT))
hogweed_OBJS = $(hogweed_SOURCES:.c=.$(OBJEXT)) $(OPT_ASM_SOURCES:.asm=.$(OBJEXT)) -hogweed_PURE_OBJS = $(hogweed_OBJS:.$(OBJEXT)=.p$(OBJEXT)) $(OPT_ASM_SOURCES:.asm=.p$(OBJEXT)) +hogweed_PURE_OBJS = $(hogweed_OBJS:.$(OBJEXT)=.p$(OBJEXT))
libnettle.a: $(nettle_OBJS) -rm -f $@
This is the same workaround as done in f58d1c288f6 for salsa20-crypt. --- x86_64/sha3-permute.asm | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-)
diff --git a/x86_64/sha3-permute.asm b/x86_64/sha3-permute.asm index 0ebd70c..360a1f4 100644 --- a/x86_64/sha3-permute.asm +++ b/x86_64/sha3-permute.asm @@ -72,6 +72,10 @@ define(<STATE>, <OFFSET($1)(CTX)>)
define(<SWAP64>, <pshufd <$>0x4e,>)
+C movq calls that are equal to the corresponding movd, +C where the Apple assembler requires them to be written as movd. +define(<MOVQ>, <movd>) + C ROTL64(rot, register, temp) C Caller needs to or together the result. define(<ROTL64>, < @@ -147,12 +151,12 @@ PROLOGUE(nettle_sha3_permute)
SWAP64 C34, C34 C Holds C4, C3 movdqa C12, D34 - movq C0, D12 + MOVQ C0, D12 punpcklqdq C12, D12 C Holds C0, C1 punpckhqdq C34, D34 C Holds C2, C3 punpcklqdq D12, C34 C Holds C4, C0 - movq C34, D0 - movq C12, T0 + MOVQ C34, D0 + MOVQ C12, T0 rolq $1, T0 xorq T0, D0
@@ -236,8 +240,8 @@ PROLOGUE(nettle_sha3_permute) C `-_________-^`-^ rolq $36, A05 - movq A05, W0 - movq A0607, A05 + MOVQ A05, W0 + MOVQ A0607, A05 rolq $44, A05 C Done A05 ROTL64(6, A0607, W1) por A0607, W1 @@ -260,8 +264,8 @@ PROLOGUE(nettle_sha3_permute)
rolq $42, A10 C 42 + 25 = 3 (mod 64) SWAP64 A1112, W0 - movq A10, A1112 - movq W0, A10 + MOVQ A10, A1112 + MOVQ W0, A10 rolq $43, A10 C Done A10
punpcklqdq A1314, A1112 @@ -285,8 +289,8 @@ PROLOGUE(nettle_sha3_permute)
SWAP64 A1819, W0 rolq $41, A15 - movq A15, W1 - movq A1819, A15 + MOVQ A15, W1 + MOVQ A1819, A15 rolq $21, A15 C Done A15 SWAP64 A1617, A1819 ROTL64(45, A1617, W2) @@ -308,7 +312,7 @@ PROLOGUE(nettle_sha3_permute) C _______/
rolq $18, A20 - movq A20, W0 + MOVQ A20, W0 SWAP64 A2324, W1 movd W1, A20 rolq $14, A20 C Done A20 @@ -386,21 +390,21 @@ PROLOGUE(nettle_sha3_permute) C Swap (A05, A10) <-> A0102, and (A15, A20) <-> A0304, C and also copy to C12 and C34 while at it. - movq A05, C12 - movq A15, C34 - movq A10, W0 - movq A20, W1 + MOVQ A05, C12 + MOVQ A15, C34 + MOVQ A10, W0 + MOVQ A20, W1 movq A00, C0 punpcklqdq W0, C12 punpcklqdq W1, C34 - movq A0102, A05 - movq A0304, A15 + MOVQ A0102, A05 + MOVQ A0304, A15 psrldq $8, A0102 psrldq $8, A0304 xorq A05, C0 xorq A15, C0 - movq A0102, A10 - movq A0304, A20 + MOVQ A0102, A10 + MOVQ A0304, A20
movdqa C12, A0102 movdqa C34, A0304
Martin Storsjö martin@martin.st writes:
--- a/x86_64/sha3-permute.asm +++ b/x86_64/sha3-permute.asm
BTW, this really file needs a rewrite. It runs much slower than the C version on some (or all?) AMD processors. Probably because the movq/movd between general registers and xmm registers have a large latency penalty. One would either need to move data via memory (maybe with a separate permute/rotate passworking with general registers and memory), or squeeze (almost) all state into the xmm registers, a bit like the arm neon sha3 code I wrote the other week.
Regards, /Niels
This falls back to clock(), just like in e.g. nettle-benchmark.
This makes building succeed on e.g. OS X. --- examples/ecc-benchmark.c | 69 +++++++++++++++++++++++++++++++++++++----- examples/hogweed-benchmark.c | 69 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 122 insertions(+), 16 deletions(-)
diff --git a/examples/ecc-benchmark.c b/examples/ecc-benchmark.c index 596b2ff..e2ee3d5 100644 --- a/examples/ecc-benchmark.c +++ b/examples/ecc-benchmark.c @@ -70,22 +70,75 @@ xalloc_limbs (mp_size_t size) return xalloc (size * sizeof(mp_limb_t)); }
+#if HAVE_CLOCK_GETTIME && defined CLOCK_PROCESS_CPUTIME_ID +#define TRY_CLOCK_GETTIME 1 +struct timespec cgt_start; + +static int +cgt_works_p(void) +{ + struct timespec now; + return clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now) == 0; +} + inline static void -time_start(struct timespec *start) +cgt_time_start(void) { - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, start) < 0) + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cgt_start) < 0) die("clock_gettime failed: %s\n", strerror(errno)); }
static inline double -time_end(struct timespec *start) +cgt_time_end(void) { struct timespec end; if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end) < 0) die("clock_gettime failed: %s\n", strerror(errno));
- return end.tv_sec - start->tv_sec - + 1e-9 * (end.tv_nsec - start->tv_nsec); + return end.tv_sec - cgt_start.tv_sec + + 1e-9 * (end.tv_nsec - cgt_start.tv_nsec); +} + +static void (*time_start)(void); +static double (*time_end)(void); +static void clock_time_start(void); +static double clock_time_end(void); + +static void time_init(void) +{ + /* Choose timing function */ + if (cgt_works_p()) + { + time_start = cgt_time_start; + time_end = cgt_time_end; + } + else + { + fprintf(stderr, "clock_gettime not working, falling back to clock\n"); + time_start = clock_time_start; + time_end = clock_time_end; + } +} + +#else /* !HAVE_CLOCK_GETTIME */ +#define TRY_CLOCK_GETTIME 0 +#define time_start clock_time_start +#define time_end clock_time_end +#define time_init() +#endif /* !HAVE_CLOCK_GETTIME */ + +static clock_t clock_start; + +static void +clock_time_start(void) +{ + clock_start = clock(); +} + +static double +clock_time_end(void) +{ + return (double) (clock() - (clock_start)) / CLOCKS_PER_SEC; }
/* Returns second per function call */ @@ -100,12 +153,11 @@ time_function(void (*f)(void *arg), void *arg) for (ncalls = 10 ;;) { unsigned i; - struct timespec t;
- time_start(&t); + time_start(); for (i = 0; i < ncalls; i++) f(arg); - elapsed = time_end(&t); + elapsed = time_end(); if (elapsed > BENCH_INTERVAL) break; else if (elapsed < BENCH_INTERVAL / 10) @@ -293,6 +345,7 @@ main (int argc UNUSED, char **argv UNUSED) { unsigned i;
+ time_init(); printf ("%4s %6s %6s %6s %6s %6s %6s %6s %6s %6s %6s (us)\n", "size", "modp", "redc", "modq", "modinv", "mi_gcd", "dup_jj", "ad_jja", "ad_jjj", diff --git a/examples/hogweed-benchmark.c b/examples/hogweed-benchmark.c index 6a7da96..803f056 100644 --- a/examples/hogweed-benchmark.c +++ b/examples/hogweed-benchmark.c @@ -90,22 +90,75 @@ hash_string (const struct nettle_hash *hash, return digest; }
+#if HAVE_CLOCK_GETTIME && defined CLOCK_PROCESS_CPUTIME_ID +#define TRY_CLOCK_GETTIME 1 +struct timespec cgt_start; + +static int +cgt_works_p(void) +{ + struct timespec now; + return clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &now) == 0; +} + inline static void -time_start(struct timespec *start) +cgt_time_start(void) { - if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, start) < 0) + if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &cgt_start) < 0) die("clock_gettime failed: %s\n", strerror(errno)); }
static inline double -time_end(struct timespec *start) +cgt_time_end(void) { struct timespec end; if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end) < 0) die("clock_gettime failed: %s\n", strerror(errno));
- return end.tv_sec - start->tv_sec - + 1e-9 * (end.tv_nsec - start->tv_nsec); + return end.tv_sec - cgt_start.tv_sec + + 1e-9 * (end.tv_nsec - cgt_start.tv_nsec); +} + +static void (*time_start)(void); +static double (*time_end)(void); +static void clock_time_start(void); +static double clock_time_end(void); + +static void time_init(void) +{ + /* Choose timing function */ + if (cgt_works_p()) + { + time_start = cgt_time_start; + time_end = cgt_time_end; + } + else + { + fprintf(stderr, "clock_gettime not working, falling back to clock\n"); + time_start = clock_time_start; + time_end = clock_time_end; + } +} + +#else /* !HAVE_CLOCK_GETTIME */ +#define TRY_CLOCK_GETTIME 0 +#define time_start clock_time_start +#define time_end clock_time_end +#define time_init() +#endif /* !HAVE_CLOCK_GETTIME */ + +static clock_t clock_start; + +static void +clock_time_start(void) +{ + clock_start = clock(); +} + +static double +clock_time_end(void) +{ + return (double) (clock() - (clock_start)) / CLOCKS_PER_SEC; }
struct alg { @@ -129,12 +182,11 @@ time_function(void (*f)(void *arg), void *arg) for (ncalls = 10 ;;) { unsigned i; - struct timespec t;
- time_start(&t); + time_start(); for (i = 0; i < ncalls; i++) f(arg); - elapsed = time_end(&t); + elapsed = time_end(); if (elapsed > BENCH_INTERVAL) break; else if (elapsed < BENCH_INTERVAL / 10) @@ -625,6 +677,7 @@ main (int argc, char **argv) if (argc > 1) filter = argv[1];
+ time_init(); printf ("%15s %4s %9s %9s\n", "name", "size", "sign/ms", "verify/ms");
Martin Storsjö martin@martin.st writes:
This falls back to clock(), just like in e.g. nettle-benchmark.
For reduced code duplication, it would be nice to move the timing things to separate files, say timing.c and timing.h. Would you like to do that?
Regards, /Niels
On Mon, 25 Mar 2013, Niels Möller wrote:
Martin Storsjö martin@martin.st writes:
This falls back to clock(), just like in e.g. nettle-benchmark.
For reduced code duplication, it would be nice to move the timing things to separate files, say timing.c and timing.h. Would you like to do that?
I can do that, sure.
// Martin
The fallback is duplicated in eccdata.c to avoid having this file (which is built for the host) to include other target specific headers. --- ecc-internal.h | 1 + eccdata.c | 4 ++++ gmp-glue.h | 4 ++++ 3 files changed, 9 insertions(+)
diff --git a/ecc-internal.h b/ecc-internal.h index 0df8c9e..23207c7 100644 --- a/ecc-internal.h +++ b/ecc-internal.h @@ -29,6 +29,7 @@
#include "nettle-types.h" #include "ecc-curve.h" +#include "gmp-glue.h"
/* Name mangling */ #define ecc_generic_modp _nettle_ecc_generic_modp diff --git a/eccdata.c b/eccdata.c index ea922b5..a52e3ae 100644 --- a/eccdata.c +++ b/eccdata.c @@ -31,6 +31,10 @@
#include <gmp.h>
+#if __GNU_MP__ < 5 +typedef unsigned long int mp_bitcnt_t; +#endif + /* Affine coordinates, for simplicity. Infinity point represented as x == y == 0. */ struct ecc_point diff --git a/gmp-glue.h b/gmp-glue.h index e764571..ef17c2f 100644 --- a/gmp-glue.h +++ b/gmp-glue.h @@ -33,6 +33,10 @@ #define GMP_HAVE_mpz_limbs_read 0 #endif
+#if __GNU_MP__ < 5 +typedef unsigned long int mp_bitcnt_t; +#endif + /* Name mangling. */ #if !GMP_HAVE_mpz_limbs_read #define mpz_limbs_read _nettle_mpz_limbs_read
--- gmp-glue.c | 26 ++++++++++++++++++++++++++ gmp-glue.h | 26 ++++++++++++++++++++++++++ 2 files changed, 52 insertions(+)
diff --git a/gmp-glue.c b/gmp-glue.c index b468699..a2633a5 100644 --- a/gmp-glue.c +++ b/gmp-glue.c @@ -106,6 +106,32 @@ mpz_roinit_n (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs) } #endif /* !GMP_HAVE_mpz_limbs_read */
+#if !GMP_HAVE_mpn_copyd +void +mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t n) +{ + mp_size_t i; + for (i = n - 1; i >= 0; i--) + dst[i] = src[i]; +} + +void +mpn_copyi (mp_ptr dst, mp_srcptr src, mp_size_t n) +{ + mp_size_t i; + for (i = 0; i < n; i++) + dst[i] = src[i]; +} + +void +mpn_zero (mp_ptr ptr, mp_size_t n) +{ + mp_size_t i; + for (i = 0; i < n; i++) + ptr[i] = 0; +} +#endif /* !GMP_HAVE_mpn_copyd */ + /* Additional convenience functions. */
int diff --git a/gmp-glue.h b/gmp-glue.h index ef17c2f..27c0942 100644 --- a/gmp-glue.h +++ b/gmp-glue.h @@ -33,6 +33,12 @@ #define GMP_HAVE_mpz_limbs_read 0 #endif
+#ifdef mpz_copyd +#define GMP_HAVE_mpz_copyd 1 +#else +#define GMP_HAVE_mpz_copyd 0 +#endif + #if __GNU_MP__ < 5 typedef unsigned long int mp_bitcnt_t; #endif @@ -46,6 +52,12 @@ typedef unsigned long int mp_bitcnt_t; #define mpz_roinit_n _nettle_mpz_roinit_n #endif
+#if !GMP_HAVE_mpn_copyd +#define mpn_copyd _nettle_mpn_copyd +#define mpn_copyi _nettle_mpn_copyi +#define mpn_zero _nettle_mpn_zero +#endif + #define mpz_limbs_cmp _nettle_mpz_limbs_cmp #define mpz_limbs_read_n _nettle_mpz_limbs_read_n #define mpz_limbs_copy _nettle_mpz_limbs_copy @@ -87,6 +99,20 @@ mpz_roinit_n (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs);
#endif /* !GMP_HAVE_mpz_limbs_read */
+#if !GMP_HAVE_mpn_copyd +/* Copy elements, backwards */ +void +mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t n); + +/* Copy elements, forwards */ +void +mpn_copyi (mp_ptr dst, mp_srcptr src, mp_size_t n); + +/* Zero elements */ +void +mpn_zero (mp_ptr ptr, mp_size_t n); +#endif /* !GMP_HAVE_mpn_copyd */ + /* Convenience functions */ int mpz_limbs_cmp (mpz_srcptr a, const mp_limb_t *bp, mp_size_t bn);
On Sat, 23 Mar 2013, Martin Storsjö wrote:
gmp-glue.c | 26 ++++++++++++++++++++++++++ gmp-glue.h | 26 ++++++++++++++++++++++++++ 2 files changed, 52 insertions(+)
In addition to these, a fallback is needed for mpn_sqr if building with GMP 4.2.1 (which people who want to stay away from LGPLv3 might want to do), but that one doesn't seem to be quite as trivial as these.
Additionally, I now see that eccdata.c (which is built for the build system, not for the target) requires GMP as well - this does complicate some situations where one cross-builds nettle on a system that doesn't have GMP installed system wide already. (E.g., cross building from OS X to windows, which I do regularly.) In these setups, one obviously cross-builds GMP for the target, but adding a step to build a local copy of GMP just for the build-time tools does complicate things slightly.
Or would the files produced by eccdata.c be architecture/target independent? In those cases, they could perhaps be included in release tarballs, to avoid the host-GMP-requirement when crosscompiling?
// Martin
Martin Storsjö martin@martin.st writes:
In addition to these, a fallback is needed for mpn_sqr if building with GMP 4.2.1 (which people who want to stay away from LGPLv3 might want to do), but that one doesn't seem to be quite as trivial as these.
I guess the simplest workaround is something like
#define mpn_sqr(rp, ap, n) mpn_mul_n((rp), (ap), (ap), (n))
IIRC, the squaring function is available also in older GMP releases, under the name mpn_sqr_n, but it was undocumented and intended for internal use only.
At some point, we have to abandon older GMP releases. As for supporting GPLv2-only applications, I know that GMP developers have considered doing GPLv2+ and LGPLv3+ dual licensing. People who have a *real* interest in that (rather than hypotheticals like "some other people might not like LGPLv3") should contact GMP developers and offer help and encouragement.
Additionally, I now see that eccdata.c (which is built for the build system, not for the target) requires GMP [...]
Or would the files produced by eccdata.c be architecture/target independent?
They're archtecture dependent, depending mainly on GMP_NUMB_BITS on the target system. One option is to bundle mini-gmp, see http://gmplib.org:8000/gmp/file/mini-gmp. Or if one is prepared to limit the support to 32-bit and 64-bit limbs, one could generate tables for both sizes and include in the tarballs.
Regards, /Niels
On Mon, 25 Mar 2013, Niels Möller wrote:
Martin Storsjö martin@martin.st writes:
In addition to these, a fallback is needed for mpn_sqr if building with GMP 4.2.1 (which people who want to stay away from LGPLv3 might want to do), but that one doesn't seem to be quite as trivial as these.
I guess the simplest workaround is something like
#define mpn_sqr(rp, ap, n) mpn_mul_n((rp), (ap), (ap), (n))
IIRC, the squaring function is available also in older GMP releases, under the name mpn_sqr_n, but it was undocumented and intended for internal use only.
Right, thanks.
At some point, we have to abandon older GMP releases.
Yes, that's quite true. For these cases where the fallback is pretty simple I'd rather put off requiring the newer version thogh.
As for supporting GPLv2-only applications, I know that GMP developers have considered doing GPLv2+ and LGPLv3+ dual licensing. People who have a *real* interest in that (rather than hypotheticals like "some other people might not like LGPLv3") should contact GMP developers and offer help and encouragement.
Additionally, I now see that eccdata.c (which is built for the build system, not for the target) requires GMP [...]
Or would the files produced by eccdata.c be architecture/target independent?
They're archtecture dependent, depending mainly on GMP_NUMB_BITS on the target system. One option is to bundle mini-gmp, see http://gmplib.org:8000/gmp/file/mini-gmp. Or if one is prepared to limit the support to 32-bit and 64-bit limbs, one could generate tables for both sizes and include in the tarballs.
Hmm, both solutions do sound pretty sensible - and thanks for the pointer to mini-gmp. Hooking that up during the cross-builds I mentioned should possibly be easier than building and installing a full GMP, even if it isn't included in release tarballs.
// Martin
Martin Storsjö martin@martin.st writes:
On Mon, 25 Mar 2013, Niels Möller wrote:
They're archtecture dependent, depending mainly on GMP_NUMB_BITS on the target system. One option is to bundle mini-gmp, see http://gmplib.org:8000/gmp/file/mini-gmp. Or if one is prepared to limit the support to 32-bit and 64-bit limbs, one could generate tables for both sizes and include in the tarballs.
Hmm, both solutions do sound pretty sensible - and thanks for the pointer to mini-gmp. Hooking that up during the cross-builds I mentioned should possibly be easier than building and installing a full GMP, even if it isn't included in release tarballs.
I'm about to add mini-gmp now. Should help also for native compilation, in the case that -lgmp isn't enough for the linker to find a suitable gmp library.
eccdata needs some tedious changes to work with mini-gmp, since it lacks gmp_f?printf. Those calls have to be replaced by a mix of regular printf and mpz_out_str.
(Note that mini-gmp is LGPLv3, just like recent GMP, but that shouldn't matter for nettle users as long as mini-gmp is used only for the eccdata program).
Regards, /Niels
On Wed, 17 Apr 2013, Niels Möller wrote:
Martin Storsjö martin@martin.st writes:
On Mon, 25 Mar 2013, Niels Möller wrote:
They're archtecture dependent, depending mainly on GMP_NUMB_BITS on the target system. One option is to bundle mini-gmp, see http://gmplib.org:8000/gmp/file/mini-gmp. Or if one is prepared to limit the support to 32-bit and 64-bit limbs, one could generate tables for both sizes and include in the tarballs.
Hmm, both solutions do sound pretty sensible - and thanks for the pointer to mini-gmp. Hooking that up during the cross-builds I mentioned should possibly be easier than building and installing a full GMP, even if it isn't included in release tarballs.
I'm about to add mini-gmp now. Should help also for native compilation, in the case that -lgmp isn't enough for the linker to find a suitable gmp library.
Great, that sounds promising, and will absolutely help a lot in at least two setups I know of.
eccdata needs some tedious changes to work with mini-gmp, since it lacks gmp_f?printf. Those calls have to be replaced by a mix of regular printf and mpz_out_str.
(Note that mini-gmp is LGPLv3, just like recent GMP, but that shouldn't matter for nettle users as long as mini-gmp is used only for the eccdata program).
Yes, this shouldn't be an issue.
// Martin
On Mon, Mar 25, 2013 at 9:53 AM, Niels Möller nisse@lysator.liu.se wrote:
At some point, we have to abandon older GMP releases. As for supporting GPLv2-only applications, I know that GMP developers have considered doing GPLv2+ and LGPLv3+ dual licensing. People who have a *real* interest in that (rather than hypotheticals like "some other people might not like LGPLv3") should contact GMP developers and offer help and encouragement.
Well, I feel a bit awkward now because my understanding from our previous discussion that this was a planned move for gmp. I believe I gave you concrete examples of projects that have issues. I add here that my GPLv2 project [0] has issues since because of gmp it can only be distributed under GPLv3. Feel free to forward that to any mailing list (I don't see the point of repeating oneself though; there have already been discussions [1], what is missing is the actual action.)
I really don't understand what you mean about help and encouragement. If it is about practicalities, wouldn't placing a copy of GPLv2 in the directory and saing in a readme that you provide an exception to distribute the library under GPLv2, be sufficient? Why would you need to do anything more than that? If by encouragement you mean something else could you please clarify that?
regards, Nikos
[0]. http://www.infradead.org/ocserv/ [1]. http://gmplib.org/list-archives/gmp-devel/2011-May/001946.html
Nikos Mavrogiannopoulos n.mavrogiannopoulos@gmail.com writes:
Well, I feel a bit awkward now because my understanding from our previous discussion that this was a planned move for gmp.
Sorry if I've been unclear. My understanding is that none of the gmp developers have any objections, but also that all of them think they have more interesting things to work on. (And Torbjörn himself is on a pretty tight schedule for his PhD thesis; he can get distracted from that by interesting GMP work (maybe too easily...) , but he will not be distracted by anything uninteresting).
So it's been discussed, but not yet "planned" in any concrete sense. No one has been saying "Ok, I'll get it done, it's no big deal."
I believe I gave you concrete examples of projects that have issues. I add here that my GPLv2 project [0] has issues since because of gmp it can only be distributed under GPLv3.
That appears to be GPLv2 or (user's option) later, (I just looked at the header on one file, so I may have missed something). If so, this is the first time I hear anybody having problems with GPLv2+ and LGPLv3. Honestly.
I really don't understand what you mean about help and encouragement. If it is about practicalities, wouldn't placing a copy of GPLv2 in the directory and saing in a readme that you provide an exception to distribute the library under GPLv2, be sufficient?
I think the recomended way (http://www.gnu.org/prep/maintain/maintain.html#Licensing-of-GNU-Packages) is to put a dual licensing notice in every source file. And then various documentation files will need updating as well. So a nice script to update all copyright notices, and a patch for relevant documentation files, would be a great help for the practicalities.
And Simon, who iirc was the one initially driving the relicensing discussion, has been silent for a while. I can understand if he (and you too) has been frustrated by the lack of activity from the GMP side, though.
If by encouragement you mean something else could you please clarify that?
CUPS seems to be the most well-known example of a GPLv2-only program which uses (or should use) gnutls, which then depends on gmp and nettle. I know almost nothing about CUPS. So if GMP relicensing is required to suit CUPS' needs, then it would be encouraging if someone who actually *knows* CUPS (both technically and the licensing/policy issues) would step forward and be willing to discuss it.
If we go only by third-party information, we might end up going through a relicensing process which distracts us from real work, only to learn later thet the CUPS maintainers decided to use openssl exclusively anyway.
Regards, /Niels
On Mon, Mar 25, 2013 at 11:31 AM, Niels Möller nisse@lysator.liu.se wrote:
I believe I gave you concrete examples of projects that have issues. I add here that my GPLv2 project [0] has issues since because of gmp it can only be distributed under GPLv3.
That appears to be GPLv2 or (user's option) later, (I just looked at the header on one file, so I may have missed something). If so, this is the first time I hear anybody having problems with GPLv2+ and LGPLv3.
Well there is first time for everything :) The issue here is that I have chosen GPLv2+ and _not_ GPLv3+, and the license of GMP forces me to distribute under GPLv3+. Note that GPLv2+ says, "you can distribute under this license ... or (at your option) any later version". Now the "at your option" part is gone and I am forced to distribute under GPLv3+. If I wanted to release my code under GPLv3+ I would have done it already.
I think the recomended way (http://www.gnu.org/prep/maintain/maintain.html#Licensing-of-GNU-Packages) is to put a dual licensing notice in every source file.
I wouldn't go into that. I see the GPLv2+/LGPLv3+ dual license as a temporal solution until FSF solves that issue either by releasing LGPLv4 or something similar. Also you are most probably not required to have the precise boilerplate on every file. If you see other gnu projects (i.e. gnulib) their license terms are made explicit in the module text files rather than the .c/h files (that typically contain a GPLv2+ boilerplate).
CUPS seems to be the most well-known example of a GPLv2-only program which uses (or should use) gnutls, which then depends on gmp and nettle. I know almost nothing about CUPS. So if GMP relicensing is required to suit CUPS' needs, then it would be encouraging if someone who actually *knows* CUPS (both technically and the licensing/policy issues) would step forward and be willing to discuss it.
I really don't understand what is there to discuss but please contact them directly if you think there is something that needs to be discussed (if you check my previous mails an the discussion in gmplib there are more packages than CUPS with that issue). As I said I don't care about handling the case on an individual case for each package (that may even have already reverted to using openssl due to the long time taken to handle the issue), but rather solving the GPLv2 incompatibility issue in gnutls.
regards, Nikos
Hello,
Le 25/03/2013 11:31, Niels Möller a écrit :
Nikos Mavrogiannopoulos n.mavrogiannopoulos-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org writes:
If by encouragement you mean something else could you please clarify that?
CUPS seems to be the most well-known example of a GPLv2-only program which uses (or should use) gnutls, which then depends on gmp and nettle.
We also use gnutls (and nettle, and thus gmp) in VLC media player.
While technically our code is GPLv2 or later, we would prefer to distribute binaries under GPLv2, as stated in our press release: http://www.videolan.org/press/2007-1.html
To remain compatible with GPLv2 we are using an old release (4.2.1) http://git.videolan.org/?p=vlc.git;a=commitdiff;h=7e69850c6cf579dc01ff2e7c20...
which lacks for example compatibility with Windows 64bits, and according to Martin Storsjö, it also gives problems on MacOSX.
I'm willing to help you with dual-licensing LGPLv3/GPLv2 as it would very much help us on VLC.
I know almost nothing about CUPS. So if GMP relicensing is required to suit CUPS' needs, then it would be encouraging if someone who actually *knows* CUPS (both technically and the licensing/policy issues) would step forward and be willing to discuss it.
If we go only by third-party information, we might end up going through a relicensing process which distracts us from real work, only to learn later thet the CUPS maintainers decided to use openssl exclusively anyway.
Regards,
On Mon, Mar 25, 2013 at 9:53 AM, Niels Möller nisse@lysator.liu.se wrote:
IIRC, the squaring function is available also in older GMP releases, under the name mpn_sqr_n, but it was undocumented and intended for internal use only. At some point, we have to abandon older GMP releases. As for supporting GPLv2-only applications,
I think there is benefit from Martin's patches irrespective of the LGPL argument. The system I'm using at work has an old gmp (not for license reasons, just an old distribution which is not up to me to upgrade) and I needed Martin's patches in order to compile nettle. Being able to compile nettle in older distributions is I think an advantage.
regards, Nikos
Nikos Mavrogiannopoulos nmav@gnutls.org writes:
Being able to compile nettle in older distributions is I think an advantage.
Point taken.
Regards, /Niels
Nikos Mavrogiannopoulos nmav@gnutls.org writes:
I think there is benefit from Martin's patches irrespective of the LGPL argument. The system I'm using at work has an old gmp (not for license reasons, just an old distribution which is not up to me to upgrade)
Checked in now. I think I have all Martin's patches in now (let me know if I forgot something). It would be good if you or Martin could check if it works with older gmp releases now.
Other recent changes:
* Today, I wrote some documentation on the high-level ecc functions (basically, the highest level ecdsa functions and what's needed to use them). Comments appreciated.
* I added the ecc_point_mul and ecc_point_mul_g functions (but testcases missing).
* I added the salsa20r12 testvectors you sent me a while ago.
* I have arranged the ecc code to use gmp's mpn_cnd_{add,sub}_n functions when available (not yet in any release). Mixed benchmarking results on ARM; I use mpn_addmul_1 and mpn_submul_1 as fallbacks, and for small operands mpn_addmul_1 appears to be slightly faster than mpn_add_n on that machine, slowing some operations down a little.
Regards, /Niels
On Thu, 4 Apr 2013, Niels Möller wrote:
Checked in now. I think I have all Martin's patches in now (let me know if I forgot something). It would be good if you or Martin could check if it works with older gmp releases now.
Didn't compile test it yet, but I rebased my local patches on top of your master, and it seems that the mp_bitcnt_t fallback still is missing.
// Martin
Martin Storsjö martin@martin.st writes:
Didn't compile test it yet, but I rebased my local patches on top of your master, and it seems that the mp_bitcnt_t fallback still is missing.
Ooops, I missed that one. Looking at it again now, I wonder if a fallback is the right solution, maybe it's easier to replace all uses of mp_bitcnt_t (it's used only for some local variables, it seems) by a plain unsigned. Like in bignum-random-prime.c, which carries the comment
/* Avoid the mp_bitcnt_t type for compatibility with older GMP versions. */
Or maybe we should use unsigned long, but I think plain unsigned should be fine even on platforms where unsigned is 16 bits; we don't handle any numbers beyond 65000 bits, in particular not on 16-bit platforms.
Regards, /Niels
On Thu, 4 Apr 2013, Niels Möller wrote:
Martin Storsjö martin@martin.st writes:
Didn't compile test it yet, but I rebased my local patches on top of your master, and it seems that the mp_bitcnt_t fallback still is missing.
Ooops, I missed that one. Looking at it again now, I wonder if a fallback is the right solution, maybe it's easier to replace all uses of mp_bitcnt_t (it's used only for some local variables, it seems) by a plain unsigned. Like in bignum-random-prime.c, which carries the comment
/* Avoid the mp_bitcnt_t type for compatibility with older GMP versions. */
Or maybe we should use unsigned long, but I think plain unsigned should be fine even on platforms where unsigned is 16 bits; we don't handle any numbers beyond 65000 bits, in particular not on 16-bit platforms.
Yes, this is probably easier.
And I do agree that long probably isn't needed (does nettle even run on a platform where the native ints are 16 bit?).
// Martin
Martin Storsjö martin@martin.st writes:
Didn't compile test it yet, but I rebased my local patches on top of your master, and it seems that the mp_bitcnt_t fallback still is missing.
I think I have replaced all uses of mp_bitcnt_t now.
Regards, /Niels
On 04/04/2013 06:15 PM, Niels Möller wrote:
Checked in now. I think I have all Martin's patches in now (let me know if I forgot something). It would be good if you or Martin could check if it works with older gmp releases now.
- I added the ecc_point_mul and ecc_point_mul_g functions (but testcases
missing).
Thank you. A utility function such as the attached is also quite useful.
regards, Nikos
nisse@lysator.liu.se (Niels Möller) writes:
- I added the ecc_point_mul and ecc_point_mul_g functions (but testcases missing).
These functions still lack testing. Does anyone here have suitable ecdh test vectors (a bit like draft-turner-thecurve25519function-00, but for the more traditional curves? Wikipedia points to http://www.secg.org/download/aid-390/gec2.pdf, but that site appears to be down at the moment.
Regards, /Niels
nisse@lysator.liu.se (Niels Möller) writes:
Does anyone here have suitable ecdh test vectors (a bit like draft-turner-thecurve25519function-00, but for the more traditional curves? Wikipedia points to http://www.secg.org/download/aid-390/gec2.pdf, but that site appears to be down at the moment.
For the time being, I wrote a pari/gp script to generate some DH test data. See https://git.lysator.liu.se/nettle/nettle/blob/curve25519/misc/ecc-ref.gp
Luckily, ecc_point_mul and ecc_point_mul_g seem to pass the new tests.
Regards, /Niels
--- I had accidentally botched the name of some of the functions and defines in gmp-glue.h in the previous iteration. ---
gmp-glue.c | 26 ++++++++++++++++++++++++++ gmp-glue.h | 26 ++++++++++++++++++++++++++ 2 files changed, 52 insertions(+)
diff --git a/gmp-glue.c b/gmp-glue.c index b468699..a2633a5 100644 --- a/gmp-glue.c +++ b/gmp-glue.c @@ -106,6 +106,32 @@ mpz_roinit_n (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs) } #endif /* !GMP_HAVE_mpz_limbs_read */
+#if !GMP_HAVE_mpn_copyd +void +mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t n) +{ + mp_size_t i; + for (i = n - 1; i >= 0; i--) + dst[i] = src[i]; +} + +void +mpn_copyi (mp_ptr dst, mp_srcptr src, mp_size_t n) +{ + mp_size_t i; + for (i = 0; i < n; i++) + dst[i] = src[i]; +} + +void +mpn_zero (mp_ptr ptr, mp_size_t n) +{ + mp_size_t i; + for (i = 0; i < n; i++) + ptr[i] = 0; +} +#endif /* !GMP_HAVE_mpn_copyd */ + /* Additional convenience functions. */
int diff --git a/gmp-glue.h b/gmp-glue.h index ef17c2f..0cde62f 100644 --- a/gmp-glue.h +++ b/gmp-glue.h @@ -33,6 +33,12 @@ #define GMP_HAVE_mpz_limbs_read 0 #endif
+#ifdef mpn_copyd +#define GMP_HAVE_mpn_copyd 1 +#else +#define GMP_HAVE_mpn_copyd 0 +#endif + #if __GNU_MP__ < 5 typedef unsigned long int mp_bitcnt_t; #endif @@ -46,6 +52,12 @@ typedef unsigned long int mp_bitcnt_t; #define mpz_roinit_n _nettle_mpz_roinit_n #endif
+#if !GMP_HAVE_mpn_copyd +#define mpn_copyd _nettle_mpn_copyd +#define mpn_copyi _nettle_mpn_copyi +#define mpn_zero _nettle_mpn_zero +#endif + #define mpz_limbs_cmp _nettle_mpz_limbs_cmp #define mpz_limbs_read_n _nettle_mpz_limbs_read_n #define mpz_limbs_copy _nettle_mpz_limbs_copy @@ -87,6 +99,20 @@ mpz_roinit_n (mpz_ptr x, const mp_limb_t *xp, mp_size_t xs);
#endif /* !GMP_HAVE_mpz_limbs_read */
+#if !GMP_HAVE_mpn_copyd +/* Copy elements, backwards */ +void +mpn_copyd (mp_ptr dst, mp_srcptr src, mp_size_t n); + +/* Copy elements, forwards */ +void +mpn_copyi (mp_ptr dst, mp_srcptr src, mp_size_t n); + +/* Zero elements */ +void +mpn_zero (mp_ptr ptr, mp_size_t n); +#endif /* !GMP_HAVE_mpn_copyd */ + /* Convenience functions */ int mpz_limbs_cmp (mpz_srcptr a, const mp_limb_t *bp, mp_size_t bn);
I'm not sure I want to add a lot of compatibility code for older gmp versions right now. I'm planning to use more new gmp function (like the mpn_cnd_add_n which I plan to make a public gmp feature). We'll see later what it takes to support older gmp versions.
Regards, /Niels
Martin Storsjö martin@martin.st writes:
--- a/Makefile.in +++ b/Makefile.in @@ -180,7 +180,7 @@ nettle_OBJS = $(nettle_SOURCES:.c=.$(OBJEXT)) $(LIBOBJS) nettle_PURE_OBJS = $(nettle_OBJS:.$(OBJEXT)=.p$(OBJEXT))
hogweed_OBJS = $(hogweed_SOURCES:.c=.$(OBJEXT)) $(OPT_ASM_SOURCES:.asm=.$(OBJEXT)) -hogweed_PURE_OBJS = $(hogweed_OBJS:.$(OBJEXT)=.p$(OBJEXT)) $(OPT_ASM_SOURCES:.asm=.p$(OBJEXT)) +hogweed_PURE_OBJS = $(hogweed_OBJS:.$(OBJEXT)=.p$(OBJEXT))
libnettle.a: $(nettle_OBJS) -rm -f $@
Checked in now. This was reported earlier (privately) by Nikos, but I didn't get the fix comitted at the time.
Regards, /Niels
nettle-bugs@lists.lysator.liu.se