From wk at gnupg.org Mon Aug 4 11:37:18 2014 From: wk at gnupg.org (Werner Koch) Date: Mon, 04 Aug 2014 11:37:18 +0200 Subject: _gcry_ath_mutex_lock: Assertion In-Reply-To: <20140730160115.GC6050@thessa> (David Goulet's message of "Wed, 30 Jul 2014 12:01:15 -0400") References: <20140730160115.GC6050@thessa> Message-ID: <871tswioj5.fsf@vigenere.g10code.de> On Wed, 30 Jul 2014 18:01, dgoulet at ev0ke.net said: > I see that in libgcrypt 1.6, it has been removed so is there a way to > avoid the issue for < 1.6 without defining NDEBUG? You mean the problem is in 1.5.3 but not in 1.6 ? What version of libgpg-error is used. I need the exact versions and whether it has been patched by Debian or you are using upstream versions. Can I look at the OTR code? Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From dgoulet at ev0ke.net Mon Aug 4 15:00:28 2014 From: dgoulet at ev0ke.net (David Goulet) Date: Mon, 4 Aug 2014 09:00:28 -0400 Subject: _gcry_ath_mutex_lock: Assertion In-Reply-To: <871tswioj5.fsf@vigenere.g10code.de> References: <20140730160115.GC6050@thessa> <871tswioj5.fsf@vigenere.g10code.de> Message-ID: <20140804130028.GA5786@thessa> On 04 Aug (11:37:18), Werner Koch wrote: > On Wed, 30 Jul 2014 18:01, dgoulet at ev0ke.net said: > > > I see that in libgcrypt 1.6, it has been removed so is there a way to > > avoid the issue for < 1.6 without defining NDEBUG? > > You mean the problem is in 1.5.3 but not in 1.6 ? Yes, sorry for the confusion. The problem is in 1.5.3 and not 1.6.x. > What version of > libgpg-error is used. I need the exact versions and whether it has been > patched by Debian or you are using upstream versions. I'm using the Debian package and the exact version of the package is: libgpg-error-dev 1.13-0.2 Debian does *not* apply patches on top, I checked. https://packages.debian.org/jessie/libgpg-error-dev > > Can I look at the OTR code? Sure, the pastebin link in the previous email shows the call stack from libotr which basically gives that: otrl_message_receiving -> otrl_proto_accept_data -> gcry_md_read (_gcry_md_read) -> md_final -> md_digest_length assert mutext lock here This happens when two threads at the same time do a otrl_message_receiving() call and end up in that code path. Top of the calling chain starts here: https://bugs.otr.im/projects/libotr/repository/revisions/master/entry/src/message.c#L922 Let me know if you need more info! :) Thanks! David > > > Salam-Shalom, > > Werner > > -- > Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 603 bytes Desc: Digital signature URL: From wk at gnupg.org Mon Aug 4 21:55:32 2014 From: wk at gnupg.org (Werner Koch) Date: Mon, 04 Aug 2014 21:55:32 +0200 Subject: _gcry_ath_mutex_lock: Assertion In-Reply-To: <20140804130028.GA5786@thessa> (David Goulet's message of "Mon, 4 Aug 2014 09:00:28 -0400") References: <20140730160115.GC6050@thessa> <871tswioj5.fsf@vigenere.g10code.de> <20140804130028.GA5786@thessa> Message-ID: <874mxsf2rv.fsf@vigenere.g10code.de> Hi, checking out the repo shows that libotr does not register thread callbacks and thus it is not supposed to work. Right, there are problems with a plugin registering thread callbacks and it would be correct if the main application does this. I am pretty sure that does not happen. The only init you do is in otrl_sm_init which is correct but not sufficient. I recall that we discussed the threading issue some years ago and it might be that you did some workaround by protecting gcry_ calls with your own mutexes. That is quite fragile. Given that you need Pthread anyway, you should change the main application to init the the threading system. However, a far better solution is to go with Libgcrypt 1.6 which uses pthreads native on Linux and the initialization task is thus much easier. 1.6. is also much faster and more cleaned up. I would really recommend to do that. There is an ABI break and thus there is no problem installing both runtime versions. Your modifications should be minimal to none (as you can see by the fact that it works with 1.6). Note that libgpg-error 1.13 added a portable Mutex API which will be used by Libgcrypt 1.7. You may opt to use it also to make libotr better portable. The libgpg-error Mutex API is a little bit slower than a native one but it is easier to work with as it does not introduce build dependencies and it is availabale anyway due to the use of Libgcrypt. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From dgoulet at ev0ke.net Mon Aug 4 22:13:07 2014 From: dgoulet at ev0ke.net (David Goulet) Date: Mon, 4 Aug 2014 16:13:07 -0400 Subject: _gcry_ath_mutex_lock: Assertion In-Reply-To: <874mxsf2rv.fsf@vigenere.g10code.de> References: <20140730160115.GC6050@thessa> <871tswioj5.fsf@vigenere.g10code.de> <20140804130028.GA5786@thessa> <874mxsf2rv.fsf@vigenere.g10code.de> Message-ID: <20140804201307.GE7801@thessa> On 04 Aug (21:55:32), Werner Koch wrote: > Hi, > > checking out the repo shows that libotr does not register thread > callbacks and thus it is not supposed to work. Right, there are > problems with a plugin registering thread callbacks and it would be > correct if the main application does this. I am pretty sure that does > not happen. Right now, with current state of libotr, it's the application job to do that which we *do* in our test client. GCRY_THREAD_OPTION_PTHREAD_IMPL; I have no ideas why libotr does not register its threading system, maybe that should change... > > The only init you do is in otrl_sm_init which is correct but not > sufficient. > > I recall that we discussed the threading issue some years ago and it > might be that you did some workaround by protecting gcry_ calls with > your own mutexes. That is quite fragile. I don't see any in libotr though. > > Given that you need Pthread anyway, you should change the main > application to init the the threading system. However, a far better > solution is to go with Libgcrypt 1.6 which uses pthreads native on Linux > and the initialization task is thus much easier. 1.6. is also much > faster and more cleaned up. I would really recommend to do that. There > is an ABI break and thus there is no problem installing both runtime > versions. Your modifications should be minimal to none (as you can see > by the fact that it works with 1.6). That's a good idea and I can work on make it happen. The problem with this is packages in distribution that supports libotr but does not have libgcrypt 1.6 but for system that do supports it, that should be done anyway. Also, libotr has never claimed to be thread safe but if it happens to be someday, is libgcrypt >= 1.6 "stamped thread safe" ? Thanks! David > > Note that libgpg-error 1.13 added a portable Mutex API which will be > used by Libgcrypt 1.7. You may opt to use it also to make libotr better > portable. The libgpg-error Mutex API is a little bit slower than a > native one but it is easier to work with as it does not introduce build > dependencies and it is availabale anyway due to the use of Libgcrypt. > > > Salam-Shalom, > > Werner > > > -- > Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 603 bytes Desc: Digital signature URL: From wk at gnupg.org Tue Aug 5 10:57:17 2014 From: wk at gnupg.org (Werner Koch) Date: Tue, 05 Aug 2014 10:57:17 +0200 Subject: _gcry_ath_mutex_lock: Assertion In-Reply-To: <20140804201307.GE7801@thessa> (David Goulet's message of "Mon, 4 Aug 2014 16:13:07 -0400") References: <20140730160115.GC6050@thessa> <871tswioj5.fsf@vigenere.g10code.de> <20140804130028.GA5786@thessa> <874mxsf2rv.fsf@vigenere.g10code.de> <20140804201307.GE7801@thessa> Message-ID: <87egwve2ky.fsf@vigenere.g10code.de> On Mon, 4 Aug 2014 22:13, dgoulet at ev0ke.net said: > Right now, with current state of libotr, it's the application job to do > that which we *do* in our test client. > > GCRY_THREAD_OPTION_PTHREAD_IMPL; I can't see that: wk at wheatstone:~/s/libotr$ git branch -v * master 3172d79 Use a constant-time memory comparison for safety. wk at wheatstone:~/s/libotr$ find . -type f | xargs grep GCRY_THREAD_OPTION wk at wheatstone:~/s/libotr$ >> I recall that we discussed the threading issue some years ago and it >> might be that you did some workaround by protecting gcry_ calls with >> your own mutexes. That is quite fragile. > > I don't see any in libotr though. I guessed that because I noticed PTHREAD_MUTEX_INITIALIZER in test_suite/otr_c_client/dummy_client.c > this is packages in distribution that supports libotr but does not have > libgcrypt 1.6 but for system that do supports it, that should be done > anyway. Well, due to the ABI change (different SO number) it is not a problem to install it in addition to 1.5.3. > Also, libotr has never claimed to be thread safe but if it happens to be > someday, is libgcrypt >= 1.6 "stamped thread safe" ? libgcrypt < 1.6 was thread safe as well. As with many libraries you were required to install callback. Since 1.6 we have /* NOTE: Since Libgcrypt 1.6 the thread callbacks are not anymore used. However we keep it to allow for some source code compatibility if used in the standard way. */ Form the manual: As mentioned earlier, the Libgcrypt library is thread-safe if you adhere to the following requirements: * If you use pthread and your applications forks and does not directly call exec (even calling stdio functions), all kind of problems may occur. Future versions of Libgcrypt will try to cleanup using pthread_atfork but even that may lead to problems. This is a common problem with almost all applications using pthread and fork. * The function `gcry_check_version' must be called before any other function in the library. To achieve this in multi-threaded programs, you must synchronize the memory with respect to other threads that also want to use Libgcrypt. For this, it is sufficient to call `gcry_check_version' before creating the other threads using Libgcrypt(1). * Just like the function `gpg_strerror', the function `gcry_strerror' is not thread safe. You have to use `gpg_strerror_r' instead. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From cvs at cvs.gnupg.org Tue Aug 5 11:57:59 2014 From: cvs at cvs.gnupg.org (by Kristian Fiskerstrand) Date: Tue, 05 Aug 2014 11:57:59 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-99-ga17c298 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via a17c29844b63e9e869f7855d901bc9d859234ead (commit) from 4556f9b19c024f16bdf542da7173395c0741b91d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit a17c29844b63e9e869f7855d901bc9d859234ead Author: Kristian Fiskerstrand Date: Tue Jul 29 19:34:31 2014 +0200 Fix building for the x32 target without asm modules. * mpi/generic/mpi-asm-defs.h: Use a fixed value for the x32 ABI. -- See commit fd6721c235a5bdcb332c8eb708fbd4f96e52e824 for details. diff --git a/mpi/generic/mpi-asm-defs.h b/mpi/generic/mpi-asm-defs.h index 13424e2..e607806 100644 --- a/mpi/generic/mpi-asm-defs.h +++ b/mpi/generic/mpi-asm-defs.h @@ -1,10 +1,8 @@ -/* This file defines some basic constants for the MPI machinery. We - * need to define the types on a per-CPU basis, so it is done with - * this file here. */ +/* This file defines some basic constants for the MPI machinery. + * AMD64 compiled for the x32 ABI is special and thus we can't use the + * standard values for this ABI. */ +#if __GNUC__ >= 3 && defined(__x86_64__) && defined(__ILP32__) +#define BYTES_PER_MPI_LIMB 8 +#else #define BYTES_PER_MPI_LIMB (SIZEOF_UNSIGNED_LONG) - - - - - - +#endif ----------------------------------------------------------------------- Summary of changes: mpi/generic/mpi-asm-defs.h | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From wk at gnupg.org Tue Aug 5 12:17:59 2014 From: wk at gnupg.org (Werner Koch) Date: Tue, 05 Aug 2014 12:17:59 +0200 Subject: [PATCH 1/2] mpi: fix code path selection for x86_64 on Darwin. In-Reply-To: <1399655185-29990-2-git-send-email-funman@videolan.org> (=?utf-8?Q?=22Rafa=C3=ABl=09Carr=C3=A9=22's?= message of "Fri, 9 May 2014 19:06:24 +0200") References: <1399655185-29990-1-git-send-email-funman@videolan.org> <1399655185-29990-2-git-send-email-funman@videolan.org> Message-ID: <871tsvdyug.fsf@vigenere.g10code.de> On Fri, 9 May 2014 19:06, funman at videolan.org said: > From: Konstantin Pavlov > > This patch fixes build error observed on current Darwin platform with asm gniibe suggested that already. I applied that patch to 1.6 and master. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From cvs at cvs.gnupg.org Tue Aug 5 12:28:54 2014 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Tue, 05 Aug 2014 12:28:54 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-102-g4ce77b0 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 4ce77b0a810d3c889c07dfb385127d90fa1ae36a (commit) via d2d28298ccc0d0f3c0b03fd323deb1e8808ef74f (commit) via 71939faa7c54e7b4b28d115e748a85f134876a02 (commit) from a17c29844b63e9e869f7855d901bc9d859234ead (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 4ce77b0a810d3c889c07dfb385127d90fa1ae36a Author: Werner Koch Date: Tue Aug 5 12:26:36 2014 +0200 mpi: Fix regression for powerpc-apple-darwin detection. * mpi/config.links: Add separate entry for powerpc-apple-darwin. -- GnuPG-bug-id: 1616 diff --git a/mpi/config.links b/mpi/config.links index 4f35ea2..f44299d 100644 --- a/mpi/config.links +++ b/mpi/config.links @@ -44,7 +44,6 @@ echo '/* created by config.links - do not edit */' >./mpi/asm-syntax.h echo "/* Host: ${host} */" >>./mpi/asm-syntax.h case "${host}" in - powerpc-apple-darwin* | \ i[34567]86*-*-openbsd[12]* | \ i[34567]86*-*-openbsd3.[0123]*) echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h @@ -284,6 +283,12 @@ case "${host}" in mpi_cpu_arch="m68k" ;; + powerpc-apple-darwin*) + echo '/* No working assembler modules available */' >>./mpi/asm-syntax.h + path="" + mpi_cpu_arch="ppc" + ;; + powerpc*-*-netbsd* | powerpc*-*-openbsd*) echo '/* configured {Open,Net}BSD on powerpc */' >>./mpi/asm-syntax.h echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h commit d2d28298ccc0d0f3c0b03fd323deb1e8808ef74f Author: Werner Koch Date: Tue Aug 5 12:15:26 2014 +0200 Fix bug inhibiting the use of the sentinel attribute. * src/gcrypt.h.in: Fix typo in macro. -- Reported-by: Rafa?l Carr? diff --git a/src/gcrypt.h.in b/src/gcrypt.h.in index a5f8350..9d64b22 100644 --- a/src/gcrypt.h.in +++ b/src/gcrypt.h.in @@ -102,7 +102,7 @@ extern "C" { #define _GCRY_GCC_ATTR_PRINTF(f,a) __attribute__ ((format (printf,f,a))) -#if _GCRT_GCC_VERSION >= 40000 +#if _GCRY_GCC_VERSION >= 40000 #define _GCRY_GCC_ATTR_SENTINEL(a) __attribute__ ((sentinel(a))) #endif commit 71939faa7c54e7b4b28d115e748a85f134876a02 Author: Werner Koch Date: Tue Aug 5 12:12:52 2014 +0200 mpi: Use BSD syntax for x86_64-apple-darwin * mpi/config.links: Add case for x86_64-apple-darwin. -- Suggested by gniibe on 2014-04-24. diff --git a/mpi/config.links b/mpi/config.links index 0217d35..4f35ea2 100644 --- a/mpi/config.links +++ b/mpi/config.links @@ -127,6 +127,12 @@ case "${host}" in path="i586 i386" mpi_cpu_arch="x86" ;; + x86_64-apple-darwin*) + echo '#define BSD_SYNTAX' >>./mpi/asm-syntax.h + cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h + path="amd64" + mpi_cpu_arch="x86" + ;; x86_64-*-*) echo '#define ELF_SYNTAX' >>./mpi/asm-syntax.h cat $srcdir/mpi/i386/syntax.h >>./mpi/asm-syntax.h ----------------------------------------------------------------------- Summary of changes: mpi/config.links | 13 ++++++++++++- src/gcrypt.h.in | 2 +- 2 files changed, 13 insertions(+), 2 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From wk at gnupg.org Tue Aug 5 12:35:17 2014 From: wk at gnupg.org (Werner Koch) Date: Tue, 05 Aug 2014 12:35:17 +0200 Subject: GCM mode and GCRY_CIPHER_AES256 In-Reply-To: <5388D5B2.6090007@nulltxt.se> (David Dahl's message of "Fri, 30 May 2014 14:02:10 -0500") References: <5387C15D.2010705@nulltxt.se> <87r43bupzb.fsf@vigenere.g10code.de> <5388D5B2.6090007@nulltxt.se> Message-ID: <87silbcjh6.fsf@vigenere.g10code.de> On Fri, 30 May 2014 21:02, ddahl at nulltxt.se said: > err = gcry_cipher_open(&handle, GCRY_CIPHER, GCRY_CIPHER_MODE, 0); Please do not define your own symbols with a GCRY|_GCRY|gcry|_gcry prefix. They are reserved by Libgcrypt. If you use them any update of Libgcrypt may break your code. Did you meanwhile found a solution for your problem or is it still open? Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Tue Aug 5 13:01:27 2014 From: wk at gnupg.org (Werner Koch) Date: Tue, 05 Aug 2014 13:01:27 +0200 Subject: Moving forward with Curve25519 (was: [PATCH] Curve25519 patch revised) In-Reply-To: <1403270939.3855.0.camel@latx1.gniibe.org> (NIIBE Yutaka's message of "Fri, 20 Jun 2014 22:28:59 +0900") References: <1403157515.2821.8.camel@cfw2.gniibe.org> <1403168653.2821.9.camel@cfw2.gniibe.org> <1403231035.2376.2.camel@cfw2.gniibe.org> <87a998ne2n.fsf@vigenere.g10code.de> <1403270939.3855.0.camel@latx1.gniibe.org> Message-ID: <87oavzci9k.fsf_-_@vigenere.g10code.de> On Fri, 20 Jun 2014 15:28, gniibe at fsij.org said: > For Montgomery curve, it doesn't compute y-coordinate, and the > representation in my current implementation is: > > 04 || X || ZERO I would suggest to use 41 || X and we are done. Simon's draft-josefsson-tls-curve25519-05 for TLS does the same. 0x41 is not used by SEC1 but it is quite similar to it. A nice property of the prefix bytes is that they avoid misintrepretation as a negative value and are thus compatible to OpenPGP MPIs. Thus my suggestion is to define these prefix bytes: 40 := Native point format of the curve follows 41 := Only X coordinate follows. 42 := Only Y coordinate follows. In GnuPG master (and libgcrypt 1.7) 0x40 is already supported for Ed25519 keys. I also working on an I-D for EdDSA (ed25519) support in OpenPGP to get an algorithm id assigned. > IIUC, draft-jivsov-ecc-compact-05 can be applied to 6637 > straightforwardly, and fingerprint (or keygrip) will be different when > representation will be changed. Is this right? Should not because we are already using the Jivsov method for key creation. However, I doubt that we need that right now and I would propose to just go forward and not wait on the IETF to decide on new curve and point representation. The whole thing is delayed way too long and there are no signs that there will be any soon decision. I am more and more convinced we should set the standard by using it. OpenSSH and several other projects settled for the Chicago curves instead of waiting until the IETF participants (where some of them work for the NSA or govt contractors) agree on something. Using the Montgomery coordinates for ECDH is just fine. If an implementation wants to use its Edwards maths it can be easily done and mapped to Montgomery coordinates. A revision of RFC-6637 can always be made and document the new compression scheme. We can also wait for an successor of RFC-4880 to obsolete the current OpenPGP RFCs. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From dgoulet at ev0ke.net Tue Aug 5 14:21:44 2014 From: dgoulet at ev0ke.net (David Goulet) Date: Tue, 5 Aug 2014 08:21:44 -0400 Subject: _gcry_ath_mutex_lock: Assertion In-Reply-To: <87egwve2ky.fsf@vigenere.g10code.de> References: <20140730160115.GC6050@thessa> <871tswioj5.fsf@vigenere.g10code.de> <20140804130028.GA5786@thessa> <874mxsf2rv.fsf@vigenere.g10code.de> <20140804201307.GE7801@thessa> <87egwve2ky.fsf@vigenere.g10code.de> Message-ID: <20140805122144.GA6233@thessa> On 05 Aug (10:57:17), Werner Koch wrote: > On Mon, 4 Aug 2014 22:13, dgoulet at ev0ke.net said: > > > Right now, with current state of libotr, it's the application job to do > > that which we *do* in our test client. > > > > GCRY_THREAD_OPTION_PTHREAD_IMPL; > > I can't see that: > > wk at wheatstone:~/s/libotr$ git branch -v > * master 3172d79 Use a constant-time memory comparison for safety. > wk at wheatstone:~/s/libotr$ find . -type f | xargs grep GCRY_THREAD_OPTION > wk at wheatstone:~/s/libotr$ Oh so sorry, I should have told you that the test suite we are developing is in an other repository! My mistake! See below. > > >> I recall that we discussed the threading issue some years ago and it > >> might be that you did some workaround by protecting gcry_ calls with > >> your own mutexes. That is quite fragile. > > > > I don't see any in libotr though. > > I guessed that because I noticed PTHREAD_MUTEX_INITIALIZER in > test_suite/otr_c_client/dummy_client.c This is obsolete, you should look at: https://bugs.otr.im/projects/libotr/repository/libotr-next/revisions/test-suites/entry/tests/regression/client/client.c#L42 > > > this is packages in distribution that supports libotr but does not have > > libgcrypt 1.6 but for system that do supports it, that should be done > > anyway. > > Well, due to the ABI change (different SO number) it is not a problem to > install it in addition to 1.5.3. Yes absolutely, just that the test suite needs to use 1.6 but we can make it happen with some autoconf magic :). With 1.5.3, we are hitting this original issue of this thread very fast! with two threads which I had to use a mutex to synchronize the calls to libotr. https://bugs.otr.im/projects/libotr/repository/libotr-next/revisions/test-suites/entry/tests/regression/client/client.c#L86 This workaround is ok for now. I'll make it work with 1.6 and see if I can remove that lock. > > > Also, libotr has never claimed to be thread safe but if it happens to be > > someday, is libgcrypt >= 1.6 "stamped thread safe" ? > > libgcrypt < 1.6 was thread safe as well. As with many libraries you > were required to install callback. Since 1.6 we have > > /* NOTE: Since Libgcrypt 1.6 the thread callbacks are not anymore > used. However we keep it to allow for some source code > compatibility if used in the standard way. */ > > Form the manual: > > As mentioned earlier, the Libgcrypt library is thread-safe if you > adhere to the following requirements: > > * If you use pthread and your applications forks and does not > directly call exec (even calling stdio functions), all kind of > problems may occur. Future versions of Libgcrypt will try to > cleanup using pthread_atfork but even that may lead to problems. > This is a common problem with almost all applications using > pthread and fork. > > * The function `gcry_check_version' must be called before any other > function in the library. To achieve this in multi-threaded > programs, you must synchronize the memory with respect to other > threads that also want to use Libgcrypt. For this, it is > sufficient to call `gcry_check_version' before creating the other > threads using Libgcrypt(1). > > * Just like the function `gpg_strerror', the function > `gcry_strerror' is not thread safe. You have to use > `gpg_strerror_r' instead. > Ah superb! This is very helpful, much appreciate! Cheers! David > > > Shalom-Salam, > > Werner > > -- > Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 603 bytes Desc: Digital signature URL: From openpgp at brainhub.org Wed Aug 6 00:40:50 2014 From: openpgp at brainhub.org (Andrey Jivsov) Date: Tue, 05 Aug 2014 15:40:50 -0700 Subject: Moving forward with Curve25519 In-Reply-To: <87oavzci9k.fsf_-_@vigenere.g10code.de> References: <1403157515.2821.8.camel@cfw2.gniibe.org> <1403168653.2821.9.camel@cfw2.gniibe.org> <1403231035.2376.2.camel@cfw2.gniibe.org> <87a998ne2n.fsf@vigenere.g10code.de> <1403270939.3855.0.camel@latx1.gniibe.org> <87oavzci9k.fsf_-_@vigenere.g10code.de> Message-ID: <53E15D72.3030202@brainhub.org> On 08/05/2014 04:01 AM, Werner Koch wrote: > On Fri, 20 Jun 2014 15:28, gniibe at fsij.org said: > >> For Montgomery curve, it doesn't compute y-coordinate, and the >> representation in my current implementation is: >> >> 04 || X || ZERO > > I would suggest to use > > 41 || X > > and we are done. Simon's draft-josefsson-tls-curve25519-05 for TLS does > the same. > > 0x41 is not used by SEC1 but it is quite similar to it. A nice property > of the prefix bytes is that they avoid misintrepretation as a negative > value and are thus compatible to OpenPGP MPIs. Thus my suggestion is to > define these prefix bytes: > > 40 := Native point format of the curve follows > 41 := Only X coordinate follows. > 42 := Only Y coordinate follows. For all protocols that I know, including OpenPGP, the Y coordinate is not used in the calculation of the shared secret in ECDH. This is especially true for Curve25519 ECDH, which uses Montgomery curve in the original paper, given that the Montgomery formulas don't even compute Y. To compute the Y one needs to move an X into an isogenous curve, such as EC25519, and use Edwards formulas there. You typically need Y if you depend on the exact sign of the point, which is needed when you add points, but ECDH doesn't do point additions. Assuming that there is no interest here to represent Curve25519 point used for encryption with anything but a point on the Montgomery curve, in the original representation, sending anything but X for ECDH is a (small) waste of space and the need to commit to yet another tag. X has aesthetically pleasing 32 byte size. X is an integer, which fits perfectly into the OpenPGP container, which is an MPI. I think that OpenPGP should adopt X as the format for the ECDH. This works with Curve25519 encryption or any other ECDH scheme. Because "just X" is the minimal representation (i.e. the size is never more than 256 bits), this is an unambiguous encoding. It means "if you need Y, go and calculate it yourself". http://tools.ietf.org/html/draft-jivsov-ecc-compact provides one unambiguous method to know the other coordinate from this minimal format, but, as mentioned above, this is not needed for ECDH. ( Besides, the value 41 or 42 is implied by the curve OID in the following way. If we are talking about encryption and the OID is Curve25519, you know it's 41. The value 40 v.s. {41,42} is implied by the curveID and the size of the MPI. ) Thank you. > > In GnuPG master (and libgcrypt 1.7) 0x40 is already supported for > Ed25519 keys. I also working on an I-D for EdDSA (ed25519) support in > OpenPGP to get an algorithm id assigned. > >> IIUC, draft-jivsov-ecc-compact-05 can be applied to 6637 >> straightforwardly, and fingerprint (or keygrip) will be different when >> representation will be changed. Is this right? > > Should not because we are already using the Jivsov method for key > creation. > > However, I doubt that we need that right now and I would propose to just > go forward and not wait on the IETF to decide on new curve and point > representation. The whole thing is delayed way too long and there are > no signs that there will be any soon decision. I am more and more > convinced we should set the standard by using it. OpenSSH and several > other projects settled for the Chicago curves instead of waiting until > the IETF participants (where some of them work for the NSA or govt > contractors) agree on something. > > Using the Montgomery coordinates for ECDH is just fine. If an > implementation wants to use its Edwards maths it can be easily done and > mapped to Montgomery coordinates. A revision of RFC-6637 can always be > made and document the new compression scheme. We can also wait for an > successor of RFC-4880 to obsolete the current OpenPGP RFCs. > > > Shalom-Salam, > > Werner > From wk at gnupg.org Wed Aug 6 09:21:46 2014 From: wk at gnupg.org (Werner Koch) Date: Wed, 06 Aug 2014 09:21:46 +0200 Subject: _gcry_ath_mutex_lock: Assertion In-Reply-To: <20140805122144.GA6233@thessa> (David Goulet's message of "Tue, 5 Aug 2014 08:21:44 -0400") References: <20140730160115.GC6050@thessa> <871tswioj5.fsf@vigenere.g10code.de> <20140804130028.GA5786@thessa> <874mxsf2rv.fsf@vigenere.g10code.de> <20140804201307.GE7801@thessa> <87egwve2ky.fsf@vigenere.g10code.de> <20140805122144.GA6233@thessa> Message-ID: <874mxq5bhx.fsf@vigenere.g10code.de> On Tue, 5 Aug 2014 14:21, dgoulet at ev0ke.net said: > https://bugs.otr.im/projects/libotr/repository/libotr-next/revisions/test-suites/entry/tests/regression/client/client.c#L42 Thanks. However, I can't find a gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); anywhere in the test-suite or master branches. The GCRY_THREAD_OPTION_PTHREAD_IMPL; defines the gcry_threads_pthread structure which then needs to be passed to the above gcry_control call. This is all described in the manual, but take care to read the 1.5 manual and not the 1.6 where this is not anymore needed and thus not described. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Wed Aug 6 09:53:19 2014 From: wk at gnupg.org (Werner Koch) Date: Wed, 06 Aug 2014 09:53:19 +0200 Subject: Moving forward with Curve25519 In-Reply-To: <53E15D72.3030202@brainhub.org> (Andrey Jivsov's message of "Tue, 05 Aug 2014 15:40:50 -0700") References: <1403157515.2821.8.camel@cfw2.gniibe.org> <1403168653.2821.9.camel@cfw2.gniibe.org> <1403231035.2376.2.camel@cfw2.gniibe.org> <87a998ne2n.fsf@vigenere.g10code.de> <1403270939.3855.0.camel@latx1.gniibe.org> <87oavzci9k.fsf_-_@vigenere.g10code.de> <53E15D72.3030202@brainhub.org> Message-ID: <87zjfi3vgw.fsf@vigenere.g10code.de> On Wed, 6 Aug 2014 00:40, openpgp at brainhub.org said: > For all protocols that I know, including OpenPGP, the Y coordinate is > not used in the calculation of the shared secret in ECDH. This is Sure. I mentioned 0x42 only for completeness. We do not need it. > X has aesthetically pleasing 32 byte size. X is an integer, which fits > perfectly into the OpenPGP container, which is an MPI. Only 50% of those values would fit as 32 bytes into an OpenPGP MPI. As soon as the high bit is set we should prefix it with a 0x00 byte to avoid signed/unsigned problems. Further, OpenPGP _requires_ us to strip off leading zero bytes. Thus there won't be a fixed length anyway. Using a constant prefix makes things easy. With the prefix byte we always have 35 bytes (2 bytes length, 1 byte prefix, and 32 byte value) and the length will always be 263 (bits). This allows to keep the code very small by writing or reading the constant string 0x01,0x07,0x40 which is the followed by the 32 bytes for X. And other implementations may use the regular MPI machinery for processing the data. Actually you did the same in RFC-6637 by requiring the 0x04 prefix. > I think that OpenPGP should adopt X as the format for the ECDH. This > works with Curve25519 encryption or any other ECDH scheme. I concur. > ( Besides, the value 41 or 42 is implied by the curve OID in the > following way. If we are talking about encryption and the OID is > Curve25519, you know it's 41. The value 40 v.s. {41,42} is implied by > the curveID and the size of the MPI. ) Sure. I actually considered to make that implicit by either the OID or even by looking at the size of the MPI and map that to a certain curve. However, this breaks with the existing ECC format and has is slightly annoying in that we do not known in advance what will come. (We have a similar problem with the IV for the key protection which depends on the block length of the cipher algorithm; if you do not known that algorithm you can't properly parse the packet). A more compact key representation would be useful but I do not think we should do that with v4 packets. If we need a shorter key presentation we can do that outside of OpenPGP. For example in a QR code we may want a different encoding of the key data (e.g. human readable with checksum). Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From gniibe at fsij.org Wed Aug 6 11:20:16 2014 From: gniibe at fsij.org (NIIBE Yutaka) Date: Wed, 06 Aug 2014 18:20:16 +0900 Subject: Moving forward with Curve25519 (was: [PATCH] Curve25519 patch revised) In-Reply-To: <87oavzci9k.fsf_-_@vigenere.g10code.de> References: <1403157515.2821.8.camel@cfw2.gniibe.org> <1403168653.2821.9.camel@cfw2.gniibe.org> <1403231035.2376.2.camel@cfw2.gniibe.org> <87a998ne2n.fsf@vigenere.g10code.de> <1403270939.3855.0.camel@latx1.gniibe.org> <87oavzci9k.fsf_-_@vigenere.g10code.de> Message-ID: <1407316816.1341.1.camel@latx1.gniibe.org> On 2014-08-05 at 13:01 +0200, Werner Koch wrote: > I would suggest to use > > 41 || X > > and we are done. Simon's draft-josefsson-tls-curve25519-05 for TLS does > the same. Please clarify: X in MPI? In draft-josefsson-tls-curve25519-05, it seems that it's in original format (little endian). > 0x41 is not used by SEC1 but it is quite similar to it. A nice property > of the prefix bytes is that they avoid misintrepretation as a negative > value and are thus compatible to OpenPGP MPIs. Thus my suggestion is to > define these prefix bytes: > > 40 := Native point format of the curve follows > 41 := Only X coordinate follows. > 42 := Only Y coordinate follows. > > In GnuPG master (and libgcrypt 1.7) 0x40 is already supported for > Ed25519 keys. I also working on an I-D for EdDSA (ed25519) support in > OpenPGP to get an algorithm id assigned. And prefix 0x40 for Curve25519 ECDH is in original format? -- From wk at gnupg.org Wed Aug 6 13:59:31 2014 From: wk at gnupg.org (Werner Koch) Date: Wed, 06 Aug 2014 13:59:31 +0200 Subject: Moving forward with Curve25519 In-Reply-To: <1407316816.1341.1.camel@latx1.gniibe.org> (NIIBE Yutaka's message of "Wed, 06 Aug 2014 18:20:16 +0900") References: <1403157515.2821.8.camel@cfw2.gniibe.org> <1403168653.2821.9.camel@cfw2.gniibe.org> <1403231035.2376.2.camel@cfw2.gniibe.org> <87a998ne2n.fsf@vigenere.g10code.de> <1403270939.3855.0.camel@latx1.gniibe.org> <87oavzci9k.fsf_-_@vigenere.g10code.de> <1407316816.1341.1.camel@latx1.gniibe.org> Message-ID: <87r40t4yn0.fsf@vigenere.g10code.de> On Wed, 6 Aug 2014 11:20, gniibe at fsij.org said: > Please clarify: X in MPI? > > In draft-josefsson-tls-curve25519-05, it seems that it's in original > format (little endian). I would use whatever has been specified for the curve. Or well in this case in the software describing the use of the curve. I have not checked but I am pretty sure that OpenSSH uses the native (i.e. littel endian format). So let's define it as 0x41 || X_in_native_format > And prefix 0x40 for Curve25519 ECDH is in original format? 0x40 || X_and_Y_in_native_format If Curve25519 specifies its own compressed format (does it?) that would be that format. If it does not define a compressed format it would be the full point in the format defined for the Curve25519. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From dgoulet at ev0ke.net Wed Aug 6 15:07:41 2014 From: dgoulet at ev0ke.net (David Goulet) Date: Wed, 6 Aug 2014 09:07:41 -0400 Subject: _gcry_ath_mutex_lock: Assertion In-Reply-To: <874mxq5bhx.fsf@vigenere.g10code.de> References: <20140730160115.GC6050@thessa> <871tswioj5.fsf@vigenere.g10code.de> <20140804130028.GA5786@thessa> <874mxsf2rv.fsf@vigenere.g10code.de> <20140804201307.GE7801@thessa> <87egwve2ky.fsf@vigenere.g10code.de> <20140805122144.GA6233@thessa> <874mxq5bhx.fsf@vigenere.g10code.de> Message-ID: <20140806130741.GA6085@thessa> On 06 Aug (09:21:46), Werner Koch wrote: > On Tue, 5 Aug 2014 14:21, dgoulet at ev0ke.net said: > > > https://bugs.otr.im/projects/libotr/repository/libotr-next/revisions/test-suites/entry/tests/regression/client/client.c#L42 > > Thanks. However, I can't find a > > gcry_control (GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); My mistake! I confirm that fixes the bug. I just ran an hour of stress test and I can't hit that anymore. :) Also, I've tried on libgcrypt 1.6 and it's also fixed! We have a small problem in one unit test with it but I have to investiguate more, it seems a different return code is sent back for otrl signature verification on error. Anyhow, big thanks for your help! David > > anywhere in the test-suite or master branches. The > > GCRY_THREAD_OPTION_PTHREAD_IMPL; > > defines the gcry_threads_pthread structure which then needs to be passed > to the above gcry_control call. This is all described in the manual, > but take care to read the 1.5 manual and not the 1.6 where this is not > anymore needed and thus not described. > > > Salam-Shalom, > > Werner > > -- > Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. > -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 603 bytes Desc: Digital signature URL: From openpgp at brainhub.org Wed Aug 6 19:29:17 2014 From: openpgp at brainhub.org (Andrey Jivsov) Date: Wed, 06 Aug 2014 10:29:17 -0700 Subject: Moving forward with Curve25519 In-Reply-To: <87zjfi3vgw.fsf@vigenere.g10code.de> References: <1403157515.2821.8.camel@cfw2.gniibe.org> <1403168653.2821.9.camel@cfw2.gniibe.org> <1403231035.2376.2.camel@cfw2.gniibe.org> <87a998ne2n.fsf@vigenere.g10code.de> <1403270939.3855.0.camel@latx1.gniibe.org> <87oavzci9k.fsf_-_@vigenere.g10code.de> <53E15D72.3030202@brainhub.org> <87zjfi3vgw.fsf@vigenere.g10code.de> Message-ID: <53E265ED.5030804@brainhub.org> On 08/06/2014 12:53 AM, Werner Koch wrote: > On Wed, 6 Aug 2014 00:40, openpgp at brainhub.org said: > >> For all protocols that I know, including OpenPGP, the Y coordinate is >> not used in the calculation of the shared secret in ECDH. This is > > Sure. I mentioned 0x42 only for completeness. We do not need it. > >> X has aesthetically pleasing 32 byte size. X is an integer, which fits >> perfectly into the OpenPGP container, which is an MPI. > > Only 50% of those values would fit as 32 bytes into an OpenPGP MPI. As > soon as the high bit is set we should prefix it with a 0x00 byte to > avoid signed/unsigned problems. Further, OpenPGP _requires_ us to strip > off leading zero bytes. Thus there won't be a fixed length anyway. > Hello Werner. Curve25519 always has the high bit set to zero because it fits into 255 bits. ( For ECDH anyway; one may in theory reuse the high bit for something else if needed, but OpenPGP can standardize that the high bit is always zero ) To show how what I proposed always works, let's say we are encoding some Curve256189 (a similar prime closest to 2^256). In this case the point representation still fits into 32 bytes and the highest bit of the 32 byte can be 1. In OpenPGP these 32 bytes are encoded as an MPI. MPI in OpenPGP encodes the size in bits, counting from the most significant bit (MSB). If the MSB of a particular point is bit 250, that's fine. There is even an advantage with the format I am proposing in that one can realize even greater space savings by trial-generating public EC keys so that they have high bits as zeros. This will allow the MPI encoding to fit into smaller number of octets. We cannot do this when we prefix an integer with a tag value, because the tag value will assure that the high bits are set. In more details, the selection criteria that I mentioned earlier work as follows. If the tag is used, a 255-bit MPI cannot be encoded in fewer than 256 bits, while it will be fewer than 256 bits in case of the Curve25519. > Using a constant prefix makes things easy. With the prefix byte we > always have 35 bytes (2 bytes length, 1 byte prefix, and 32 byte value) > and the length will always be 263 (bits). This allows to keep the code > very small by writing or reading the constant string 0x01,0x07,0x40 > which is the followed by the 32 bytes for X. And other implementations > may use the regular MPI machinery for processing the data. > > Actually you did the same in RFC-6637 by requiring the 0x04 prefix. This was for two reasons that don't apply to Curve25519: 1. patents 2. there is a ~5% cost to decompress a point on short Weierstrass curves (NIST Suite-B curves, Brainpool curves). #1: never applied to ECDH, definitely doesn't apply in 2014. #2: Montgomery curves don't need Y, thus there is no cost of decompression. > >> I think that OpenPGP should adopt X as the format for the ECDH. This >> works with Curve25519 encryption or any other ECDH scheme. > > I concur. > >> ( Besides, the value 41 or 42 is implied by the curve OID in the >> following way. If we are talking about encryption and the OID is >> Curve25519, you know it's 41. The value 40 v.s. {41,42} is implied by >> the curveID and the size of the MPI. ) > > Sure. I actually considered to make that implicit by either the OID or > even by looking at the size of the MPI and map that to a certain curve. > However, this breaks with the existing ECC format and has is slightly > annoying in that we do not known in advance what will come. One has to switch either by the tag or by the size of MPI. I think the logic based on MPI size is clear enough (if MPI size in bits <= 255 ==> only X is used). Support for multiple formats causes complexity. Given what we know now about modern curves, I think the default should be an uncompressed point. This is the case we should optimize for. (We have a > similar problem with the IV for the key protection which depends on the > block length of the cipher algorithm; if you do not known that algorithm > you can't properly parse the packet). It makes little sense to talk about "uncompressed" Montgomery point. We should have a single blessed format, and it's clearly a "compressed" one. (There is some argument to say that the format should be an Edwards representation so that keys can be used for both DH and signatures. However, in all cases the standard should probably be some "compressed" form). > > A more compact key representation would be useful but I do not think we > should do that with v4 packets. If we need a shorter key presentation > we can do that outside of OpenPGP. For example in a QR code we may want > a different encoding of the key data (e.g. human readable with checksum). True, there are applications where short keys are important. 32 byte keys are short enough that humans can handle them (i.e. type them encoded in base32 format, read them, and it's easier to scan them too). The abovementioned method to reduce the size of a public key makes this a bit easier for humans. Thank you > > > > Shalom-Salam, > > Werner > From wk at gnupg.org Wed Aug 6 21:04:43 2014 From: wk at gnupg.org (Werner Koch) Date: Wed, 06 Aug 2014 21:04:43 +0200 Subject: _gcry_ath_mutex_lock: Assertion In-Reply-To: <20140806130741.GA6085@thessa> (David Goulet's message of "Wed, 6 Aug 2014 09:07:41 -0400") References: <20140730160115.GC6050@thessa> <871tswioj5.fsf@vigenere.g10code.de> <20140804130028.GA5786@thessa> <874mxsf2rv.fsf@vigenere.g10code.de> <20140804201307.GE7801@thessa> <87egwve2ky.fsf@vigenere.g10code.de> <20140805122144.GA6233@thessa> <874mxq5bhx.fsf@vigenere.g10code.de> <20140806130741.GA6085@thessa> Message-ID: <874mxp30dw.fsf@vigenere.g10code.de> On Wed, 6 Aug 2014 15:07, dgoulet at ev0ke.net said: > Anyhow, big thanks for your help! I am pleased to help with one of my favorite tools. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From gniibe at fsij.org Thu Aug 7 07:47:27 2014 From: gniibe at fsij.org (NIIBE Yutaka) Date: Thu, 07 Aug 2014 14:47:27 +0900 Subject: [PATCH] Curve25519 patch revised In-Reply-To: <87iomq3est.fsf@vigenere.g10code.de> References: <1403157515.2821.8.camel@cfw2.gniibe.org> <1403168653.2821.9.camel@cfw2.gniibe.org> <1403231035.2376.2.camel@cfw2.gniibe.org> <87a998ne2n.fsf@vigenere.g10code.de> <1403270939.3855.0.camel@latx1.gniibe.org> <1405498318.20960.1.camel@cfw2.gniibe.org> <1405519330.3778.0.camel@latx1.gniibe.org> <87iomq3est.fsf@vigenere.g10code.de> Message-ID: <1407390447.1549.6.camel@cfw2.gniibe.org> On 2014-07-21 at 17:35 +0200, Werner Koch wrote: > On Wed, 16 Jul 2014 16:02, gniibe at fsij.org said: > > Here is a patch adding cofactor to the domain parameters of ECC. > > > > Note that this introduce KEYGRIP value change. > > That is bad. Why not exclude it from the keygrip computation? I see, excluding the cofactor is better (to be compatible). Here is the patch keeping compute_keygrip untouched. OK to commit? diff --git a/cipher/ecc-common.h b/cipher/ecc-common.h index f066b4b..83bf20d 100644 --- a/cipher/ecc-common.h +++ b/cipher/ecc-common.h @@ -32,6 +32,7 @@ typedef struct or d as used by Twisted Edwards curves. */ mpi_point_struct G; /* Base point (generator). */ gcry_mpi_t n; /* Order of G. */ + gcry_mpi_t h; /* Cofactor. */ const char *name; /* Name of the curve or NULL. */ } elliptic_curve_t; @@ -75,7 +76,7 @@ gpg_err_code_t _gcry_ecc_update_curve_param (const char *name, enum ecc_dialects *dialect, gcry_mpi_t *p, gcry_mpi_t *a, gcry_mpi_t *b, gcry_mpi_t *g, - gcry_mpi_t *n); + gcry_mpi_t *n, gcry_mpi_t *h); const char *_gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c index cd85361..fd47c1d 100644 --- a/cipher/ecc-curves.c +++ b/cipher/ecc-curves.c @@ -110,6 +110,7 @@ typedef struct Curves b is used for d. */ const char *n; /* The order of the base point. */ const char *g_x, *g_y; /* Base point. */ + const char *h; /* Cofactor. */ } ecc_domain_parms_t; @@ -125,7 +126,8 @@ static const ecc_domain_parms_t domain_parms[] = "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", - "0x6666666666666666666666666666666666666666666666666666666666666658" + "0x6666666666666666666666666666666666666666666666666666666666666658", + "0x08" }, #if 0 /* No real specs yet found. */ { @@ -140,7 +142,8 @@ static const ecc_domain_parms_t domain_parms[] = "706022B36F1C0338AD63CF181B0E71A5E106AF79", "0x1A334905141443300218C0631C326E5FCD46369F44C03EC7F57FF35498A4AB4D" "6D6BA111301A73FAA8537C64C4FD3812F3CBC595", - "0x22" + "0x22", + "0x08" }, #endif /*0*/ { @@ -152,7 +155,8 @@ static const ecc_domain_parms_t domain_parms[] = "0xffffffffffffffffffffffff99def836146bc9b1b4d22831", "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", - "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811" + "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811", + "0x01" }, { "NIST P-224", 224, 1, @@ -163,7 +167,8 @@ static const ecc_domain_parms_t domain_parms[] = "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" , "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", - "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34" + "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", + "0x01" }, { "NIST P-256", 256, 1, @@ -174,7 +179,8 @@ static const ecc_domain_parms_t domain_parms[] = "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" + "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "0x01" }, { "NIST P-384", 384, 1, @@ -191,7 +197,8 @@ static const ecc_domain_parms_t domain_parms[] = "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" "5502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" - "0a60b1ce1d7e819d7a431d7c90ea0e5f" + "0a60b1ce1d7e819d7a431d7c90ea0e5f", + "0x01" }, { "NIST P-521", 521, 1, @@ -208,7 +215,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d" "3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e" - "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" + "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", + "0x01" }, { "brainpoolP160r1", 160, 0, @@ -218,7 +226,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x1e589a8595423412134faa2dbdec95c8d8675e58", "0xe95e4a5f737059dc60df5991d45029409e60fc09", "0xbed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3", - "0x1667cb477a1a8ec338f94741669c976316da6321" + "0x1667cb477a1a8ec338f94741669c976316da6321", + "0x01" }, { "brainpoolP192r1", 192, 0, @@ -228,7 +237,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x469a28ef7c28cca3dc721d044f4496bcca7ef4146fbf25c9", "0xc302f41d932a36cda7a3462f9e9e916b5be8f1029ac4acc1", "0xc0a0647eaab6a48753b033c56cb0f0900a2f5c4853375fd6", - "0x14b690866abd5bb88b5f4828c1490002e6773fa2fa299b8f" + "0x14b690866abd5bb88b5f4828c1490002e6773fa2fa299b8f", + "0x01" }, { "brainpoolP224r1", 224, 0, @@ -238,7 +248,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x2580f63ccfe44138870713b1a92369e33e2135d266dbb372386c400b", "0xd7c134aa264366862a18302575d0fb98d116bc4b6ddebca3a5a7939f", "0x0d9029ad2c7e5cf4340823b2a87dc68c9e4ce3174c1e6efdee12c07d", - "0x58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd" + "0x58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd", + "0x01" }, { "brainpoolP256r1", 256, 0, @@ -248,7 +259,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6", "0xa9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7", "0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262", - "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997" + "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997", + "0x01" }, { "brainpoolP320r1", 320, 0, @@ -264,7 +276,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x43bd7e9afb53d8b85289bcc48ee5bfe6f20137d10a087eb6e7871e2a10a599c7" "10af8d0d39e20611", "0x14fdd05545ec1cc8ab4093247f77275e0743ffed117182eaa9c77877aaac6ac7" - "d35245d1692e8ee1" + "d35245d1692e8ee1", + "0x01" }, { "brainpoolP384r1", 384, 0, @@ -280,7 +293,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8" "e826e03436d646aaef87b2e247d4af1e", "0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff9912928" - "0e4646217791811142820341263c5315" + "0e4646217791811142820341263c5315", + "0x01" }, { "brainpoolP512r1", 512, 0, @@ -296,7 +310,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098e" "ff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822", "0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111" - "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892" + "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892", + "0x01" }, { "GOST2001-test", 256, 0, @@ -308,6 +323,7 @@ static const ecc_domain_parms_t domain_parms[] = "0x0000000000000000000000000000000000000000000000000000000000000002", "0x08e2a8a0e65147d4bd6316030e16d19c85c97f0a9ca267122b96abbcea7e8fc8", + "0x01" }, { "GOST2001-CryptoPro-A", 256, 0, @@ -317,7 +333,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x00000000000000000000000000000000000000000000000000000000000000a6", "0xffffffffffffffffffffffffffffffff6c611070995ad10045841b09b761b893", "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x8d91e471e0989cda27df505a453f2b7635294f2ddf23e3b122acc99c9e9f1e14" + "0x8d91e471e0989cda27df505a453f2b7635294f2ddf23e3b122acc99c9e9f1e14", + "0x01" }, { "GOST2001-CryptoPro-B", 256, 0, @@ -327,7 +344,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x3e1af419a269a5f866a7d3c25c3df80ae979259373ff2b182f49d4ce7e1bbc8b", "0x800000000000000000000000000000015f700cfff1a624e5e497161bcc8a198f", "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x3fa8124359f96680b83d1c3eb2c070e5c545c9858d03ecfb744bf8d717717efc" + "0x3fa8124359f96680b83d1c3eb2c070e5c545c9858d03ecfb744bf8d717717efc", + "0x01" }, { "GOST2001-CryptoPro-C", 256, 0, @@ -337,7 +355,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x000000000000000000000000000000000000000000000000000000000000805a", "0x9b9f605f5a858107ab1ec85e6b41c8aa582ca3511eddfb74f02f3a6598980bb9", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x41ece55743711a8c3cbf3783cd08c0ee4d4dc440d4641a8f366e550dfdb3bb67" + "0x41ece55743711a8c3cbf3783cd08c0ee4d4dc440d4641a8f366e550dfdb3bb67", + "0x01" }, { "GOST2012-test", 511, 0, @@ -354,6 +373,7 @@ static const ecc_domain_parms_t domain_parms[] = "fd60611262cd838dc6b60aa7eee804e28bc849977fac33b4b530f1b120248a9a", "0x2bb312a43bd2ce6e0d020613c857acddcfbf061e91e5f2c3f32447c259f39b2" "c83ab156d77f1496bf7eb3351e1ee4e43dc1a18b91b24640b6dbb92cb1add371e", + "0x01" }, { "GOST2012-tc26-A", 512, 0, @@ -370,6 +390,7 @@ static const ecc_domain_parms_t domain_parms[] = "0000000000000000000000000000000000000000000000000000000000000003", "0x7503cfe87a836ae3a61b8816e25450e6ce5e1c93acf1abc1778064fdcbefa921" "df1626be4fd036e93d75e6a50e3a41e98028fe5fc235f5b889a589cb5215f2a4", + "0x01" }, { "GOST2012-tc26-B", 512, 0, @@ -386,6 +407,7 @@ static const ecc_domain_parms_t domain_parms[] = "0000000000000000000000000000000000000000000000000000000000000002", "0x1a8f7eda389b094c2c071e3647a8940f3c123b697578c213be6dd9e6c8ec7335" "dcb228fd1edf4a39152cbcaaf8c0398828041055f94ceeec7e21340780fe41bd", + "0x01" }, { @@ -396,10 +418,11 @@ static const ecc_domain_parms_t domain_parms[] = "0x0000000000000000000000000000000000000000000000000000000000000007", "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", - "0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8" + "0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", + "0x01" }, - { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL } + { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } }; @@ -530,6 +553,8 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, curve->b = scanval (domain_parms[idx].b); if (!curve->n) curve->n = scanval (domain_parms[idx].n); + if (!curve->h) + curve->h = scanval (domain_parms[idx].h); if (!curve->G.x) curve->G.x = scanval (domain_parms[idx].g_x); if (!curve->G.y) @@ -545,7 +570,7 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, /* Give the name of the curve NAME, store the curve parameters into P, - A, B, G, and N if they point to NULL value. Note that G is returned + A, B, G, N, and H if they point to NULL value. Note that G is returned in standard uncompressed format. Also update MODEL and DIALECT if they are not NULL. */ gpg_err_code_t @@ -553,7 +578,7 @@ _gcry_ecc_update_curve_param (const char *name, enum gcry_mpi_ec_models *model, enum ecc_dialects *dialect, gcry_mpi_t *p, gcry_mpi_t *a, gcry_mpi_t *b, - gcry_mpi_t *g, gcry_mpi_t *n) + gcry_mpi_t *g, gcry_mpi_t *n, gcry_mpi_t *h) { int idx; @@ -603,6 +628,11 @@ _gcry_ecc_update_curve_param (const char *name, _gcry_mpi_release (*n); *n = scanval (domain_parms[idx].n); } + if (h) + { + _gcry_mpi_release (*h); + *h = scanval (domain_parms[idx].h); + } return 0; } @@ -640,8 +670,8 @@ _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) /* * Extract the curve parameters.. */ - rc = gpg_err_code (sexp_extract_param (keyparms, NULL, "-pabgn", - &E.p, &E.a, &E.b, &mpi_g, &E.n, + rc = gpg_err_code (sexp_extract_param (keyparms, NULL, "-pabgnh", + &E.p, &E.a, &E.b, &mpi_g, &E.n, &E.h, NULL)); if (rc == GPG_ERR_NO_OBJ) { @@ -699,17 +729,22 @@ _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) if (!mpi_cmp (tmp, E.n)) { mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_x); - if (!mpi_cmp (tmp, E.G.x)) + tmp = scanval (domain_parms[idx].h); + if (!mpi_cmp (tmp, E.h)) { mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_y); - if (!mpi_cmp (tmp, E.G.y)) + tmp = scanval (domain_parms[idx].g_x); + if (!mpi_cmp (tmp, E.G.x)) { - result = domain_parms[idx].desc; - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - goto leave; + mpi_free (tmp); + tmp = scanval (domain_parms[idx].g_y); + if (!mpi_cmp (tmp, E.G.y)) + { + result = domain_parms[idx].desc; + if (r_nbits) + *r_nbits = domain_parms[idx].nbits; + goto leave; + } } } } @@ -726,6 +761,7 @@ _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) _gcry_mpi_release (mpi_g); _gcry_mpi_point_free_parts (&E.G); _gcry_mpi_release (E.n); + _gcry_mpi_release (E.h); return result; } @@ -857,6 +893,7 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, gcry_mpi_t b = NULL; gcry_mpi_point_t G = NULL; gcry_mpi_t n = NULL; + gcry_mpi_t h = NULL; gcry_mpi_point_t Q = NULL; gcry_mpi_t d = NULL; int flags = 0; @@ -899,6 +936,9 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, errc = mpi_from_keyparam (&n, keyparam, "n"); if (errc) goto leave; + errc = mpi_from_keyparam (&h, keyparam, "h"); + if (errc) + goto leave; } } else @@ -972,6 +1012,11 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, n = E->n; E->n = NULL; } + if (!h) + { + h = E->h; + E->h = NULL; + } _gcry_ecc_curve_free (E); xfree (E); } @@ -998,6 +1043,11 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, ec->n = n; n = NULL; } + if (h) + { + ec->h = h; + h = NULL; + } /* Now that we know the curve name we can look for the public key Q. point_from_keyparam needs to know the curve parameters so @@ -1036,6 +1086,7 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, mpi_free (b); _gcry_mpi_point_release (G); mpi_free (n); + mpi_free (h); _gcry_mpi_point_release (Q); mpi_free (d); return errc; @@ -1050,7 +1101,7 @@ _gcry_ecc_get_param_sexp (const char *name) elliptic_curve_t E; mpi_ec_t ctx; gcry_mpi_t g_x, g_y; - gcry_mpi_t pkey[6]; + gcry_mpi_t pkey[7]; gcry_sexp_t result; int i; @@ -1074,14 +1125,15 @@ _gcry_ecc_get_param_sexp (const char *name) pkey[2] = E.b; pkey[3] = _gcry_ecc_ec2os (g_x, g_y, E.p); pkey[4] = E.n; - pkey[5] = NULL; + pkey[5] = E.h; + pkey[6] = NULL; mpi_free (g_x); mpi_free (g_y); if (sexp_build (&result, NULL, - "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))", - pkey[0], pkey[1], pkey[2], pkey[3], pkey[4])) + "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)))", + pkey[0], pkey[1], pkey[2], pkey[3], pkey[4], pkey[5])) result = NULL; for (i=0; pkey[i]; i++) @@ -1108,6 +1160,8 @@ _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b); if (!strcmp (name, "n") && ec->n) return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n); + if (!strcmp (name, "h") && ec->h) + return mpi_is_const (ec->h) && !copy? ec->h : mpi_copy (ec->h); if (!strcmp (name, "d") && ec->d) return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d); @@ -1206,6 +1260,11 @@ _gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec) mpi_free (ec->n); ec->n = mpi_copy (newvalue); } + else if (!strcmp (name, "h")) + { + mpi_free (ec->h); + ec->h = mpi_copy (newvalue); + } else if (*name == 'q' && (!name[1] || name[1] == '@')) { if (newvalue) diff --git a/cipher/ecc-eddsa.c b/cipher/ecc-eddsa.c index 65024a3..a12ebab 100644 --- a/cipher/ecc-eddsa.c +++ b/cipher/ecc-eddsa.c @@ -525,6 +525,7 @@ _gcry_ecc_eddsa_genkey (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx, point_init (&sk->E.G); point_set (&sk->E.G, &E->G); sk->E.n = mpi_copy (E->n); + sk->E.h = mpi_copy (E->h); point_init (&sk->Q); point_set (&sk->Q, &Q); diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c index 3f284fe..88266b5 100644 --- a/cipher/ecc-misc.c +++ b/cipher/ecc-misc.c @@ -43,6 +43,7 @@ _gcry_ecc_curve_free (elliptic_curve_t *E) mpi_free (E->b); E->b = NULL; _gcry_mpi_point_free_parts (&E->G); mpi_free (E->n); E->n = NULL; + mpi_free (E->h); E->h = NULL; } @@ -63,6 +64,7 @@ _gcry_ecc_curve_copy (elliptic_curve_t E) _gcry_mpi_point_init (&R.G); point_set (&R.G, &E.G); R.n = mpi_copy (E.n); + R.h = mpi_copy (E.h); return R; } diff --git a/cipher/ecc.c b/cipher/ecc.c index a27d2c6..8eb7ba4 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -142,6 +142,7 @@ nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx, point_init (&sk->E.G); point_set (&sk->E.G, &E->G); sk->E.n = mpi_copy (E->n); + sk->E.h = mpi_copy (E->h); point_init (&sk->Q); /* We want the Q=(x,y) be a "compliant key" in terms of the @@ -456,6 +457,7 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey) log_printmpi ("ecgen curve a", E.a); log_printmpi ("ecgen curve b", E.b); log_printmpi ("ecgen curve n", E.n); + log_printmpi ("ecgen curve h", E.h); log_printpnt ("ecgen curve G", &E.G, NULL); } @@ -524,14 +526,14 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey) rc = sexp_build (r_skey, NULL, "(key-data" " (public-key" - " (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))" + " (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)))" " (private-key" - " (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))" + " (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)(d%m)))" " )", curve_info, curve_flags, - sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public, + sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, sk.E.h, public, curve_info, curve_flags, - sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public, secret); + sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, sk.E.h, public, secret); else rc = sexp_build (r_skey, NULL, "(key-data" @@ -554,6 +556,7 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey) log_printmpi ("ecgen result b", sk.E.b); log_printmpi ("ecgen result G", base); log_printmpi ("ecgen result n", sk.E.n); + log_printmpi ("ecgen result h", sk.E.h); log_printmpi ("ecgen result Q", public); log_printmpi ("ecgen result d", secret); if ((flags & PUBKEY_FLAG_EDDSA)) @@ -604,9 +607,9 @@ ecc_check_secret_key (gcry_sexp_t keyparms) /* Extract the parameters. */ if ((flags & PUBKEY_FLAG_PARAM)) - rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?/q?+d", + rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?h?/q?+d", &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n, - &mpi_q, &sk.d, NULL); + &sk.E.h, &mpi_q, &sk.d, NULL); else rc = sexp_extract_param (keyparms, NULL, "/q?+d", &mpi_q, &sk.d, NULL); @@ -624,7 +627,7 @@ ecc_check_secret_key (gcry_sexp_t keyparms) rc = _gcry_ecc_update_curve_param (curvename, &sk.E.model, &sk.E.dialect, &sk.E.p, &sk.E.a, &sk.E.b, - &mpi_g, &sk.E.n); + &mpi_g, &sk.E.n, &sk.E.h); if (rc) return rc; } @@ -660,11 +663,12 @@ ecc_check_secret_key (gcry_sexp_t keyparms) log_printmpi ("ecc_testkey b", sk.E.b); log_printpnt ("ecc_testkey g", &sk.E.G, NULL); log_printmpi ("ecc_testkey n", sk.E.n); + log_printmpi ("ecc_testkey h", sk.E.h); log_printmpi ("ecc_testkey q", mpi_q); if (!fips_mode ()) log_printmpi ("ecc_testkey d", sk.d); } - if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.d) + if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.E.h || !sk.d) { rc = GPG_ERR_NO_OBJ; goto leave; @@ -701,6 +705,7 @@ ecc_check_secret_key (gcry_sexp_t keyparms) _gcry_mpi_release (mpi_g); point_free (&sk.E.G); _gcry_mpi_release (sk.E.n); + _gcry_mpi_release (sk.E.h); _gcry_mpi_release (mpi_q); point_free (&sk.Q); _gcry_mpi_release (sk.d); @@ -741,9 +746,9 @@ ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms) * Extract the key. */ if ((ctx.flags & PUBKEY_FLAG_PARAM)) - rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?/q?+d", + rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?h?/q?+d", &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n, - &mpi_q, &sk.d, NULL); + &sk.E.h, &mpi_q, &sk.d, NULL); else rc = sexp_extract_param (keyparms, NULL, "/q?+d", &mpi_q, &sk.d, NULL); @@ -793,11 +798,12 @@ ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms) log_printmpi ("ecc_sign b", sk.E.b); log_printpnt ("ecc_sign g", &sk.E.G, NULL); log_printmpi ("ecc_sign n", sk.E.n); + log_printmpi ("ecc_sign h", sk.E.h); log_printmpi ("ecc_sign q", mpi_q); if (!fips_mode ()) log_printmpi ("ecc_sign d", sk.d); } - if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.d) + if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.E.h || !sk.d) { rc = GPG_ERR_NO_OBJ; goto leave; @@ -838,6 +844,7 @@ ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms) _gcry_mpi_release (mpi_g); point_free (&sk.E.G); _gcry_mpi_release (sk.E.n); + _gcry_mpi_release (sk.E.h); _gcry_mpi_release (mpi_q); point_free (&sk.Q); _gcry_mpi_release (sk.d); @@ -905,9 +912,9 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms) * Extract the key. */ if ((ctx.flags & PUBKEY_FLAG_PARAM)) - rc = sexp_extract_param (s_keyparms, NULL, "-p?a?b?g?n?/q", + rc = sexp_extract_param (s_keyparms, NULL, "-p?a?b?g?n?h?/q", &pk.E.p, &pk.E.a, &pk.E.b, &mpi_g, &pk.E.n, - &mpi_q, NULL); + &pk.E.n, &mpi_q, NULL); else rc = sexp_extract_param (s_keyparms, NULL, "/q", &mpi_q, NULL); @@ -958,9 +965,10 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms) log_printmpi ("ecc_verify b", pk.E.b); log_printpnt ("ecc_verify g", &pk.E.G, NULL); log_printmpi ("ecc_verify n", pk.E.n); + log_printmpi ("ecc_verify h", pk.E.h); log_printmpi ("ecc_verify q", mpi_q); } - if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !mpi_q) + if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !pk.E.h || !mpi_q) { rc = GPG_ERR_NO_OBJ; goto leave; @@ -1036,6 +1044,7 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms) _gcry_mpi_release (mpi_g); point_free (&pk.E.G); _gcry_mpi_release (pk.E.n); + _gcry_mpi_release (pk.E.h); _gcry_mpi_release (mpi_q); point_free (&pk.Q); _gcry_mpi_release (data); @@ -1115,8 +1124,8 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) /* * Extract the key. */ - rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?+q", - &pk.E.p, &pk.E.a, &pk.E.b, &mpi_g, &pk.E.n, + rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?h?+q", + &pk.E.p, &pk.E.a, &pk.E.b, &mpi_g, &pk.E.n, &pk.E.h, &mpi_q, NULL); if (rc) goto leave; @@ -1159,9 +1168,10 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) log_printmpi ("ecc_encrypt b", pk.E.b); log_printpnt ("ecc_encrypt g", &pk.E.G, NULL); log_printmpi ("ecc_encrypt n", pk.E.n); + log_printmpi ("ecc_encrypt n", pk.E.h); log_printmpi ("ecc_encrypt q", mpi_q); } - if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !mpi_q) + if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !pk.E.h || !mpi_q) { rc = GPG_ERR_NO_OBJ; goto leave; @@ -1219,6 +1229,7 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) _gcry_mpi_release (mpi_g); point_free (&pk.E.G); _gcry_mpi_release (pk.E.n); + _gcry_mpi_release (pk.E.h); _gcry_mpi_release (mpi_q); point_free (&pk.Q); _gcry_mpi_release (data); @@ -1282,9 +1293,9 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) /* * Extract the key. */ - rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?+d", + rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?h?+d", &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n, - &sk.d, NULL); + &sk.E.h, &sk.d, NULL); if (rc) goto leave; if (mpi_g) @@ -1325,10 +1336,11 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) log_printmpi ("ecc_decrypt b", sk.E.b); log_printpnt ("ecc_decrypt g", &sk.E.G, NULL); log_printmpi ("ecc_decrypt n", sk.E.n); + log_printmpi ("ecc_decrypt h", sk.E.h); if (!fips_mode ()) log_printmpi ("ecc_decrypt d", sk.d); } - if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.d) + if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.E.h || !sk.d) { rc = GPG_ERR_NO_OBJ; goto leave; @@ -1385,6 +1397,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) _gcry_mpi_release (mpi_g); point_free (&sk.E.G); _gcry_mpi_release (sk.E.n); + _gcry_mpi_release (sk.E.h); _gcry_mpi_release (sk.d); _gcry_mpi_release (data_e); xfree (curvename); @@ -1624,7 +1637,7 @@ _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec) gcry_mpi_t mpi_G = NULL; gcry_mpi_t mpi_Q = NULL; - if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n) + if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n || !ec->h) return GPG_ERR_BAD_CRYPT_CTX; if (mode == GCRY_PK_GET_SECKEY && !ec->d) @@ -1676,15 +1689,15 @@ _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec) { /* Let's return a private key. */ rc = sexp_build (r_sexp, NULL, - "(private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))", - ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q, ec->d); + "(private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)(d%m)))", + ec->p, ec->a, ec->b, mpi_G, ec->n, ec->h, mpi_Q, ec->d); } else if (ec->Q) { /* Let's return a public key. */ rc = sexp_build (r_sexp, NULL, - "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))", - ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q); + "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)))", + ec->p, ec->a, ec->b, mpi_G, ec->n, ec->h, mpi_Q); } else rc = GPG_ERR_BAD_CRYPT_CTX; @@ -1744,7 +1757,7 @@ gcry_pk_spec_t _gcry_pubkey_spec_ecc = GCRY_PK_ECC, { 0, 0 }, (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR), "ECC", ecc_names, - "pabgnq", "pabgnqd", "sw", "rs", "pabgnq", + "pabgnhq", "pabgnhqd", "sw", "rs", "pabgnhq", ecc_generate, ecc_check_secret_key, ecc_encrypt_raw, diff --git a/mpi/ec.c b/mpi/ec.c index 4f35de0..737f12c 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -429,6 +429,7 @@ ec_deinit (void *opaque) mpi_free (ctx->b); _gcry_mpi_point_release (ctx->G); mpi_free (ctx->n); + mpi_free (ctx->h); /* The key. */ _gcry_mpi_point_release (ctx->Q); diff --git a/src/ec-context.h b/src/ec-context.h index 60ca759..c8f2ad0 100644 --- a/src/ec-context.h +++ b/src/ec-context.h @@ -38,6 +38,7 @@ struct mpi_ec_ctx_s gcry_mpi_t b; /* Second coefficient of the Weierstrass equation. */ gcry_mpi_point_t G; /* Base point (generator). */ gcry_mpi_t n; /* Order of G. */ + gcry_mpi_t h; /* Cofactor. */ /* The actual key. May not be set. */ gcry_mpi_point_t Q; /* Public key. */ diff --git a/tests/curves.c b/tests/curves.c index 0581452..178a192 100644 --- a/tests/curves.c +++ b/tests/curves.c @@ -41,6 +41,7 @@ static char const sample_key_1[] = " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)\n" " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)\n" +" (h #000000000000000000000000000000000000000000000000000000000000000001#)\n" " (q #0442B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146EE" "86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E#)\n" " ))"; @@ -57,6 +58,7 @@ static char const sample_key_2[] = " (g #04bed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3" "1667cb477a1a8ec338f94741669c976316da6321#)\n" " (n #00e95e4a5f737059dc60df5991d45029409e60fc09#)\n" +" (h #000000000000000000000000000000000000000000000000000000000000000001#)\n" " (q #041111111111111111111111111111111111111111" "2222222222222222222222222222222222222222#)\n" " ))"; diff --git a/tests/keygrip.c b/tests/keygrip.c index 72960ea..717535d 100644 --- a/tests/keygrip.c +++ b/tests/keygrip.c @@ -110,8 +110,9 @@ static struct " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" + " (h #000000000000000000000000000000000000000000000000000000000000000001#)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + "\xE6\xBA\x0B\x38\xFC\xD0\x5C\x74\x47\x4C\x8E\x92\xD5\xCA\xE4\x69\xED\xEB\xC9\x1F" }, { GCRY_PK_ECDSA, @@ -122,8 +123,9 @@ static struct " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" + " (h #000000000000000000000000000000000000000000000000000000000000000001#)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + "\xE6\xBA\x0B\x38\xFC\xD0\x5C\x74\x47\x4C\x8E\x92\xD5\xCA\xE4\x69\xED\xEB\xC9\x1F" }, { GCRY_PK_ECDSA, @@ -134,8 +136,9 @@ static struct " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" + " (h #000000000000000000000000000000000000000000000000000000000000000001#)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + "\xE6\xBA\x0B\x38\xFC\xD0\x5C\x74\x47\x4C\x8E\x92\xD5\xCA\xE4\x69\xED\xEB\xC9\x1F" }, { GCRY_PK_ECDSA, @@ -143,7 +146,7 @@ static struct " (ecdsa" " (curve secp256r1)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + "\xE6\xBA\x0B\x38\xFC\xD0\x5C\x74\x47\x4C\x8E\x92\xD5\xCA\xE4\x69\xED\xEB\xC9\x1F" }, { GCRY_PK_ECC, @@ -151,7 +154,7 @@ static struct " (ecc" " (curve secp256r1)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + "\xE6\xBA\x0B\x38\xFC\xD0\x5C\x74\x47\x4C\x8E\x92\xD5\xCA\xE4\x69\xED\xEB\xC9\x1F" }, { /* Ed25519 standard */ GCRY_PK_ECC, @@ -162,8 +165,8 @@ static struct " 1CC662926E7EFF4982B7FB8B928E61CD74CCDD85277CC57196C3AD20B611085F" " 47BD24842905C049257673B3F5249524E0A41FAA17B25B818D0F97E625F1A1D0#)" " ))", - "\x0C\xCA\xB2\xFD\x48\x9A\x33\x40\x2C\xE8" - "\xE0\x4A\x1F\xB2\x45\xEA\x80\x3D\x0A\xF1" + "\x9F\x7F\xED\x00\x5C\x18\x7C\x07\x01\x7D" + "\xFC\xF2\xA2\xD4\xD1\xCE\x11\x59\x4F\x72" }, { /* Ed25519+EdDSA */ GCRY_PK_ECC, @@ -172,8 +175,8 @@ static struct " (curve Ed25519)(flags eddsa)" " (q #773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB#)" " ))", - "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" - "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" + "\x06\xCC\xA3\x1F\x4D\x23\x08\xF7\x91\xA2" + "\x48\xF7\x0E\x41\x4A\x70\x76\xC2\xA4\x95" }, { /* Ed25519+EdDSA (with compression prefix) */ GCRY_PK_ECC, @@ -195,8 +198,8 @@ static struct " 629ad237d1ed04dcd4abe1711dd699a1cf51b1584c4de7a4ef8b8a640180b26f" " 5bb7c29018ece0f46b01f2960e99041a5779afe7e2292b65f9d51f8c84723e77#)" " ))", - "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" - "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" + "\x06\xCC\xA3\x1F\x4D\x23\x08\xF7\x91\xA2" + "\x48\xF7\x0E\x41\x4A\x70\x76\xC2\xA4\x95" } }; diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c index 88bb5bd..d72cd27 100644 --- a/tests/t-mpi-point.c +++ b/tests/t-mpi-point.c @@ -57,6 +57,7 @@ static struct const char *a, *b; /* The coefficients. */ const char *n; /* The order of the base point. */ const char *g_x, *g_y; /* Base point. */ + const char *h; /* Cofactor. */ } test_curve[] = { { @@ -67,7 +68,8 @@ static struct "0xffffffffffffffffffffffff99def836146bc9b1b4d22831", "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", - "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811" + "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811", + "0x01" }, { "NIST P-224", @@ -77,7 +79,8 @@ static struct "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" , "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", - "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34" + "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", + "0x01" }, { "NIST P-256", @@ -87,7 +90,8 @@ static struct "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" + "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "0x01" }, { "NIST P-384", @@ -103,7 +107,8 @@ static struct "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" "5502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" - "0a60b1ce1d7e819d7a431d7c90ea0e5f" + "0a60b1ce1d7e819d7a431d7c90ea0e5f", + "0x01" }, { "NIST P-521", @@ -119,7 +124,8 @@ static struct "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d" "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6" - "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" + "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", + "0x01" }, { "Ed25519", @@ -128,9 +134,10 @@ static struct "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", - "0x6666666666666666666666666666666666666666666666666666666666666658" + "0x6666666666666666666666666666666666666666666666666666666666666658", + "0x08" }, - { NULL, NULL, NULL, NULL, NULL } + { NULL, NULL, NULL, NULL, NULL, NULL } }; /* A sample public key for NIST P-256. */ @@ -556,6 +563,8 @@ context_param (void) if (get_and_cmp_point ("g", test_curve[idx].g_x, test_curve[idx].g_y, test_curve[idx].desc, ctx)) continue; + if (get_and_cmp_mpi ("h", test_curve[idx].h, test_curve[idx].desc, ctx)) + continue; } -- From wk at gnupg.org Thu Aug 7 11:36:40 2014 From: wk at gnupg.org (Werner Koch) Date: Thu, 07 Aug 2014 11:36:40 +0200 Subject: [PATCH] Curve25519 patch revised In-Reply-To: <1407390447.1549.6.camel@cfw2.gniibe.org> (NIIBE Yutaka's message of "Thu, 07 Aug 2014 14:47:27 +0900") References: <1403157515.2821.8.camel@cfw2.gniibe.org> <1403168653.2821.9.camel@cfw2.gniibe.org> <1403231035.2376.2.camel@cfw2.gniibe.org> <87a998ne2n.fsf@vigenere.g10code.de> <1403270939.3855.0.camel@latx1.gniibe.org> <1405498318.20960.1.camel@cfw2.gniibe.org> <1405519330.3778.0.camel@latx1.gniibe.org> <87iomq3est.fsf@vigenere.g10code.de> <1407390447.1549.6.camel@cfw2.gniibe.org> Message-ID: <87mwbg1w0n.fsf@vigenere.g10code.de> On Thu, 7 Aug 2014 07:47, gniibe at fsij.org said: > Here is the patch keeping compute_keygrip untouched. > > OK to commit? Yes. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Thu Aug 7 13:33:45 2014 From: wk at gnupg.org (Werner Koch) Date: Thu, 07 Aug 2014 13:33:45 +0200 Subject: Moving forward with Curve25519 In-Reply-To: <53E265ED.5030804@brainhub.org> (Andrey Jivsov's message of "Wed, 06 Aug 2014 10:29:17 -0700") References: <1403157515.2821.8.camel@cfw2.gniibe.org> <1403168653.2821.9.camel@cfw2.gniibe.org> <1403231035.2376.2.camel@cfw2.gniibe.org> <87a998ne2n.fsf@vigenere.g10code.de> <1403270939.3855.0.camel@latx1.gniibe.org> <87oavzci9k.fsf_-_@vigenere.g10code.de> <53E15D72.3030202@brainhub.org> <87zjfi3vgw.fsf@vigenere.g10code.de> <53E265ED.5030804@brainhub.org> Message-ID: <87mwbgzg86.fsf@vigenere.g10code.de> On Wed, 6 Aug 2014 19:29, openpgp at brainhub.org said: > Curve25519 always has the high bit set to zero because it fits into > 255 bits. ( For ECDH anyway; one may in theory reuse the high bit for Right. > the 32 byte can be 1. In OpenPGP these 32 bytes are encoded as an > MPI. MPI in OpenPGP encodes the size in bits, counting from the most > significant bit (MSB). I mentioned that OpenPGP allows that; but experience has shown that an MPI with the MSBit set is easily messed up due to the common 2-compl encoding of integers. Thus to represent an arbitrary octet string it is better to make sure the MSBit is cleared. Also the fixed size due to the prefix byte has advantages over the small saving in 1 of 128 cases. Actually the code in GnuPG and Libgcrypt does not care about it because ECC points are considered opaque values but the fixed size makes it easier for simpler implementations to pass a fixed string to the NaCL library. > realize even greater space savings by trial-generating public EC keys > so that they have high bits as zeros. This will allow the MPI encoding > to fit into smaller number of octets. We cannot do this when we prefix Limiting the search space is not considered good style. After all we do not save much compared to the overhead the OpenPGP encoding introduces anyway (right, I suggested the longer OID approach). > This was for two reasons that don't apply to Curve25519: I know. > 1. patents > 2. there is a ~5% cost to decompress a point on short Weierstrass > curves (NIST Suite-B curves, Brainpool curves). > > #1: never applied to ECDH, definitely doesn't apply in 2014. And the compression patent expired last week. I am not sure whether the X-only format was also covered by this patent but recent discussion pointed out that the last harming patent was this one. > #2: Montgomery curves don't need Y, thus there is no cost of decompression. Agreed. > One has to switch either by the tag or by the size of MPI. I think the > logic based on MPI size is clear enough (if MPI size in bits <= 255 > ==> only X is used). After all this is a different key due to the different fingerprint (but note that the creation date may also be used to create a different fingerprint). > Support for multiple formats causes complexity. Given what we know now > about modern curves, I think the default should be an uncompressed > point. This is the case we should optimize for. This contradicts with your dislike for the prefix byte due to space reasons. A compressed format with prefix byte is shorter than the uncompressed format. I guess we have some kind of misunderstanding here. > It makes little sense to talk about "uncompressed" Montgomery > point. We should have a single blessed format, and it's clearly a > "compressed" one. Okay, we agree on X only, right? There are two open questions: - Native format as used by the reference implementation and the common use of a certain curve (i.e. little endian for Curve25519). Or the usual network byte order. I favor the native format. - Use of a prefix byte. I prefer a 0x41 prefix byte for two reasons: - Fixed length operations. - It is compatible with the proposed format of TLS. > (There is some argument to say that the format should be an Edwards > representation so that keys can be used for both DH and > signatures. However, in all cases the standard should probably be some If someone wants to use such a questionable design the NIST or Brainpool curves may be used for that. I do not plan to explicitly allow that in GnuPG. > True, there are applications where short keys are important. 32 byte > keys are short enough that humans can handle them (i.e. type them > encoded in base32 format, read them, and it's easier to scan them > too). The abovementioned method to reduce the size of a public key > makes this a bit easier for humans. Not really, there is still some overhead. For a base32 format (or zbase32) a dedicated format can be used: Just the 4 byte timestamp, a 1 byte non-IETF identifier for the curve, and the plain key (leaving out the prefix byte). [With base32 we need to have a multiple of 5 bytes and thus the above (4 + 1 + 32) leaves us with 3 spare bytes which could be used to keep the prefix and length bytes.] Reading Simon's draft again, he actually defines 0x41 as "montgomery_x_le" (Montgomery X coordinate, little endian). Which is the definition we should of course also use. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Thu Aug 7 20:48:49 2014 From: wk at gnupg.org (Werner Koch) Date: Thu, 07 Aug 2014 20:48:49 +0200 Subject: Libgcrypt 1.5.4 released Message-ID: <87mwbgw2y6.fsf@vigenere.g10code.de> Hello! The GNU project is pleased to announce an update of the Libgcrypt 1.5 series: version 1.5.4. This is a maintenance release with backports of fixes from the current stable 1.6 series. In general it is preferable to use the latest stable version. However, the 1.6 series introduced an ABI break and thus some older software may not build or work correctly with 1.6. Libgcrypt is a general purpose library of cryptographic building blocks. It does not provide any implementation of OpenPGP or other protocols. Thorough understanding of applied cryptography is required for proper use Libgcrypt. Noteworthy changes in version 1.5.4 (2014-08-07) ================================================ * Declare 2016-12-31 as end-of-life for 1.5. Backported from 1.6: * Improved performance of RSA, DSA, and Elgamal by using a new exponentiation algorithm. * Fixed a subtle bug in mpi_set_bit which could set spurious bits. * Fixed a bug in an internal division function. Download ======== Source code is hosted at the GnuPG FTP server and its mirrors as listed at http://www.gnupg.org/download/mirrors.html . On the primary server the source tarball and its digital signature are: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.4.tar.bz2 (1478k) ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.4.tar.bz2.sig That file is bzip2 compressed. A gzip compressed version is here: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.4.tar.gz (1763k) ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.4.tar.gz.sig Alternativley you may upgrade using this patch file: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.3-1.5.4.diff.bz2 (17k) In order to check that the version of Libgcrypt you are going to build is an original and unmodified one, you can do it in one of the following ways: * Check the supplied OpenPGP signature. For example to check the signature of the file libgcrypt-1.5.4.tar.bz2 you would use this command: gpg --verify libgcrypt-1.5.4.tar.bz2.sig This checks whether the signature file matches the source file. You should see a message indicating that the signature is good and made by the release signing key 4F25E3B6 which is certified by my well known key 1E42B367. To retrieve the keys you may use the command "gpg --fetch-key finger:wk at g10code.com". * If you are not able to use GnuPG, you have to verify the SHA-1 checksum: sha1sum libgcrypt-1.5.4.tar.bz2 and check that the output matches the first line from the following list: bdf4b04a0d2aabc04ab3564fbe38fd094135aa7a libgcrypt-1.5.4.tar.bz2 71e432e0ae8792076a40c6059667997250abbb9d libgcrypt-1.5.4.tar.gz 8876ae002751e6ec26c76e510d17fc3e0eccb3ed libgcrypt-1.5.3-1.5.4.diff.bz2 Copying ======= Libgcrypt is distributed under the terms of the GNU Lesser General Public License (LGPLv2.1+). The helper programs as well as the documentation are distributed under the terms of the GNU General Public License (GPLv2+). The file LICENSES has notices about contributions that require these additional notices are distributed. Support ======= For help on developing with Libgcrypt you should read the included manual and optional ask on the gcrypt-devel mailing list [1]. A listing with commercial support offers for Libgcrypt and related software is available at the GnuPG web site [2]. The driving force behind the development of Libgcrypt is my company g10 Code. Maintenance and improvement of Libgcrypt and related software takes up most of our resources. To allow us to continue our work on free software, we ask to either purchase a support contract, engage us for custom enhancements, or to donate money: http://gnupg.org/donate/ Thanks ====== Many thanks to all who contributed to Libgcrypt development, be it bug fixes, code, documentation, testing or helping users. Happy hacking, Werner [1] https://lists.gnupg.org/mailman/listinfo/gcrypt-devel [2] https://gnupg.org/service.html -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 180 bytes Desc: not available URL: From gniibe at fsij.org Fri Aug 8 02:49:22 2014 From: gniibe at fsij.org (NIIBE Yutaka) Date: Fri, 08 Aug 2014 09:49:22 +0900 Subject: [PATCH] Curve25519 patch revised In-Reply-To: <87mwbg1w0n.fsf@vigenere.g10code.de> References: <1403157515.2821.8.camel@cfw2.gniibe.org> <1403168653.2821.9.camel@cfw2.gniibe.org> <1403231035.2376.2.camel@cfw2.gniibe.org> <87a998ne2n.fsf@vigenere.g10code.de> <1403270939.3855.0.camel@latx1.gniibe.org> <1405498318.20960.1.camel@cfw2.gniibe.org> <1405519330.3778.0.camel@latx1.gniibe.org> <87iomq3est.fsf@vigenere.g10code.de> <1407390447.1549.6.camel@cfw2.gniibe.org> <87mwbg1w0n.fsf@vigenere.g10code.de> Message-ID: <1407458962.1568.0.camel@cfw2.gniibe.org> On 2014-08-07 at 11:36 +0200, Werner Koch wrote: > On Thu, 7 Aug 2014 07:47, gniibe at fsij.org said: > > > Here is the patch keeping compute_keygrip untouched. > > > > OK to commit? > > Yes. Sorry, the version I sent yesterday had mistakes and a bug: * Typo in log_printmpi message. * Fix of compute_keygrip to be compatible. Yesterday, I just reverted the patch of compute_keygrip, but as _gcry_ecc_update_curve_param changed, it should be fixed. * I forgot to revert the keygrip values in tests/keygrip.c. Here's the change over yesterday's patch. I committed & pushed, after "make check" confirmation. diff --git a/cipher/ecc.c b/cipher/ecc.c index 8eb7ba4..8bdbd56 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -1168,7 +1168,7 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) log_printmpi ("ecc_encrypt b", pk.E.b); log_printpnt ("ecc_encrypt g", &pk.E.G, NULL); log_printmpi ("ecc_encrypt n", pk.E.n); - log_printmpi ("ecc_encrypt n", pk.E.h); + log_printmpi ("ecc_encrypt h", pk.E.h); log_printmpi ("ecc_encrypt q", mpi_q); } if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !pk.E.h || !mpi_q) @@ -1467,8 +1467,8 @@ ecc_get_nbits (gcry_sexp_t parms) static gpg_err_code_t compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms) { -#define N_COMPONENTS 6 - static const char names[N_COMPONENTS+1] = "pabgnq"; +#define N_COMPONENTS 7 + static const char names[N_COMPONENTS] = "pabgnhq"; gpg_err_code_t rc; gcry_sexp_t l1; gcry_mpi_t values[N_COMPONENTS]; @@ -1496,24 +1496,24 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms) if ((flags & PUBKEY_FLAG_PARAM)) { if ((flags & PUBKEY_FLAG_EDDSA)) - rc = sexp_extract_param (keyparms, NULL, "p?a?b?g?n?/q", + rc = sexp_extract_param (keyparms, NULL, "p?a?b?g?n?h?/q", &values[0], &values[1], &values[2], &values[3], &values[4], &values[5], - NULL); + &values[6], NULL); else - rc = sexp_extract_param (keyparms, NULL, "p?a?b?g?n?q", + rc = sexp_extract_param (keyparms, NULL, "p?a?b?g?n?h?q", &values[0], &values[1], &values[2], &values[3], &values[4], &values[5], - NULL); + &values[6], NULL); } else { if ((flags & PUBKEY_FLAG_EDDSA)) rc = sexp_extract_param (keyparms, NULL, "/q", - &values[5], NULL); + &values[6], NULL); else rc = sexp_extract_param (keyparms, NULL, "q", - &values[5], NULL); + &values[6], NULL); } if (rc) goto leave; @@ -1530,7 +1530,7 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms) rc = _gcry_ecc_update_curve_param (curvename, &model, &dialect, &values[0], &values[1], &values[2], - &values[3], &values[4]); + &values[3], &values[4], &values[5]); if (rc) goto leave; } @@ -1568,7 +1568,7 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms) if ((flags & PUBKEY_FLAG_EDDSA)) { if (dialect == ECC_DIALECT_ED25519) - rc = _gcry_ecc_eddsa_ensure_compact (values[5], 256); + rc = _gcry_ecc_eddsa_ensure_compact (values[6], 256); else rc = GPG_ERR_NOT_IMPLEMENTED; if (rc) @@ -1580,6 +1580,9 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms) { char buf[30]; + if (idx == 5) + continue; /* Skip cofactor. */ + if (mpi_is_opaque (values[idx])) { const unsigned char *raw; diff --git a/tests/keygrip.c b/tests/keygrip.c index 717535d..3ef1de1 100644 --- a/tests/keygrip.c +++ b/tests/keygrip.c @@ -112,7 +112,7 @@ static struct " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" " (h #000000000000000000000000000000000000000000000000000000000000000001#)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xBA\x0B\x38\xFC\xD0\x5C\x74\x47\x4C\x8E\x92\xD5\xCA\xE4\x69\xED\xEB\xC9\x1F" + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" }, { GCRY_PK_ECDSA, @@ -125,7 +125,7 @@ static struct " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" " (h #000000000000000000000000000000000000000000000000000000000000000001#)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xBA\x0B\x38\xFC\xD0\x5C\x74\x47\x4C\x8E\x92\xD5\xCA\xE4\x69\xED\xEB\xC9\x1F" + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" }, { GCRY_PK_ECDSA, @@ -138,7 +138,7 @@ static struct " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" " (h #000000000000000000000000000000000000000000000000000000000000000001#)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xBA\x0B\x38\xFC\xD0\x5C\x74\x47\x4C\x8E\x92\xD5\xCA\xE4\x69\xED\xEB\xC9\x1F" + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" }, { GCRY_PK_ECDSA, @@ -146,7 +146,7 @@ static struct " (ecdsa" " (curve secp256r1)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xBA\x0B\x38\xFC\xD0\x5C\x74\x47\x4C\x8E\x92\xD5\xCA\xE4\x69\xED\xEB\xC9\x1F" + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" }, { GCRY_PK_ECC, @@ -154,7 +154,7 @@ static struct " (ecc" " (curve secp256r1)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xBA\x0B\x38\xFC\xD0\x5C\x74\x47\x4C\x8E\x92\xD5\xCA\xE4\x69\xED\xEB\xC9\x1F" + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" }, { /* Ed25519 standard */ GCRY_PK_ECC, @@ -165,8 +165,8 @@ static struct " 1CC662926E7EFF4982B7FB8B928E61CD74CCDD85277CC57196C3AD20B611085F" " 47BD24842905C049257673B3F5249524E0A41FAA17B25B818D0F97E625F1A1D0#)" " ))", - "\x9F\x7F\xED\x00\x5C\x18\x7C\x07\x01\x7D" - "\xFC\xF2\xA2\xD4\xD1\xCE\x11\x59\x4F\x72" + "\x0C\xCA\xB2\xFD\x48\x9A\x33\x40\x2C\xE8" + "\xE0\x4A\x1F\xB2\x45\xEA\x80\x3D\x0A\xF1" }, { /* Ed25519+EdDSA */ GCRY_PK_ECC, @@ -175,8 +175,8 @@ static struct " (curve Ed25519)(flags eddsa)" " (q #773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB#)" " ))", - "\x06\xCC\xA3\x1F\x4D\x23\x08\xF7\x91\xA2" - "\x48\xF7\x0E\x41\x4A\x70\x76\xC2\xA4\x95" + "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" + "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" }, { /* Ed25519+EdDSA (with compression prefix) */ GCRY_PK_ECC, @@ -198,8 +198,8 @@ static struct " 629ad237d1ed04dcd4abe1711dd699a1cf51b1584c4de7a4ef8b8a640180b26f" " 5bb7c29018ece0f46b01f2960e99041a5779afe7e2292b65f9d51f8c84723e77#)" " ))", - "\x06\xCC\xA3\x1F\x4D\x23\x08\xF7\x91\xA2" - "\x48\xF7\x0E\x41\x4A\x70\x76\xC2\xA4\x95" + "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" + "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" } }; -- From gniibe at fsij.org Fri Aug 8 04:22:18 2014 From: gniibe at fsij.org (NIIBE Yutaka) Date: Fri, 08 Aug 2014 11:22:18 +0900 Subject: [PATCH] ecc: support Montgomery curve for gcry_mpi_ec_add_points Message-ID: <1407464538.1568.4.camel@cfw2.gniibe.org> Here is a patch to support Montgomery curve for gcry_mpi_ec_mul_point. Only x-coordinate is valid for this curve. OK to commit? diff --git a/mpi/ec.c b/mpi/ec.c index 737f12c..2dc97aa 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -601,10 +601,17 @@ _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t point, case MPI_EC_MONTGOMERY: { - log_fatal ("%s: %s not yet supported\n", - "_gcry_mpi_ec_get_affine", "Montgomery"); + if (x) + mpi_set (x, point->x); + + if (y) + { + log_fatal ("%s: Getting Y-coordinate on %s is not supported\n", + "_gcry_mpi_ec_get_affine", "Montgomery"); + return -1; + } } - return -1; + return 0; case MPI_EC_EDWARDS: { @@ -1074,6 +1081,35 @@ add_points_edwards (mpi_point_t result, } +/* Compute a step of Montgomery Ladder (only use X and Z in the point). + Inputs: P1, P2, and x-coordinate of DIF = P1 - P1. + Outputs: PRD = 2 * P1 and SUM = P1 + P2. */ +static void +montgomery_ladder (mpi_point_t prd, mpi_point_t sum, + mpi_point_t p1, mpi_point_t p2, gcry_mpi_t dif_x, + mpi_ec_t ctx) +{ + ec_addm (sum->x, p2->x, p2->z, ctx); + ec_subm (p2->z, p2->x, p2->z, ctx); + ec_addm (prd->x, p1->x, p1->z, ctx); + ec_subm (p1->z, p1->x, p1->z, ctx); + ec_mulm (p2->x, p1->z, sum->x, ctx); + ec_mulm (p2->z, prd->x, p2->z, ctx); + ec_pow2 (p1->x, prd->x, ctx); + ec_pow2 (p1->z, p1->z, ctx); + ec_addm (sum->x, p2->x, p2->z, ctx); + ec_subm (p2->z, p2->x, p2->z, ctx); + ec_mulm (prd->x, p1->x, p1->z, ctx); + ec_subm (p1->z, p1->x, p1->z, ctx); + ec_pow2 (sum->x, sum->x, ctx); + ec_pow2 (sum->z, p2->z, ctx); + ec_mulm (prd->z, p1->z, ctx->a, ctx); /* ctx->a: (A-2)/4 */ + ec_mulm (sum->z, sum->z, dif_x, ctx); + ec_addm (prd->z, p1->x, prd->z, ctx); + ec_mulm (prd->z, prd->z, p1->z, ctx); +} + + /* RESULT = P1 + P2 */ void _gcry_mpi_ec_add_points (mpi_point_t result, @@ -1145,6 +1181,72 @@ _gcry_mpi_ec_mul_point (mpi_point_t result, } return; } + else if (ctx->model == MPI_EC_MONTGOMERY) + { + unsigned int nbits; + int j; + mpi_point_struct p1_, p2_; + unsigned long sw; + + /* Compute scalar point multiplication with Montgomery Ladder. + Note that we don't use Y-coordinate in the points at all. + RESULT->Y will be filled by zero. */ + + nbits = mpi_get_nbits (scalar); + point_init (&p1); + point_init (&p2); + point_init (&p1_); + point_init (&p2_); + mpi_set_ui (p1.x, 1); + mpi_free (p2.x); + p2.x = mpi_copy (point->x); + mpi_set_ui (p2.z, 1); + + for (j=nbits-1; j >= 0; j--) + { + sw = mpi_test_bit (scalar, j); + mpi_swap_cond (p1.x, p2.x, sw); + mpi_swap_cond (p1.z, p2.z, sw); + montgomery_ladder (&p1_, &p2_, &p1, &p2, point->x, ctx); + mpi_swap_cond (p1_.x, p2_.x, sw); + mpi_swap_cond (p1_.z, p2_.z, sw); + + if (--j < 0) + break; + + sw = mpi_test_bit (scalar, j); + mpi_swap_cond (p1_.x, p2_.x, sw); + mpi_swap_cond (p1_.z, p2_.z, sw); + montgomery_ladder (&p1, &p2, &p1_, &p2_, point->x, ctx); + mpi_swap_cond (p1.x, p2.x, sw); + mpi_swap_cond (p1.z, p2.z, sw); + } + + z1 = mpi_new (0); + mpi_clear (result->y); + sw = (nbits & 1); + mpi_swap_cond (p1.x, p1_.x, sw); + mpi_swap_cond (p1.z, p1_.z, sw); + + if (p1.z->nlimbs == 0) + { + mpi_set_ui (result->x, 1); + mpi_set_ui (result->z, 0); + } + else + { + ec_invm (z1, p1.z, ctx); + ec_mulm (result->x, p1.x, z1, ctx); + mpi_set_ui (result->z, 1); + } + + mpi_free (z1); + point_free (&p1); + point_free (&p2); + point_free (&p1_); + point_free (&p2_); + return; + } x1 = mpi_alloc_like (ctx->p); y1 = mpi_alloc_like (ctx->p); -- From gniibe at fsij.org Fri Aug 8 06:08:40 2014 From: gniibe at fsij.org (NIIBE Yutaka) Date: Fri, 08 Aug 2014 13:08:40 +0900 Subject: [PATCH] ecc: support Montgomery curve for gcry_mpi_ec_mul_point In-Reply-To: <1407464538.1568.4.camel@cfw2.gniibe.org> References: <1407464538.1568.4.camel@cfw2.gniibe.org> Message-ID: <1407470920.1568.7.camel@cfw2.gniibe.org> Subject in the previous mail was wrong (fixed in this mail). I wanted to say that even though gcry_mpi_ec_add_points won't be supported, gcry_mpi_ec_mul_point can be supported for Montgomery curve and it is useful for ECDH. I don't know if we should support gcry_mpi_ec_curve_point when it's x-coordinate only for Montgomery curve. It would be OK always return true for Montgomery curve. -- From cvs at cvs.gnupg.org Fri Aug 8 02:44:21 2014 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Fri, 08 Aug 2014 02:44:21 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-103-g9933b9e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 9933b9e5e1a3f5b1019c75f93bd265d4a1ecc270 (commit) from 4ce77b0a810d3c889c07dfb385127d90fa1ae36a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 9933b9e5e1a3f5b1019c75f93bd265d4a1ecc270 Author: NIIBE Yutaka Date: Fri Aug 8 09:35:31 2014 +0900 ecc: Add cofactor to domain parameters. * src/ec-context.h (mpi_ec_ctx_s): Add cofactor 'h'. * cipher/ecc-common.h (elliptic_curve_t): Add cofactor 'h'. (_gcry_ecc_update_curve_param): New API adding cofactor. * cipher/ecc-curves.c (ecc_domain_parms_t): Add cofactor 'h'. (ecc_domain_parms_t domain_parms): Add cofactors. (_gcry_ecc_fill_in_curve, _gcry_ecc_update_curve_param) (_gcry_ecc_get_curve, _gcry_mpi_ec_new, _gcry_ecc_get_param_sexp) (_gcry_ecc_get_mpi): Handle cofactor. * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_genkey): Likewise. * cipher/ecc-misc.c (_gcry_ecc_curve_free) (_gcry_ecc_curve_copy): Likewise. * cipher/ecc.c (nist_generate_key, ecc_generate) (ecc_check_secret_key, ecc_sign, ecc_verify, ecc_encrypt_raw) (ecc_decrypt_raw, _gcry_pk_ecc_get_sexp, _gcry_pubkey_spec_ecc): Likewise. (compute_keygrip): Handle cofactor, but skip it for its computation. * mpi/ec.c (ec_deinit): Likewise. * tests/t-mpi-point.c (context_param): Likewise. (test_curve): Add cofactors. * tests/curves.c (sample_key_1, sample_key_2): Add cofactors. * tests/keygrip.c (key_grips): Add cofactors. -- We keep compatibility of compute_keygrip in cipher/ecc.c. diff --git a/cipher/ecc-common.h b/cipher/ecc-common.h index f066b4b..83bf20d 100644 --- a/cipher/ecc-common.h +++ b/cipher/ecc-common.h @@ -32,6 +32,7 @@ typedef struct or d as used by Twisted Edwards curves. */ mpi_point_struct G; /* Base point (generator). */ gcry_mpi_t n; /* Order of G. */ + gcry_mpi_t h; /* Cofactor. */ const char *name; /* Name of the curve or NULL. */ } elliptic_curve_t; @@ -75,7 +76,7 @@ gpg_err_code_t _gcry_ecc_update_curve_param (const char *name, enum ecc_dialects *dialect, gcry_mpi_t *p, gcry_mpi_t *a, gcry_mpi_t *b, gcry_mpi_t *g, - gcry_mpi_t *n); + gcry_mpi_t *n, gcry_mpi_t *h); const char *_gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c index cd85361..fd47c1d 100644 --- a/cipher/ecc-curves.c +++ b/cipher/ecc-curves.c @@ -110,6 +110,7 @@ typedef struct Curves b is used for d. */ const char *n; /* The order of the base point. */ const char *g_x, *g_y; /* Base point. */ + const char *h; /* Cofactor. */ } ecc_domain_parms_t; @@ -125,7 +126,8 @@ static const ecc_domain_parms_t domain_parms[] = "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", - "0x6666666666666666666666666666666666666666666666666666666666666658" + "0x6666666666666666666666666666666666666666666666666666666666666658", + "0x08" }, #if 0 /* No real specs yet found. */ { @@ -140,7 +142,8 @@ static const ecc_domain_parms_t domain_parms[] = "706022B36F1C0338AD63CF181B0E71A5E106AF79", "0x1A334905141443300218C0631C326E5FCD46369F44C03EC7F57FF35498A4AB4D" "6D6BA111301A73FAA8537C64C4FD3812F3CBC595", - "0x22" + "0x22", + "0x08" }, #endif /*0*/ { @@ -152,7 +155,8 @@ static const ecc_domain_parms_t domain_parms[] = "0xffffffffffffffffffffffff99def836146bc9b1b4d22831", "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", - "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811" + "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811", + "0x01" }, { "NIST P-224", 224, 1, @@ -163,7 +167,8 @@ static const ecc_domain_parms_t domain_parms[] = "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" , "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", - "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34" + "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", + "0x01" }, { "NIST P-256", 256, 1, @@ -174,7 +179,8 @@ static const ecc_domain_parms_t domain_parms[] = "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" + "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "0x01" }, { "NIST P-384", 384, 1, @@ -191,7 +197,8 @@ static const ecc_domain_parms_t domain_parms[] = "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" "5502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" - "0a60b1ce1d7e819d7a431d7c90ea0e5f" + "0a60b1ce1d7e819d7a431d7c90ea0e5f", + "0x01" }, { "NIST P-521", 521, 1, @@ -208,7 +215,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d" "3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e" - "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" + "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", + "0x01" }, { "brainpoolP160r1", 160, 0, @@ -218,7 +226,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x1e589a8595423412134faa2dbdec95c8d8675e58", "0xe95e4a5f737059dc60df5991d45029409e60fc09", "0xbed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3", - "0x1667cb477a1a8ec338f94741669c976316da6321" + "0x1667cb477a1a8ec338f94741669c976316da6321", + "0x01" }, { "brainpoolP192r1", 192, 0, @@ -228,7 +237,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x469a28ef7c28cca3dc721d044f4496bcca7ef4146fbf25c9", "0xc302f41d932a36cda7a3462f9e9e916b5be8f1029ac4acc1", "0xc0a0647eaab6a48753b033c56cb0f0900a2f5c4853375fd6", - "0x14b690866abd5bb88b5f4828c1490002e6773fa2fa299b8f" + "0x14b690866abd5bb88b5f4828c1490002e6773fa2fa299b8f", + "0x01" }, { "brainpoolP224r1", 224, 0, @@ -238,7 +248,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x2580f63ccfe44138870713b1a92369e33e2135d266dbb372386c400b", "0xd7c134aa264366862a18302575d0fb98d116bc4b6ddebca3a5a7939f", "0x0d9029ad2c7e5cf4340823b2a87dc68c9e4ce3174c1e6efdee12c07d", - "0x58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd" + "0x58aa56f772c0726f24c6b89e4ecdac24354b9e99caa3f6d3761402cd", + "0x01" }, { "brainpoolP256r1", 256, 0, @@ -248,7 +259,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x26dc5c6ce94a4b44f330b5d9bbd77cbf958416295cf7e1ce6bccdc18ff8c07b6", "0xa9fb57dba1eea9bc3e660a909d838d718c397aa3b561a6f7901e0e82974856a7", "0x8bd2aeb9cb7e57cb2c4b482ffc81b7afb9de27e1e3bd23c23a4453bd9ace3262", - "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997" + "0x547ef835c3dac4fd97f8461a14611dc9c27745132ded8e545c1d54c72f046997", + "0x01" }, { "brainpoolP320r1", 320, 0, @@ -264,7 +276,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x43bd7e9afb53d8b85289bcc48ee5bfe6f20137d10a087eb6e7871e2a10a599c7" "10af8d0d39e20611", "0x14fdd05545ec1cc8ab4093247f77275e0743ffed117182eaa9c77877aaac6ac7" - "d35245d1692e8ee1" + "d35245d1692e8ee1", + "0x01" }, { "brainpoolP384r1", 384, 0, @@ -280,7 +293,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x1d1c64f068cf45ffa2a63a81b7c13f6b8847a3e77ef14fe3db7fcafe0cbd10e8" "e826e03436d646aaef87b2e247d4af1e", "0x8abe1d7520f9c2a45cb1eb8e95cfd55262b70b29feec5864e19c054ff9912928" - "0e4646217791811142820341263c5315" + "0e4646217791811142820341263c5315", + "0x01" }, { "brainpoolP512r1", 512, 0, @@ -296,7 +310,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x81aee4bdd82ed9645a21322e9c4c6a9385ed9f70b5d916c1b43b62eef4d0098e" "ff3b1f78e2d0d48d50d1687b93b97d5f7c6d5047406a5e688b352209bcb9f822", "0x7dde385d566332ecc0eabfa9cf7822fdf209f70024a57b1aa000c55b881f8111" - "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892" + "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892", + "0x01" }, { "GOST2001-test", 256, 0, @@ -308,6 +323,7 @@ static const ecc_domain_parms_t domain_parms[] = "0x0000000000000000000000000000000000000000000000000000000000000002", "0x08e2a8a0e65147d4bd6316030e16d19c85c97f0a9ca267122b96abbcea7e8fc8", + "0x01" }, { "GOST2001-CryptoPro-A", 256, 0, @@ -317,7 +333,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x00000000000000000000000000000000000000000000000000000000000000a6", "0xffffffffffffffffffffffffffffffff6c611070995ad10045841b09b761b893", "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x8d91e471e0989cda27df505a453f2b7635294f2ddf23e3b122acc99c9e9f1e14" + "0x8d91e471e0989cda27df505a453f2b7635294f2ddf23e3b122acc99c9e9f1e14", + "0x01" }, { "GOST2001-CryptoPro-B", 256, 0, @@ -327,7 +344,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x3e1af419a269a5f866a7d3c25c3df80ae979259373ff2b182f49d4ce7e1bbc8b", "0x800000000000000000000000000000015f700cfff1a624e5e497161bcc8a198f", "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x3fa8124359f96680b83d1c3eb2c070e5c545c9858d03ecfb744bf8d717717efc" + "0x3fa8124359f96680b83d1c3eb2c070e5c545c9858d03ecfb744bf8d717717efc", + "0x01" }, { "GOST2001-CryptoPro-C", 256, 0, @@ -337,7 +355,8 @@ static const ecc_domain_parms_t domain_parms[] = "0x000000000000000000000000000000000000000000000000000000000000805a", "0x9b9f605f5a858107ab1ec85e6b41c8aa582ca3511eddfb74f02f3a6598980bb9", "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x41ece55743711a8c3cbf3783cd08c0ee4d4dc440d4641a8f366e550dfdb3bb67" + "0x41ece55743711a8c3cbf3783cd08c0ee4d4dc440d4641a8f366e550dfdb3bb67", + "0x01" }, { "GOST2012-test", 511, 0, @@ -354,6 +373,7 @@ static const ecc_domain_parms_t domain_parms[] = "fd60611262cd838dc6b60aa7eee804e28bc849977fac33b4b530f1b120248a9a", "0x2bb312a43bd2ce6e0d020613c857acddcfbf061e91e5f2c3f32447c259f39b2" "c83ab156d77f1496bf7eb3351e1ee4e43dc1a18b91b24640b6dbb92cb1add371e", + "0x01" }, { "GOST2012-tc26-A", 512, 0, @@ -370,6 +390,7 @@ static const ecc_domain_parms_t domain_parms[] = "0000000000000000000000000000000000000000000000000000000000000003", "0x7503cfe87a836ae3a61b8816e25450e6ce5e1c93acf1abc1778064fdcbefa921" "df1626be4fd036e93d75e6a50e3a41e98028fe5fc235f5b889a589cb5215f2a4", + "0x01" }, { "GOST2012-tc26-B", 512, 0, @@ -386,6 +407,7 @@ static const ecc_domain_parms_t domain_parms[] = "0000000000000000000000000000000000000000000000000000000000000002", "0x1a8f7eda389b094c2c071e3647a8940f3c123b697578c213be6dd9e6c8ec7335" "dcb228fd1edf4a39152cbcaaf8c0398828041055f94ceeec7e21340780fe41bd", + "0x01" }, { @@ -396,10 +418,11 @@ static const ecc_domain_parms_t domain_parms[] = "0x0000000000000000000000000000000000000000000000000000000000000007", "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", - "0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8" + "0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", + "0x01" }, - { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL } + { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } }; @@ -530,6 +553,8 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, curve->b = scanval (domain_parms[idx].b); if (!curve->n) curve->n = scanval (domain_parms[idx].n); + if (!curve->h) + curve->h = scanval (domain_parms[idx].h); if (!curve->G.x) curve->G.x = scanval (domain_parms[idx].g_x); if (!curve->G.y) @@ -545,7 +570,7 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, /* Give the name of the curve NAME, store the curve parameters into P, - A, B, G, and N if they point to NULL value. Note that G is returned + A, B, G, N, and H if they point to NULL value. Note that G is returned in standard uncompressed format. Also update MODEL and DIALECT if they are not NULL. */ gpg_err_code_t @@ -553,7 +578,7 @@ _gcry_ecc_update_curve_param (const char *name, enum gcry_mpi_ec_models *model, enum ecc_dialects *dialect, gcry_mpi_t *p, gcry_mpi_t *a, gcry_mpi_t *b, - gcry_mpi_t *g, gcry_mpi_t *n) + gcry_mpi_t *g, gcry_mpi_t *n, gcry_mpi_t *h) { int idx; @@ -603,6 +628,11 @@ _gcry_ecc_update_curve_param (const char *name, _gcry_mpi_release (*n); *n = scanval (domain_parms[idx].n); } + if (h) + { + _gcry_mpi_release (*h); + *h = scanval (domain_parms[idx].h); + } return 0; } @@ -640,8 +670,8 @@ _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) /* * Extract the curve parameters.. */ - rc = gpg_err_code (sexp_extract_param (keyparms, NULL, "-pabgn", - &E.p, &E.a, &E.b, &mpi_g, &E.n, + rc = gpg_err_code (sexp_extract_param (keyparms, NULL, "-pabgnh", + &E.p, &E.a, &E.b, &mpi_g, &E.n, &E.h, NULL)); if (rc == GPG_ERR_NO_OBJ) { @@ -699,17 +729,22 @@ _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) if (!mpi_cmp (tmp, E.n)) { mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_x); - if (!mpi_cmp (tmp, E.G.x)) + tmp = scanval (domain_parms[idx].h); + if (!mpi_cmp (tmp, E.h)) { mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_y); - if (!mpi_cmp (tmp, E.G.y)) + tmp = scanval (domain_parms[idx].g_x); + if (!mpi_cmp (tmp, E.G.x)) { - result = domain_parms[idx].desc; - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - goto leave; + mpi_free (tmp); + tmp = scanval (domain_parms[idx].g_y); + if (!mpi_cmp (tmp, E.G.y)) + { + result = domain_parms[idx].desc; + if (r_nbits) + *r_nbits = domain_parms[idx].nbits; + goto leave; + } } } } @@ -726,6 +761,7 @@ _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) _gcry_mpi_release (mpi_g); _gcry_mpi_point_free_parts (&E.G); _gcry_mpi_release (E.n); + _gcry_mpi_release (E.h); return result; } @@ -857,6 +893,7 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, gcry_mpi_t b = NULL; gcry_mpi_point_t G = NULL; gcry_mpi_t n = NULL; + gcry_mpi_t h = NULL; gcry_mpi_point_t Q = NULL; gcry_mpi_t d = NULL; int flags = 0; @@ -899,6 +936,9 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, errc = mpi_from_keyparam (&n, keyparam, "n"); if (errc) goto leave; + errc = mpi_from_keyparam (&h, keyparam, "h"); + if (errc) + goto leave; } } else @@ -972,6 +1012,11 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, n = E->n; E->n = NULL; } + if (!h) + { + h = E->h; + E->h = NULL; + } _gcry_ecc_curve_free (E); xfree (E); } @@ -998,6 +1043,11 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, ec->n = n; n = NULL; } + if (h) + { + ec->h = h; + h = NULL; + } /* Now that we know the curve name we can look for the public key Q. point_from_keyparam needs to know the curve parameters so @@ -1036,6 +1086,7 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, mpi_free (b); _gcry_mpi_point_release (G); mpi_free (n); + mpi_free (h); _gcry_mpi_point_release (Q); mpi_free (d); return errc; @@ -1050,7 +1101,7 @@ _gcry_ecc_get_param_sexp (const char *name) elliptic_curve_t E; mpi_ec_t ctx; gcry_mpi_t g_x, g_y; - gcry_mpi_t pkey[6]; + gcry_mpi_t pkey[7]; gcry_sexp_t result; int i; @@ -1074,14 +1125,15 @@ _gcry_ecc_get_param_sexp (const char *name) pkey[2] = E.b; pkey[3] = _gcry_ecc_ec2os (g_x, g_y, E.p); pkey[4] = E.n; - pkey[5] = NULL; + pkey[5] = E.h; + pkey[6] = NULL; mpi_free (g_x); mpi_free (g_y); if (sexp_build (&result, NULL, - "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))", - pkey[0], pkey[1], pkey[2], pkey[3], pkey[4])) + "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)))", + pkey[0], pkey[1], pkey[2], pkey[3], pkey[4], pkey[5])) result = NULL; for (i=0; pkey[i]; i++) @@ -1108,6 +1160,8 @@ _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b); if (!strcmp (name, "n") && ec->n) return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n); + if (!strcmp (name, "h") && ec->h) + return mpi_is_const (ec->h) && !copy? ec->h : mpi_copy (ec->h); if (!strcmp (name, "d") && ec->d) return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d); @@ -1206,6 +1260,11 @@ _gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec) mpi_free (ec->n); ec->n = mpi_copy (newvalue); } + else if (!strcmp (name, "h")) + { + mpi_free (ec->h); + ec->h = mpi_copy (newvalue); + } else if (*name == 'q' && (!name[1] || name[1] == '@')) { if (newvalue) diff --git a/cipher/ecc-eddsa.c b/cipher/ecc-eddsa.c index 65024a3..a12ebab 100644 --- a/cipher/ecc-eddsa.c +++ b/cipher/ecc-eddsa.c @@ -525,6 +525,7 @@ _gcry_ecc_eddsa_genkey (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx, point_init (&sk->E.G); point_set (&sk->E.G, &E->G); sk->E.n = mpi_copy (E->n); + sk->E.h = mpi_copy (E->h); point_init (&sk->Q); point_set (&sk->Q, &Q); diff --git a/cipher/ecc-misc.c b/cipher/ecc-misc.c index 3f284fe..88266b5 100644 --- a/cipher/ecc-misc.c +++ b/cipher/ecc-misc.c @@ -43,6 +43,7 @@ _gcry_ecc_curve_free (elliptic_curve_t *E) mpi_free (E->b); E->b = NULL; _gcry_mpi_point_free_parts (&E->G); mpi_free (E->n); E->n = NULL; + mpi_free (E->h); E->h = NULL; } @@ -63,6 +64,7 @@ _gcry_ecc_curve_copy (elliptic_curve_t E) _gcry_mpi_point_init (&R.G); point_set (&R.G, &E.G); R.n = mpi_copy (E.n); + R.h = mpi_copy (E.h); return R; } diff --git a/cipher/ecc.c b/cipher/ecc.c index a27d2c6..8bdbd56 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -142,6 +142,7 @@ nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx, point_init (&sk->E.G); point_set (&sk->E.G, &E->G); sk->E.n = mpi_copy (E->n); + sk->E.h = mpi_copy (E->h); point_init (&sk->Q); /* We want the Q=(x,y) be a "compliant key" in terms of the @@ -456,6 +457,7 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey) log_printmpi ("ecgen curve a", E.a); log_printmpi ("ecgen curve b", E.b); log_printmpi ("ecgen curve n", E.n); + log_printmpi ("ecgen curve h", E.h); log_printpnt ("ecgen curve G", &E.G, NULL); } @@ -524,14 +526,14 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey) rc = sexp_build (r_skey, NULL, "(key-data" " (public-key" - " (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))" + " (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)))" " (private-key" - " (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))" + " (ecc%S%S(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)(d%m)))" " )", curve_info, curve_flags, - sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public, + sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, sk.E.h, public, curve_info, curve_flags, - sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, public, secret); + sk.E.p, sk.E.a, sk.E.b, base, sk.E.n, sk.E.h, public, secret); else rc = sexp_build (r_skey, NULL, "(key-data" @@ -554,6 +556,7 @@ ecc_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey) log_printmpi ("ecgen result b", sk.E.b); log_printmpi ("ecgen result G", base); log_printmpi ("ecgen result n", sk.E.n); + log_printmpi ("ecgen result h", sk.E.h); log_printmpi ("ecgen result Q", public); log_printmpi ("ecgen result d", secret); if ((flags & PUBKEY_FLAG_EDDSA)) @@ -604,9 +607,9 @@ ecc_check_secret_key (gcry_sexp_t keyparms) /* Extract the parameters. */ if ((flags & PUBKEY_FLAG_PARAM)) - rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?/q?+d", + rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?h?/q?+d", &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n, - &mpi_q, &sk.d, NULL); + &sk.E.h, &mpi_q, &sk.d, NULL); else rc = sexp_extract_param (keyparms, NULL, "/q?+d", &mpi_q, &sk.d, NULL); @@ -624,7 +627,7 @@ ecc_check_secret_key (gcry_sexp_t keyparms) rc = _gcry_ecc_update_curve_param (curvename, &sk.E.model, &sk.E.dialect, &sk.E.p, &sk.E.a, &sk.E.b, - &mpi_g, &sk.E.n); + &mpi_g, &sk.E.n, &sk.E.h); if (rc) return rc; } @@ -660,11 +663,12 @@ ecc_check_secret_key (gcry_sexp_t keyparms) log_printmpi ("ecc_testkey b", sk.E.b); log_printpnt ("ecc_testkey g", &sk.E.G, NULL); log_printmpi ("ecc_testkey n", sk.E.n); + log_printmpi ("ecc_testkey h", sk.E.h); log_printmpi ("ecc_testkey q", mpi_q); if (!fips_mode ()) log_printmpi ("ecc_testkey d", sk.d); } - if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.d) + if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.E.h || !sk.d) { rc = GPG_ERR_NO_OBJ; goto leave; @@ -701,6 +705,7 @@ ecc_check_secret_key (gcry_sexp_t keyparms) _gcry_mpi_release (mpi_g); point_free (&sk.E.G); _gcry_mpi_release (sk.E.n); + _gcry_mpi_release (sk.E.h); _gcry_mpi_release (mpi_q); point_free (&sk.Q); _gcry_mpi_release (sk.d); @@ -741,9 +746,9 @@ ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms) * Extract the key. */ if ((ctx.flags & PUBKEY_FLAG_PARAM)) - rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?/q?+d", + rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?h?/q?+d", &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n, - &mpi_q, &sk.d, NULL); + &sk.E.h, &mpi_q, &sk.d, NULL); else rc = sexp_extract_param (keyparms, NULL, "/q?+d", &mpi_q, &sk.d, NULL); @@ -793,11 +798,12 @@ ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms) log_printmpi ("ecc_sign b", sk.E.b); log_printpnt ("ecc_sign g", &sk.E.G, NULL); log_printmpi ("ecc_sign n", sk.E.n); + log_printmpi ("ecc_sign h", sk.E.h); log_printmpi ("ecc_sign q", mpi_q); if (!fips_mode ()) log_printmpi ("ecc_sign d", sk.d); } - if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.d) + if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.E.h || !sk.d) { rc = GPG_ERR_NO_OBJ; goto leave; @@ -838,6 +844,7 @@ ecc_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_data, gcry_sexp_t keyparms) _gcry_mpi_release (mpi_g); point_free (&sk.E.G); _gcry_mpi_release (sk.E.n); + _gcry_mpi_release (sk.E.h); _gcry_mpi_release (mpi_q); point_free (&sk.Q); _gcry_mpi_release (sk.d); @@ -905,9 +912,9 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms) * Extract the key. */ if ((ctx.flags & PUBKEY_FLAG_PARAM)) - rc = sexp_extract_param (s_keyparms, NULL, "-p?a?b?g?n?/q", + rc = sexp_extract_param (s_keyparms, NULL, "-p?a?b?g?n?h?/q", &pk.E.p, &pk.E.a, &pk.E.b, &mpi_g, &pk.E.n, - &mpi_q, NULL); + &pk.E.n, &mpi_q, NULL); else rc = sexp_extract_param (s_keyparms, NULL, "/q", &mpi_q, NULL); @@ -958,9 +965,10 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms) log_printmpi ("ecc_verify b", pk.E.b); log_printpnt ("ecc_verify g", &pk.E.G, NULL); log_printmpi ("ecc_verify n", pk.E.n); + log_printmpi ("ecc_verify h", pk.E.h); log_printmpi ("ecc_verify q", mpi_q); } - if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !mpi_q) + if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !pk.E.h || !mpi_q) { rc = GPG_ERR_NO_OBJ; goto leave; @@ -1036,6 +1044,7 @@ ecc_verify (gcry_sexp_t s_sig, gcry_sexp_t s_data, gcry_sexp_t s_keyparms) _gcry_mpi_release (mpi_g); point_free (&pk.E.G); _gcry_mpi_release (pk.E.n); + _gcry_mpi_release (pk.E.h); _gcry_mpi_release (mpi_q); point_free (&pk.Q); _gcry_mpi_release (data); @@ -1115,8 +1124,8 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) /* * Extract the key. */ - rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?+q", - &pk.E.p, &pk.E.a, &pk.E.b, &mpi_g, &pk.E.n, + rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?h?+q", + &pk.E.p, &pk.E.a, &pk.E.b, &mpi_g, &pk.E.n, &pk.E.h, &mpi_q, NULL); if (rc) goto leave; @@ -1159,9 +1168,10 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) log_printmpi ("ecc_encrypt b", pk.E.b); log_printpnt ("ecc_encrypt g", &pk.E.G, NULL); log_printmpi ("ecc_encrypt n", pk.E.n); + log_printmpi ("ecc_encrypt h", pk.E.h); log_printmpi ("ecc_encrypt q", mpi_q); } - if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !mpi_q) + if (!pk.E.p || !pk.E.a || !pk.E.b || !pk.E.G.x || !pk.E.n || !pk.E.h || !mpi_q) { rc = GPG_ERR_NO_OBJ; goto leave; @@ -1219,6 +1229,7 @@ ecc_encrypt_raw (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) _gcry_mpi_release (mpi_g); point_free (&pk.E.G); _gcry_mpi_release (pk.E.n); + _gcry_mpi_release (pk.E.h); _gcry_mpi_release (mpi_q); point_free (&pk.Q); _gcry_mpi_release (data); @@ -1282,9 +1293,9 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) /* * Extract the key. */ - rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?+d", + rc = sexp_extract_param (keyparms, NULL, "-p?a?b?g?n?h?+d", &sk.E.p, &sk.E.a, &sk.E.b, &mpi_g, &sk.E.n, - &sk.d, NULL); + &sk.E.h, &sk.d, NULL); if (rc) goto leave; if (mpi_g) @@ -1325,10 +1336,11 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) log_printmpi ("ecc_decrypt b", sk.E.b); log_printpnt ("ecc_decrypt g", &sk.E.G, NULL); log_printmpi ("ecc_decrypt n", sk.E.n); + log_printmpi ("ecc_decrypt h", sk.E.h); if (!fips_mode ()) log_printmpi ("ecc_decrypt d", sk.d); } - if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.d) + if (!sk.E.p || !sk.E.a || !sk.E.b || !sk.E.G.x || !sk.E.n || !sk.E.h || !sk.d) { rc = GPG_ERR_NO_OBJ; goto leave; @@ -1385,6 +1397,7 @@ ecc_decrypt_raw (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) _gcry_mpi_release (mpi_g); point_free (&sk.E.G); _gcry_mpi_release (sk.E.n); + _gcry_mpi_release (sk.E.h); _gcry_mpi_release (sk.d); _gcry_mpi_release (data_e); xfree (curvename); @@ -1454,8 +1467,8 @@ ecc_get_nbits (gcry_sexp_t parms) static gpg_err_code_t compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms) { -#define N_COMPONENTS 6 - static const char names[N_COMPONENTS+1] = "pabgnq"; +#define N_COMPONENTS 7 + static const char names[N_COMPONENTS] = "pabgnhq"; gpg_err_code_t rc; gcry_sexp_t l1; gcry_mpi_t values[N_COMPONENTS]; @@ -1483,24 +1496,24 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms) if ((flags & PUBKEY_FLAG_PARAM)) { if ((flags & PUBKEY_FLAG_EDDSA)) - rc = sexp_extract_param (keyparms, NULL, "p?a?b?g?n?/q", + rc = sexp_extract_param (keyparms, NULL, "p?a?b?g?n?h?/q", &values[0], &values[1], &values[2], &values[3], &values[4], &values[5], - NULL); + &values[6], NULL); else - rc = sexp_extract_param (keyparms, NULL, "p?a?b?g?n?q", + rc = sexp_extract_param (keyparms, NULL, "p?a?b?g?n?h?q", &values[0], &values[1], &values[2], &values[3], &values[4], &values[5], - NULL); + &values[6], NULL); } else { if ((flags & PUBKEY_FLAG_EDDSA)) rc = sexp_extract_param (keyparms, NULL, "/q", - &values[5], NULL); + &values[6], NULL); else rc = sexp_extract_param (keyparms, NULL, "q", - &values[5], NULL); + &values[6], NULL); } if (rc) goto leave; @@ -1517,7 +1530,7 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms) rc = _gcry_ecc_update_curve_param (curvename, &model, &dialect, &values[0], &values[1], &values[2], - &values[3], &values[4]); + &values[3], &values[4], &values[5]); if (rc) goto leave; } @@ -1555,7 +1568,7 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms) if ((flags & PUBKEY_FLAG_EDDSA)) { if (dialect == ECC_DIALECT_ED25519) - rc = _gcry_ecc_eddsa_ensure_compact (values[5], 256); + rc = _gcry_ecc_eddsa_ensure_compact (values[6], 256); else rc = GPG_ERR_NOT_IMPLEMENTED; if (rc) @@ -1567,6 +1580,9 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms) { char buf[30]; + if (idx == 5) + continue; /* Skip cofactor. */ + if (mpi_is_opaque (values[idx])) { const unsigned char *raw; @@ -1624,7 +1640,7 @@ _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec) gcry_mpi_t mpi_G = NULL; gcry_mpi_t mpi_Q = NULL; - if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n) + if (!ec->p || !ec->a || !ec->b || !ec->G || !ec->n || !ec->h) return GPG_ERR_BAD_CRYPT_CTX; if (mode == GCRY_PK_GET_SECKEY && !ec->d) @@ -1676,15 +1692,15 @@ _gcry_pk_ecc_get_sexp (gcry_sexp_t *r_sexp, int mode, mpi_ec_t ec) { /* Let's return a private key. */ rc = sexp_build (r_sexp, NULL, - "(private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)(d%m)))", - ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q, ec->d); + "(private-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)(d%m)))", + ec->p, ec->a, ec->b, mpi_G, ec->n, ec->h, mpi_Q, ec->d); } else if (ec->Q) { /* Let's return a public key. */ rc = sexp_build (r_sexp, NULL, - "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(q%m)))", - ec->p, ec->a, ec->b, mpi_G, ec->n, mpi_Q); + "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)(q%m)))", + ec->p, ec->a, ec->b, mpi_G, ec->n, ec->h, mpi_Q); } else rc = GPG_ERR_BAD_CRYPT_CTX; @@ -1744,7 +1760,7 @@ gcry_pk_spec_t _gcry_pubkey_spec_ecc = GCRY_PK_ECC, { 0, 0 }, (GCRY_PK_USAGE_SIGN | GCRY_PK_USAGE_ENCR), "ECC", ecc_names, - "pabgnq", "pabgnqd", "sw", "rs", "pabgnq", + "pabgnhq", "pabgnhqd", "sw", "rs", "pabgnhq", ecc_generate, ecc_check_secret_key, ecc_encrypt_raw, diff --git a/mpi/ec.c b/mpi/ec.c index 4f35de0..737f12c 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -429,6 +429,7 @@ ec_deinit (void *opaque) mpi_free (ctx->b); _gcry_mpi_point_release (ctx->G); mpi_free (ctx->n); + mpi_free (ctx->h); /* The key. */ _gcry_mpi_point_release (ctx->Q); diff --git a/src/ec-context.h b/src/ec-context.h index 60ca759..c8f2ad0 100644 --- a/src/ec-context.h +++ b/src/ec-context.h @@ -38,6 +38,7 @@ struct mpi_ec_ctx_s gcry_mpi_t b; /* Second coefficient of the Weierstrass equation. */ gcry_mpi_point_t G; /* Base point (generator). */ gcry_mpi_t n; /* Order of G. */ + gcry_mpi_t h; /* Cofactor. */ /* The actual key. May not be set. */ gcry_mpi_point_t Q; /* Public key. */ diff --git a/tests/curves.c b/tests/curves.c index 0581452..178a192 100644 --- a/tests/curves.c +++ b/tests/curves.c @@ -41,6 +41,7 @@ static char const sample_key_1[] = " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)\n" " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)\n" +" (h #000000000000000000000000000000000000000000000000000000000000000001#)\n" " (q #0442B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146EE" "86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E#)\n" " ))"; @@ -57,6 +58,7 @@ static char const sample_key_2[] = " (g #04bed5af16ea3f6a4f62938c4631eb5af7bdbcdbc3" "1667cb477a1a8ec338f94741669c976316da6321#)\n" " (n #00e95e4a5f737059dc60df5991d45029409e60fc09#)\n" +" (h #000000000000000000000000000000000000000000000000000000000000000001#)\n" " (q #041111111111111111111111111111111111111111" "2222222222222222222222222222222222222222#)\n" " ))"; diff --git a/tests/keygrip.c b/tests/keygrip.c index 72960ea..3ef1de1 100644 --- a/tests/keygrip.c +++ b/tests/keygrip.c @@ -110,6 +110,7 @@ static struct " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" + " (h #000000000000000000000000000000000000000000000000000000000000000001#)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" }, @@ -122,6 +123,7 @@ static struct " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" + " (h #000000000000000000000000000000000000000000000000000000000000000001#)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" }, @@ -134,6 +136,7 @@ static struct " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" + " (h #000000000000000000000000000000000000000000000000000000000000000001#)" " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" }, diff --git a/tests/t-mpi-point.c b/tests/t-mpi-point.c index 88bb5bd..d72cd27 100644 --- a/tests/t-mpi-point.c +++ b/tests/t-mpi-point.c @@ -57,6 +57,7 @@ static struct const char *a, *b; /* The coefficients. */ const char *n; /* The order of the base point. */ const char *g_x, *g_y; /* Base point. */ + const char *h; /* Cofactor. */ } test_curve[] = { { @@ -67,7 +68,8 @@ static struct "0xffffffffffffffffffffffff99def836146bc9b1b4d22831", "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", - "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811" + "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811", + "0x01" }, { "NIST P-224", @@ -77,7 +79,8 @@ static struct "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" , "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", - "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34" + "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", + "0x01" }, { "NIST P-256", @@ -87,7 +90,8 @@ static struct "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" + "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "0x01" }, { "NIST P-384", @@ -103,7 +107,8 @@ static struct "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" "5502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" - "0a60b1ce1d7e819d7a431d7c90ea0e5f" + "0a60b1ce1d7e819d7a431d7c90ea0e5f", + "0x01" }, { "NIST P-521", @@ -119,7 +124,8 @@ static struct "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d" "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6" - "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" + "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", + "0x01" }, { "Ed25519", @@ -128,9 +134,10 @@ static struct "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", - "0x6666666666666666666666666666666666666666666666666666666666666658" + "0x6666666666666666666666666666666666666666666666666666666666666658", + "0x08" }, - { NULL, NULL, NULL, NULL, NULL } + { NULL, NULL, NULL, NULL, NULL, NULL } }; /* A sample public key for NIST P-256. */ @@ -556,6 +563,8 @@ context_param (void) if (get_and_cmp_point ("g", test_curve[idx].g_x, test_curve[idx].g_y, test_curve[idx].desc, ctx)) continue; + if (get_and_cmp_mpi ("h", test_curve[idx].h, test_curve[idx].desc, ctx)) + continue; } ----------------------------------------------------------------------- Summary of changes: cipher/ecc-common.h | 3 +- cipher/ecc-curves.c | 129 +++++++++++++++++++++++++++++++++++++-------------- cipher/ecc-eddsa.c | 1 + cipher/ecc-misc.c | 2 + cipher/ecc.c | 88 +++++++++++++++++++++-------------- mpi/ec.c | 1 + src/ec-context.h | 1 + tests/curves.c | 2 + tests/keygrip.c | 3 ++ tests/t-mpi-point.c | 23 ++++++--- 10 files changed, 174 insertions(+), 79 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From wk at gnupg.org Fri Aug 8 11:19:46 2014 From: wk at gnupg.org (Werner Koch) Date: Fri, 08 Aug 2014 11:19:46 +0200 Subject: [PATCH] ecc: support Montgomery curve for gcry_mpi_ec_mul_point In-Reply-To: <1407470920.1568.7.camel@cfw2.gniibe.org> (NIIBE Yutaka's message of "Fri, 08 Aug 2014 13:08:40 +0900") References: <1407464538.1568.4.camel@cfw2.gniibe.org> <1407470920.1568.7.camel@cfw2.gniibe.org> Message-ID: <87wqajuyml.fsf@vigenere.g10code.de> On Fri, 8 Aug 2014 06:08, gniibe at fsij.org said: > I don't know if we should support gcry_mpi_ec_curve_point when it's > x-coordinate only for Montgomery curve. It would be OK always return > true for Montgomery curve. For a correct result we should evaluate the equation and show that Y is a square. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From teichm at in.tum.de Fri Aug 8 11:37:26 2014 From: teichm at in.tum.de (Markus Teich) Date: Fri, 8 Aug 2014 11:37:26 +0200 Subject: [PATCH revised] Add gcry_mpi_ec_sub. In-Reply-To: <1406738375-14267-1-git-send-email-teichm@in.tum.de> References: <20140722122411.GG4246@yoink.cs.uwaterloo.ca> <1406738375-14267-1-git-send-email-teichm@in.tum.de> Message-ID: <20140808093726.GD32507@trolle> Markus Teich wrote: > This function subtracts two points on the curve. Only Twisted Edwards curves > are supported with this change. Heyho, am I supposed to do something here or is this just an extended review phase? --Markus From wk at gnupg.org Fri Aug 8 15:06:07 2014 From: wk at gnupg.org (Werner Koch) Date: Fri, 08 Aug 2014 15:06:07 +0200 Subject: [PATCH revised] Add gcry_mpi_ec_sub. In-Reply-To: <20140808093726.GD32507@trolle> (Markus Teich's message of "Fri, 8 Aug 2014 11:37:26 +0200") References: <20140722122411.GG4246@yoink.cs.uwaterloo.ca> <1406738375-14267-1-git-send-email-teichm@in.tum.de> <20140808093726.GD32507@trolle> Message-ID: <877g2juo5c.fsf@vigenere.g10code.de> On Fri, 8 Aug 2014 11:37, teichm at in.tum.de said: > am I supposed to do something here or is this just an extended review phase? Are you sure the patch is complete? I have not seen changes to libgcrypt.vers and libgcrypt.def which renders this patch useless - you can't use it because the function won't be exported on systems build with the GNU toolchain. Is tehre a doc entry? A proper commit message is also missing. Please see doc/HACKING. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From teichm at in.tum.de Fri Aug 8 16:22:14 2014 From: teichm at in.tum.de (Markus Teich) Date: Fri, 8 Aug 2014 16:22:14 +0200 Subject: [PATCH revised] Add gcry_mpi_ec_sub. In-Reply-To: <877g2juo5c.fsf@vigenere.g10code.de> References: <20140722122411.GG4246@yoink.cs.uwaterloo.ca> <1406738375-14267-1-git-send-email-teichm@in.tum.de> <20140808093726.GD32507@trolle> <877g2juo5c.fsf@vigenere.g10code.de> Message-ID: <20140808142214.GF32507@trolle> Werner Koch wrote: > Are you sure the patch is complete? I have not seen changes to libgcrypt.vers > and libgcrypt.def which renders this patch useless - you can't use it because > the function won't be exported on systems build with the GNU toolchain. Is > tehre a doc entry? A proper commit message is also missing. Please see > doc/HACKING. Heyho, thanks, I missed the docu on patch submission format. Is the attached patch ok? --Markus -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-mpi-Add-gcry_mpi_ec_sub.patch Type: text/x-diff Size: 8557 bytes Desc: not available URL: From teichm at in.tum.de Fri Aug 8 21:59:25 2014 From: teichm at in.tum.de (Markus Teich) Date: Fri, 8 Aug 2014 21:59:25 +0200 Subject: ec subtract In-Reply-To: <1405083634.3861.1.camel@latx1.gniibe.org> References: <20140710171426.GE32268@trolle> <53BECEDC.106@in.tum.de> <1405044856.4772.1.camel@cfw2.gniibe.org> <20140711091241.GA2521@trolle> <1405083634.3861.1.camel@latx1.gniibe.org> Message-ID: <20140808195925.GI32507@trolle> NIIBE Yutaka wrote: > If I were you and I had to stand with such a constraint, I'd use negative > scalar for n in [n]P. I mean, I would have to modify the expression: > > Xi = [ri](Zi+1 - Zi-1) > one point subtraction and one scalar multiplication of point > > into: > > Xi = [ri]Zi+1 + [-ri]Zi-1 > two scalar multiplications of point and one point addition Heyho NIIBE, actually this does not work for me: gcry_mpi_ec_mul(*ret, priv, succ, edctx); gcry_mpi_neg(tmp, priv); gcry_mpi_ec_mul(tmpoint, tmp, pred, edctx); gcry_mpi_ec_add(*ret, *ret, tmpoint, edctx); with {*ret, succ, pred, tmpoint} beeing points and {tmp, priv} beeing mpis leads to a wrong result, while: gcry_mpi_point_get(x, y, z, pred); gcry_mpi_neg(x, x); gcry_mpi_point_set(tmpoint, x, y, z); gcry_mpi_ec_add(tmpoint2, succ, tmpoint, edctx); gcry_mpi_ec_mul(*ret, priv, tmpoint2, edctx); leads to the correct result. At least both versions produce different *ret values and the circle keys from step 3 only match if I use the second algorithm. So I will stick with the second version until the native gcry_mpi_ec_sub is released in v1.7. --Markus From ametzler at bebt.de Sat Aug 9 11:32:10 2014 From: ametzler at bebt.de (Andreas Metzler) Date: Sat, 9 Aug 2014 11:32:10 +0200 Subject: [Announce] [security fix] Libgcrypt and GnuPG References: <87egwruvz1.fsf__22173.0209225372$1407493606$gmane$org@vigenere.g10code.de> Message-ID: Werner Koch wrote: [...] > While evaluating the "Get Your Hands Off My Laptop" [1] paper I missed > to describe [2] a software combination which has not been fixed and is > thus vulnerable to the attack described by the paper. If you are using [...] > gpg2 --version > on the command line; the second line of the output gives the Libgcrypt > version: > gpg (GnuPG) 2.0.25 > libgcrypt 1.5.3 > In this example Libgcrypt is vulnerable. [ and 1.5.4 is not ... ] Hello, libgcrypt 1.5.3 -> 1.5.4 seem to be essentiall 5 git commits. - Is the bugfix in a single commit, and if it is which one? thanks, cu Andreas -- `What a good friend you are to him, Dr. Maturin. His other friends are so grateful to you.' `I sew his ears on from time to time, sure' From cvs at cvs.gnupg.org Sat Aug 9 15:00:33 2014 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Sat, 09 Aug 2014 15:00:33 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-104-ge6d3548 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via e6d354865bf8f3d4c1bb5e8157a76fdd442cff41 (commit) from 9933b9e5e1a3f5b1019c75f93bd265d4a1ecc270 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e6d354865bf8f3d4c1bb5e8157a76fdd442cff41 Author: Werner Koch Date: Sat Aug 9 14:36:59 2014 +0200 tests: Add a benchmark for Elgamal. * tests/benchmark.c (sample_public_elg_key_1024): New. (sample_private_elg_key_1024): New. (sample_public_elg_key_2048, sample_private_elg_key_2048): New. (sample_public_elg_key_3072, sample_private_elg_key_3072): New. (elg_bench): New. (main): Add elg_bench. Add commands "elg" and "public". diff --git a/tests/benchmark.c b/tests/benchmark.c index 042e721..2621551 100644 --- a/tests/benchmark.c +++ b/tests/benchmark.c @@ -250,6 +250,142 @@ static const char sample_public_dsa_key_3072[] = "))\n"; +static const char sample_public_elg_key_1024[] = +"(public-key" +" (elg" +" (p #00F7CC7C08AF096B620C545C9353B1140D698FF8BE2D97A3515C17C7F8DABCDB8FB6" + "64A46416C90C530C18DF5ABB6C1DDE3AE2FA9DDC9CE40DF644CDE2E759F6DE43F31A" + "EEEBC136A460B3E4B0A8F99326A335145B19F4C81B13804894B7D2A30F78A8A7D7F4" + "52B83836FDB0DE90BE327FB5E5318757BEF5FE0FC3A5461CBEA0D3#)" +" (g #06#)" +" (y #36B38FB63E3340A0DD8A0468E9FAA512A32DA010BF7110201D0A3DF1B8FEA0E16F3C" + "80374584E554804B96EAA8C270FE531F75D0DBD81BA65640EDB1F76D46C27D2925B7" + "3EC3B295CDAEEF242904A84D74FB2879425F82D4C5B59BB49A992F85D574168DED85" + "D227600BBEF7AF0B8F0DEB785528370E4C4B3E4D65C536122A5A#)" +" ))"; +static const char sample_private_elg_key_1024[] = +"(private-key" +" (elg" +" (p #00F7CC7C08AF096B620C545C9353B1140D698FF8BE2D97A3515C17C7F8DABCDB8FB6" + "64A46416C90C530C18DF5ABB6C1DDE3AE2FA9DDC9CE40DF644CDE2E759F6DE43F31A" + "EEEBC136A460B3E4B0A8F99326A335145B19F4C81B13804894B7D2A30F78A8A7D7F4" + "52B83836FDB0DE90BE327FB5E5318757BEF5FE0FC3A5461CBEA0D3#)" +" (g #06#)" +" (y #36B38FB63E3340A0DD8A0468E9FAA512A32DA010BF7110201D0A3DF1B8FEA0E16F3C" + "80374584E554804B96EAA8C270FE531F75D0DBD81BA65640EDB1F76D46C27D2925B7" + "3EC3B295CDAEEF242904A84D74FB2879425F82D4C5B59BB49A992F85D574168DED85" + "D227600BBEF7AF0B8F0DEB785528370E4C4B3E4D65C536122A5A#)" +" (x #03656C6186FCD27D4A4B1F5010DC0D2AE7833B501E423FCD51DE5EB6D80DACFE#)" +" ))"; + + +static const char sample_public_elg_key_2048[] = +"(public-key" +" (elg" +" (p #00BE5A2BB4E562D7B644E3D01321CB818DBA27295C339FC2C47EAE9823225EE1E7B6" + "38C5DE300E931080E09CC89A18C9D180C16559FEF0D89D6A09534BB86489CCCEE30D" + "C18E007A8726BB99F2B2D90D2694597757B120CD2435C0098AD1B74C20004C25BA97" + "73EAA4FBEC594EE17F8B25867EEB0F9F857C751116ADED68ADA2A1E9F9F4F40D18F0" + "EC1221CA6A746FC5F4CDA2B8B5D0AB83834564ACF6FDBB1AB01D4BFBD1E2C0108FF5" + "5FB3190C6D6DA4D95EA683EFA44935CFBC0BF5C6118ACC3768AEA9A98D06024841B8" + "D07C234289D22A5E3948F199C397AA991C59A55BEA0C01E91902E039116946FEA135" + "768011AF6B622C5AF366EF0196FC4EAEAA8127#)" +" (g #07#)" +" (y #5AFF87BC23D8B97AA62897A5C1CDFFA86C59F39EDBD6012B6F333CE23D872009B8C8" + "D1E220E18CFCADFE0AA16346BA2EA132472FFEC746D11C6E758896052313BB501210" + "2389C683A25A3464E9B35A192BAE0A3BB99C973126F7560D968C4A754901DC967354" + "D61A90ACD56D90DCC4337AFB71FAE3FD18C60EB0D6DD173877DF5DB5199C4931FE4E" + "5046F814422580E1162798406FC6554781142DBB7922D4B5B37A111F23761636090F" + "6212681E133365191CF15753AE737F17943ED4B7506DE0A85C3B6D63227F9D65ADF8" + "2C3DF0676C8F43B5B1C07D9AD4E6D0C812401D7DA7B9484DBA8CD3B73B19A95EB237" + "D493E092AEA2371AA904009C8960B0969D12#)" +" ))"; +static const char sample_private_elg_key_2048[] = +"(private-key" +" (elg" +" (p #00BE5A2BB4E562D7B644E3D01321CB818DBA27295C339FC2C47EAE9823225EE1E7B6" + "38C5DE300E931080E09CC89A18C9D180C16559FEF0D89D6A09534BB86489CCCEE30D" + "C18E007A8726BB99F2B2D90D2694597757B120CD2435C0098AD1B74C20004C25BA97" + "73EAA4FBEC594EE17F8B25867EEB0F9F857C751116ADED68ADA2A1E9F9F4F40D18F0" + "EC1221CA6A746FC5F4CDA2B8B5D0AB83834564ACF6FDBB1AB01D4BFBD1E2C0108FF5" + "5FB3190C6D6DA4D95EA683EFA44935CFBC0BF5C6118ACC3768AEA9A98D06024841B8" + "D07C234289D22A5E3948F199C397AA991C59A55BEA0C01E91902E039116946FEA135" + "768011AF6B622C5AF366EF0196FC4EAEAA8127#)" +" (g #07#)" +" (y #5AFF87BC23D8B97AA62897A5C1CDFFA86C59F39EDBD6012B6F333CE23D872009B8C8" + "D1E220E18CFCADFE0AA16346BA2EA132472FFEC746D11C6E758896052313BB501210" + "2389C683A25A3464E9B35A192BAE0A3BB99C973126F7560D968C4A754901DC967354" + "D61A90ACD56D90DCC4337AFB71FAE3FD18C60EB0D6DD173877DF5DB5199C4931FE4E" + "5046F814422580E1162798406FC6554781142DBB7922D4B5B37A111F23761636090F" + "6212681E133365191CF15753AE737F17943ED4B7506DE0A85C3B6D63227F9D65ADF8" + "2C3DF0676C8F43B5B1C07D9AD4E6D0C812401D7DA7B9484DBA8CD3B73B19A95EB237" + "D493E092AEA2371AA904009C8960B0969D12#)" +" (x #0628C3903972C55BDC1BC4223075616D3F3BA57D55532DDB40CB14CF72070E0D28BF" + "D0402B9088D25ED8FC#)" +" ))"; + +static const char sample_public_elg_key_3072[] = +"(public-key" +" (elg" +" (p #008EAA3497AFE3706E1A57FFA52E68C64C500731B58EBAFEB51C4A20AB15BA57FA72" + "BA1510A4703D5AA6F05DB67E4A776F92AD08800577DC686D00B793167A5D79C997E0" + "5B9A9E5974B4B68B4D71ED8EC37F2F45235D901997D72915643F058E712AA18275A2" + "C6F9F7C2B9B7CD1E814D215F12A840800B546AEF2A2E6C077CDD1A322738FFD36DB2" + "FA5420B5848EED870BC1A6CF55040AE8D2A5945F11AE2BCBE107B41A59EFDBD3B05C" + "F4C876C02C9AEAE22CD4C86806A415302936E4C1E5AA59DBBCCD2F83C20941A29888" + "A70ADB94D3B8A6489C46BF2C5219CD9FD2341EA21D4E68A4ECC468FD09D215FE96D4" + "7AEA12FD22B2456D2CC13672FC7E9772A365C68668157C51E46966B6A1831C429BA0" + "D513519713C49C13C5FC7C14BE0A117627B204C4478D0A93C6B57929E448C9B65BF2" + "390E04BC5940320C0262FC1A221E7C796493432239A6F12BC62C5CF32E8ADBC1730C" + "84C6E6E6BD95AF62835941F3F344AF46BFE5A8F629D5FA699FE37EF8B8C6A2484E42" + "D226206FDF7D1FB93A5457#)" +" (g #0B#)" +" (y #18E734FF645AE169079AEAFC78772371089AD3088627ECF77034AFBDF33ADF594AAF" + "3288F6979E0DB59CE3D2F0FEE031DFF187F1E4549D3C79668794CB19C14481ECDE2D" + "D50861AB674F87A011D50D35F28E424D0D2353850899C2CDD0CC8FDBFC5A0CA395F0" + "E605D46CBDD140DBEF426EBD638C9ADD83C195C45CE84ED2D2B21B87800C783A4F79" + "12226FEFBDA01C66B254534A51765AF09687275AA80C5DFBA143A6262E47C547D7E2" + "289413F8C5C56AED3FA7E5DF5526958E2294FE318AF590C0E720029C202563E6E686" + "9EC810F39A859262FB6047C1D418CAA9047A00BDB127B44B69CF6BC8E6B3709B4C23" + "79783C5F8457EFE23EDA6FF00D1DDCC29268FC4A6C18577BE2B7004089CBB824027A" + "A53C86B51DB054CC83B4F50C8923E2E9431F0A77D741237226CC68591083A2E40171" + "5C7B74100BB74003E2264F8B44A0B0BC5404C44218ABE65C04AA573877506CE4F48C" + "9E3F8AD1CD8DD9F285DD015C2FC5DEBCFA5779AD87F0BBC62E9EC6246021AB450DB9" + "4DDDEFAFD2C7C66E235D#)" +" ))"; +static const char sample_private_elg_key_3072[] = +"(private-key" +" (elg" +" (p #008EAA3497AFE3706E1A57FFA52E68C64C500731B58EBAFEB51C4A20AB15BA57FA72" + "BA1510A4703D5AA6F05DB67E4A776F92AD08800577DC686D00B793167A5D79C997E0" + "5B9A9E5974B4B68B4D71ED8EC37F2F45235D901997D72915643F058E712AA18275A2" + "C6F9F7C2B9B7CD1E814D215F12A840800B546AEF2A2E6C077CDD1A322738FFD36DB2" + "FA5420B5848EED870BC1A6CF55040AE8D2A5945F11AE2BCBE107B41A59EFDBD3B05C" + "F4C876C02C9AEAE22CD4C86806A415302936E4C1E5AA59DBBCCD2F83C20941A29888" + "A70ADB94D3B8A6489C46BF2C5219CD9FD2341EA21D4E68A4ECC468FD09D215FE96D4" + "7AEA12FD22B2456D2CC13672FC7E9772A365C68668157C51E46966B6A1831C429BA0" + "D513519713C49C13C5FC7C14BE0A117627B204C4478D0A93C6B57929E448C9B65BF2" + "390E04BC5940320C0262FC1A221E7C796493432239A6F12BC62C5CF32E8ADBC1730C" + "84C6E6E6BD95AF62835941F3F344AF46BFE5A8F629D5FA699FE37EF8B8C6A2484E42" + "D226206FDF7D1FB93A5457#)" +" (g #0B#)" +" (y #18E734FF645AE169079AEAFC78772371089AD3088627ECF77034AFBDF33ADF594AAF" + "3288F6979E0DB59CE3D2F0FEE031DFF187F1E4549D3C79668794CB19C14481ECDE2D" + "D50861AB674F87A011D50D35F28E424D0D2353850899C2CDD0CC8FDBFC5A0CA395F0" + "E605D46CBDD140DBEF426EBD638C9ADD83C195C45CE84ED2D2B21B87800C783A4F79" + "12226FEFBDA01C66B254534A51765AF09687275AA80C5DFBA143A6262E47C547D7E2" + "289413F8C5C56AED3FA7E5DF5526958E2294FE318AF590C0E720029C202563E6E686" + "9EC810F39A859262FB6047C1D418CAA9047A00BDB127B44B69CF6BC8E6B3709B4C23" + "79783C5F8457EFE23EDA6FF00D1DDCC29268FC4A6C18577BE2B7004089CBB824027A" + "A53C86B51DB054CC83B4F50C8923E2E9431F0A77D741237226CC68591083A2E40171" + "5C7B74100BB74003E2264F8B44A0B0BC5404C44218ABE65C04AA573877506CE4F48C" + "9E3F8AD1CD8DD9F285DD015C2FC5DEBCFA5779AD87F0BBC62E9EC6246021AB450DB9" + "4DDDEFAFD2C7C66E235D#)" +" (x #03A73F0389E470AAC831B039F8AA0C4EBD3A47DD083E32EEA08E4911236CD597C272" + "9823D47A51C8535DA52FE6DAB3E8D1C20D#)" +" ))"; + + #define DIM(v) (sizeof(v)/sizeof((v)[0])) #define DIMof(type,member) DIM(((type *)0)->member) #define BUG() do {fprintf ( stderr, "Ooops at %s:%d\n", __FILE__ , __LINE__ );\ @@ -877,7 +1013,7 @@ rsa_bench (int iterations, int print_header, int no_blinding) int testno; if (print_header) - printf ("Algorithm generate %4d*sign %4d*verify\n" + printf ("Algorithm generate %4d*priv %4d*public\n" "------------------------------------------------\n", iterations, iterations ); for (testno=0; testno < DIM (p_sizes); testno++) @@ -989,6 +1125,115 @@ rsa_bench (int iterations, int print_header, int no_blinding) } +static void +elg_bench (int iterations, int print_header) +{ + gpg_error_t err; + gcry_sexp_t pub_key[3], sec_key[3]; + int p_sizes[3] = { 1024, 2048, 3072 }; + gcry_sexp_t data = NULL; + gcry_sexp_t enc = NULL; + gcry_sexp_t plain = NULL; + int i, j; + + err = gcry_sexp_sscan (pub_key+0, NULL, sample_public_elg_key_1024, + strlen (sample_public_elg_key_1024)); + if (!err) + err = gcry_sexp_sscan (sec_key+0, NULL, sample_private_elg_key_1024, + strlen (sample_private_elg_key_1024)); + if (!err) + err = gcry_sexp_sscan (pub_key+1, NULL, sample_public_elg_key_2048, + strlen (sample_public_elg_key_2048)); + if (!err) + err = gcry_sexp_sscan (sec_key+1, NULL, sample_private_elg_key_2048, + strlen (sample_private_elg_key_2048)); + if (!err) + err = gcry_sexp_sscan (pub_key+2, NULL, sample_public_elg_key_3072, + strlen (sample_public_elg_key_3072)); + if (!err) + err = gcry_sexp_sscan (sec_key+2, NULL, sample_private_elg_key_3072, + strlen (sample_private_elg_key_3072)); + if (err) + { + fprintf (stderr, PGM ": converting sample keys failed: %s\n", + gcry_strerror (err)); + exit (1); + } + + if (print_header) + printf ("Algorithm generate %4d*priv %4d*public\n" + "------------------------------------------------\n", + iterations, iterations ); + for (i=0; i < DIM (p_sizes); i++) + { + char timerbuf1[100]; + + { + gcry_mpi_t x = gcry_mpi_new (p_sizes[i]); + gcry_mpi_randomize (x, p_sizes[i] - 16, GCRY_WEAK_RANDOM); + err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x); + gcry_mpi_release (x); + } + if (err) + { + fprintf (stderr, PGM ": converting data failed: %s\n", + gcry_strerror (err)); + exit (1); + } + + printf ("ELG %d bit -", p_sizes[i]); + fflush (stdout); + + start_timer (); + for (j=0; j < iterations; j++) + { + gcry_sexp_release (enc); + err = gcry_pk_encrypt (&enc, data, pub_key[i]); + if (err) + { + putchar ('\n'); + fprintf (stderr, PGM ": encrypt failed: %s\n", + gpg_strerror (err)); + exit (1); + } + } + stop_timer (); + snprintf (timerbuf1, sizeof timerbuf1, " %s", elapsed_time ()); + fflush (stdout); + + start_timer (); + for (j=0; j < iterations; j++) + { + gcry_sexp_release (plain); + err = gcry_pk_decrypt (&plain, enc, sec_key[i]); + if (err) + { + putchar ('\n'); + fprintf (stderr, PGM ": decrypt failed: %s\n", + gpg_strerror (err)); + exit (1); + } + } + stop_timer (); + + printf (" %s %s\n", elapsed_time (), timerbuf1); + fflush (stdout); + + gcry_sexp_release (plain); + plain = NULL; + gcry_sexp_release (enc); + enc = NULL; + gcry_sexp_release (data); + data = NULL; + } + + for (i=0; i < DIM (p_sizes); i++) + { + gcry_sexp_release (sec_key[i]); + gcry_sexp_release (pub_key[i]); + } +} + static void dsa_bench (int iterations, int print_header) @@ -1026,7 +1271,7 @@ dsa_bench (int iterations, int print_header) } if (print_header) - printf ("Algorithm generate %4d*sign %4d*verify\n" + printf ("Algorithm generate %4d*priv %4d*public\n" "------------------------------------------------\n", iterations, iterations ); for (i=0; i < DIM (q_sizes); i++) @@ -1104,7 +1349,7 @@ ecc_bench (int iterations, int print_header) int testno; if (print_header) - printf ("Algorithm generate %4d*sign %4d*verify\n" + printf ("Algorithm generate %4d*priv %4d*public\n" "------------------------------------------------\n", iterations, iterations ); for (testno=0; testno < DIM (p_sizes); testno++) @@ -1511,6 +1756,7 @@ main( int argc, char **argv ) cipher_bench (NULL); putchar ('\n'); rsa_bench (pk_count, 1, no_blinding); + elg_bench (pk_count, 0); dsa_bench (pk_count, 0); ecc_bench (pk_count, 0); putchar ('\n'); @@ -1559,11 +1805,24 @@ main( int argc, char **argv ) { mpi_bench (); } + else if ( !strcmp (*argv, "pubkey")) + { + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + rsa_bench (pk_count, 1, no_blinding); + elg_bench (pk_count, 0); + dsa_bench (pk_count, 0); + ecc_bench (pk_count, 0); + } else if ( !strcmp (*argv, "rsa")) { gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); rsa_bench (pk_count, 1, no_blinding); } + else if ( !strcmp (*argv, "elg")) + { + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + elg_bench (pk_count, 1); + } else if ( !strcmp (*argv, "dsa")) { gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); ----------------------------------------------------------------------- Summary of changes: tests/benchmark.c | 265 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 262 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From ametzler at bebt.de Sat Aug 9 18:37:58 2014 From: ametzler at bebt.de (Andreas Metzler) Date: Sat, 9 Aug 2014 18:37:58 +0200 Subject: Libgcrypt 1.5.4 released References: <87mwbgw2y6.fsf@vigenere.g10code.de> Message-ID: <4cvhbb-p13.ln1@argenau.downhill.at.eu.org> Werner Koch wrote: > The GNU project is pleased to announce an update of the Libgcrypt 1.5 > series: version 1.5.4. This is a maintenance release with backports of > fixes from the current stable 1.6 series. [...] Hello, ChangeLog lists this change: -------------- 2013-12-09 Werner Koch tests: Add bench-slope. * tests/bench-slope.c: New. This is a stripped down version taken from master. * tests/Makefile.am (noinst_PROGRAMS): Add bench-slope. --------------- And while the test is indeed added and built it is not run at on "make check" since it not listed in tests/Makefile.am's TESTS. Is this done intentionally? cu Andreas -- `What a good friend you are to him, Dr. Maturin. His other friends are so grateful to you.' `I sew his ears on from time to time, sure' From branko at majic.rs Sat Aug 9 22:52:57 2014 From: branko at majic.rs (Branko Majic) Date: Sat, 9 Aug 2014 22:52:57 +0200 Subject: [Announce] [security fix] Libgcrypt and GnuPG In-Reply-To: <87egwruvz1.fsf@vigenere.g10code.de> References: <87egwruvz1.fsf@vigenere.g10code.de> Message-ID: <20140809225257.129e7843@zetkin.primekey.se> On Fri, 08 Aug 2014 12:17:06 +0200 Werner Koch wrote: > Hi! > > While evaluating the "Get Your Hands Off My Laptop" [1] paper I missed > to describe [2] a software combination which has not been fixed and is > thus vulnerable to the attack described by the paper. If you are using > a GnuPG version with a *Libgcrypt version < 1.6.0*, it is possible to > mount the described side-channel attack on Elgamal encryption subkeys. > To check whether you are using a vulnerable Libgcrypt version, enter > > gpg2 --version > > on the command line; the second line of the output gives the Libgcrypt > version: > > gpg (GnuPG) 2.0.25 > libgcrypt 1.5.3 > > In this example Libgcrypt is vulnerable. If you see 1.6.0 or 1.6.1 you > are fine. GnuPG versions since 1.4.16 are not affected because they do > not use Libgcrypt. > > The recommendation is to update any Libgcrypt version below 1.6.0 to at > least the latest version from the 1.5 series which is 1.5.4. Updating > to 1.6.1 is also possible but that requires to rebuild GnuPG. > > Libgcrypt 1.5.4 has been released yesterday [3]; for convenience I > include the download instructions below. A CVE-id has not yet been > assigned. > > Many thanks to Daniel Genkin for pointing out this problem. > > > Shalom-Salam, > > Werner > > > [1] http://www.cs.tau.ac.il/~tromer/handsoff > [2] http://lists.gnupg.org/pipermail/gnupg-announce/2014q3/000349.html > [3] http://lists.gnupg.org/pipermail/gnupg-announce/2014q3/000351.html > > Download > ======== > > Libgcrypt source code is hosted at the GnuPG FTP server and its mirrors > as listed at https://www.gnupg.org/download/mirrors.html . On the > primary server the source tarball and its digital signature are: > > ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.4.tar.bz2 (1478k) > ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.4.tar.bz2.sig > > That file is bzip2 compressed. A gzip compressed version is here: > > ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.4.tar.gz (1763k) > ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.4.tar.gz.sig > > Alternativley you may upgrade using this patch file: > > ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.3-1.5.4.diff.bz2 (17k) > > In order to check that the version of Libgcrypt you are going to build > is an original and unmodified one, you can do it in one of the following > ways: > > * Check the supplied OpenPGP signature. For example to check the > signature of the file libgcrypt-1.5.4.tar.bz2 you would use this > command: > > gpg --verify libgcrypt-1.5.4.tar.bz2.sig > > This checks whether the signature file matches the source file. You > should see a message indicating that the signature is good and made > by the release signing key 4F25E3B6 which is certified by my well > known key 1E42B367. To retrieve the keys you may use the command > "gpg --fetch-key finger:wk at g10code.com". > > * If you are not able to use GnuPG, you have to verify the SHA-1 > checksum: > > sha1sum libgcrypt-1.5.4.tar.bz2 > > and check that the output matches the first line from the > following list: > > bdf4b04a0d2aabc04ab3564fbe38fd094135aa7a libgcrypt-1.5.4.tar.bz2 > 71e432e0ae8792076a40c6059667997250abbb9d libgcrypt-1.5.4.tar.gz > 8876ae002751e6ec26c76e510d17fc3e0eccb3ed libgcrypt-1.5.3-1.5.4.diff.bz2 > > > Watching out for possible security problems and working with researches > to fix them takes a lot of time. g10 Code GmbH, a German company owned > and headed by me, is bearing these costs. To help us carry on this > work, we need your support; please see https://gnupg.org/donate/ . > Skimming through the description, does it mean that users with OpenPGP cards should be impervious to this attack? Can the attack be used to leak symmetric keys during the GnuPG operation? Best regards -- Branko Majic Jabber: branko at majic.rs Please use only Free formats when sending attachments to me. ?????? ????? ?????: branko at majic.rs ????? ??? ?? ??????? ?????? ????????? ? ????????? ?????????. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: From ametzler at bebt.de Sun Aug 10 11:51:27 2014 From: ametzler at bebt.de (Andreas Metzler) Date: Sun, 10 Aug 2014 11:51:27 +0200 Subject: [patch] libgcrypt 1.5.4 error with texinfo 5.1 In-Reply-To: <20140810094935.GA9217@downhill.g.la> References: <20140810094935.GA9217@downhill.g.la> Message-ID: <20140810095127.GB9217@downhill.g.la> On 2014-08-10 Andreas Metzler wrote: > Good morning, > libgcrypt 1.5.x requires the attached patch for compatibility with > texinfo >= 5.1. Otherwise one gets these errors: [...] complete patch attached, now. -- `What a good friend you are to him, Dr. Maturin. His other friends are so grateful to you.' `I sew his ears on from time to time, sure' -------------- next part -------------- A non-text attachment was scrubbed... Name: 20_texinfo.diff Type: text/x-diff Size: 1494 bytes Desc: not available URL: From ametzler at bebt.de Sun Aug 10 11:49:35 2014 From: ametzler at bebt.de (Andreas Metzler) Date: Sun, 10 Aug 2014 11:49:35 +0200 Subject: [patch] libgcrypt 1.5.4 error with texinfo 5.1 Message-ID: <20140810094935.GA9217@downhill.g.la> Good morning, libgcrypt 1.5.x requires the attached patch for compatibility with texinfo >= 5.1. Otherwise one gets these errors: | /tmp/GCR/libgcrypt-1.5.4/doc/./gcrypt.texi:2015: Argument of @asis has an extra | }. | | @par | | } | @doitemize ...1}@setbox 0 = @hbox {@itemcontents } | @ifx @itemcontents @empty ... | l.2015 @itemize @asis | | ? | [101] (/tmp/GCR/libgcrypt-1.5.4/doc/lgpl.texi | (GNU Lesser General Public License) [102] [103] [104] [105] [106] [107] | [108] | /tmp/GCR/libgcrypt-1.5.4/doc/lgpl.texi:480: This command can appear only outsid | e of any environment, not in environment @enumerate. | @badenverr ...temp , not @inenvironment @thisenv } | | @checkenv ... at ifx @thisenv @temp @else @badenverr | @fi | @sectionheading #1#2#3#4->{@checkenv {} | @csname #2fonts at endcsname @rmisbold @... | | @\heading ...tionheading {#1}{sec}{Yomitfromtoc}{} | @suppressfirstparagraphin... | l.480 @heading NO WARRANTY | | ? Patch originates from Ubuntu's libgcrypt11 (1.5.3-2ubuntu3) by Matthias Klose . I am sorry for forgetting to forward this earlier, in time for 1.5.4. cu Andreas -- `What a good friend you are to him, Dr. Maturin. His other friends are so grateful to you.' `I sew his ears on from time to time, sure' -------------- next part -------------- A non-text attachment was scrubbed... Name: 20_texinfo.diff Type: text/x-diff Size: 606 bytes Desc: not available URL: From gniibe at fsij.org Mon Aug 11 05:52:44 2014 From: gniibe at fsij.org (NIIBE Yutaka) Date: Mon, 11 Aug 2014 12:52:44 +0900 Subject: [PATCH] ecc: support Montgomery curve for gcry_mpi_ec_mul_point In-Reply-To: <87wqajuyml.fsf@vigenere.g10code.de> References: <1407464538.1568.4.camel@cfw2.gniibe.org> <1407470920.1568.7.camel@cfw2.gniibe.org> <87wqajuyml.fsf@vigenere.g10code.de> Message-ID: <1407729164.1644.4.camel@cfw2.gniibe.org> On 2014-08-08 at 11:19 +0200, Werner Koch wrote: > On Fri, 8 Aug 2014 06:08, gniibe at fsij.org said: > > > I don't know if we should support gcry_mpi_ec_curve_point when it's > > x-coordinate only for Montgomery curve. It would be OK always return > > true for Montgomery curve. > > For a correct result we should evaluate the equation and show that Y is > a square. I see. gcry_mpi_ec_curve_point checks if such Y exists. diff --git a/mpi/ec.c b/mpi/ec.c index 737f12c..0a60209 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -601,10 +601,17 @@ _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t point, case MPI_EC_MONTGOMERY: { - log_fatal ("%s: %s not yet supported\n", - "_gcry_mpi_ec_get_affine", "Montgomery"); + if (x) + mpi_set (x, point->x); + + if (y) + { + log_fatal ("%s: Getting Y-coordinate on %s is not supported\n", + "_gcry_mpi_ec_get_affine", "Montgomery"); + return -1; + } } - return -1; + return 0; case MPI_EC_EDWARDS: { @@ -1074,6 +1081,35 @@ add_points_edwards (mpi_point_t result, } +/* Compute a step of Montgomery Ladder (only use X and Z in the point). + Inputs: P1, P2, and x-coordinate of DIF = P1 - P1. + Outputs: PRD = 2 * P1 and SUM = P1 + P2. */ +static void +montgomery_ladder (mpi_point_t prd, mpi_point_t sum, + mpi_point_t p1, mpi_point_t p2, gcry_mpi_t dif_x, + mpi_ec_t ctx) +{ + ec_addm (sum->x, p2->x, p2->z, ctx); + ec_subm (p2->z, p2->x, p2->z, ctx); + ec_addm (prd->x, p1->x, p1->z, ctx); + ec_subm (p1->z, p1->x, p1->z, ctx); + ec_mulm (p2->x, p1->z, sum->x, ctx); + ec_mulm (p2->z, prd->x, p2->z, ctx); + ec_pow2 (p1->x, prd->x, ctx); + ec_pow2 (p1->z, p1->z, ctx); + ec_addm (sum->x, p2->x, p2->z, ctx); + ec_subm (p2->z, p2->x, p2->z, ctx); + ec_mulm (prd->x, p1->x, p1->z, ctx); + ec_subm (p1->z, p1->x, p1->z, ctx); + ec_pow2 (sum->x, sum->x, ctx); + ec_pow2 (sum->z, p2->z, ctx); + ec_mulm (prd->z, p1->z, ctx->a, ctx); /* CTX->A: (a-2)/4 */ + ec_mulm (sum->z, sum->z, dif_x, ctx); + ec_addm (prd->z, p1->x, prd->z, ctx); + ec_mulm (prd->z, prd->z, p1->z, ctx); +} + + /* RESULT = P1 + P2 */ void _gcry_mpi_ec_add_points (mpi_point_t result, @@ -1145,6 +1181,72 @@ _gcry_mpi_ec_mul_point (mpi_point_t result, } return; } + else if (ctx->model == MPI_EC_MONTGOMERY) + { + unsigned int nbits; + int j; + mpi_point_struct p1_, p2_; + unsigned long sw; + + /* Compute scalar point multiplication with Montgomery Ladder. + Note that we don't use Y-coordinate in the points at all. + RESULT->Y will be filled by zero. */ + + nbits = mpi_get_nbits (scalar); + point_init (&p1); + point_init (&p2); + point_init (&p1_); + point_init (&p2_); + mpi_set_ui (p1.x, 1); + mpi_free (p2.x); + p2.x = mpi_copy (point->x); + mpi_set_ui (p2.z, 1); + + for (j=nbits-1; j >= 0; j--) + { + sw = mpi_test_bit (scalar, j); + mpi_swap_cond (p1.x, p2.x, sw); + mpi_swap_cond (p1.z, p2.z, sw); + montgomery_ladder (&p1_, &p2_, &p1, &p2, point->x, ctx); + mpi_swap_cond (p1_.x, p2_.x, sw); + mpi_swap_cond (p1_.z, p2_.z, sw); + + if (--j < 0) + break; + + sw = mpi_test_bit (scalar, j); + mpi_swap_cond (p1_.x, p2_.x, sw); + mpi_swap_cond (p1_.z, p2_.z, sw); + montgomery_ladder (&p1, &p2, &p1_, &p2_, point->x, ctx); + mpi_swap_cond (p1.x, p2.x, sw); + mpi_swap_cond (p1.z, p2.z, sw); + } + + z1 = mpi_new (0); + mpi_clear (result->y); + sw = (nbits & 1); + mpi_swap_cond (p1.x, p1_.x, sw); + mpi_swap_cond (p1.z, p1_.z, sw); + + if (p1.z->nlimbs == 0) + { + mpi_set_ui (result->x, 1); + mpi_set_ui (result->z, 0); + } + else + { + ec_invm (z1, p1.z, ctx); + ec_mulm (result->x, p1.x, z1, ctx); + mpi_set_ui (result->z, 1); + } + + mpi_free (z1); + point_free (&p1); + point_free (&p2); + point_free (&p1_); + point_free (&p2_); + return; + } x1 = mpi_alloc_like (ctx->p); y1 = mpi_alloc_like (ctx->p); @@ -1243,15 +1345,15 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) y = mpi_new (0); w = mpi_new (0); - if (_gcry_mpi_ec_get_affine (x, y, point, ctx)) - return 0; - switch (ctx->model) { case MPI_EC_WEIERSTRASS: { gcry_mpi_t xxx = mpi_new (0); + if (_gcry_mpi_ec_get_affine (x, y, point, ctx)) + return 0; + /* y^2 == x^3 + a?x + b */ ec_pow2 (y, y, ctx); @@ -1267,11 +1369,40 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) } break; case MPI_EC_MONTGOMERY: - log_fatal ("%s: %s not yet supported\n", - "_gcry_mpi_ec_curve_point", "Montgomery"); + { +#define xx y + /* With Montgomery curve, only X-coordinate is valid. */ + if (_gcry_mpi_ec_get_affine (x, NULL, point, ctx)) + return 0; + + /* The equation is: b * y^2 == x^3 + a ? x^2 + x */ + /* We check if right hand is quadratic residue or not by + Euler's criterion. */ + /* CTX->A has (a-2)/4 and CTX->B has b^-1 */ + ec_mulm (w, ctx->a, mpi_const (MPI_C_FOUR), ctx); + ec_addm (w, w, mpi_const (MPI_C_TWO), ctx); + ec_mulm (w, w, x, ctx); + ec_pow2 (xx, x, ctx); + ec_addm (w, w, xx, ctx); + ec_addm (w, w, mpi_const (MPI_C_ONE), ctx); + ec_mulm (w, w, x, ctx); + ec_mulm (w, w, ctx->b, ctx); +#undef xx + /* Compute Euler's criterion: w^(p-1)/2 */ +#define p_minus1 y + ec_subm (p_minus1, ctx->p, mpi_const (MPI_C_ONE), ctx); + mpi_rshift (p_minus1, p_minus1, 1); + ec_powm (w, w, p_minus1, ctx); + + res = mpi_cmp_ui (w, 1); +#undef p_minus1 + } break; case MPI_EC_EDWARDS: { + if (_gcry_mpi_ec_get_affine (x, y, point, ctx)) + return 0; + /* a ? x^2 + y^2 - 1 - b ? x^2 ? y^2 == 0 */ ec_pow2 (x, x, ctx); ec_pow2 (y, y, ctx); -- From wk at gnupg.org Mon Aug 11 10:21:55 2014 From: wk at gnupg.org (Werner Koch) Date: Mon, 11 Aug 2014 10:21:55 +0200 Subject: [Announce] [security fix] Libgcrypt and GnuPG In-Reply-To: <20140809225257.129e7843@zetkin.primekey.se> (Branko Majic's message of "Sat, 9 Aug 2014 22:52:57 +0200") References: <87egwruvz1.fsf@vigenere.g10code.de> <20140809225257.129e7843@zetkin.primekey.se> Message-ID: <8761hzsafw.fsf@vigenere.g10code.de> Hi, [94 lines of full quote deleted - pretty please strip quote to what is needed. I nearly missed your question] On Sat, 9 Aug 2014 22:52, branko at majic.rs said: > Skimming through the description, does it mean that users with OpenPGP > cards should be impervious to this attack? Can the attack be used to > leak symmetric keys during the GnuPG operation? It is unlikely that this particular attack can be used against smart cards. They are quite different from a general purpose PC. Modern cards are designed to mitigate many classes of side-channel attacks since cards started to be targeted more than 25 years ago. The private keys are only on the card and not accessible from the PC. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Mon Aug 11 10:22:46 2014 From: wk at gnupg.org (Werner Koch) Date: Mon, 11 Aug 2014 10:22:46 +0200 Subject: Libgcrypt 1.5.4 released In-Reply-To: <4cvhbb-p13.ln1@argenau.downhill.at.eu.org> (Andreas Metzler's message of "Sat, 9 Aug 2014 18:37:58 +0200") References: <87mwbgw2y6.fsf@vigenere.g10code.de> <4cvhbb-p13.ln1@argenau.downhill.at.eu.org> Message-ID: <87zjfbqvu1.fsf@vigenere.g10code.de> On Sat, 9 Aug 2014 18:37, ametzler at bebt.de said: > And while the test is indeed added and built it is not run at on "make > check" since it not listed in tests/Makefile.am's TESTS. Is this done > intentionally? Yes. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Mon Aug 11 10:25:41 2014 From: wk at gnupg.org (Werner Koch) Date: Mon, 11 Aug 2014 10:25:41 +0200 Subject: [patch] libgcrypt 1.5.4 error with texinfo 5.1 In-Reply-To: <20140810094935.GA9217@downhill.g.la> (Andreas Metzler's message of "Sun, 10 Aug 2014 11:49:35 +0200") References: <20140810094935.GA9217@downhill.g.la> Message-ID: <87vbpzqvp6.fsf@vigenere.g10code.de> On Sun, 10 Aug 2014 11:49, ametzler at bebt.de said: > libgcrypt 1.5.x requires the attached patch for compatibility with > texinfo >= 5.1. Otherwise one gets these errors: Maybe. GNU stuff is rapidly degrading in backward compatibility :-(. > I am sorry for forgetting to forward this earlier, in time for 1.5.4. There was no plan for doing another release and I am reluctant to apply a patch wich might break again with the next textinfo. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Mon Aug 11 10:31:27 2014 From: wk at gnupg.org (Werner Koch) Date: Mon, 11 Aug 2014 10:31:27 +0200 Subject: [PATCH] ecc: support Montgomery curve for gcry_mpi_ec_mul_point In-Reply-To: <1407729164.1644.4.camel@cfw2.gniibe.org> (NIIBE Yutaka's message of "Mon, 11 Aug 2014 12:52:44 +0900") References: <1407464538.1568.4.camel@cfw2.gniibe.org> <1407470920.1568.7.camel@cfw2.gniibe.org> <87wqajuyml.fsf@vigenere.g10code.de> <1407729164.1644.4.camel@cfw2.gniibe.org> Message-ID: <87r40nqvfk.fsf@vigenere.g10code.de> On Mon, 11 Aug 2014 05:52, gniibe at fsij.org said: >> For a correct result we should evaluate the equation and show that Y is >> a square. > > I see. I think that the applications should decide whether the check is needed but if it does the check the check should do the Right Thing. Feel free to push. Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From wk at gnupg.org Mon Aug 11 12:11:33 2014 From: wk at gnupg.org (Werner Koch) Date: Mon, 11 Aug 2014 12:11:33 +0200 Subject: [Announce] [security fix] Libgcrypt and GnuPG In-Reply-To: (Andreas Metzler's message of "Sat, 9 Aug 2014 11:32:10 +0200") References: <87egwruvz1.fsf__22173.0209225372$1407493606$gmane$org@vigenere.g10code.de> Message-ID: <87lhqvqqsq.fsf@vigenere.g10code.de> On Sat, 9 Aug 2014 11:32, ametzler at bebt.de said: > libgcrypt 1.5.3 -> 1.5.4 seem to be essentiall 5 git commits. - Is > the bugfix in a single commit, and if it is which one? 7235b8d Release 1.5.4. e2ba318 mpi: fix gcry_mpi_powm for negative base. * 62e8e12 mpi: mpi-pow improvement. 6c3598f Replace deliberate division by zero with _gcry_divide_by_zero. 2c05a94 mpi: Fix a subtle bug setting spurious bits with in mpi_set_bit. 6366348 Declare eol. 450adc3 tests: Add bench-slope. 182640a w32: Fix installing of .def file. 497478c Fix bug in _gcry_mpi_tdiv_q_2exp. The fix is the marked one. However, the previous fix is also needed to apply cleanly. I would also suggest to apply 2c05a94 which might be the reason for some rare bugs. Some applications might be affected by 497478c. e2ba318 is for correctness. The others are not important. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From edv at kommunalkredit.at Mon Aug 11 13:21:32 2014 From: edv at kommunalkredit.at (KA IT User) Date: Mon, 11 Aug 2014 11:21:32 +0000 Subject: AW: [Announce] [security fix] Libgcrypt and GnuPG In-Reply-To: <87egwruvz1.fsf@vigenere.g10code.de> References: <87egwruvz1.fsf@vigenere.g10code.de> Message-ID: <0C39E0E86B37AB42BDB05B782357995BF524A272@vwp-ex01.kommunalkredit.at> Hi, please remove us from the mailing list. We are not longer using GnuPG in our company. Mit freundlichen Gr??en / Kind regards __________________________ Ing. Roman H?ller, MSc Informationstechnologie Information Technology Kommunalkredit Austria AG 1092 Wien, T?rkenstra?e 9 Tel.: +43 (0) 1/31631 519, Fax: -99519 Mobil: +43 (0) 664/80 31631 519 r.hoeller at kommunalkredit.at www.kommunalkredit.at -----Urspr?ngliche Nachricht----- Von: Gnupg-announce [mailto:gnupg-announce-bounces at gnupg.org] Im Auftrag von Werner Koch Gesendet: Freitag, 08. August 2014 12:28 An: gnupg-announce at gnupg.org; info-gnu at gnu.org Betreff: [Announce] [security fix] Libgcrypt and GnuPG Hi! While evaluating the "Get Your Hands Off My Laptop" [1] paper I missed to describe [2] a software combination which has not been fixed and is thus vulnerable to the attack described by the paper. If you are using a GnuPG version with a *Libgcrypt version < 1.6.0*, it is possible to mount the described side-channel attack on Elgamal encryption subkeys. To check whether you are using a vulnerable Libgcrypt version, enter gpg2 --version on the command line; the second line of the output gives the Libgcrypt version: gpg (GnuPG) 2.0.25 libgcrypt 1.5.3 In this example Libgcrypt is vulnerable. If you see 1.6.0 or 1.6.1 you are fine. GnuPG versions since 1.4.16 are not affected because they do not use Libgcrypt. The recommendation is to update any Libgcrypt version below 1.6.0 to at least the latest version from the 1.5 series which is 1.5.4. Updating to 1.6.1 is also possible but that requires to rebuild GnuPG. Libgcrypt 1.5.4 has been released yesterday [3]; for convenience I include the download instructions below. A CVE-id has not yet been assigned. Many thanks to Daniel Genkin for pointing out this problem. Shalom-Salam, Werner [1] http://www.cs.tau.ac.il/~tromer/handsoff [2] http://lists.gnupg.org/pipermail/gnupg-announce/2014q3/000349.html [3] http://lists.gnupg.org/pipermail/gnupg-announce/2014q3/000351.html Download ======== Libgcrypt source code is hosted at the GnuPG FTP server and its mirrors as listed at https://www.gnupg.org/download/mirrors.html . On the primary server the source tarball and its digital signature are: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.4.tar.bz2 (1478k) ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.4.tar.bz2.sig That file is bzip2 compressed. A gzip compressed version is here: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.4.tar.gz (1763k) ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.4.tar.gz.sig Alternativley you may upgrade using this patch file: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.5.3-1.5.4.diff.bz2 (17k) In order to check that the version of Libgcrypt you are going to build is an original and unmodified one, you can do it in one of the following ways: * Check the supplied OpenPGP signature. For example to check the signature of the file libgcrypt-1.5.4.tar.bz2 you would use this command: gpg --verify libgcrypt-1.5.4.tar.bz2.sig This checks whether the signature file matches the source file. You should see a message indicating that the signature is good and made by the release signing key 4F25E3B6 which is certified by my well known key 1E42B367. To retrieve the keys you may use the command "gpg --fetch-key finger:wk at g10code.com". * If you are not able to use GnuPG, you have to verify the SHA-1 checksum: sha1sum libgcrypt-1.5.4.tar.bz2 and check that the output matches the first line from the following list: bdf4b04a0d2aabc04ab3564fbe38fd094135aa7a libgcrypt-1.5.4.tar.bz2 71e432e0ae8792076a40c6059667997250abbb9d libgcrypt-1.5.4.tar.gz 8876ae002751e6ec26c76e510d17fc3e0eccb3ed libgcrypt-1.5.3-1.5.4.diff.bz2 Watching out for possible security problems and working with researches to fix them takes a lot of time. g10 Code GmbH, a German company owned and headed by me, is bearing these costs. To help us carry on this work, we need your support; please see https://gnupg.org/donate/ . -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. Company Disclaimer / Legal Notices http://www.kommunalkredit.at/disclaimer/ Kommunalkredit Austria AG, T?rkenstrasse 9, 1092 Wien - FN 45776 v, Handelsgericht Wien SAVE PAPER - THINK BEFORE YOU PRINT From wk at gnupg.org Tue Aug 12 00:00:19 2014 From: wk at gnupg.org (Werner Koch) Date: Tue, 12 Aug 2014 00:00:19 +0200 Subject: AW: [Announce] [security fix] Libgcrypt and GnuPG In-Reply-To: <0C39E0E86B37AB42BDB05B782357995BF524A272@vwp-ex01.kommunalkredit.at> (KA IT User's message of "Mon, 11 Aug 2014 11:21:32 +0000") References: <87egwruvz1.fsf@vigenere.g10code.de> <0C39E0E86B37AB42BDB05B782357995BF524A272@vwp-ex01.kommunalkredit.at> Message-ID: <87oavqptzg.fsf@vigenere.g10code.de> On Mon, 11 Aug 2014 13:21, edv at kommunalkredit.at said: > please remove us from the mailing list. We are not longer using GnuPG in our company. What about visiting the URL shown as last line of each mail send through this mailing list? Or looking into the list mail headers? Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From cvs at cvs.gnupg.org Tue Aug 12 03:11:55 2014 From: cvs at cvs.gnupg.org (by NIIBE Yutaka) Date: Tue, 12 Aug 2014 03:11:55 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-105-g34bb55e Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via 34bb55ee36df3aca3ebca88f8b61c786cd0c0701 (commit) from e6d354865bf8f3d4c1bb5e8157a76fdd442cff41 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 34bb55ee36df3aca3ebca88f8b61c786cd0c0701 Author: NIIBE Yutaka Date: Tue Aug 12 10:03:39 2014 +0900 ecc: Support Montgomery curve for gcry_mpi_ec_mul_point. * mpi/ec.c (_gcry_mpi_ec_get_affine): Support Montgomery curve. (montgomery_ladder): New. (_gcry_mpi_ec_mul_point): Implemention using montgomery_ladder. (_gcry_mpi_ec_curve_point): Check x-coordinate is valid. -- Given Montgomery curve: b * y^2 == x^3 + a * x^2 + x CTX->A has (a-2)/4 and CTX->B has b^-1 Note that _gcry_mpi_ec_add_points is not supported for this curve. diff --git a/mpi/ec.c b/mpi/ec.c index 737f12c..a55291a 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -601,10 +601,17 @@ _gcry_mpi_ec_get_affine (gcry_mpi_t x, gcry_mpi_t y, mpi_point_t point, case MPI_EC_MONTGOMERY: { - log_fatal ("%s: %s not yet supported\n", - "_gcry_mpi_ec_get_affine", "Montgomery"); + if (x) + mpi_set (x, point->x); + + if (y) + { + log_fatal ("%s: Getting Y-coordinate on %s is not supported\n", + "_gcry_mpi_ec_get_affine", "Montgomery"); + return -1; + } } - return -1; + return 0; case MPI_EC_EDWARDS: { @@ -1074,6 +1081,35 @@ add_points_edwards (mpi_point_t result, } +/* Compute a step of Montgomery Ladder (only use X and Z in the point). + Inputs: P1, P2, and x-coordinate of DIF = P1 - P1. + Outputs: PRD = 2 * P1 and SUM = P1 + P2. */ +static void +montgomery_ladder (mpi_point_t prd, mpi_point_t sum, + mpi_point_t p1, mpi_point_t p2, gcry_mpi_t dif_x, + mpi_ec_t ctx) +{ + ec_addm (sum->x, p2->x, p2->z, ctx); + ec_subm (p2->z, p2->x, p2->z, ctx); + ec_addm (prd->x, p1->x, p1->z, ctx); + ec_subm (p1->z, p1->x, p1->z, ctx); + ec_mulm (p2->x, p1->z, sum->x, ctx); + ec_mulm (p2->z, prd->x, p2->z, ctx); + ec_pow2 (p1->x, prd->x, ctx); + ec_pow2 (p1->z, p1->z, ctx); + ec_addm (sum->x, p2->x, p2->z, ctx); + ec_subm (p2->z, p2->x, p2->z, ctx); + ec_mulm (prd->x, p1->x, p1->z, ctx); + ec_subm (p1->z, p1->x, p1->z, ctx); + ec_pow2 (sum->x, sum->x, ctx); + ec_pow2 (sum->z, p2->z, ctx); + ec_mulm (prd->z, p1->z, ctx->a, ctx); /* CTX->A: (a-2)/4 */ + ec_mulm (sum->z, sum->z, dif_x, ctx); + ec_addm (prd->z, p1->x, prd->z, ctx); + ec_mulm (prd->z, prd->z, p1->z, ctx); +} + + /* RESULT = P1 + P2 */ void _gcry_mpi_ec_add_points (mpi_point_t result, @@ -1145,6 +1181,72 @@ _gcry_mpi_ec_mul_point (mpi_point_t result, } return; } + else if (ctx->model == MPI_EC_MONTGOMERY) + { + unsigned int nbits; + int j; + mpi_point_struct p1_, p2_; + unsigned long sw; + + /* Compute scalar point multiplication with Montgomery Ladder. + Note that we don't use Y-coordinate in the points at all. + RESULT->Y will be filled by zero. */ + + nbits = mpi_get_nbits (scalar); + point_init (&p1); + point_init (&p2); + point_init (&p1_); + point_init (&p2_); + mpi_set_ui (p1.x, 1); + mpi_free (p2.x); + p2.x = mpi_copy (point->x); + mpi_set_ui (p2.z, 1); + + for (j=nbits-1; j >= 0; j--) + { + sw = mpi_test_bit (scalar, j); + mpi_swap_cond (p1.x, p2.x, sw); + mpi_swap_cond (p1.z, p2.z, sw); + montgomery_ladder (&p1_, &p2_, &p1, &p2, point->x, ctx); + mpi_swap_cond (p1_.x, p2_.x, sw); + mpi_swap_cond (p1_.z, p2_.z, sw); + + if (--j < 0) + break; + + sw = mpi_test_bit (scalar, j); + mpi_swap_cond (p1_.x, p2_.x, sw); + mpi_swap_cond (p1_.z, p2_.z, sw); + montgomery_ladder (&p1, &p2, &p1_, &p2_, point->x, ctx); + mpi_swap_cond (p1.x, p2.x, sw); + mpi_swap_cond (p1.z, p2.z, sw); + } + + z1 = mpi_new (0); + mpi_clear (result->y); + sw = (nbits & 1); + mpi_swap_cond (p1.x, p1_.x, sw); + mpi_swap_cond (p1.z, p1_.z, sw); + + if (p1.z->nlimbs == 0) + { + mpi_set_ui (result->x, 1); + mpi_set_ui (result->z, 0); + } + else + { + ec_invm (z1, p1.z, ctx); + ec_mulm (result->x, p1.x, z1, ctx); + mpi_set_ui (result->z, 1); + } + + mpi_free (z1); + point_free (&p1); + point_free (&p2); + point_free (&p1_); + point_free (&p2_); + return; + } x1 = mpi_alloc_like (ctx->p); y1 = mpi_alloc_like (ctx->p); @@ -1243,15 +1345,15 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) y = mpi_new (0); w = mpi_new (0); - if (_gcry_mpi_ec_get_affine (x, y, point, ctx)) - return 0; - switch (ctx->model) { case MPI_EC_WEIERSTRASS: { gcry_mpi_t xxx = mpi_new (0); + if (_gcry_mpi_ec_get_affine (x, y, point, ctx)) + return 0; + /* y^2 == x^3 + a?x + b */ ec_pow2 (y, y, ctx); @@ -1267,11 +1369,40 @@ _gcry_mpi_ec_curve_point (gcry_mpi_point_t point, mpi_ec_t ctx) } break; case MPI_EC_MONTGOMERY: - log_fatal ("%s: %s not yet supported\n", - "_gcry_mpi_ec_curve_point", "Montgomery"); + { +#define xx y + /* With Montgomery curve, only X-coordinate is valid. */ + if (_gcry_mpi_ec_get_affine (x, NULL, point, ctx)) + return 0; + + /* The equation is: b * y^2 == x^3 + a ? x^2 + x */ + /* We check if right hand is quadratic residue or not by + Euler's criterion. */ + /* CTX->A has (a-2)/4 and CTX->B has b^-1 */ + ec_mulm (w, ctx->a, mpi_const (MPI_C_FOUR), ctx); + ec_addm (w, w, mpi_const (MPI_C_TWO), ctx); + ec_mulm (w, w, x, ctx); + ec_pow2 (xx, x, ctx); + ec_addm (w, w, xx, ctx); + ec_addm (w, w, mpi_const (MPI_C_ONE), ctx); + ec_mulm (w, w, x, ctx); + ec_mulm (w, w, ctx->b, ctx); +#undef xx + /* Compute Euler's criterion: w^(p-1)/2 */ +#define p_minus1 y + ec_subm (p_minus1, ctx->p, mpi_const (MPI_C_ONE), ctx); + mpi_rshift (p_minus1, p_minus1, 1); + ec_powm (w, w, p_minus1, ctx); + + res = mpi_cmp_ui (w, 1); +#undef p_minus1 + } break; case MPI_EC_EDWARDS: { + if (_gcry_mpi_ec_get_affine (x, y, point, ctx)) + return 0; + /* a ? x^2 + y^2 - 1 - b ? x^2 ? y^2 == 0 */ ec_pow2 (x, x, ctx); ec_pow2 (y, y, ctx); ----------------------------------------------------------------------- Summary of changes: mpi/ec.c | 147 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 139 insertions(+), 8 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From gniibe at fsij.org Tue Aug 12 09:56:55 2014 From: gniibe at fsij.org (NIIBE Yutaka) Date: Tue, 12 Aug 2014 16:56:55 +0900 Subject: [PATCH] ecc: Support Montgomery curve (1) Message-ID: <1407830215.1542.4.camel@cfw2.gniibe.org> Hello, This patch is improving support of Montgomery curve. * Enable MPI_EC_MONTGOMERY in _gcry_ecc_fill_in_curve * Since test_keys checks keys by ecdsa/eddsa, new function test_ecdh_only_keys which checks keys by ecdh is added. * Handle MPI_EC_MONTGOMERY in check_secret_key It also includes fixes for my mistakes: * TAB characters in compute_keygrip. * mpi_resize in _gcry_mpi_ec_mul_point and code clean up. With this patch, Montgomery curve is not fully supported yet, we need to fix its support for encoding/decoding key, key generation, and encrypt/decrypt. diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c index fd47c1d..9975bb4 100644 --- a/cipher/ecc-curves.c +++ b/cipher/ecc-curves.c @@ -530,9 +530,8 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, { case MPI_EC_WEIERSTRASS: case MPI_EC_EDWARDS: - break; case MPI_EC_MONTGOMERY: - return GPG_ERR_NOT_SUPPORTED; + break; default: return GPG_ERR_BUG; } diff --git a/cipher/ecc.c b/cipher/ecc.c index 8bdbd56..fa219fb 100644 --- a/cipher/ecc.c +++ b/cipher/ecc.c @@ -81,6 +81,7 @@ static void *progress_cb_data; /* Local prototypes. */ static void test_keys (ECC_secret_key * sk, unsigned int nbits); +static void test_ecdh_only_keys (ECC_secret_key * sk, unsigned int nbits); static unsigned int ecc_get_nbits (gcry_sexp_t parms); @@ -209,7 +210,10 @@ nist_generate_key (ECC_secret_key *sk, elliptic_curve_t *E, mpi_ec_t ctx, point_free (&Q); /* Now we can test our keys (this should never fail!). */ - test_keys (sk, nbits - 64); + if (sk->E.model != MPI_EC_MONTGOMERY) + test_keys (sk, nbits - 64); + else + test_ecdh_only_keys (sk, nbits - 64); return 0; } @@ -266,6 +270,80 @@ test_keys (ECC_secret_key *sk, unsigned int nbits) } +static void +test_ecdh_only_keys (ECC_secret_key *sk, unsigned int nbits) +{ + ECC_public_key pk; + gcry_mpi_t test; + mpi_point_struct R_; + gcry_mpi_t x0, x1; + mpi_ec_t ec; + + if (DBG_CIPHER) + log_debug ("Testing key.\n"); + + point_init (&R_); + + pk.E = _gcry_ecc_curve_copy (sk->E); + point_init (&pk.Q); + point_set (&pk.Q, &sk->Q); + + if (sk->E.dialect == ECC_DIALECT_ED25519) + { + char *rndbuf; + + test = mpi_new (256); + rndbuf = _gcry_random_bytes (32, GCRY_WEAK_RANDOM); + rndbuf[0] &= 0x7f; /* Clear bit 255. */ + rndbuf[0] |= 0x40; /* Set bit 254. */ + rndbuf[31] &= 0xf8; /* Clear bits 2..0 so that d mod 8 == 0 */ + _gcry_mpi_set_buffer (test, rndbuf, 32, 0); + xfree (rndbuf); + } + else + { + test = mpi_new (nbits); + _gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM); + } + + ec = _gcry_mpi_ec_p_internal_new (pk.E.model, pk.E.dialect, 0, + pk.E.p, pk.E.a, pk.E.b); + x0 = mpi_new (0); + x1 = mpi_new (0); + + /* R_ = hkQ <=> R_ = hkdG */ + _gcry_mpi_ec_mul_point (&R_, test, &pk.Q, ec); + if (sk->E.dialect != ECC_DIALECT_ED25519) + _gcry_mpi_ec_mul_point (&R_, ec->h, &R, ec); + if (_gcry_mpi_ec_get_affine (x0, NULL, &R_, ec)) + log_fatal ("ecdh: Failed to get affine coordinates for hkQ\n"); + + _gcry_mpi_ec_mul_point (&R_, test, &pk.E.G, ec); + _gcry_mpi_ec_mul_point (&R_, sk->d, &R_, ec); + /* R_ = hdkG */ + if (sk->E.dialect != ECC_DIALECT_ED25519) + _gcry_mpi_ec_mul_point (&R_, ec->h, &R, ec); + + if (_gcry_mpi_ec_get_affine (x1, NULL, &R_, ec)) + log_fatal ("ecdh: Failed to get affine coordinates for hdkG\n"); + + if (mpi_cmp (x0, x1)) + { + log_fatal ("ECDH test failed.\n"); + } + + mpi_free (x0); + mpi_free (x1); + _gcry_mpi_ec_free (ec); + + point_free (&pk.Q); + _gcry_ecc_curve_free (&pk.E); + + point_free (&R_); + mpi_free (test); +} + + /* * To check the validity of the value, recalculate the correspondence * between the public value and the secret one. @@ -281,7 +359,10 @@ check_secret_key (ECC_secret_key *sk, mpi_ec_t ec, int flags) point_init (&Q); x1 = mpi_new (0); - y1 = mpi_new (0); + if (ec->model == MPI_EC_MONTGOMERY) + y1 = NULL; + else + y1 = mpi_new (0); /* G in E(F_p) */ if (!_gcry_mpi_ec_curve_point (&sk->E.G, ec)) @@ -338,7 +419,7 @@ check_secret_key (ECC_secret_key *sk, mpi_ec_t ec, int flags) else if (!mpi_cmp_ui (sk->Q.z, 1)) { /* Fast path if Q is already in affine coordinates. */ - if (mpi_cmp (x1, sk->Q.x) || mpi_cmp (y1, sk->Q.y)) + if (mpi_cmp (x1, sk->Q.x) || (!y1 && mpi_cmp (y1, sk->Q.y))) { if (DBG_CIPHER) log_debug @@ -1581,7 +1662,7 @@ compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparms) char buf[30]; if (idx == 5) - continue; /* Skip cofactor. */ + continue; /* Skip cofactor. */ if (mpi_is_opaque (values[idx])) { diff --git a/mpi/ec.c b/mpi/ec.c index a55291a..1f65a7c 100644 --- a/mpi/ec.c +++ b/mpi/ec.c @@ -1186,7 +1186,9 @@ _gcry_mpi_ec_mul_point (mpi_point_t result, unsigned int nbits; int j; mpi_point_struct p1_, p2_; + mpi_point_t q1, q2, prd, sum; unsigned long sw; + size_t nlimbs; /* Compute scalar point multiplication with Montgomery Ladder. Note that we don't use Y-coordinate in the points at all. @@ -1202,27 +1204,35 @@ _gcry_mpi_ec_mul_point (mpi_point_t result, p2.x = mpi_copy (point->x); mpi_set_ui (p2.z, 1); + nlimbs = 2*(nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB+1; + mpi_resize (p1.x, nlimbs); + mpi_resize (p1.z, nlimbs); + mpi_resize (p2.x, nlimbs); + mpi_resize (p2.z, nlimbs); + mpi_resize (p1_.x, nlimbs); + mpi_resize (p1_.z, nlimbs); + mpi_resize (p2_.x, nlimbs); + mpi_resize (p2_.z, nlimbs); + + q1 = &p1; + q2 = &p2; + prd = &p1_; + sum = &p2_; + for (j=nbits-1; j >= 0; j--) { - sw = mpi_test_bit (scalar, j); - mpi_swap_cond (p1.x, p2.x, sw); - mpi_swap_cond (p1.z, p2.z, sw); - montgomery_ladder (&p1_, &p2_, &p1, &p2, point->x, ctx); - mpi_swap_cond (p1_.x, p2_.x, sw); - mpi_swap_cond (p1_.z, p2_.z, sw); - - if (--j < 0) - break; + mpi_point_t t; sw = mpi_test_bit (scalar, j); - mpi_swap_cond (p1_.x, p2_.x, sw); - mpi_swap_cond (p1_.z, p2_.z, sw); - montgomery_ladder (&p1, &p2, &p1_, &p2_, point->x, ctx); - mpi_swap_cond (p1.x, p2.x, sw); - mpi_swap_cond (p1.z, p2.z, sw); + mpi_swap_cond (q1->x, q2->x, sw); + mpi_swap_cond (q1->z, q2->z, sw); + montgomery_ladder (prd, sum, q1, q2, point->x, ctx); + mpi_swap_cond (prd->x, sum->x, sw); + mpi_swap_cond (prd->z, sum->z, sw); + t = q1; q1 = prd; prd = t; + t = q2; q2 = sum; sum = t; } - z1 = mpi_new (0); mpi_clear (result->y); sw = (nbits & 1); mpi_swap_cond (p1.x, p1_.x, sw); @@ -1235,12 +1245,13 @@ _gcry_mpi_ec_mul_point (mpi_point_t result, } else { + z1 = mpi_new (0); ec_invm (z1, p1.z, ctx); ec_mulm (result->x, p1.x, z1, ctx); mpi_set_ui (result->z, 1); + mpi_free (z1); } - mpi_free (z1); point_free (&p1); point_free (&p2); point_free (&p1_); -- From ndurner at googlemail.com Mon Aug 18 09:24:08 2014 From: ndurner at googlemail.com (Nils Durner) Date: Mon, 18 Aug 2014 09:24:08 +0200 Subject: libgpg-error FTBS on MinGW Message-ID: Hi, libgpg-error 1.13 fails to build on MinGW(.org): http://pastebin.com/BBsRLYJp config.log: http://pastebin.com/kVa5Bp6z Apologies if this has already been fixed. Please CC answers to the sender address as I am not subscribed to the mailing list. Best regards, Nils Durner -------------- next part -------------- An HTML attachment was scrubbed... URL: From wk at gnupg.org Mon Aug 18 16:09:26 2014 From: wk at gnupg.org (Werner Koch) Date: Mon, 18 Aug 2014 16:09:26 +0200 Subject: libgpg-error FTBS on MinGW In-Reply-To: (Nils Durner's message of "Mon, 18 Aug 2014 09:24:08 +0200") References: Message-ID: <8738ctanzd.fsf@vigenere.g10code.de> On Mon, 18 Aug 2014 09:24, ndurner at googlemail.com said: > libgpg-error 1.13 fails to build on MinGW(.org): Native builds on Windows are not supported. How often do I need to repeat that? Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From cvs at cvs.gnupg.org Thu Aug 21 12:27:12 2014 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 21 Aug 2014 12:27:12 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-107-gf850add Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via f850add813d783f31ca6a60459dea25ef71bce7e (commit) via 18056ace7f466cb8c1eaf08e5dc0400516d83b4c (commit) from 34bb55ee36df3aca3ebca88f8b61c786cd0c0701 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f850add813d783f31ca6a60459dea25ef71bce7e Author: Werner Koch Date: Thu Aug 21 11:47:16 2014 +0200 cipher: Fix a segv in case of calling with wrong parameters. * cipher/md.c (_gcry_md_info): Fix arg testing. -- GnuPG-bug-id: 1697 diff --git a/cipher/md.c b/cipher/md.c index a1e5859..df8b027 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -1181,7 +1181,7 @@ _gcry_md_info (gcry_md_hd_t h, int cmd, void *buffer, size_t *nbytes) GcryDigestEntry *r; int algo; - if ( !buffer || (nbytes && (*nbytes != sizeof (int)))) + if ( !buffer || !nbytes || *nbytes != sizeof (int)) rc = GPG_ERR_INV_ARG; else { commit 18056ace7f466cb8c1eaf08e5dc0400516d83b4c Author: Werner Koch Date: Thu Aug 21 11:39:17 2014 +0200 cipher: Fix possible NULL deref in call to prime generator. * cipher/primegen.c (_gcry_generate_elg_prime): Change to return an error code. * cipher/dsa.c (generate): Take care of new return code. * cipher/elgamal.c (generate): Change to return an error code. Take care of _gcry_generate_elg_prime return code. (generate_using_x): Take care of _gcry_generate_elg_prime return code. (elg_generate): Propagate return code from generate. -- GnuPG-bug-id: 1699, 1700 Reported-by: S.K. Gupta Note that the NULL deref may have only happened on malloc failure. diff --git a/cipher/dsa.c b/cipher/dsa.c index 1707d8c..09cd969 100644 --- a/cipher/dsa.c +++ b/cipher/dsa.c @@ -196,6 +196,7 @@ static gpg_err_code_t generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, int transient_key, dsa_domain_t *domain, gcry_mpi_t **ret_factors ) { + gpg_err_code_t rc; gcry_mpi_t p; /* the prime */ gcry_mpi_t q; /* the 160 bit prime factor */ gcry_mpi_t g; /* the generator */ @@ -247,7 +248,10 @@ generate (DSA_secret_key *sk, unsigned int nbits, unsigned int qbits, else { /* Generate new domain parameters. */ - p = _gcry_generate_elg_prime (1, nbits, qbits, NULL, ret_factors); + rc = _gcry_generate_elg_prime (1, nbits, qbits, NULL, &p, ret_factors); + if (rc) + return rc; + /* Get q out of factors. */ q = mpi_copy ((*ret_factors)[0]); gcry_assert (mpi_get_nbits (q) == qbits); diff --git a/cipher/elgamal.c b/cipher/elgamal.c index a71a9bc..cb3ca43 100644 --- a/cipher/elgamal.c +++ b/cipher/elgamal.c @@ -61,7 +61,8 @@ static const char *elg_names[] = static int test_keys (ELG_secret_key *sk, unsigned int nbits, int nodie); static gcry_mpi_t gen_k (gcry_mpi_t p, int small_k); -static void generate (ELG_secret_key *sk, unsigned nbits, gcry_mpi_t **factors); +static gcry_err_code_t generate (ELG_secret_key *sk, unsigned nbits, + gcry_mpi_t **factors); static int check_secret_key (ELG_secret_key *sk); static void do_encrypt (gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey); @@ -268,9 +269,10 @@ gen_k( gcry_mpi_t p, int small_k ) * Returns: 2 structures filled with all needed values * and an array with n-1 factors of (p-1) */ -static void +static gcry_err_code_t generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors ) { + gcry_err_code_t rc; gcry_mpi_t p; /* the prime */ gcry_mpi_t p_min1; gcry_mpi_t g; @@ -285,7 +287,13 @@ generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors ) if( qbits & 1 ) /* better have a even one */ qbits++; g = mpi_alloc(1); - p = _gcry_generate_elg_prime( 0, nbits, qbits, g, ret_factors ); + rc = _gcry_generate_elg_prime (0, nbits, qbits, g, &p, ret_factors); + if (rc) + { + mpi_free (p_min1); + mpi_free (g); + return rc; + } mpi_sub_ui(p_min1, p, 1); @@ -359,6 +367,8 @@ generate ( ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t **ret_factors ) /* Now we can test our keys (this should never fail!) */ test_keys ( sk, nbits - 64, 0 ); + + return 0; } @@ -373,6 +383,7 @@ static gcry_err_code_t generate_using_x (ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t x, gcry_mpi_t **ret_factors ) { + gcry_err_code_t rc; gcry_mpi_t p; /* The prime. */ gcry_mpi_t p_min1; /* The prime minus 1. */ gcry_mpi_t g; /* The generator. */ @@ -395,7 +406,13 @@ generate_using_x (ELG_secret_key *sk, unsigned int nbits, gcry_mpi_t x, if ( (qbits & 1) ) /* Better have an even one. */ qbits++; g = mpi_alloc (1); - p = _gcry_generate_elg_prime ( 0, nbits, qbits, g, ret_factors ); + rc = _gcry_generate_elg_prime (0, nbits, qbits, g, &p, ret_factors ); + if (rc) + { + mpi_free (p_min1); + mpi_free (g); + return rc; + } mpi_sub_ui (p_min1, p, 1); if (DBG_CIPHER) @@ -662,8 +679,7 @@ elg_generate (const gcry_sexp_t genparms, gcry_sexp_t *r_skey) } else { - generate (&sk, nbits, &factors); - rc = 0; + rc = generate (&sk, nbits, &factors); } if (rc) goto leave; diff --git a/cipher/primegen.c b/cipher/primegen.c index 9f6ec70..14a5ccf 100644 --- a/cipher/primegen.c +++ b/cipher/primegen.c @@ -726,19 +726,22 @@ prime_generate_internal (int need_q_factor, /* Generate a prime used for discrete logarithm algorithms; i.e. this - prime will be public and no strong random is required. */ -gcry_mpi_t + prime will be public and no strong random is required. On success + R_PRIME receives a new MPI with the prime. On error R_PRIME is set + to NULL and an error code is returned. If RET_FACTORS is not NULL + it is set to an allocated array of factors on success or to NULL on + error. */ +gcry_err_code_t _gcry_generate_elg_prime (int mode, unsigned pbits, unsigned qbits, - gcry_mpi_t g, gcry_mpi_t **ret_factors) + gcry_mpi_t g, + gcry_mpi_t *r_prime, gcry_mpi_t **ret_factors) { - gcry_mpi_t prime = NULL; - - if (prime_generate_internal ((mode == 1), &prime, pbits, qbits, g, - ret_factors, GCRY_WEAK_RANDOM, 0, 0, - NULL, NULL)) - prime = NULL; /* (Should be NULL in the error case anyway.) */ - - return prime; + *r_prime = NULL; + if (ret_factors) + *ret_factors = NULL; + return prime_generate_internal ((mode == 1), r_prime, pbits, qbits, g, + ret_factors, GCRY_WEAK_RANDOM, 0, 0, + NULL, NULL); } diff --git a/src/g10lib.h b/src/g10lib.h index 43dc011..238871d 100644 --- a/src/g10lib.h +++ b/src/g10lib.h @@ -236,9 +236,12 @@ gcry_mpi_t _gcry_generate_public_prime (unsigned int nbits, gcry_random_level_t random_level, int (*extra_check)(void*, gcry_mpi_t), void *extra_check_arg); -gcry_mpi_t _gcry_generate_elg_prime (int mode, - unsigned int pbits, unsigned int qbits, - gcry_mpi_t g, gcry_mpi_t **factors); +gcry_err_code_t _gcry_generate_elg_prime (int mode, + unsigned int pbits, + unsigned int qbits, + gcry_mpi_t g, + gcry_mpi_t *r_prime, + gcry_mpi_t **factors); gcry_mpi_t _gcry_derive_x931_prime (const gcry_mpi_t xp, const gcry_mpi_t xp1, const gcry_mpi_t xp2, const gcry_mpi_t e, ----------------------------------------------------------------------- Summary of changes: cipher/dsa.c | 6 +++++- cipher/elgamal.c | 28 ++++++++++++++++++++++------ cipher/md.c | 2 +- cipher/primegen.c | 25 ++++++++++++++----------- src/g10lib.h | 9 ++++++--- 5 files changed, 48 insertions(+), 22 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From cvs at cvs.gnupg.org Thu Aug 21 14:15:58 2014 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Thu, 21 Aug 2014 14:15:58 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-108-ge606d5f Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via e606d5f1bada1f2d21faeedd3fa2cf2dca7b274c (commit) from f850add813d783f31ca6a60459dea25ef71bce7e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e606d5f1bada1f2d21faeedd3fa2cf2dca7b274c Author: Werner Koch Date: Thu Aug 21 14:12:55 2014 +0200 sexp: Check args of gcry_sexp_build. * src/sexp.c (do_vsexp_sscan): Return error for invalid args. -- This helps to avoid usage errors by passing NULL for the return variable and the format string. diff --git a/src/sexp.c b/src/sexp.c index 0e4af52..9bc13ca 100644 --- a/src/sexp.c +++ b/src/sexp.c @@ -1119,6 +1119,13 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, int arg_counter = 0; int level = 0; + if (!retsexp) + return GPG_ERR_INV_ARG; + *retsexp = NULL; + + if (!buffer) + return GPG_ERR_INV_ARG; + if (!erroff) erroff = &dummy_erroff; @@ -1160,7 +1167,7 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, the provided one. However, we add space for one extra datalen so that the code which does the ST_CLOSE can use MAKE_SPACE */ c.allocated = length + sizeof(DATALEN); - if (buffer && length && _gcry_is_secure (buffer)) + if (length && _gcry_is_secure (buffer)) c.sexp = xtrymalloc_secure (sizeof *c.sexp + c.allocated - 1); else c.sexp = xtrymalloc (sizeof *c.sexp + c.allocated - 1); @@ -1682,8 +1689,6 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1); xfree (c.sexp); } - /* This might be expected by existing code... */ - *retsexp = NULL; } else *retsexp = normalize (c.sexp); ----------------------------------------------------------------------- Summary of changes: src/sexp.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From wk at gnupg.org Thu Aug 21 15:39:26 2014 From: wk at gnupg.org (Werner Koch) Date: Thu, 21 Aug 2014 15:39:26 +0200 Subject: Libgcrypt 1.6.2 released Message-ID: <87oave3qsx.fsf@vigenere.g10code.de> Hello! The GNU project is pleased to announce the availability of Libgcrypt version 1.6.2. This is a maintenance release to fix problems found in the recently released versions. Libgcrypt is a general purpose library of cryptographic building blocks. It does not provide any implementation of OpenPGP or other protocols. Thorough understanding of applied cryptography is required for proper use Libgcrypt. Noteworthy changes in version 1.6.2 (2014-08-21) ================================================ * Map deprecated RSA algo number to the RSA algo number for better backward compatibility. * Support a 0x40 compression prefix for EdDSA. * Improve ARM hardware feature detection and building. * Fix powerpc-apple-darwin detection * Fix building for the x32 ABI platform. * Support building using the latest mingw-w64 toolchain. * Fix some possible NULL deref bugs. Download ======== Source code is hosted at the GnuPG FTP server and its mirrors as listed at http://www.gnupg.org/download/mirrors.html . On the primary server the source tarball and its digital signature are: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.2.tar.bz2 (2418k) ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.2.tar.bz2.sig That file is bzip2 compressed. A gzip compressed version is here: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.2.tar.gz (2874k) ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.2.tar.gz.sig Alternativley you may upgrade using this patch file: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-1.6.1-1.6.2.diff.bz2 (17k) In order to check that the version of Libgcrypt you are going to build is an original and unmodified one, you can do it in one of the following ways: * Check the supplied OpenPGP signature. For example to check the signature of the file libgcrypt-1.6.3.tar.bz2 you would use this command: gpg --verify libgcrypt-1.6.3.tar.bz2.sig This checks whether the signature file matches the source file. You should see a message indicating that the signature is good and made by the release signing key 4F25E3B6 which is certified by my well known key 1E42B367. To retrieve the keys you may use the command "gpg --fetch-key finger:wk at g10code.com". * If you are not able to use GnuPG, you have to verify the SHA-1 checksum: sha1sum libgcrypt-1.6.3.tar.bz2 and check that the output matches the first line from the following list: cc31aca87e4a3769cb86884a3f5982b2cc8eb7ec libgcrypt-1.6.2.tar.bz2 cdaf2bdd5f34b20f4f9d926536673c15b857d2e6 libgcrypt-1.6.2.tar.gz 302592ec4183b727ad07bdd47fc4d50d717f42e2 libgcrypt-1.6.1-1.6.2.diff.bz2 Copying ======= Libgcrypt is distributed under the terms of the GNU Lesser General Public License (LGPLv2.1+). The helper programs as well as the documentation are distributed under the terms of the GNU General Public License (GPLv2+). The file LICENSES has notices about contributions that require these additional notices are distributed. Support ======= For help on developing with Libgcrypt you should read the included manual and optional ask on the gcrypt-devel mailing list [1]. A listing with commercial support offers for Libgcrypt and related software is available at the GnuPG web site [2]. The driving force behind the development of Libgcrypt is my company g10 Code. Maintenance and improvement of Libgcrypt and related software takes up most of our resources. To allow us to continue our work on free software, we ask to either purchase a support contract, engage us for custom enhancements, or to donate money: https://gnupg.org/donate/ Thanks ====== Many thanks to all who contributed to Libgcrypt development, be it bug fixes, code, documentation, testing or helping users. Happy hacking, Werner [1] http://lists.gnupg.org/mailman/listinfo/gcrypt-devel [2] https://www.gnupg.org/service.html -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 180 bytes Desc: not available URL: From smueller at chronox.de Thu Aug 21 21:56:45 2014 From: smueller at chronox.de (Stephan Mueller) Date: Thu, 21 Aug 2014 21:56:45 +0200 Subject: SP800-90A Deterministic Random Bit Generator Message-ID: <12581970.NLC2q70N0f@myon.chronox.de> Hi, I created the bug tracker entry https://bugs.g10code.com/gnupg/issue1701 holding an updated patch set for the DRBG. This implementation of the DRBG shares large portions of the DRBG implementation now present in the Linux kernel 3.17 RC1. Note, both were developed with the same code base. This DRBG implementation is required for a successful validation of libgcrypt according to FIPS 140-2. Although the previous submissions of the DRBG patch set seem to have not been noticed, I am asking for a review of the code and for an includion of the code into libgcrypt. -- Ciao Stephan From metaschima at inbox.com Fri Aug 22 00:34:58 2014 From: metaschima at inbox.com (Meta Schima) Date: Thu, 21 Aug 2014 14:34:58 -0800 Subject: [PATCH 1/1] Improved ripemd160 perfromance Message-ID: Hello, I am new to the mailing list. I have a patch here to improve ripemd160 performance by interleaving left and right lanes. On my system before: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 3.31 ns/B 288.1 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 2.08 ns/B 458.3 MiB/s - c/B Note that I removed one temporary u32 variable, and this reduces the stack burn from 108 to 104, hope this is right. ~ Andrei ---- diff -ruNp libgcrypt-1.6.2/cipher/rmd160.c libgcrypt-1.6.3/cipher/rmd160.c --- libgcrypt-1.6.2/cipher/rmd160.c 2014-08-21 07:50:39.000000000 -0500 +++ libgcrypt-1.6.3/cipher/rmd160.c 2014-08-21 17:15:13.678664524 -0500 @@ -178,8 +178,7 @@ static unsigned int transform ( void *ctx, const unsigned char *data ) { RMD160_CONTEXT *hd = ctx; - register u32 a,b,c,d,e; - u32 aa,bb,cc,dd,ee,t; + register u32 al, ar, bl, br, cl, cr, dl, dr, el, er; u32 x[16]; int i; @@ -201,196 +200,186 @@ transform ( void *ctx, const unsigned ch #define F2(x,y,z) ( ((x) | ~(y)) ^ (z) ) #define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) ) #define F4(x,y,z) ( (x) ^ ((y) | ~(z)) ) -#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \ - a = rol(t,s) + e; \ +#define R(a,b,c,d,e,f,k,r,s) do { a += f(b,c,d) + k + x[r]; \ + a = rol(a,s) + e; \ c = rol(c,10); \ } while(0) - /* left lane */ - a = hd->h0; - b = hd->h1; - c = hd->h2; - d = hd->h3; - e = hd->h4; - R( a, b, c, d, e, F0, K0, 0, 11 ); - R( e, a, b, c, d, F0, K0, 1, 14 ); - R( d, e, a, b, c, F0, K0, 2, 15 ); - R( c, d, e, a, b, F0, K0, 3, 12 ); - R( b, c, d, e, a, F0, K0, 4, 5 ); - R( a, b, c, d, e, F0, K0, 5, 8 ); - R( e, a, b, c, d, F0, K0, 6, 7 ); - R( d, e, a, b, c, F0, K0, 7, 9 ); - R( c, d, e, a, b, F0, K0, 8, 11 ); - R( b, c, d, e, a, F0, K0, 9, 13 ); - R( a, b, c, d, e, F0, K0, 10, 14 ); - R( e, a, b, c, d, F0, K0, 11, 15 ); - R( d, e, a, b, c, F0, K0, 12, 6 ); - R( c, d, e, a, b, F0, K0, 13, 7 ); - R( b, c, d, e, a, F0, K0, 14, 9 ); - R( a, b, c, d, e, F0, K0, 15, 8 ); - R( e, a, b, c, d, F1, K1, 7, 7 ); - R( d, e, a, b, c, F1, K1, 4, 6 ); - R( c, d, e, a, b, F1, K1, 13, 8 ); - R( b, c, d, e, a, F1, K1, 1, 13 ); - R( a, b, c, d, e, F1, K1, 10, 11 ); - R( e, a, b, c, d, F1, K1, 6, 9 ); - R( d, e, a, b, c, F1, K1, 15, 7 ); - R( c, d, e, a, b, F1, K1, 3, 15 ); - R( b, c, d, e, a, F1, K1, 12, 7 ); - R( a, b, c, d, e, F1, K1, 0, 12 ); - R( e, a, b, c, d, F1, K1, 9, 15 ); - R( d, e, a, b, c, F1, K1, 5, 9 ); - R( c, d, e, a, b, F1, K1, 2, 11 ); - R( b, c, d, e, a, F1, K1, 14, 7 ); - R( a, b, c, d, e, F1, K1, 11, 13 ); - R( e, a, b, c, d, F1, K1, 8, 12 ); - R( d, e, a, b, c, F2, K2, 3, 11 ); - R( c, d, e, a, b, F2, K2, 10, 13 ); - R( b, c, d, e, a, F2, K2, 14, 6 ); - R( a, b, c, d, e, F2, K2, 4, 7 ); - R( e, a, b, c, d, F2, K2, 9, 14 ); - R( d, e, a, b, c, F2, K2, 15, 9 ); - R( c, d, e, a, b, F2, K2, 8, 13 ); - R( b, c, d, e, a, F2, K2, 1, 15 ); - R( a, b, c, d, e, F2, K2, 2, 14 ); - R( e, a, b, c, d, F2, K2, 7, 8 ); - R( d, e, a, b, c, F2, K2, 0, 13 ); - R( c, d, e, a, b, F2, K2, 6, 6 ); - R( b, c, d, e, a, F2, K2, 13, 5 ); - R( a, b, c, d, e, F2, K2, 11, 12 ); - R( e, a, b, c, d, F2, K2, 5, 7 ); - R( d, e, a, b, c, F2, K2, 12, 5 ); - R( c, d, e, a, b, F3, K3, 1, 11 ); - R( b, c, d, e, a, F3, K3, 9, 12 ); - R( a, b, c, d, e, F3, K3, 11, 14 ); - R( e, a, b, c, d, F3, K3, 10, 15 ); - R( d, e, a, b, c, F3, K3, 0, 14 ); - R( c, d, e, a, b, F3, K3, 8, 15 ); - R( b, c, d, e, a, F3, K3, 12, 9 ); - R( a, b, c, d, e, F3, K3, 4, 8 ); - R( e, a, b, c, d, F3, K3, 13, 9 ); - R( d, e, a, b, c, F3, K3, 3, 14 ); - R( c, d, e, a, b, F3, K3, 7, 5 ); - R( b, c, d, e, a, F3, K3, 15, 6 ); - R( a, b, c, d, e, F3, K3, 14, 8 ); - R( e, a, b, c, d, F3, K3, 5, 6 ); - R( d, e, a, b, c, F3, K3, 6, 5 ); - R( c, d, e, a, b, F3, K3, 2, 12 ); - R( b, c, d, e, a, F4, K4, 4, 9 ); - R( a, b, c, d, e, F4, K4, 0, 15 ); - R( e, a, b, c, d, F4, K4, 5, 5 ); - R( d, e, a, b, c, F4, K4, 9, 11 ); - R( c, d, e, a, b, F4, K4, 7, 6 ); - R( b, c, d, e, a, F4, K4, 12, 8 ); - R( a, b, c, d, e, F4, K4, 2, 13 ); - R( e, a, b, c, d, F4, K4, 10, 12 ); - R( d, e, a, b, c, F4, K4, 14, 5 ); - R( c, d, e, a, b, F4, K4, 1, 12 ); - R( b, c, d, e, a, F4, K4, 3, 13 ); - R( a, b, c, d, e, F4, K4, 8, 14 ); - R( e, a, b, c, d, F4, K4, 11, 11 ); - R( d, e, a, b, c, F4, K4, 6, 8 ); - R( c, d, e, a, b, F4, K4, 15, 5 ); - R( b, c, d, e, a, F4, K4, 13, 6 ); - - aa = a; bb = b; cc = c; dd = d; ee = e; - - /* right lane */ - a = hd->h0; - b = hd->h1; - c = hd->h2; - d = hd->h3; - e = hd->h4; - R( a, b, c, d, e, F4, KK0, 5, 8); - R( e, a, b, c, d, F4, KK0, 14, 9); - R( d, e, a, b, c, F4, KK0, 7, 9); - R( c, d, e, a, b, F4, KK0, 0, 11); - R( b, c, d, e, a, F4, KK0, 9, 13); - R( a, b, c, d, e, F4, KK0, 2, 15); - R( e, a, b, c, d, F4, KK0, 11, 15); - R( d, e, a, b, c, F4, KK0, 4, 5); - R( c, d, e, a, b, F4, KK0, 13, 7); - R( b, c, d, e, a, F4, KK0, 6, 7); - R( a, b, c, d, e, F4, KK0, 15, 8); - R( e, a, b, c, d, F4, KK0, 8, 11); - R( d, e, a, b, c, F4, KK0, 1, 14); - R( c, d, e, a, b, F4, KK0, 10, 14); - R( b, c, d, e, a, F4, KK0, 3, 12); - R( a, b, c, d, e, F4, KK0, 12, 6); - R( e, a, b, c, d, F3, KK1, 6, 9); - R( d, e, a, b, c, F3, KK1, 11, 13); - R( c, d, e, a, b, F3, KK1, 3, 15); - R( b, c, d, e, a, F3, KK1, 7, 7); - R( a, b, c, d, e, F3, KK1, 0, 12); - R( e, a, b, c, d, F3, KK1, 13, 8); - R( d, e, a, b, c, F3, KK1, 5, 9); - R( c, d, e, a, b, F3, KK1, 10, 11); - R( b, c, d, e, a, F3, KK1, 14, 7); - R( a, b, c, d, e, F3, KK1, 15, 7); - R( e, a, b, c, d, F3, KK1, 8, 12); - R( d, e, a, b, c, F3, KK1, 12, 7); - R( c, d, e, a, b, F3, KK1, 4, 6); - R( b, c, d, e, a, F3, KK1, 9, 15); - R( a, b, c, d, e, F3, KK1, 1, 13); - R( e, a, b, c, d, F3, KK1, 2, 11); - R( d, e, a, b, c, F2, KK2, 15, 9); - R( c, d, e, a, b, F2, KK2, 5, 7); - R( b, c, d, e, a, F2, KK2, 1, 15); - R( a, b, c, d, e, F2, KK2, 3, 11); - R( e, a, b, c, d, F2, KK2, 7, 8); - R( d, e, a, b, c, F2, KK2, 14, 6); - R( c, d, e, a, b, F2, KK2, 6, 6); - R( b, c, d, e, a, F2, KK2, 9, 14); - R( a, b, c, d, e, F2, KK2, 11, 12); - R( e, a, b, c, d, F2, KK2, 8, 13); - R( d, e, a, b, c, F2, KK2, 12, 5); - R( c, d, e, a, b, F2, KK2, 2, 14); - R( b, c, d, e, a, F2, KK2, 10, 13); - R( a, b, c, d, e, F2, KK2, 0, 13); - R( e, a, b, c, d, F2, KK2, 4, 7); - R( d, e, a, b, c, F2, KK2, 13, 5); - R( c, d, e, a, b, F1, KK3, 8, 15); - R( b, c, d, e, a, F1, KK3, 6, 5); - R( a, b, c, d, e, F1, KK3, 4, 8); - R( e, a, b, c, d, F1, KK3, 1, 11); - R( d, e, a, b, c, F1, KK3, 3, 14); - R( c, d, e, a, b, F1, KK3, 11, 14); - R( b, c, d, e, a, F1, KK3, 15, 6); - R( a, b, c, d, e, F1, KK3, 0, 14); - R( e, a, b, c, d, F1, KK3, 5, 6); - R( d, e, a, b, c, F1, KK3, 12, 9); - R( c, d, e, a, b, F1, KK3, 2, 12); - R( b, c, d, e, a, F1, KK3, 13, 9); - R( a, b, c, d, e, F1, KK3, 9, 12); - R( e, a, b, c, d, F1, KK3, 7, 5); - R( d, e, a, b, c, F1, KK3, 10, 15); - R( c, d, e, a, b, F1, KK3, 14, 8); - R( b, c, d, e, a, F0, KK4, 12, 8); - R( a, b, c, d, e, F0, KK4, 15, 5); - R( e, a, b, c, d, F0, KK4, 10, 12); - R( d, e, a, b, c, F0, KK4, 4, 9); - R( c, d, e, a, b, F0, KK4, 1, 12); - R( b, c, d, e, a, F0, KK4, 5, 5); - R( a, b, c, d, e, F0, KK4, 8, 14); - R( e, a, b, c, d, F0, KK4, 7, 6); - R( d, e, a, b, c, F0, KK4, 6, 8); - R( c, d, e, a, b, F0, KK4, 2, 13); - R( b, c, d, e, a, F0, KK4, 13, 6); - R( a, b, c, d, e, F0, KK4, 14, 5); - R( e, a, b, c, d, F0, KK4, 0, 15); - R( d, e, a, b, c, F0, KK4, 3, 13); - R( c, d, e, a, b, F0, KK4, 9, 11); - R( b, c, d, e, a, F0, KK4, 11, 11); - - - t = hd->h1 + d + cc; - hd->h1 = hd->h2 + e + dd; - hd->h2 = hd->h3 + a + ee; - hd->h3 = hd->h4 + b + aa; - hd->h4 = hd->h0 + c + bb; - hd->h0 = t; + /* left lane and right lanes interleaved */ + al = ar = hd->h0; + bl = br = hd->h1; + cl = cr = hd->h2; + dl = dr = hd->h3; + el = er = hd->h4; + R( al, bl, cl, dl, el, F0, K0, 0, 11 ); + R( ar, br, cr, dr, er, F4, KK0, 5, 8); + R( el, al, bl, cl, dl, F0, K0, 1, 14 ); + R( er, ar, br, cr, dr, F4, KK0, 14, 9); + R( dl, el, al, bl, cl, F0, K0, 2, 15 ); + R( dr, er, ar, br, cr, F4, KK0, 7, 9); + R( cl, dl, el, al, bl, F0, K0, 3, 12 ); + R( cr, dr, er, ar, br, F4, KK0, 0, 11); + R( bl, cl, dl, el, al, F0, K0, 4, 5 ); + R( br, cr, dr, er, ar, F4, KK0, 9, 13); + R( al, bl, cl, dl, el, F0, K0, 5, 8 ); + R( ar, br, cr, dr, er, F4, KK0, 2, 15); + R( el, al, bl, cl, dl, F0, K0, 6, 7 ); + R( er, ar, br, cr, dr, F4, KK0, 11, 15); + R( dl, el, al, bl, cl, F0, K0, 7, 9 ); + R( dr, er, ar, br, cr, F4, KK0, 4, 5); + R( cl, dl, el, al, bl, F0, K0, 8, 11 ); + R( cr, dr, er, ar, br, F4, KK0, 13, 7); + R( bl, cl, dl, el, al, F0, K0, 9, 13 ); + R( br, cr, dr, er, ar, F4, KK0, 6, 7); + R( al, bl, cl, dl, el, F0, K0, 10, 14 ); + R( ar, br, cr, dr, er, F4, KK0, 15, 8); + R( el, al, bl, cl, dl, F0, K0, 11, 15 ); + R( er, ar, br, cr, dr, F4, KK0, 8, 11); + R( dl, el, al, bl, cl, F0, K0, 12, 6 ); + R( dr, er, ar, br, cr, F4, KK0, 1, 14); + R( cl, dl, el, al, bl, F0, K0, 13, 7 ); + R( cr, dr, er, ar, br, F4, KK0, 10, 14); + R( bl, cl, dl, el, al, F0, K0, 14, 9 ); + R( br, cr, dr, er, ar, F4, KK0, 3, 12); + R( al, bl, cl, dl, el, F0, K0, 15, 8 ); + R( ar, br, cr, dr, er, F4, KK0, 12, 6); + R( el, al, bl, cl, dl, F1, K1, 7, 7 ); + R( er, ar, br, cr, dr, F3, KK1, 6, 9); + R( dl, el, al, bl, cl, F1, K1, 4, 6 ); + R( dr, er, ar, br, cr, F3, KK1, 11, 13); + R( cl, dl, el, al, bl, F1, K1, 13, 8 ); + R( cr, dr, er, ar, br, F3, KK1, 3, 15); + R( bl, cl, dl, el, al, F1, K1, 1, 13 ); + R( br, cr, dr, er, ar, F3, KK1, 7, 7); + R( al, bl, cl, dl, el, F1, K1, 10, 11 ); + R( ar, br, cr, dr, er, F3, KK1, 0, 12); + R( el, al, bl, cl, dl, F1, K1, 6, 9 ); + R( er, ar, br, cr, dr, F3, KK1, 13, 8); + R( dl, el, al, bl, cl, F1, K1, 15, 7 ); + R( dr, er, ar, br, cr, F3, KK1, 5, 9); + R( cl, dl, el, al, bl, F1, K1, 3, 15 ); + R( cr, dr, er, ar, br, F3, KK1, 10, 11); + R( bl, cl, dl, el, al, F1, K1, 12, 7 ); + R( br, cr, dr, er, ar, F3, KK1, 14, 7); + R( al, bl, cl, dl, el, F1, K1, 0, 12 ); + R( ar, br, cr, dr, er, F3, KK1, 15, 7); + R( el, al, bl, cl, dl, F1, K1, 9, 15 ); + R( er, ar, br, cr, dr, F3, KK1, 8, 12); + R( dl, el, al, bl, cl, F1, K1, 5, 9 ); + R( dr, er, ar, br, cr, F3, KK1, 12, 7); + R( cl, dl, el, al, bl, F1, K1, 2, 11 ); + R( cr, dr, er, ar, br, F3, KK1, 4, 6); + R( bl, cl, dl, el, al, F1, K1, 14, 7 ); + R( br, cr, dr, er, ar, F3, KK1, 9, 15); + R( al, bl, cl, dl, el, F1, K1, 11, 13 ); + R( ar, br, cr, dr, er, F3, KK1, 1, 13); + R( el, al, bl, cl, dl, F1, K1, 8, 12 ); + R( er, ar, br, cr, dr, F3, KK1, 2, 11); + R( dl, el, al, bl, cl, F2, K2, 3, 11 ); + R( dr, er, ar, br, cr, F2, KK2, 15, 9); + R( cl, dl, el, al, bl, F2, K2, 10, 13 ); + R( cr, dr, er, ar, br, F2, KK2, 5, 7); + R( bl, cl, dl, el, al, F2, K2, 14, 6 ); + R( br, cr, dr, er, ar, F2, KK2, 1, 15); + R( al, bl, cl, dl, el, F2, K2, 4, 7 ); + R( ar, br, cr, dr, er, F2, KK2, 3, 11); + R( el, al, bl, cl, dl, F2, K2, 9, 14 ); + R( er, ar, br, cr, dr, F2, KK2, 7, 8); + R( dl, el, al, bl, cl, F2, K2, 15, 9 ); + R( dr, er, ar, br, cr, F2, KK2, 14, 6); + R( cl, dl, el, al, bl, F2, K2, 8, 13 ); + R( cr, dr, er, ar, br, F2, KK2, 6, 6); + R( bl, cl, dl, el, al, F2, K2, 1, 15 ); + R( br, cr, dr, er, ar, F2, KK2, 9, 14); + R( al, bl, cl, dl, el, F2, K2, 2, 14 ); + R( ar, br, cr, dr, er, F2, KK2, 11, 12); + R( el, al, bl, cl, dl, F2, K2, 7, 8 ); + R( er, ar, br, cr, dr, F2, KK2, 8, 13); + R( dl, el, al, bl, cl, F2, K2, 0, 13 ); + R( dr, er, ar, br, cr, F2, KK2, 12, 5); + R( cl, dl, el, al, bl, F2, K2, 6, 6 ); + R( cr, dr, er, ar, br, F2, KK2, 2, 14); + R( bl, cl, dl, el, al, F2, K2, 13, 5 ); + R( br, cr, dr, er, ar, F2, KK2, 10, 13); + R( al, bl, cl, dl, el, F2, K2, 11, 12 ); + R( ar, br, cr, dr, er, F2, KK2, 0, 13); + R( el, al, bl, cl, dl, F2, K2, 5, 7 ); + R( er, ar, br, cr, dr, F2, KK2, 4, 7); + R( dl, el, al, bl, cl, F2, K2, 12, 5 ); + R( dr, er, ar, br, cr, F2, KK2, 13, 5); + R( cl, dl, el, al, bl, F3, K3, 1, 11 ); + R( cr, dr, er, ar, br, F1, KK3, 8, 15); + R( bl, cl, dl, el, al, F3, K3, 9, 12 ); + R( br, cr, dr, er, ar, F1, KK3, 6, 5); + R( al, bl, cl, dl, el, F3, K3, 11, 14 ); + R( ar, br, cr, dr, er, F1, KK3, 4, 8); + R( el, al, bl, cl, dl, F3, K3, 10, 15 ); + R( er, ar, br, cr, dr, F1, KK3, 1, 11); + R( dl, el, al, bl, cl, F3, K3, 0, 14 ); + R( dr, er, ar, br, cr, F1, KK3, 3, 14); + R( cl, dl, el, al, bl, F3, K3, 8, 15 ); + R( cr, dr, er, ar, br, F1, KK3, 11, 14); + R( bl, cl, dl, el, al, F3, K3, 12, 9 ); + R( br, cr, dr, er, ar, F1, KK3, 15, 6); + R( al, bl, cl, dl, el, F3, K3, 4, 8 ); + R( ar, br, cr, dr, er, F1, KK3, 0, 14); + R( el, al, bl, cl, dl, F3, K3, 13, 9 ); + R( er, ar, br, cr, dr, F1, KK3, 5, 6); + R( dl, el, al, bl, cl, F3, K3, 3, 14 ); + R( dr, er, ar, br, cr, F1, KK3, 12, 9); + R( cl, dl, el, al, bl, F3, K3, 7, 5 ); + R( cr, dr, er, ar, br, F1, KK3, 2, 12); + R( bl, cl, dl, el, al, F3, K3, 15, 6 ); + R( br, cr, dr, er, ar, F1, KK3, 13, 9); + R( al, bl, cl, dl, el, F3, K3, 14, 8 ); + R( ar, br, cr, dr, er, F1, KK3, 9, 12); + R( el, al, bl, cl, dl, F3, K3, 5, 6 ); + R( er, ar, br, cr, dr, F1, KK3, 7, 5); + R( dl, el, al, bl, cl, F3, K3, 6, 5 ); + R( dr, er, ar, br, cr, F1, KK3, 10, 15); + R( cl, dl, el, al, bl, F3, K3, 2, 12 ); + R( cr, dr, er, ar, br, F1, KK3, 14, 8); + R( bl, cl, dl, el, al, F4, K4, 4, 9 ); + R( br, cr, dr, er, ar, F0, KK4, 12, 8); + R( al, bl, cl, dl, el, F4, K4, 0, 15 ); + R( ar, br, cr, dr, er, F0, KK4, 15, 5); + R( el, al, bl, cl, dl, F4, K4, 5, 5 ); + R( er, ar, br, cr, dr, F0, KK4, 10, 12); + R( dl, el, al, bl, cl, F4, K4, 9, 11 ); + R( dr, er, ar, br, cr, F0, KK4, 4, 9); + R( cl, dl, el, al, bl, F4, K4, 7, 6 ); + R( cr, dr, er, ar, br, F0, KK4, 1, 12); + R( bl, cl, dl, el, al, F4, K4, 12, 8 ); + R( br, cr, dr, er, ar, F0, KK4, 5, 5); + R( al, bl, cl, dl, el, F4, K4, 2, 13 ); + R( ar, br, cr, dr, er, F0, KK4, 8, 14); + R( el, al, bl, cl, dl, F4, K4, 10, 12 ); + R( er, ar, br, cr, dr, F0, KK4, 7, 6); + R( dl, el, al, bl, cl, F4, K4, 14, 5 ); + R( dr, er, ar, br, cr, F0, KK4, 6, 8); + R( cl, dl, el, al, bl, F4, K4, 1, 12 ); + R( cr, dr, er, ar, br, F0, KK4, 2, 13); + R( bl, cl, dl, el, al, F4, K4, 3, 13 ); + R( br, cr, dr, er, ar, F0, KK4, 13, 6); + R( al, bl, cl, dl, el, F4, K4, 8, 14 ); + R( ar, br, cr, dr, er, F0, KK4, 14, 5); + R( el, al, bl, cl, dl, F4, K4, 11, 11 ); + R( er, ar, br, cr, dr, F0, KK4, 0, 15); + R( dl, el, al, bl, cl, F4, K4, 6, 8 ); + R( dr, er, ar, br, cr, F0, KK4, 3, 13); + R( cl, dl, el, al, bl, F4, K4, 15, 5 ); + R( cr, dr, er, ar, br, F0, KK4, 9, 11); + R( bl, cl, dl, el, al, F4, K4, 13, 6 ); + R( br, cr, dr, er, ar, F0, KK4, 11, 11); + + dr += cl + hd->h1; + hd->h1 = hd->h2 + dl + er; + hd->h2 = hd->h3 + el + ar; + hd->h3 = hd->h4 + al + br; + hd->h4 = hd->h0 + bl + cr; + hd->h0 = dr; - return /*burn_stack*/ 108+5*sizeof(void*); + return /*burn_stack*/ 104+5*sizeof(void*); } ---- ____________________________________________________________ FREE ONLINE PHOTOSHARING - Share your photos online with your friends and family! Visit http://www.inbox.com/photosharing to find out more! From metaschima at inbox.com Fri Aug 22 03:51:15 2014 From: metaschima at inbox.com (Meta Schima) Date: Thu, 21 Aug 2014 17:51:15 -0800 Subject: [PATCH 1/1] Improved whirlpool hash performance Message-ID: This patch improves whirlpool hash performance. before: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 7.74 ns/B 123.1 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 6.63 ns/B 143.8 MiB/s - c/B Note that I changed around some variables, I removed 4 x whirlpool_block_t sized variables (BLOCK_SIZE/8), but added 2 x u64 [2][BLOCK_SIZE / 8], so that's still the same size to be burned from the stack as before. I also added a macro and made the lookup tables into one large array because this improves lookup time. ~ Andrei ---- diff -ruNp libgcrypt-1.6.2/cipher/whirlpool.c libgcrypt-1.6.3/cipher/whirlpool.c --- libgcrypt-1.6.2/cipher/whirlpool.c 2014-08-21 07:50:39.000000000 -0500 +++ libgcrypt-1.6.3/cipher/whirlpool.c 2014-08-21 20:43:46.446406268 -0500 @@ -87,6 +87,17 @@ typedef struct { for (i = 0; i < 8; i++) \ block_dst[i] ^= block_src[i]; +/* XOR lookup boxes with index SRC [(SHIFT + n) & 7] >> x. */ +#define WHIRLPOOL_XOR(src, shift) \ + C[((unsigned int)(src[ (shift) ] >> 56) ) ] ^ \ + C[((unsigned int)(src[((shift) + 7) & 7] >> 48) & 0xff) + 256 ] ^ \ + C[((unsigned int)(src[((shift) + 6) & 7] >> 40) & 0xff) + (256*2)] ^ \ + C[((unsigned int)(src[((shift) + 5) & 7] >> 32) & 0xff) + (256*3)] ^ \ + C[((unsigned int)(src[((shift) + 4) & 7] >> 24) & 0xff) + (256*4)] ^ \ + C[((unsigned int)(src[((shift) + 3) & 7] >> 16) & 0xff) + (256*5)] ^ \ + C[((unsigned int)(src[((shift) + 2) & 7] >> 8) & 0xff) + (256*6)] ^ \ + C[((unsigned int)(src[((shift) + 1) & 7] ) & 0xff) + (256*7)] \ + ? /* Round constants. */ @@ -107,7 +118,7 @@ static const u64 rc[R] = ? /* Main lookup boxes. */ -static const u64 C0[256] = +static const u64 C[8*256] = { U64_C (0x18186018c07830d8), U64_C (0x23238c2305af4626), U64_C (0xc6c63fc67ef991b8), U64_C (0xe8e887e8136fcdfb), @@ -237,10 +248,7 @@ static const u64 C0[256] = U64_C (0x98985a98b4c22d2c), U64_C (0xa4a4aaa4490e55ed), U64_C (0x2828a0285d885075), U64_C (0x5c5c6d5cda31b886), U64_C (0xf8f8c7f8933fed6b), U64_C (0x8686228644a411c2), - }; -static const u64 C1[256] = - { U64_C (0xd818186018c07830), U64_C (0x2623238c2305af46), U64_C (0xb8c6c63fc67ef991), U64_C (0xfbe8e887e8136fcd), U64_C (0xcb878726874ca113), U64_C (0x11b8b8dab8a9626d), @@ -369,10 +377,7 @@ static const u64 C1[256] = U64_C (0x2c98985a98b4c22d), U64_C (0xeda4a4aaa4490e55), U64_C (0x752828a0285d8850), U64_C (0x865c5c6d5cda31b8), U64_C (0x6bf8f8c7f8933fed), U64_C (0xc28686228644a411), - }; -static const u64 C2[256] = - { U64_C (0x30d818186018c078), U64_C (0x462623238c2305af), U64_C (0x91b8c6c63fc67ef9), U64_C (0xcdfbe8e887e8136f), U64_C (0x13cb878726874ca1), U64_C (0x6d11b8b8dab8a962), @@ -501,10 +506,7 @@ static const u64 C2[256] = U64_C (0x2d2c98985a98b4c2), U64_C (0x55eda4a4aaa4490e), U64_C (0x50752828a0285d88), U64_C (0xb8865c5c6d5cda31), U64_C (0xed6bf8f8c7f8933f), U64_C (0x11c28686228644a4), - }; -static const u64 C3[256] = - { U64_C (0x7830d818186018c0), U64_C (0xaf462623238c2305), U64_C (0xf991b8c6c63fc67e), U64_C (0x6fcdfbe8e887e813), U64_C (0xa113cb878726874c), U64_C (0x626d11b8b8dab8a9), @@ -633,10 +635,7 @@ static const u64 C3[256] = U64_C (0xc22d2c98985a98b4), U64_C (0x0e55eda4a4aaa449), U64_C (0x8850752828a0285d), U64_C (0x31b8865c5c6d5cda), U64_C (0x3fed6bf8f8c7f893), U64_C (0xa411c28686228644), - }; -static const u64 C4[256] = - { U64_C (0xc07830d818186018), U64_C (0x05af462623238c23), U64_C (0x7ef991b8c6c63fc6), U64_C (0x136fcdfbe8e887e8), U64_C (0x4ca113cb87872687), U64_C (0xa9626d11b8b8dab8), @@ -765,10 +764,7 @@ static const u64 C4[256] = U64_C (0xb4c22d2c98985a98), U64_C (0x490e55eda4a4aaa4), U64_C (0x5d8850752828a028), U64_C (0xda31b8865c5c6d5c), U64_C (0x933fed6bf8f8c7f8), U64_C (0x44a411c286862286), - }; -static const u64 C5[256] = - { U64_C (0x18c07830d8181860), U64_C (0x2305af462623238c), U64_C (0xc67ef991b8c6c63f), U64_C (0xe8136fcdfbe8e887), U64_C (0x874ca113cb878726), U64_C (0xb8a9626d11b8b8da), @@ -897,10 +893,7 @@ static const u64 C5[256] = U64_C (0x98b4c22d2c98985a), U64_C (0xa4490e55eda4a4aa), U64_C (0x285d8850752828a0), U64_C (0x5cda31b8865c5c6d), U64_C (0xf8933fed6bf8f8c7), U64_C (0x8644a411c2868622), - }; -static const u64 C6[256] = - { U64_C (0x6018c07830d81818), U64_C (0x8c2305af46262323), U64_C (0x3fc67ef991b8c6c6), U64_C (0x87e8136fcdfbe8e8), U64_C (0x26874ca113cb8787), U64_C (0xdab8a9626d11b8b8), @@ -1029,10 +1022,7 @@ static const u64 C6[256] = U64_C (0x5a98b4c22d2c9898), U64_C (0xaaa4490e55eda4a4), U64_C (0xa0285d8850752828), U64_C (0x6d5cda31b8865c5c), U64_C (0xc7f8933fed6bf8f8), U64_C (0x228644a411c28686), - }; -static const u64 C7[256] = - { U64_C (0x186018c07830d818), U64_C (0x238c2305af462623), U64_C (0xc63fc67ef991b8c6), U64_C (0xe887e8136fcdfbe8), U64_C (0x8726874ca113cb87), U64_C (0xb8dab8a9626d11b8), @@ -1163,7 +1153,6 @@ static const u64 C7[256] = U64_C (0xf8c7f8933fed6bf8), U64_C (0x86228644a411c286), }; - ? /* * Transform block. @@ -1172,97 +1161,38 @@ static unsigned int whirlpool_transform (void *ctx, const unsigned char *data) { whirlpool_context_t *context = ctx; - whirlpool_block_t data_block; - whirlpool_block_t key; - whirlpool_block_t state; - whirlpool_block_t block; + u64 key[2][BLOCK_SIZE / 8]; + u64 state[2][BLOCK_SIZE / 8]; unsigned int r; unsigned int i; - buffer_to_block (data, data_block, i); - block_copy (key, context->hash_state, i); - block_copy (state, context->hash_state, i); - block_xor (state, data_block, i); + /* buffer_to_block and block_xor at once */ + + for (i = 0; i < 8; i++) + state[0][i] = buf_get_be64((data) + i * 8) ^ context->hash_state[i]; - for (r = 0; r < R; r++) + block_copy (key[0], context->hash_state, i); + block_copy (context->hash_state, state[0], i); + + for (r = 0, i = 0; r < R; r++) { - /* Compute round key K^r. */ + /* Compute round key K^r, and apply r-th round transformation, interleaved */ + + state[!i][0] = WHIRLPOOL_XOR(state[i], 0) ^ (key[!i][0] = WHIRLPOOL_XOR(key[i], 0) ^ rc[r]); + state[!i][1] = WHIRLPOOL_XOR(state[i], 1) ^ (key[!i][1] = WHIRLPOOL_XOR(key[i], 1)); + state[!i][2] = WHIRLPOOL_XOR(state[i], 2) ^ (key[!i][2] = WHIRLPOOL_XOR(key[i], 2)); + state[!i][3] = WHIRLPOOL_XOR(state[i], 3) ^ (key[!i][3] = WHIRLPOOL_XOR(key[i], 3)); + state[!i][4] = WHIRLPOOL_XOR(state[i], 4) ^ (key[!i][4] = WHIRLPOOL_XOR(key[i], 4)); + state[!i][5] = WHIRLPOOL_XOR(state[i], 5) ^ (key[!i][5] = WHIRLPOOL_XOR(key[i], 5)); + state[!i][6] = WHIRLPOOL_XOR(state[i], 6) ^ (key[!i][6] = WHIRLPOOL_XOR(key[i], 6)); + state[!i][7] = WHIRLPOOL_XOR(state[i], 7) ^ (key[!i][7] = WHIRLPOOL_XOR(key[i], 7)); - block[0] = (C0[(key[0] >> 56) & 0xFF] ^ C1[(key[7] >> 48) & 0xFF] ^ - C2[(key[6] >> 40) & 0xFF] ^ C3[(key[5] >> 32) & 0xFF] ^ - C4[(key[4] >> 24) & 0xFF] ^ C5[(key[3] >> 16) & 0xFF] ^ - C6[(key[2] >> 8) & 0xFF] ^ C7[(key[1] >> 0) & 0xFF] ^ rc[r]); - block[1] = (C0[(key[1] >> 56) & 0xFF] ^ C1[(key[0] >> 48) & 0xFF] ^ - C2[(key[7] >> 40) & 0xFF] ^ C3[(key[6] >> 32) & 0xFF] ^ - C4[(key[5] >> 24) & 0xFF] ^ C5[(key[4] >> 16) & 0xFF] ^ - C6[(key[3] >> 8) & 0xFF] ^ C7[(key[2] >> 0) & 0xFF]); - block[2] = (C0[(key[2] >> 56) & 0xFF] ^ C1[(key[1] >> 48) & 0xFF] ^ - C2[(key[0] >> 40) & 0xFF] ^ C3[(key[7] >> 32) & 0xFF] ^ - C4[(key[6] >> 24) & 0xFF] ^ C5[(key[5] >> 16) & 0xFF] ^ - C6[(key[4] >> 8) & 0xFF] ^ C7[(key[3] >> 0) & 0xFF]); - block[3] = (C0[(key[3] >> 56) & 0xFF] ^ C1[(key[2] >> 48) & 0xFF] ^ - C2[(key[1] >> 40) & 0xFF] ^ C3[(key[0] >> 32) & 0xFF] ^ - C4[(key[7] >> 24) & 0xFF] ^ C5[(key[6] >> 16) & 0xFF] ^ - C6[(key[5] >> 8) & 0xFF] ^ C7[(key[4] >> 0) & 0xFF]); - block[4] = (C0[(key[4] >> 56) & 0xFF] ^ C1[(key[3] >> 48) & 0xFF] ^ - C2[(key[2] >> 40) & 0xFF] ^ C3[(key[1] >> 32) & 0xFF] ^ - C4[(key[0] >> 24) & 0xFF] ^ C5[(key[7] >> 16) & 0xFF] ^ - C6[(key[6] >> 8) & 0xFF] ^ C7[(key[5] >> 0) & 0xFF]); - block[5] = (C0[(key[5] >> 56) & 0xFF] ^ C1[(key[4] >> 48) & 0xFF] ^ - C2[(key[3] >> 40) & 0xFF] ^ C3[(key[2] >> 32) & 0xFF] ^ - C4[(key[1] >> 24) & 0xFF] ^ C5[(key[0] >> 16) & 0xFF] ^ - C6[(key[7] >> 8) & 0xFF] ^ C7[(key[6] >> 0) & 0xFF]); - block[6] = (C0[(key[6] >> 56) & 0xFF] ^ C1[(key[5] >> 48) & 0xFF] ^ - C2[(key[4] >> 40) & 0xFF] ^ C3[(key[3] >> 32) & 0xFF] ^ - C4[(key[2] >> 24) & 0xFF] ^ C5[(key[1] >> 16) & 0xFF] ^ - C6[(key[0] >> 8) & 0xFF] ^ C7[(key[7] >> 0) & 0xFF]); - block[7] = (C0[(key[7] >> 56) & 0xFF] ^ C1[(key[6] >> 48) & 0xFF] ^ - C2[(key[5] >> 40) & 0xFF] ^ C3[(key[4] >> 32) & 0xFF] ^ - C4[(key[3] >> 24) & 0xFF] ^ C5[(key[2] >> 16) & 0xFF] ^ - C6[(key[1] >> 8) & 0xFF] ^ C7[(key[0] >> 0) & 0xFF]); - block_copy (key, block, i); - - /* Apply r-th round transformation. */ - - block[0] = (C0[(state[0] >> 56) & 0xFF] ^ C1[(state[7] >> 48) & 0xFF] ^ - C2[(state[6] >> 40) & 0xFF] ^ C3[(state[5] >> 32) & 0xFF] ^ - C4[(state[4] >> 24) & 0xFF] ^ C5[(state[3] >> 16) & 0xFF] ^ - C6[(state[2] >> 8) & 0xFF] ^ C7[(state[1] >> 0) & 0xFF] ^ key[0]); - block[1] = (C0[(state[1] >> 56) & 0xFF] ^ C1[(state[0] >> 48) & 0xFF] ^ - C2[(state[7] >> 40) & 0xFF] ^ C3[(state[6] >> 32) & 0xFF] ^ - C4[(state[5] >> 24) & 0xFF] ^ C5[(state[4] >> 16) & 0xFF] ^ - C6[(state[3] >> 8) & 0xFF] ^ C7[(state[2] >> 0) & 0xFF] ^ key[1]); - block[2] = (C0[(state[2] >> 56) & 0xFF] ^ C1[(state[1] >> 48) & 0xFF] ^ - C2[(state[0] >> 40) & 0xFF] ^ C3[(state[7] >> 32) & 0xFF] ^ - C4[(state[6] >> 24) & 0xFF] ^ C5[(state[5] >> 16) & 0xFF] ^ - C6[(state[4] >> 8) & 0xFF] ^ C7[(state[3] >> 0) & 0xFF] ^ key[2]); - block[3] = (C0[(state[3] >> 56) & 0xFF] ^ C1[(state[2] >> 48) & 0xFF] ^ - C2[(state[1] >> 40) & 0xFF] ^ C3[(state[0] >> 32) & 0xFF] ^ - C4[(state[7] >> 24) & 0xFF] ^ C5[(state[6] >> 16) & 0xFF] ^ - C6[(state[5] >> 8) & 0xFF] ^ C7[(state[4] >> 0) & 0xFF] ^ key[3]); - block[4] = (C0[(state[4] >> 56) & 0xFF] ^ C1[(state[3] >> 48) & 0xFF] ^ - C2[(state[2] >> 40) & 0xFF] ^ C3[(state[1] >> 32) & 0xFF] ^ - C4[(state[0] >> 24) & 0xFF] ^ C5[(state[7] >> 16) & 0xFF] ^ - C6[(state[6] >> 8) & 0xFF] ^ C7[(state[5] >> 0) & 0xFF] ^ key[4]); - block[5] = (C0[(state[5] >> 56) & 0xFF] ^ C1[(state[4] >> 48) & 0xFF] ^ - C2[(state[3] >> 40) & 0xFF] ^ C3[(state[2] >> 32) & 0xFF] ^ - C4[(state[1] >> 24) & 0xFF] ^ C5[(state[0] >> 16) & 0xFF] ^ - C6[(state[7] >> 8) & 0xFF] ^ C7[(state[6] >> 0) & 0xFF] ^ key[5]); - block[6] = (C0[(state[6] >> 56) & 0xFF] ^ C1[(state[5] >> 48) & 0xFF] ^ - C2[(state[4] >> 40) & 0xFF] ^ C3[(state[3] >> 32) & 0xFF] ^ - C4[(state[2] >> 24) & 0xFF] ^ C5[(state[1] >> 16) & 0xFF] ^ - C6[(state[0] >> 8) & 0xFF] ^ C7[(state[7] >> 0) & 0xFF] ^ key[6]); - block[7] = (C0[(state[7] >> 56) & 0xFF] ^ C1[(state[6] >> 48) & 0xFF] ^ - C2[(state[5] >> 40) & 0xFF] ^ C3[(state[4] >> 32) & 0xFF] ^ - C4[(state[3] >> 24) & 0xFF] ^ C5[(state[2] >> 16) & 0xFF] ^ - C6[(state[1] >> 8) & 0xFF] ^ C7[(state[0] >> 0) & 0xFF] ^ key[7]); - block_copy (state, block, i); + i = !i; } /* Compression. */ - block_xor (context->hash_state, data_block, i); - block_xor (context->hash_state, state, i); + block_xor (context->hash_state, state[0], i); return /*burn_stack*/ 4 * sizeof(whirlpool_block_t) + 2 * sizeof(int) + 4 * sizeof(void*); ---- ____________________________________________________________ Can't remember your password? Do you need a strong and secure password? Use Password manager! It stores your passwords & protects your account. Check it out at http://mysecurelogon.com/manager From jussi.kivilinna at iki.fi Fri Aug 22 09:56:08 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Fri, 22 Aug 2014 10:56:08 +0300 Subject: [PATCH 1/1] Improved ripemd160 perfromance In-Reply-To: References: Message-ID: <53F6F798.4030506@iki.fi> On 2014-08-22 01:34, Meta Schima wrote: > Hello, I am new to the mailing list. I have a patch here to improve ripemd160 performance by interleaving left and right lanes. On my system before: Hello, Nice improvement... When submitting benchmarking results, I personally am interested to know what kind of CPU these tests were run (Intel, AMD, model). There can be quite big differences in results even between x86-64 CPUs. > Hash: > | nanosecs/byte mebibytes/sec cycles/byte > RIPEMD160 | 3.31 ns/B 288.1 MiB/s - c/B > after: > Hash: > | nanosecs/byte mebibytes/sec cycles/byte > RIPEMD160 | 2.08 ns/B 458.3 MiB/s - c/B > > Note that I removed one temporary u32 variable, and this reduces the stack burn from 108 to 104, hope this is right. > > ~ Andrei You need to check doc/HACKING about how to contribute to libgcrypt. You need to check the part about DCO & Signed-off-by and how to start commit log. -Jussi From wk at gnupg.org Fri Aug 22 10:40:23 2014 From: wk at gnupg.org (Werner Koch) Date: Fri, 22 Aug 2014 10:40:23 +0200 Subject: [PATCH 1/1] Improved ripemd160 perfromance In-Reply-To: <53F6F798.4030506@iki.fi> (Jussi Kivilinna's message of "Fri, 22 Aug 2014 10:56:08 +0300") References: <53F6F798.4030506@iki.fi> Message-ID: <877g205348.fsf@vigenere.g10code.de> On Fri, 22 Aug 2014 09:56, jussi.kivilinna at iki.fi said: > You need to check doc/HACKING about how to contribute to libgcrypt. You > need to check the part about DCO & Signed-off-by and how to start commit > log. Right, me for example won't look close at patches which do not follow the rules. Having read doc/HACKING can be expected frrom a hacker ;-) Shalom-Salam, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From andsch at inbox.com Fri Aug 22 18:11:28 2014 From: andsch at inbox.com (And Sch) Date: Fri, 22 Aug 2014 08:11:28 -0800 Subject: DCO signed Message-ID: -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Libgcrypt Developer's Certificate of Origin. Version 1.0 ========================================================= By making a contribution to the Libgcrypt project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the free software license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate free software license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same free software license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the free software license(s) involved. Signed-off-by: Andrei Scherer -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAEBAgAGBQJT92mTAAoJEClrD5EX5v64XGQIAK8f4EMERoL4/Snpo5zSB8Q7 6wYh+pPAIKARvSlrMh5pxivaT3VLQLcJmYS/aiGtZdsXogywh/XLwyMcB7LN96SI aht7LfBVmXTETAvc9ueTvNOfobWGZdMmTxQmOHc+KmCRP0BERwHlrJ5CR3H858P2 qRlNQv31FJIrs3VlOtXeZ/qzgOwxJmlQKyOq8EPkf7x+Fixh6DGR/T51Bpy+L2yp 8SZWcKRgiBZ27lfb38xqeNZvUWVeEO50IUhvMpI2SkG9MQce3cG5VQFtsv2x0tMY 2GL5OkSIA7wAeUMhACQUkjrJBzFbjA4eA45otM0JfRdmS2hdBA+eF2rbUhGpSco= =R08i -----END PGP SIGNATURE----- ____________________________________________________________ Can't remember your password? Do you need a strong and secure password? Use Password manager! It stores your passwords & protects your account. Check it out at http://mysecurelogon.com/manager From andsch at inbox.com Fri Aug 22 18:27:51 2014 From: andsch at inbox.com (And Sch) Date: Fri, 22 Aug 2014 08:27:51 -0800 Subject: [PATCH 1/1] Improved whirlpool hash performance Message-ID: Hello again, I have signed the DCO now. Here is the whirlpool patch again, signed. I uploaded my public key to the keyserver as well. before: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 7.75 ns/B 123.0 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 6.70 ns/B 142.3 MiB/s - c/B -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 diff -ruNp libgcrypt-1.6.2/cipher/whirlpool.c libgcrypt-1.6.3/cipher/whirlpool.c - --- libgcrypt-1.6.2/cipher/whirlpool.c 2014-08-21 07:50:39.000000000 -0500 +++ libgcrypt-1.6.3/cipher/whirlpool.c 2014-08-22 11:17:06.496754032 -0500 @@ -87,6 +87,17 @@ typedef struct { for (i = 0; i < 8; i++) \ block_dst[i] ^= block_src[i]; +/* XOR lookup boxes with index SRC [(SHIFT + n) & 7] >> x. */ +#define WHIRLPOOL_XOR(src, shift) \ + C[((unsigned int)(src[ (shift) ] >> 56) ) ] ^ \ + C[((unsigned int)(src[((shift) + 7) & 7] >> 48) & 0xff) + 256 ] ^ \ + C[((unsigned int)(src[((shift) + 6) & 7] >> 40) & 0xff) + (256*2)] ^ \ + C[((unsigned int)(src[((shift) + 5) & 7] >> 32) & 0xff) + (256*3)] ^ \ + C[((unsigned int)(src[((shift) + 4) & 7] >> 24) & 0xff) + (256*4)] ^ \ + C[((unsigned int)(src[((shift) + 3) & 7] >> 16) & 0xff) + (256*5)] ^ \ + C[((unsigned int)(src[((shift) + 2) & 7] >> 8) & 0xff) + (256*6)] ^ \ + C[((unsigned int)(src[((shift) + 1) & 7] ) & 0xff) + (256*7)] \ + ? /* Round constants. */ @@ -107,7 +118,7 @@ static const u64 rc[R] = ? /* Main lookup boxes. */ - -static const u64 C0[256] = +static const u64 C[8*256] = { U64_C (0x18186018c07830d8), U64_C (0x23238c2305af4626), U64_C (0xc6c63fc67ef991b8), U64_C (0xe8e887e8136fcdfb), @@ -237,10 +248,7 @@ static const u64 C0[256] = U64_C (0x98985a98b4c22d2c), U64_C (0xa4a4aaa4490e55ed), U64_C (0x2828a0285d885075), U64_C (0x5c5c6d5cda31b886), U64_C (0xf8f8c7f8933fed6b), U64_C (0x8686228644a411c2), - - }; - -static const u64 C1[256] = - - { U64_C (0xd818186018c07830), U64_C (0x2623238c2305af46), U64_C (0xb8c6c63fc67ef991), U64_C (0xfbe8e887e8136fcd), U64_C (0xcb878726874ca113), U64_C (0x11b8b8dab8a9626d), @@ -369,10 +377,7 @@ static const u64 C1[256] = U64_C (0x2c98985a98b4c22d), U64_C (0xeda4a4aaa4490e55), U64_C (0x752828a0285d8850), U64_C (0x865c5c6d5cda31b8), U64_C (0x6bf8f8c7f8933fed), U64_C (0xc28686228644a411), - - }; - -static const u64 C2[256] = - - { U64_C (0x30d818186018c078), U64_C (0x462623238c2305af), U64_C (0x91b8c6c63fc67ef9), U64_C (0xcdfbe8e887e8136f), U64_C (0x13cb878726874ca1), U64_C (0x6d11b8b8dab8a962), @@ -501,10 +506,7 @@ static const u64 C2[256] = U64_C (0x2d2c98985a98b4c2), U64_C (0x55eda4a4aaa4490e), U64_C (0x50752828a0285d88), U64_C (0xb8865c5c6d5cda31), U64_C (0xed6bf8f8c7f8933f), U64_C (0x11c28686228644a4), - - }; - -static const u64 C3[256] = - - { U64_C (0x7830d818186018c0), U64_C (0xaf462623238c2305), U64_C (0xf991b8c6c63fc67e), U64_C (0x6fcdfbe8e887e813), U64_C (0xa113cb878726874c), U64_C (0x626d11b8b8dab8a9), @@ -633,10 +635,7 @@ static const u64 C3[256] = U64_C (0xc22d2c98985a98b4), U64_C (0x0e55eda4a4aaa449), U64_C (0x8850752828a0285d), U64_C (0x31b8865c5c6d5cda), U64_C (0x3fed6bf8f8c7f893), U64_C (0xa411c28686228644), - - }; - -static const u64 C4[256] = - - { U64_C (0xc07830d818186018), U64_C (0x05af462623238c23), U64_C (0x7ef991b8c6c63fc6), U64_C (0x136fcdfbe8e887e8), U64_C (0x4ca113cb87872687), U64_C (0xa9626d11b8b8dab8), @@ -765,10 +764,7 @@ static const u64 C4[256] = U64_C (0xb4c22d2c98985a98), U64_C (0x490e55eda4a4aaa4), U64_C (0x5d8850752828a028), U64_C (0xda31b8865c5c6d5c), U64_C (0x933fed6bf8f8c7f8), U64_C (0x44a411c286862286), - - }; - -static const u64 C5[256] = - - { U64_C (0x18c07830d8181860), U64_C (0x2305af462623238c), U64_C (0xc67ef991b8c6c63f), U64_C (0xe8136fcdfbe8e887), U64_C (0x874ca113cb878726), U64_C (0xb8a9626d11b8b8da), @@ -897,10 +893,7 @@ static const u64 C5[256] = U64_C (0x98b4c22d2c98985a), U64_C (0xa4490e55eda4a4aa), U64_C (0x285d8850752828a0), U64_C (0x5cda31b8865c5c6d), U64_C (0xf8933fed6bf8f8c7), U64_C (0x8644a411c2868622), - - }; - -static const u64 C6[256] = - - { U64_C (0x6018c07830d81818), U64_C (0x8c2305af46262323), U64_C (0x3fc67ef991b8c6c6), U64_C (0x87e8136fcdfbe8e8), U64_C (0x26874ca113cb8787), U64_C (0xdab8a9626d11b8b8), @@ -1029,10 +1022,7 @@ static const u64 C6[256] = U64_C (0x5a98b4c22d2c9898), U64_C (0xaaa4490e55eda4a4), U64_C (0xa0285d8850752828), U64_C (0x6d5cda31b8865c5c), U64_C (0xc7f8933fed6bf8f8), U64_C (0x228644a411c28686), - - }; - -static const u64 C7[256] = - - { U64_C (0x186018c07830d818), U64_C (0x238c2305af462623), U64_C (0xc63fc67ef991b8c6), U64_C (0xe887e8136fcdfbe8), U64_C (0x8726874ca113cb87), U64_C (0xb8dab8a9626d11b8), @@ -1163,7 +1153,6 @@ static const u64 C7[256] = U64_C (0xf8c7f8933fed6bf8), U64_C (0x86228644a411c286), }; - - ? /* * Transform block. @@ -1172,97 +1161,36 @@ static unsigned int whirlpool_transform (void *ctx, const unsigned char *data) { whirlpool_context_t *context = ctx; - - whirlpool_block_t data_block; - - whirlpool_block_t key; - - whirlpool_block_t state; - - whirlpool_block_t block; + u64 key[2][BLOCK_SIZE / 8]; + u64 state[2][BLOCK_SIZE / 8]; unsigned int r; unsigned int i; - - buffer_to_block (data, data_block, i); - - block_copy (key, context->hash_state, i); - - block_copy (state, context->hash_state, i); - - block_xor (state, data_block, i); + /* buffer_to_block and block_xor at once */ + + for (i = 0; i < 8; i++) + state[0][i] = buf_get_be64((data) + i * 8) ^ context->hash_state[i]; + + block_copy (key[0], context->hash_state, i); + block_copy (context->hash_state, state[0], i); - - for (r = 0; r < R; r++) + for (r = 0, i = 0; r < R; r++, i = !i) { - - /* Compute round key K^r. */ + /* Compute round key K^r, and apply r-th round transformation, interleaved */ - - block[0] = (C0[(key[0] >> 56) & 0xFF] ^ C1[(key[7] >> 48) & 0xFF] ^ - - C2[(key[6] >> 40) & 0xFF] ^ C3[(key[5] >> 32) & 0xFF] ^ - - C4[(key[4] >> 24) & 0xFF] ^ C5[(key[3] >> 16) & 0xFF] ^ - - C6[(key[2] >> 8) & 0xFF] ^ C7[(key[1] >> 0) & 0xFF] ^ rc[r]); - - block[1] = (C0[(key[1] >> 56) & 0xFF] ^ C1[(key[0] >> 48) & 0xFF] ^ - - C2[(key[7] >> 40) & 0xFF] ^ C3[(key[6] >> 32) & 0xFF] ^ - - C4[(key[5] >> 24) & 0xFF] ^ C5[(key[4] >> 16) & 0xFF] ^ - - C6[(key[3] >> 8) & 0xFF] ^ C7[(key[2] >> 0) & 0xFF]); - - block[2] = (C0[(key[2] >> 56) & 0xFF] ^ C1[(key[1] >> 48) & 0xFF] ^ - - C2[(key[0] >> 40) & 0xFF] ^ C3[(key[7] >> 32) & 0xFF] ^ - - C4[(key[6] >> 24) & 0xFF] ^ C5[(key[5] >> 16) & 0xFF] ^ - - C6[(key[4] >> 8) & 0xFF] ^ C7[(key[3] >> 0) & 0xFF]); - - block[3] = (C0[(key[3] >> 56) & 0xFF] ^ C1[(key[2] >> 48) & 0xFF] ^ - - C2[(key[1] >> 40) & 0xFF] ^ C3[(key[0] >> 32) & 0xFF] ^ - - C4[(key[7] >> 24) & 0xFF] ^ C5[(key[6] >> 16) & 0xFF] ^ - - C6[(key[5] >> 8) & 0xFF] ^ C7[(key[4] >> 0) & 0xFF]); - - block[4] = (C0[(key[4] >> 56) & 0xFF] ^ C1[(key[3] >> 48) & 0xFF] ^ - - C2[(key[2] >> 40) & 0xFF] ^ C3[(key[1] >> 32) & 0xFF] ^ - - C4[(key[0] >> 24) & 0xFF] ^ C5[(key[7] >> 16) & 0xFF] ^ - - C6[(key[6] >> 8) & 0xFF] ^ C7[(key[5] >> 0) & 0xFF]); - - block[5] = (C0[(key[5] >> 56) & 0xFF] ^ C1[(key[4] >> 48) & 0xFF] ^ - - C2[(key[3] >> 40) & 0xFF] ^ C3[(key[2] >> 32) & 0xFF] ^ - - C4[(key[1] >> 24) & 0xFF] ^ C5[(key[0] >> 16) & 0xFF] ^ - - C6[(key[7] >> 8) & 0xFF] ^ C7[(key[6] >> 0) & 0xFF]); - - block[6] = (C0[(key[6] >> 56) & 0xFF] ^ C1[(key[5] >> 48) & 0xFF] ^ - - C2[(key[4] >> 40) & 0xFF] ^ C3[(key[3] >> 32) & 0xFF] ^ - - C4[(key[2] >> 24) & 0xFF] ^ C5[(key[1] >> 16) & 0xFF] ^ - - C6[(key[0] >> 8) & 0xFF] ^ C7[(key[7] >> 0) & 0xFF]); - - block[7] = (C0[(key[7] >> 56) & 0xFF] ^ C1[(key[6] >> 48) & 0xFF] ^ - - C2[(key[5] >> 40) & 0xFF] ^ C3[(key[4] >> 32) & 0xFF] ^ - - C4[(key[3] >> 24) & 0xFF] ^ C5[(key[2] >> 16) & 0xFF] ^ - - C6[(key[1] >> 8) & 0xFF] ^ C7[(key[0] >> 0) & 0xFF]); - - block_copy (key, block, i); - - - - /* Apply r-th round transformation. */ - - - - block[0] = (C0[(state[0] >> 56) & 0xFF] ^ C1[(state[7] >> 48) & 0xFF] ^ - - C2[(state[6] >> 40) & 0xFF] ^ C3[(state[5] >> 32) & 0xFF] ^ - - C4[(state[4] >> 24) & 0xFF] ^ C5[(state[3] >> 16) & 0xFF] ^ - - C6[(state[2] >> 8) & 0xFF] ^ C7[(state[1] >> 0) & 0xFF] ^ key[0]); - - block[1] = (C0[(state[1] >> 56) & 0xFF] ^ C1[(state[0] >> 48) & 0xFF] ^ - - C2[(state[7] >> 40) & 0xFF] ^ C3[(state[6] >> 32) & 0xFF] ^ - - C4[(state[5] >> 24) & 0xFF] ^ C5[(state[4] >> 16) & 0xFF] ^ - - C6[(state[3] >> 8) & 0xFF] ^ C7[(state[2] >> 0) & 0xFF] ^ key[1]); - - block[2] = (C0[(state[2] >> 56) & 0xFF] ^ C1[(state[1] >> 48) & 0xFF] ^ - - C2[(state[0] >> 40) & 0xFF] ^ C3[(state[7] >> 32) & 0xFF] ^ - - C4[(state[6] >> 24) & 0xFF] ^ C5[(state[5] >> 16) & 0xFF] ^ - - C6[(state[4] >> 8) & 0xFF] ^ C7[(state[3] >> 0) & 0xFF] ^ key[2]); - - block[3] = (C0[(state[3] >> 56) & 0xFF] ^ C1[(state[2] >> 48) & 0xFF] ^ - - C2[(state[1] >> 40) & 0xFF] ^ C3[(state[0] >> 32) & 0xFF] ^ - - C4[(state[7] >> 24) & 0xFF] ^ C5[(state[6] >> 16) & 0xFF] ^ - - C6[(state[5] >> 8) & 0xFF] ^ C7[(state[4] >> 0) & 0xFF] ^ key[3]); - - block[4] = (C0[(state[4] >> 56) & 0xFF] ^ C1[(state[3] >> 48) & 0xFF] ^ - - C2[(state[2] >> 40) & 0xFF] ^ C3[(state[1] >> 32) & 0xFF] ^ - - C4[(state[0] >> 24) & 0xFF] ^ C5[(state[7] >> 16) & 0xFF] ^ - - C6[(state[6] >> 8) & 0xFF] ^ C7[(state[5] >> 0) & 0xFF] ^ key[4]); - - block[5] = (C0[(state[5] >> 56) & 0xFF] ^ C1[(state[4] >> 48) & 0xFF] ^ - - C2[(state[3] >> 40) & 0xFF] ^ C3[(state[2] >> 32) & 0xFF] ^ - - C4[(state[1] >> 24) & 0xFF] ^ C5[(state[0] >> 16) & 0xFF] ^ - - C6[(state[7] >> 8) & 0xFF] ^ C7[(state[6] >> 0) & 0xFF] ^ key[5]); - - block[6] = (C0[(state[6] >> 56) & 0xFF] ^ C1[(state[5] >> 48) & 0xFF] ^ - - C2[(state[4] >> 40) & 0xFF] ^ C3[(state[3] >> 32) & 0xFF] ^ - - C4[(state[2] >> 24) & 0xFF] ^ C5[(state[1] >> 16) & 0xFF] ^ - - C6[(state[0] >> 8) & 0xFF] ^ C7[(state[7] >> 0) & 0xFF] ^ key[6]); - - block[7] = (C0[(state[7] >> 56) & 0xFF] ^ C1[(state[6] >> 48) & 0xFF] ^ - - C2[(state[5] >> 40) & 0xFF] ^ C3[(state[4] >> 32) & 0xFF] ^ - - C4[(state[3] >> 24) & 0xFF] ^ C5[(state[2] >> 16) & 0xFF] ^ - - C6[(state[1] >> 8) & 0xFF] ^ C7[(state[0] >> 0) & 0xFF] ^ key[7]); - - block_copy (state, block, i); + state[!i][0] = WHIRLPOOL_XOR(state[i], 0) ^ (key[!i][0] = WHIRLPOOL_XOR(key[i], 0) ^ rc[r]); + state[!i][1] = WHIRLPOOL_XOR(state[i], 1) ^ (key[!i][1] = WHIRLPOOL_XOR(key[i], 1)); + state[!i][2] = WHIRLPOOL_XOR(state[i], 2) ^ (key[!i][2] = WHIRLPOOL_XOR(key[i], 2)); + state[!i][3] = WHIRLPOOL_XOR(state[i], 3) ^ (key[!i][3] = WHIRLPOOL_XOR(key[i], 3)); + state[!i][4] = WHIRLPOOL_XOR(state[i], 4) ^ (key[!i][4] = WHIRLPOOL_XOR(key[i], 4)); + state[!i][5] = WHIRLPOOL_XOR(state[i], 5) ^ (key[!i][5] = WHIRLPOOL_XOR(key[i], 5)); + state[!i][6] = WHIRLPOOL_XOR(state[i], 6) ^ (key[!i][6] = WHIRLPOOL_XOR(key[i], 6)); + state[!i][7] = WHIRLPOOL_XOR(state[i], 7) ^ (key[!i][7] = WHIRLPOOL_XOR(key[i], 7)); } /* Compression. */ - - block_xor (context->hash_state, data_block, i); - - block_xor (context->hash_state, state, i); + block_xor (context->hash_state, state[0], i); return /*burn_stack*/ 4 * sizeof(whirlpool_block_t) + 2 * sizeof(int) + 4 * sizeof(void*); -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAEBAgAGBQJT927aAAoJEClrD5EX5v64jR0H/Ax+eamg7Z1mfLz/E/HWmtZm ibSEkN4Z5PnqCw7GedoguuoSnxmLJI3ovJ85hXvJGrxVHy/kIy2RstZZfqbrJIgi xTypSuRCx81zebgmgQOn6MZ1MVQF1h3N8KYsJEwjtcVbOioGBKfEPZbcX7ySLSdX vNWYhyoZwXBgICaluP6M8QSeLQov1CkmWl/TLk8P3r1o68djTcI4O1YeFvazfqWj z1mMmVpmfIDZJGac/rrKR8rNL/HUW+sCNTaJ84OGBWrwFPqkf0ABTxCrMpDQrHCc GVi8cAfiI0t2JfcAQB2zruU8girJamT7ox/94CMKwYfo2AaqltnHkRnlFqm4sAo= =5Nuj -----END PGP SIGNATURE----- ____________________________________________________________ Can't remember your password? Do you need a strong and secure password? Use Password manager! It stores your passwords & protects your account. Check it out at http://mysecurelogon.com/manager From andsch at inbox.com Fri Aug 22 18:32:35 2014 From: andsch at inbox.com (And Sch) Date: Fri, 22 Aug 2014 08:32:35 -0800 Subject: [PATCH 1/1] Improved ripemd160 performance Message-ID: Here is the ripemd160 performance patch, signed. before: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 3.31 ns/B 288.0 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 2.08 ns/B 458.5 MiB/s - c/B -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 diff -ruNp libgcrypt-1.6.2/cipher/rmd160.c libgcrypt-1.6.3/cipher/rmd160.c - --- libgcrypt-1.6.2/cipher/rmd160.c 2014-08-21 07:50:39.000000000 -0500 +++ libgcrypt-1.6.3/cipher/rmd160.c 2014-08-21 17:15:13.678664524 -0500 @@ -178,8 +178,7 @@ static unsigned int transform ( void *ctx, const unsigned char *data ) { RMD160_CONTEXT *hd = ctx; - - register u32 a,b,c,d,e; - - u32 aa,bb,cc,dd,ee,t; + register u32 al, ar, bl, br, cl, cr, dl, dr, el, er; u32 x[16]; int i; @@ -201,196 +200,186 @@ transform ( void *ctx, const unsigned ch #define F2(x,y,z) ( ((x) | ~(y)) ^ (z) ) #define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) ) #define F4(x,y,z) ( (x) ^ ((y) | ~(z)) ) - -#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \ - - a = rol(t,s) + e; \ +#define R(a,b,c,d,e,f,k,r,s) do { a += f(b,c,d) + k + x[r]; \ + a = rol(a,s) + e; \ c = rol(c,10); \ } while(0) - - /* left lane */ - - a = hd->h0; - - b = hd->h1; - - c = hd->h2; - - d = hd->h3; - - e = hd->h4; - - R( a, b, c, d, e, F0, K0, 0, 11 ); - - R( e, a, b, c, d, F0, K0, 1, 14 ); - - R( d, e, a, b, c, F0, K0, 2, 15 ); - - R( c, d, e, a, b, F0, K0, 3, 12 ); - - R( b, c, d, e, a, F0, K0, 4, 5 ); - - R( a, b, c, d, e, F0, K0, 5, 8 ); - - R( e, a, b, c, d, F0, K0, 6, 7 ); - - R( d, e, a, b, c, F0, K0, 7, 9 ); - - R( c, d, e, a, b, F0, K0, 8, 11 ); - - R( b, c, d, e, a, F0, K0, 9, 13 ); - - R( a, b, c, d, e, F0, K0, 10, 14 ); - - R( e, a, b, c, d, F0, K0, 11, 15 ); - - R( d, e, a, b, c, F0, K0, 12, 6 ); - - R( c, d, e, a, b, F0, K0, 13, 7 ); - - R( b, c, d, e, a, F0, K0, 14, 9 ); - - R( a, b, c, d, e, F0, K0, 15, 8 ); - - R( e, a, b, c, d, F1, K1, 7, 7 ); - - R( d, e, a, b, c, F1, K1, 4, 6 ); - - R( c, d, e, a, b, F1, K1, 13, 8 ); - - R( b, c, d, e, a, F1, K1, 1, 13 ); - - R( a, b, c, d, e, F1, K1, 10, 11 ); - - R( e, a, b, c, d, F1, K1, 6, 9 ); - - R( d, e, a, b, c, F1, K1, 15, 7 ); - - R( c, d, e, a, b, F1, K1, 3, 15 ); - - R( b, c, d, e, a, F1, K1, 12, 7 ); - - R( a, b, c, d, e, F1, K1, 0, 12 ); - - R( e, a, b, c, d, F1, K1, 9, 15 ); - - R( d, e, a, b, c, F1, K1, 5, 9 ); - - R( c, d, e, a, b, F1, K1, 2, 11 ); - - R( b, c, d, e, a, F1, K1, 14, 7 ); - - R( a, b, c, d, e, F1, K1, 11, 13 ); - - R( e, a, b, c, d, F1, K1, 8, 12 ); - - R( d, e, a, b, c, F2, K2, 3, 11 ); - - R( c, d, e, a, b, F2, K2, 10, 13 ); - - R( b, c, d, e, a, F2, K2, 14, 6 ); - - R( a, b, c, d, e, F2, K2, 4, 7 ); - - R( e, a, b, c, d, F2, K2, 9, 14 ); - - R( d, e, a, b, c, F2, K2, 15, 9 ); - - R( c, d, e, a, b, F2, K2, 8, 13 ); - - R( b, c, d, e, a, F2, K2, 1, 15 ); - - R( a, b, c, d, e, F2, K2, 2, 14 ); - - R( e, a, b, c, d, F2, K2, 7, 8 ); - - R( d, e, a, b, c, F2, K2, 0, 13 ); - - R( c, d, e, a, b, F2, K2, 6, 6 ); - - R( b, c, d, e, a, F2, K2, 13, 5 ); - - R( a, b, c, d, e, F2, K2, 11, 12 ); - - R( e, a, b, c, d, F2, K2, 5, 7 ); - - R( d, e, a, b, c, F2, K2, 12, 5 ); - - R( c, d, e, a, b, F3, K3, 1, 11 ); - - R( b, c, d, e, a, F3, K3, 9, 12 ); - - R( a, b, c, d, e, F3, K3, 11, 14 ); - - R( e, a, b, c, d, F3, K3, 10, 15 ); - - R( d, e, a, b, c, F3, K3, 0, 14 ); - - R( c, d, e, a, b, F3, K3, 8, 15 ); - - R( b, c, d, e, a, F3, K3, 12, 9 ); - - R( a, b, c, d, e, F3, K3, 4, 8 ); - - R( e, a, b, c, d, F3, K3, 13, 9 ); - - R( d, e, a, b, c, F3, K3, 3, 14 ); - - R( c, d, e, a, b, F3, K3, 7, 5 ); - - R( b, c, d, e, a, F3, K3, 15, 6 ); - - R( a, b, c, d, e, F3, K3, 14, 8 ); - - R( e, a, b, c, d, F3, K3, 5, 6 ); - - R( d, e, a, b, c, F3, K3, 6, 5 ); - - R( c, d, e, a, b, F3, K3, 2, 12 ); - - R( b, c, d, e, a, F4, K4, 4, 9 ); - - R( a, b, c, d, e, F4, K4, 0, 15 ); - - R( e, a, b, c, d, F4, K4, 5, 5 ); - - R( d, e, a, b, c, F4, K4, 9, 11 ); - - R( c, d, e, a, b, F4, K4, 7, 6 ); - - R( b, c, d, e, a, F4, K4, 12, 8 ); - - R( a, b, c, d, e, F4, K4, 2, 13 ); - - R( e, a, b, c, d, F4, K4, 10, 12 ); - - R( d, e, a, b, c, F4, K4, 14, 5 ); - - R( c, d, e, a, b, F4, K4, 1, 12 ); - - R( b, c, d, e, a, F4, K4, 3, 13 ); - - R( a, b, c, d, e, F4, K4, 8, 14 ); - - R( e, a, b, c, d, F4, K4, 11, 11 ); - - R( d, e, a, b, c, F4, K4, 6, 8 ); - - R( c, d, e, a, b, F4, K4, 15, 5 ); - - R( b, c, d, e, a, F4, K4, 13, 6 ); - - - - aa = a; bb = b; cc = c; dd = d; ee = e; - - - - /* right lane */ - - a = hd->h0; - - b = hd->h1; - - c = hd->h2; - - d = hd->h3; - - e = hd->h4; - - R( a, b, c, d, e, F4, KK0, 5, 8); - - R( e, a, b, c, d, F4, KK0, 14, 9); - - R( d, e, a, b, c, F4, KK0, 7, 9); - - R( c, d, e, a, b, F4, KK0, 0, 11); - - R( b, c, d, e, a, F4, KK0, 9, 13); - - R( a, b, c, d, e, F4, KK0, 2, 15); - - R( e, a, b, c, d, F4, KK0, 11, 15); - - R( d, e, a, b, c, F4, KK0, 4, 5); - - R( c, d, e, a, b, F4, KK0, 13, 7); - - R( b, c, d, e, a, F4, KK0, 6, 7); - - R( a, b, c, d, e, F4, KK0, 15, 8); - - R( e, a, b, c, d, F4, KK0, 8, 11); - - R( d, e, a, b, c, F4, KK0, 1, 14); - - R( c, d, e, a, b, F4, KK0, 10, 14); - - R( b, c, d, e, a, F4, KK0, 3, 12); - - R( a, b, c, d, e, F4, KK0, 12, 6); - - R( e, a, b, c, d, F3, KK1, 6, 9); - - R( d, e, a, b, c, F3, KK1, 11, 13); - - R( c, d, e, a, b, F3, KK1, 3, 15); - - R( b, c, d, e, a, F3, KK1, 7, 7); - - R( a, b, c, d, e, F3, KK1, 0, 12); - - R( e, a, b, c, d, F3, KK1, 13, 8); - - R( d, e, a, b, c, F3, KK1, 5, 9); - - R( c, d, e, a, b, F3, KK1, 10, 11); - - R( b, c, d, e, a, F3, KK1, 14, 7); - - R( a, b, c, d, e, F3, KK1, 15, 7); - - R( e, a, b, c, d, F3, KK1, 8, 12); - - R( d, e, a, b, c, F3, KK1, 12, 7); - - R( c, d, e, a, b, F3, KK1, 4, 6); - - R( b, c, d, e, a, F3, KK1, 9, 15); - - R( a, b, c, d, e, F3, KK1, 1, 13); - - R( e, a, b, c, d, F3, KK1, 2, 11); - - R( d, e, a, b, c, F2, KK2, 15, 9); - - R( c, d, e, a, b, F2, KK2, 5, 7); - - R( b, c, d, e, a, F2, KK2, 1, 15); - - R( a, b, c, d, e, F2, KK2, 3, 11); - - R( e, a, b, c, d, F2, KK2, 7, 8); - - R( d, e, a, b, c, F2, KK2, 14, 6); - - R( c, d, e, a, b, F2, KK2, 6, 6); - - R( b, c, d, e, a, F2, KK2, 9, 14); - - R( a, b, c, d, e, F2, KK2, 11, 12); - - R( e, a, b, c, d, F2, KK2, 8, 13); - - R( d, e, a, b, c, F2, KK2, 12, 5); - - R( c, d, e, a, b, F2, KK2, 2, 14); - - R( b, c, d, e, a, F2, KK2, 10, 13); - - R( a, b, c, d, e, F2, KK2, 0, 13); - - R( e, a, b, c, d, F2, KK2, 4, 7); - - R( d, e, a, b, c, F2, KK2, 13, 5); - - R( c, d, e, a, b, F1, KK3, 8, 15); - - R( b, c, d, e, a, F1, KK3, 6, 5); - - R( a, b, c, d, e, F1, KK3, 4, 8); - - R( e, a, b, c, d, F1, KK3, 1, 11); - - R( d, e, a, b, c, F1, KK3, 3, 14); - - R( c, d, e, a, b, F1, KK3, 11, 14); - - R( b, c, d, e, a, F1, KK3, 15, 6); - - R( a, b, c, d, e, F1, KK3, 0, 14); - - R( e, a, b, c, d, F1, KK3, 5, 6); - - R( d, e, a, b, c, F1, KK3, 12, 9); - - R( c, d, e, a, b, F1, KK3, 2, 12); - - R( b, c, d, e, a, F1, KK3, 13, 9); - - R( a, b, c, d, e, F1, KK3, 9, 12); - - R( e, a, b, c, d, F1, KK3, 7, 5); - - R( d, e, a, b, c, F1, KK3, 10, 15); - - R( c, d, e, a, b, F1, KK3, 14, 8); - - R( b, c, d, e, a, F0, KK4, 12, 8); - - R( a, b, c, d, e, F0, KK4, 15, 5); - - R( e, a, b, c, d, F0, KK4, 10, 12); - - R( d, e, a, b, c, F0, KK4, 4, 9); - - R( c, d, e, a, b, F0, KK4, 1, 12); - - R( b, c, d, e, a, F0, KK4, 5, 5); - - R( a, b, c, d, e, F0, KK4, 8, 14); - - R( e, a, b, c, d, F0, KK4, 7, 6); - - R( d, e, a, b, c, F0, KK4, 6, 8); - - R( c, d, e, a, b, F0, KK4, 2, 13); - - R( b, c, d, e, a, F0, KK4, 13, 6); - - R( a, b, c, d, e, F0, KK4, 14, 5); - - R( e, a, b, c, d, F0, KK4, 0, 15); - - R( d, e, a, b, c, F0, KK4, 3, 13); - - R( c, d, e, a, b, F0, KK4, 9, 11); - - R( b, c, d, e, a, F0, KK4, 11, 11); - - - - - - t = hd->h1 + d + cc; - - hd->h1 = hd->h2 + e + dd; - - hd->h2 = hd->h3 + a + ee; - - hd->h3 = hd->h4 + b + aa; - - hd->h4 = hd->h0 + c + bb; - - hd->h0 = t; + /* left lane and right lanes interleaved */ + al = ar = hd->h0; + bl = br = hd->h1; + cl = cr = hd->h2; + dl = dr = hd->h3; + el = er = hd->h4; + R( al, bl, cl, dl, el, F0, K0, 0, 11 ); + R( ar, br, cr, dr, er, F4, KK0, 5, 8); + R( el, al, bl, cl, dl, F0, K0, 1, 14 ); + R( er, ar, br, cr, dr, F4, KK0, 14, 9); + R( dl, el, al, bl, cl, F0, K0, 2, 15 ); + R( dr, er, ar, br, cr, F4, KK0, 7, 9); + R( cl, dl, el, al, bl, F0, K0, 3, 12 ); + R( cr, dr, er, ar, br, F4, KK0, 0, 11); + R( bl, cl, dl, el, al, F0, K0, 4, 5 ); + R( br, cr, dr, er, ar, F4, KK0, 9, 13); + R( al, bl, cl, dl, el, F0, K0, 5, 8 ); + R( ar, br, cr, dr, er, F4, KK0, 2, 15); + R( el, al, bl, cl, dl, F0, K0, 6, 7 ); + R( er, ar, br, cr, dr, F4, KK0, 11, 15); + R( dl, el, al, bl, cl, F0, K0, 7, 9 ); + R( dr, er, ar, br, cr, F4, KK0, 4, 5); + R( cl, dl, el, al, bl, F0, K0, 8, 11 ); + R( cr, dr, er, ar, br, F4, KK0, 13, 7); + R( bl, cl, dl, el, al, F0, K0, 9, 13 ); + R( br, cr, dr, er, ar, F4, KK0, 6, 7); + R( al, bl, cl, dl, el, F0, K0, 10, 14 ); + R( ar, br, cr, dr, er, F4, KK0, 15, 8); + R( el, al, bl, cl, dl, F0, K0, 11, 15 ); + R( er, ar, br, cr, dr, F4, KK0, 8, 11); + R( dl, el, al, bl, cl, F0, K0, 12, 6 ); + R( dr, er, ar, br, cr, F4, KK0, 1, 14); + R( cl, dl, el, al, bl, F0, K0, 13, 7 ); + R( cr, dr, er, ar, br, F4, KK0, 10, 14); + R( bl, cl, dl, el, al, F0, K0, 14, 9 ); + R( br, cr, dr, er, ar, F4, KK0, 3, 12); + R( al, bl, cl, dl, el, F0, K0, 15, 8 ); + R( ar, br, cr, dr, er, F4, KK0, 12, 6); + R( el, al, bl, cl, dl, F1, K1, 7, 7 ); + R( er, ar, br, cr, dr, F3, KK1, 6, 9); + R( dl, el, al, bl, cl, F1, K1, 4, 6 ); + R( dr, er, ar, br, cr, F3, KK1, 11, 13); + R( cl, dl, el, al, bl, F1, K1, 13, 8 ); + R( cr, dr, er, ar, br, F3, KK1, 3, 15); + R( bl, cl, dl, el, al, F1, K1, 1, 13 ); + R( br, cr, dr, er, ar, F3, KK1, 7, 7); + R( al, bl, cl, dl, el, F1, K1, 10, 11 ); + R( ar, br, cr, dr, er, F3, KK1, 0, 12); + R( el, al, bl, cl, dl, F1, K1, 6, 9 ); + R( er, ar, br, cr, dr, F3, KK1, 13, 8); + R( dl, el, al, bl, cl, F1, K1, 15, 7 ); + R( dr, er, ar, br, cr, F3, KK1, 5, 9); + R( cl, dl, el, al, bl, F1, K1, 3, 15 ); + R( cr, dr, er, ar, br, F3, KK1, 10, 11); + R( bl, cl, dl, el, al, F1, K1, 12, 7 ); + R( br, cr, dr, er, ar, F3, KK1, 14, 7); + R( al, bl, cl, dl, el, F1, K1, 0, 12 ); + R( ar, br, cr, dr, er, F3, KK1, 15, 7); + R( el, al, bl, cl, dl, F1, K1, 9, 15 ); + R( er, ar, br, cr, dr, F3, KK1, 8, 12); + R( dl, el, al, bl, cl, F1, K1, 5, 9 ); + R( dr, er, ar, br, cr, F3, KK1, 12, 7); + R( cl, dl, el, al, bl, F1, K1, 2, 11 ); + R( cr, dr, er, ar, br, F3, KK1, 4, 6); + R( bl, cl, dl, el, al, F1, K1, 14, 7 ); + R( br, cr, dr, er, ar, F3, KK1, 9, 15); + R( al, bl, cl, dl, el, F1, K1, 11, 13 ); + R( ar, br, cr, dr, er, F3, KK1, 1, 13); + R( el, al, bl, cl, dl, F1, K1, 8, 12 ); + R( er, ar, br, cr, dr, F3, KK1, 2, 11); + R( dl, el, al, bl, cl, F2, K2, 3, 11 ); + R( dr, er, ar, br, cr, F2, KK2, 15, 9); + R( cl, dl, el, al, bl, F2, K2, 10, 13 ); + R( cr, dr, er, ar, br, F2, KK2, 5, 7); + R( bl, cl, dl, el, al, F2, K2, 14, 6 ); + R( br, cr, dr, er, ar, F2, KK2, 1, 15); + R( al, bl, cl, dl, el, F2, K2, 4, 7 ); + R( ar, br, cr, dr, er, F2, KK2, 3, 11); + R( el, al, bl, cl, dl, F2, K2, 9, 14 ); + R( er, ar, br, cr, dr, F2, KK2, 7, 8); + R( dl, el, al, bl, cl, F2, K2, 15, 9 ); + R( dr, er, ar, br, cr, F2, KK2, 14, 6); + R( cl, dl, el, al, bl, F2, K2, 8, 13 ); + R( cr, dr, er, ar, br, F2, KK2, 6, 6); + R( bl, cl, dl, el, al, F2, K2, 1, 15 ); + R( br, cr, dr, er, ar, F2, KK2, 9, 14); + R( al, bl, cl, dl, el, F2, K2, 2, 14 ); + R( ar, br, cr, dr, er, F2, KK2, 11, 12); + R( el, al, bl, cl, dl, F2, K2, 7, 8 ); + R( er, ar, br, cr, dr, F2, KK2, 8, 13); + R( dl, el, al, bl, cl, F2, K2, 0, 13 ); + R( dr, er, ar, br, cr, F2, KK2, 12, 5); + R( cl, dl, el, al, bl, F2, K2, 6, 6 ); + R( cr, dr, er, ar, br, F2, KK2, 2, 14); + R( bl, cl, dl, el, al, F2, K2, 13, 5 ); + R( br, cr, dr, er, ar, F2, KK2, 10, 13); + R( al, bl, cl, dl, el, F2, K2, 11, 12 ); + R( ar, br, cr, dr, er, F2, KK2, 0, 13); + R( el, al, bl, cl, dl, F2, K2, 5, 7 ); + R( er, ar, br, cr, dr, F2, KK2, 4, 7); + R( dl, el, al, bl, cl, F2, K2, 12, 5 ); + R( dr, er, ar, br, cr, F2, KK2, 13, 5); + R( cl, dl, el, al, bl, F3, K3, 1, 11 ); + R( cr, dr, er, ar, br, F1, KK3, 8, 15); + R( bl, cl, dl, el, al, F3, K3, 9, 12 ); + R( br, cr, dr, er, ar, F1, KK3, 6, 5); + R( al, bl, cl, dl, el, F3, K3, 11, 14 ); + R( ar, br, cr, dr, er, F1, KK3, 4, 8); + R( el, al, bl, cl, dl, F3, K3, 10, 15 ); + R( er, ar, br, cr, dr, F1, KK3, 1, 11); + R( dl, el, al, bl, cl, F3, K3, 0, 14 ); + R( dr, er, ar, br, cr, F1, KK3, 3, 14); + R( cl, dl, el, al, bl, F3, K3, 8, 15 ); + R( cr, dr, er, ar, br, F1, KK3, 11, 14); + R( bl, cl, dl, el, al, F3, K3, 12, 9 ); + R( br, cr, dr, er, ar, F1, KK3, 15, 6); + R( al, bl, cl, dl, el, F3, K3, 4, 8 ); + R( ar, br, cr, dr, er, F1, KK3, 0, 14); + R( el, al, bl, cl, dl, F3, K3, 13, 9 ); + R( er, ar, br, cr, dr, F1, KK3, 5, 6); + R( dl, el, al, bl, cl, F3, K3, 3, 14 ); + R( dr, er, ar, br, cr, F1, KK3, 12, 9); + R( cl, dl, el, al, bl, F3, K3, 7, 5 ); + R( cr, dr, er, ar, br, F1, KK3, 2, 12); + R( bl, cl, dl, el, al, F3, K3, 15, 6 ); + R( br, cr, dr, er, ar, F1, KK3, 13, 9); + R( al, bl, cl, dl, el, F3, K3, 14, 8 ); + R( ar, br, cr, dr, er, F1, KK3, 9, 12); + R( el, al, bl, cl, dl, F3, K3, 5, 6 ); + R( er, ar, br, cr, dr, F1, KK3, 7, 5); + R( dl, el, al, bl, cl, F3, K3, 6, 5 ); + R( dr, er, ar, br, cr, F1, KK3, 10, 15); + R( cl, dl, el, al, bl, F3, K3, 2, 12 ); + R( cr, dr, er, ar, br, F1, KK3, 14, 8); + R( bl, cl, dl, el, al, F4, K4, 4, 9 ); + R( br, cr, dr, er, ar, F0, KK4, 12, 8); + R( al, bl, cl, dl, el, F4, K4, 0, 15 ); + R( ar, br, cr, dr, er, F0, KK4, 15, 5); + R( el, al, bl, cl, dl, F4, K4, 5, 5 ); + R( er, ar, br, cr, dr, F0, KK4, 10, 12); + R( dl, el, al, bl, cl, F4, K4, 9, 11 ); + R( dr, er, ar, br, cr, F0, KK4, 4, 9); + R( cl, dl, el, al, bl, F4, K4, 7, 6 ); + R( cr, dr, er, ar, br, F0, KK4, 1, 12); + R( bl, cl, dl, el, al, F4, K4, 12, 8 ); + R( br, cr, dr, er, ar, F0, KK4, 5, 5); + R( al, bl, cl, dl, el, F4, K4, 2, 13 ); + R( ar, br, cr, dr, er, F0, KK4, 8, 14); + R( el, al, bl, cl, dl, F4, K4, 10, 12 ); + R( er, ar, br, cr, dr, F0, KK4, 7, 6); + R( dl, el, al, bl, cl, F4, K4, 14, 5 ); + R( dr, er, ar, br, cr, F0, KK4, 6, 8); + R( cl, dl, el, al, bl, F4, K4, 1, 12 ); + R( cr, dr, er, ar, br, F0, KK4, 2, 13); + R( bl, cl, dl, el, al, F4, K4, 3, 13 ); + R( br, cr, dr, er, ar, F0, KK4, 13, 6); + R( al, bl, cl, dl, el, F4, K4, 8, 14 ); + R( ar, br, cr, dr, er, F0, KK4, 14, 5); + R( el, al, bl, cl, dl, F4, K4, 11, 11 ); + R( er, ar, br, cr, dr, F0, KK4, 0, 15); + R( dl, el, al, bl, cl, F4, K4, 6, 8 ); + R( dr, er, ar, br, cr, F0, KK4, 3, 13); + R( cl, dl, el, al, bl, F4, K4, 15, 5 ); + R( cr, dr, er, ar, br, F0, KK4, 9, 11); + R( bl, cl, dl, el, al, F4, K4, 13, 6 ); + R( br, cr, dr, er, ar, F0, KK4, 11, 11); + + dr += cl + hd->h1; + hd->h1 = hd->h2 + dl + er; + hd->h2 = hd->h3 + el + ar; + hd->h3 = hd->h4 + al + br; + hd->h4 = hd->h0 + bl + cr; + hd->h0 = dr; - - return /*burn_stack*/ 108+5*sizeof(void*); + return /*burn_stack*/ 104+5*sizeof(void*); } -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAEBAgAGBQJT92/OAAoJEClrD5EX5v64RYoH/RV6nJQhAhLbsFQ/UgueDRV9 b5RQm4NqkTQnM/10UlhX4rDf29Vs1Cx9mSG8UJfe5IjjVmV3XKe3MnwLw1b1SWp+ 3EDOOIYb8Hn8Viw2tnx3+LAVb/GTmXaLwlRECzeHbLWOOHsLt+nFZstwqzi1A8Od G3/grLdzXVReMS0SQ3P4N9UlJqggAArbzMsAX6gx3rjHeT+TcyTZYCVgoED8iXNq rux+GdwpVRmc+w6QvirN4Hdk5QY4P/Yh68yFiQ05+vmUtr1KtYhQ/34vQdb9w5E6 V9juVG4+6Ap1p/LUVEV163RL5pKVMaRJdX23xd2Zb6fLYwwaUzRVnTmYYk3Ahjk= =/Wks -----END PGP SIGNATURE----- ____________________________________________________________ FREE 3D EARTH SCREENSAVER - Watch the Earth right on your desktop! Check it out at http://www.inbox.com/earth From branko at majic.rs Fri Aug 22 20:50:19 2014 From: branko at majic.rs (Branko Majic) Date: Fri, 22 Aug 2014 20:50:19 +0200 Subject: [Announce] [security fix] Libgcrypt and GnuPG In-Reply-To: <8761hzsafw.fsf@vigenere.g10code.de> References: <87egwruvz1.fsf@vigenere.g10code.de> <20140809225257.129e7843@zetkin.primekey.se> <8761hzsafw.fsf@vigenere.g10code.de> Message-ID: <20140822205019.74892181@zetkin.primekey.se> On Mon, 11 Aug 2014 10:21:55 +0200 Werner Koch wrote: > On Sat, 9 Aug 2014 22:52, branko at majic.rs said: > > > Skimming through the description, does it mean that users with OpenPGP > > cards should be impervious to this attack? Can the attack be used to > > leak symmetric keys during the GnuPG operation? > > It is unlikely that this particular attack can be used against smart > cards. They are quite different from a general purpose PC. Modern > cards are designed to mitigate many classes of side-channel attacks > since cards started to be targeted more than 25 years ago. > > The private keys are only on the card and not accessible from the PC. > I should've been more specific with my question (or perhaps I misunderstood the answer a bit :) If I understand correctly (please do correct me if not), when encrypting/decrypting a file with GnuPG using an OpenPGP card, a symmetric key is created that will encrypt the file, and subsequently this symmetric key will be encrypted using the OpenPGP card, with the encrypted symmetric key becoming part of the encrypted file. This symmetric key is generated outside of the OpenPGP card (if I got it right), and encryption/decryption of a file itself is performed outside of the OpenPGP card (i.e. on host computer). Can the attack be used to obtain this symmetric key for encrypting the file during encryption/decryption operations performed by GnuPG? Best regards P.S. Sorry for the original lost quote, I'll try to keep 'em shorter :) -- Branko Majic Jabber: branko at majic.rs Please use only Free formats when sending attachments to me. ?????? ????? ?????: branko at majic.rs ????? ??? ?? ??????? ?????? ????????? ? ????????? ?????????. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: From smueller at chronox.de Fri Aug 22 22:45:22 2014 From: smueller at chronox.de (Stephan Mueller) Date: Fri, 22 Aug 2014 22:45:22 +0200 Subject: DCO signed Message-ID: <2008899.25OeoelVVA@myon.chronox.de> Libgcrypt Developer's Certificate of Origin. Version 1.0 ========================================================= By making a contribution to the Libgcrypt project, I certify that: (a) The contribution was created in whole or in part by me and I have the right to submit it under the free software license indicated in the file; or (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate free software license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same free software license (unless I am permitted to submit under a different license), as indicated in the file; or (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the free software license(s) involved. Signed-off-by: Stephan Mueller -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: This is a digitally signed message part. URL: From smueller at chronox.de Mon Aug 25 12:37:20 2014 From: smueller at chronox.de (Stephan Mueller) Date: Mon, 25 Aug 2014 12:37:20 +0200 Subject: Cipher FIPS flag enforcement Message-ID: <1926944.R0LCOrcss8@tauon> Hi, all of the the cipher definitions contain and define the flag unsigned int fips:1; in their _spec_t types. Up to 1.4.x, that field was enforced in the cipher init functions (i.e. if the FIPS mode is set, only fips=1 ciphers are allowed). The random/ code still contains such logic. But all other fips flag enforcement code is gone. Is this intentional? Note, FIPS can live without such restrictions, but then why keep the fips flag lingering? Ciao Stephan From wk at gnupg.org Mon Aug 25 17:06:52 2014 From: wk at gnupg.org (Werner Koch) Date: Mon, 25 Aug 2014 17:06:52 +0200 Subject: Cipher FIPS flag enforcement In-Reply-To: <1926944.R0LCOrcss8@tauon> (Stephan Mueller's message of "Mon, 25 Aug 2014 12:37:20 +0200") References: <1926944.R0LCOrcss8@tauon> Message-ID: <87lhqc1ucz.fsf@vigenere.g10code.de> On Mon, 25 Aug 2014 12:37, smueller at chronox.de said: > The random/ code still contains such logic. But all other fips flag > enforcement code is gone. That was due to the major revamp of the code. I did not care about keeping the FIPS functionality. I was anyway not able to check the functionality and thus I concluded that those companies planning to sell FIPS stuff should contact me or send a proper patch which I can apply without spending a lot of unpaid time. Salam-Shalom, Werner -- Die Gedanken sind frei. Ausnahmen regelt ein Bundesgesetz. From andsch at inbox.com Thu Aug 28 17:28:43 2014 From: andsch at inbox.com (And Sch) Date: Thu, 28 Aug 2014 07:28:43 -0800 Subject: [PATCH 1/1] Improved ripemd160 performance In-Reply-To: Message-ID: <0A8D50D0894.00000D4Fandsch@inbox.com> The benchmarks on different systems: Intel(R) Atom(TM) CPU N570 @ 1.66GHz before: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 13.07 ns/B 72.97 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 11.37 ns/B 83.84 MiB/s - c/B Intel(R) Core(TM) i5-4670 CPU @ 3.40GHz before: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 3.31 ns/B 288.0 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 2.08 ns/B 458.5 MiB/s - c/B ____________________________________________________________ FREE ONLINE PHOTOSHARING - Share your photos online with your friends and family! Visit http://www.inbox.com/photosharing to find out more! From andsch at inbox.com Thu Aug 28 17:31:37 2014 From: andsch at inbox.com (And Sch) Date: Thu, 28 Aug 2014 07:31:37 -0800 Subject: [PATCH 1/1] Improved whirlpool hash performance In-Reply-To: Message-ID: <0A93C7423DD.00000D5Eandsch@inbox.com> Benchmark on different systems: Intel(R) Atom(TM) CPU N570 @ 1.66GHz before: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 63.40 ns/B 15.04 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 46.21 ns/B 20.64 MiB/s - c/B Intel(R) Core(TM) i5-4670 CPU @ 3.40GHz before: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 7.75 ns/B 123.0 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 6.70 ns/B 142.3 MiB/s - c/B This one actually shows greater improvement on the Atom system. ____________________________________________________________ FREE 3D EARTH SCREENSAVER - Watch the Earth right on your desktop! Check it out at http://www.inbox.com/earth From jussi.kivilinna at iki.fi Thu Aug 28 19:05:40 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 28 Aug 2014 20:05:40 +0300 Subject: [PATCH 1/1] Improved ripemd160 performance In-Reply-To: References: Message-ID: <53FF6164.1040408@iki.fi> Hello, The patch format still is not quite the right. The patch message should start with GNU ChangeLog style entries about the changes that patch makes. This is followed by line with '--' as separator and additional commit log (for example benchmark results) and ends with 'Signed-off-by: Name-you-used-in-Signed-DCO ' line. You do _not_ need to sign the patch, just need that 'Signed-off-by' line. So, for example, proper patch message could look something like this: [PATCH 1/1] Improved ripemd160 performance * cipher/rmd160.c (transform): Interleave the left and right line rounds to introduce more instruction level parallelism. -- The benchmarks on different systems: Intel(R) Atom(TM) CPU N570 @ 1.66GHz before: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 13.07 ns/B 72.97 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 11.37 ns/B 83.84 MiB/s - c/B Intel(R) Core(TM) i5-4670 CPU @ 3.40GHz before: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 3.31 ns/B 288.0 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 2.08 ns/B 458.5 MiB/s - c/B Signed-off-by: Xxxx Xxxx --- diff -ruNp libgcrypt-1.6.2/cipher/rmd160.c libgcrypt-1.6.3/cipher/rmd160.c --- libgcrypt-1.6.2/cipher/rmd160.c 2014-08-21 07:50:39.000000000 -0500 +++ libgcrypt-1.6.3/cipher/rmd160.c 2014-08-21 17:15:13.678664524 -0500 @@ -178,8 +178,7 @@ static unsigned int .. and so on. -Jussi On 22/08/14 19:32, And Sch wrote: > Here is the ripemd160 performance patch, signed. > before: > Hash: > | nanosecs/byte mebibytes/sec cycles/byte > RIPEMD160 | 3.31 ns/B 288.0 MiB/s - c/B > > after: > Hash: > | nanosecs/byte mebibytes/sec cycles/byte > RIPEMD160 | 2.08 ns/B 458.5 MiB/s - c/B > > diff -ruNp libgcrypt-1.6.2/cipher/rmd160.c libgcrypt-1.6.3/cipher/rmd160.c > --- libgcrypt-1.6.2/cipher/rmd160.c 2014-08-21 07:50:39.000000000 -0500 > +++ libgcrypt-1.6.3/cipher/rmd160.c 2014-08-21 17:15:13.678664524 -0500 > @@ -178,8 +178,7 @@ static unsigned int > transform ( void *ctx, const unsigned char *data ) > { > RMD160_CONTEXT *hd = ctx; > - register u32 a,b,c,d,e; > - u32 aa,bb,cc,dd,ee,t; > + register u32 al, ar, bl, br, cl, cr, dl, dr, el, er; > u32 x[16]; > int i; > > @@ -201,196 +200,186 @@ transform ( void *ctx, const unsigned ch > #define F2(x,y,z) ( ((x) | ~(y)) ^ (z) ) > #define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) ) > #define F4(x,y,z) ( (x) ^ ((y) | ~(z)) ) > -#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \ > - a = rol(t,s) + e; \ > +#define R(a,b,c,d,e,f,k,r,s) do { a += f(b,c,d) + k + x[r]; \ > + a = rol(a,s) + e; \ > c = rol(c,10); \ > } while(0) > > - /* left lane */ > - a = hd->h0; > - b = hd->h1; > - c = hd->h2; > - d = hd->h3; > - e = hd->h4; > - R( a, b, c, d, e, F0, K0, 0, 11 ); > - R( e, a, b, c, d, F0, K0, 1, 14 ); > - R( d, e, a, b, c, F0, K0, 2, 15 ); > - R( c, d, e, a, b, F0, K0, 3, 12 ); > - R( b, c, d, e, a, F0, K0, 4, 5 ); > - R( a, b, c, d, e, F0, K0, 5, 8 ); > - R( e, a, b, c, d, F0, K0, 6, 7 ); > - R( d, e, a, b, c, F0, K0, 7, 9 ); > - R( c, d, e, a, b, F0, K0, 8, 11 ); > - R( b, c, d, e, a, F0, K0, 9, 13 ); > - R( a, b, c, d, e, F0, K0, 10, 14 ); > - R( e, a, b, c, d, F0, K0, 11, 15 ); > - R( d, e, a, b, c, F0, K0, 12, 6 ); > - R( c, d, e, a, b, F0, K0, 13, 7 ); > - R( b, c, d, e, a, F0, K0, 14, 9 ); > - R( a, b, c, d, e, F0, K0, 15, 8 ); > - R( e, a, b, c, d, F1, K1, 7, 7 ); > - R( d, e, a, b, c, F1, K1, 4, 6 ); > - R( c, d, e, a, b, F1, K1, 13, 8 ); > - R( b, c, d, e, a, F1, K1, 1, 13 ); > - R( a, b, c, d, e, F1, K1, 10, 11 ); > - R( e, a, b, c, d, F1, K1, 6, 9 ); > - R( d, e, a, b, c, F1, K1, 15, 7 ); > - R( c, d, e, a, b, F1, K1, 3, 15 ); > - R( b, c, d, e, a, F1, K1, 12, 7 ); > - R( a, b, c, d, e, F1, K1, 0, 12 ); > - R( e, a, b, c, d, F1, K1, 9, 15 ); > - R( d, e, a, b, c, F1, K1, 5, 9 ); > - R( c, d, e, a, b, F1, K1, 2, 11 ); > - R( b, c, d, e, a, F1, K1, 14, 7 ); > - R( a, b, c, d, e, F1, K1, 11, 13 ); > - R( e, a, b, c, d, F1, K1, 8, 12 ); > - R( d, e, a, b, c, F2, K2, 3, 11 ); > - R( c, d, e, a, b, F2, K2, 10, 13 ); > - R( b, c, d, e, a, F2, K2, 14, 6 ); > - R( a, b, c, d, e, F2, K2, 4, 7 ); > - R( e, a, b, c, d, F2, K2, 9, 14 ); > - R( d, e, a, b, c, F2, K2, 15, 9 ); > - R( c, d, e, a, b, F2, K2, 8, 13 ); > - R( b, c, d, e, a, F2, K2, 1, 15 ); > - R( a, b, c, d, e, F2, K2, 2, 14 ); > - R( e, a, b, c, d, F2, K2, 7, 8 ); > - R( d, e, a, b, c, F2, K2, 0, 13 ); > - R( c, d, e, a, b, F2, K2, 6, 6 ); > - R( b, c, d, e, a, F2, K2, 13, 5 ); > - R( a, b, c, d, e, F2, K2, 11, 12 ); > - R( e, a, b, c, d, F2, K2, 5, 7 ); > - R( d, e, a, b, c, F2, K2, 12, 5 ); > - R( c, d, e, a, b, F3, K3, 1, 11 ); > - R( b, c, d, e, a, F3, K3, 9, 12 ); > - R( a, b, c, d, e, F3, K3, 11, 14 ); > - R( e, a, b, c, d, F3, K3, 10, 15 ); > - R( d, e, a, b, c, F3, K3, 0, 14 ); > - R( c, d, e, a, b, F3, K3, 8, 15 ); > - R( b, c, d, e, a, F3, K3, 12, 9 ); > - R( a, b, c, d, e, F3, K3, 4, 8 ); > - R( e, a, b, c, d, F3, K3, 13, 9 ); > - R( d, e, a, b, c, F3, K3, 3, 14 ); > - R( c, d, e, a, b, F3, K3, 7, 5 ); > - R( b, c, d, e, a, F3, K3, 15, 6 ); > - R( a, b, c, d, e, F3, K3, 14, 8 ); > - R( e, a, b, c, d, F3, K3, 5, 6 ); > - R( d, e, a, b, c, F3, K3, 6, 5 ); > - R( c, d, e, a, b, F3, K3, 2, 12 ); > - R( b, c, d, e, a, F4, K4, 4, 9 ); > - R( a, b, c, d, e, F4, K4, 0, 15 ); > - R( e, a, b, c, d, F4, K4, 5, 5 ); > - R( d, e, a, b, c, F4, K4, 9, 11 ); > - R( c, d, e, a, b, F4, K4, 7, 6 ); > - R( b, c, d, e, a, F4, K4, 12, 8 ); > - R( a, b, c, d, e, F4, K4, 2, 13 ); > - R( e, a, b, c, d, F4, K4, 10, 12 ); > - R( d, e, a, b, c, F4, K4, 14, 5 ); > - R( c, d, e, a, b, F4, K4, 1, 12 ); > - R( b, c, d, e, a, F4, K4, 3, 13 ); > - R( a, b, c, d, e, F4, K4, 8, 14 ); > - R( e, a, b, c, d, F4, K4, 11, 11 ); > - R( d, e, a, b, c, F4, K4, 6, 8 ); > - R( c, d, e, a, b, F4, K4, 15, 5 ); > - R( b, c, d, e, a, F4, K4, 13, 6 ); > - > - aa = a; bb = b; cc = c; dd = d; ee = e; > - > - /* right lane */ > - a = hd->h0; > - b = hd->h1; > - c = hd->h2; > - d = hd->h3; > - e = hd->h4; > - R( a, b, c, d, e, F4, KK0, 5, 8); > - R( e, a, b, c, d, F4, KK0, 14, 9); > - R( d, e, a, b, c, F4, KK0, 7, 9); > - R( c, d, e, a, b, F4, KK0, 0, 11); > - R( b, c, d, e, a, F4, KK0, 9, 13); > - R( a, b, c, d, e, F4, KK0, 2, 15); > - R( e, a, b, c, d, F4, KK0, 11, 15); > - R( d, e, a, b, c, F4, KK0, 4, 5); > - R( c, d, e, a, b, F4, KK0, 13, 7); > - R( b, c, d, e, a, F4, KK0, 6, 7); > - R( a, b, c, d, e, F4, KK0, 15, 8); > - R( e, a, b, c, d, F4, KK0, 8, 11); > - R( d, e, a, b, c, F4, KK0, 1, 14); > - R( c, d, e, a, b, F4, KK0, 10, 14); > - R( b, c, d, e, a, F4, KK0, 3, 12); > - R( a, b, c, d, e, F4, KK0, 12, 6); > - R( e, a, b, c, d, F3, KK1, 6, 9); > - R( d, e, a, b, c, F3, KK1, 11, 13); > - R( c, d, e, a, b, F3, KK1, 3, 15); > - R( b, c, d, e, a, F3, KK1, 7, 7); > - R( a, b, c, d, e, F3, KK1, 0, 12); > - R( e, a, b, c, d, F3, KK1, 13, 8); > - R( d, e, a, b, c, F3, KK1, 5, 9); > - R( c, d, e, a, b, F3, KK1, 10, 11); > - R( b, c, d, e, a, F3, KK1, 14, 7); > - R( a, b, c, d, e, F3, KK1, 15, 7); > - R( e, a, b, c, d, F3, KK1, 8, 12); > - R( d, e, a, b, c, F3, KK1, 12, 7); > - R( c, d, e, a, b, F3, KK1, 4, 6); > - R( b, c, d, e, a, F3, KK1, 9, 15); > - R( a, b, c, d, e, F3, KK1, 1, 13); > - R( e, a, b, c, d, F3, KK1, 2, 11); > - R( d, e, a, b, c, F2, KK2, 15, 9); > - R( c, d, e, a, b, F2, KK2, 5, 7); > - R( b, c, d, e, a, F2, KK2, 1, 15); > - R( a, b, c, d, e, F2, KK2, 3, 11); > - R( e, a, b, c, d, F2, KK2, 7, 8); > - R( d, e, a, b, c, F2, KK2, 14, 6); > - R( c, d, e, a, b, F2, KK2, 6, 6); > - R( b, c, d, e, a, F2, KK2, 9, 14); > - R( a, b, c, d, e, F2, KK2, 11, 12); > - R( e, a, b, c, d, F2, KK2, 8, 13); > - R( d, e, a, b, c, F2, KK2, 12, 5); > - R( c, d, e, a, b, F2, KK2, 2, 14); > - R( b, c, d, e, a, F2, KK2, 10, 13); > - R( a, b, c, d, e, F2, KK2, 0, 13); > - R( e, a, b, c, d, F2, KK2, 4, 7); > - R( d, e, a, b, c, F2, KK2, 13, 5); > - R( c, d, e, a, b, F1, KK3, 8, 15); > - R( b, c, d, e, a, F1, KK3, 6, 5); > - R( a, b, c, d, e, F1, KK3, 4, 8); > - R( e, a, b, c, d, F1, KK3, 1, 11); > - R( d, e, a, b, c, F1, KK3, 3, 14); > - R( c, d, e, a, b, F1, KK3, 11, 14); > - R( b, c, d, e, a, F1, KK3, 15, 6); > - R( a, b, c, d, e, F1, KK3, 0, 14); > - R( e, a, b, c, d, F1, KK3, 5, 6); > - R( d, e, a, b, c, F1, KK3, 12, 9); > - R( c, d, e, a, b, F1, KK3, 2, 12); > - R( b, c, d, e, a, F1, KK3, 13, 9); > - R( a, b, c, d, e, F1, KK3, 9, 12); > - R( e, a, b, c, d, F1, KK3, 7, 5); > - R( d, e, a, b, c, F1, KK3, 10, 15); > - R( c, d, e, a, b, F1, KK3, 14, 8); > - R( b, c, d, e, a, F0, KK4, 12, 8); > - R( a, b, c, d, e, F0, KK4, 15, 5); > - R( e, a, b, c, d, F0, KK4, 10, 12); > - R( d, e, a, b, c, F0, KK4, 4, 9); > - R( c, d, e, a, b, F0, KK4, 1, 12); > - R( b, c, d, e, a, F0, KK4, 5, 5); > - R( a, b, c, d, e, F0, KK4, 8, 14); > - R( e, a, b, c, d, F0, KK4, 7, 6); > - R( d, e, a, b, c, F0, KK4, 6, 8); > - R( c, d, e, a, b, F0, KK4, 2, 13); > - R( b, c, d, e, a, F0, KK4, 13, 6); > - R( a, b, c, d, e, F0, KK4, 14, 5); > - R( e, a, b, c, d, F0, KK4, 0, 15); > - R( d, e, a, b, c, F0, KK4, 3, 13); > - R( c, d, e, a, b, F0, KK4, 9, 11); > - R( b, c, d, e, a, F0, KK4, 11, 11); > - > - > - t = hd->h1 + d + cc; > - hd->h1 = hd->h2 + e + dd; > - hd->h2 = hd->h3 + a + ee; > - hd->h3 = hd->h4 + b + aa; > - hd->h4 = hd->h0 + c + bb; > - hd->h0 = t; > + /* left lane and right lanes interleaved */ > + al = ar = hd->h0; > + bl = br = hd->h1; > + cl = cr = hd->h2; > + dl = dr = hd->h3; > + el = er = hd->h4; > + R( al, bl, cl, dl, el, F0, K0, 0, 11 ); > + R( ar, br, cr, dr, er, F4, KK0, 5, 8); > + R( el, al, bl, cl, dl, F0, K0, 1, 14 ); > + R( er, ar, br, cr, dr, F4, KK0, 14, 9); > + R( dl, el, al, bl, cl, F0, K0, 2, 15 ); > + R( dr, er, ar, br, cr, F4, KK0, 7, 9); > + R( cl, dl, el, al, bl, F0, K0, 3, 12 ); > + R( cr, dr, er, ar, br, F4, KK0, 0, 11); > + R( bl, cl, dl, el, al, F0, K0, 4, 5 ); > + R( br, cr, dr, er, ar, F4, KK0, 9, 13); > + R( al, bl, cl, dl, el, F0, K0, 5, 8 ); > + R( ar, br, cr, dr, er, F4, KK0, 2, 15); > + R( el, al, bl, cl, dl, F0, K0, 6, 7 ); > + R( er, ar, br, cr, dr, F4, KK0, 11, 15); > + R( dl, el, al, bl, cl, F0, K0, 7, 9 ); > + R( dr, er, ar, br, cr, F4, KK0, 4, 5); > + R( cl, dl, el, al, bl, F0, K0, 8, 11 ); > + R( cr, dr, er, ar, br, F4, KK0, 13, 7); > + R( bl, cl, dl, el, al, F0, K0, 9, 13 ); > + R( br, cr, dr, er, ar, F4, KK0, 6, 7); > + R( al, bl, cl, dl, el, F0, K0, 10, 14 ); > + R( ar, br, cr, dr, er, F4, KK0, 15, 8); > + R( el, al, bl, cl, dl, F0, K0, 11, 15 ); > + R( er, ar, br, cr, dr, F4, KK0, 8, 11); > + R( dl, el, al, bl, cl, F0, K0, 12, 6 ); > + R( dr, er, ar, br, cr, F4, KK0, 1, 14); > + R( cl, dl, el, al, bl, F0, K0, 13, 7 ); > + R( cr, dr, er, ar, br, F4, KK0, 10, 14); > + R( bl, cl, dl, el, al, F0, K0, 14, 9 ); > + R( br, cr, dr, er, ar, F4, KK0, 3, 12); > + R( al, bl, cl, dl, el, F0, K0, 15, 8 ); > + R( ar, br, cr, dr, er, F4, KK0, 12, 6); > + R( el, al, bl, cl, dl, F1, K1, 7, 7 ); > + R( er, ar, br, cr, dr, F3, KK1, 6, 9); > + R( dl, el, al, bl, cl, F1, K1, 4, 6 ); > + R( dr, er, ar, br, cr, F3, KK1, 11, 13); > + R( cl, dl, el, al, bl, F1, K1, 13, 8 ); > + R( cr, dr, er, ar, br, F3, KK1, 3, 15); > + R( bl, cl, dl, el, al, F1, K1, 1, 13 ); > + R( br, cr, dr, er, ar, F3, KK1, 7, 7); > + R( al, bl, cl, dl, el, F1, K1, 10, 11 ); > + R( ar, br, cr, dr, er, F3, KK1, 0, 12); > + R( el, al, bl, cl, dl, F1, K1, 6, 9 ); > + R( er, ar, br, cr, dr, F3, KK1, 13, 8); > + R( dl, el, al, bl, cl, F1, K1, 15, 7 ); > + R( dr, er, ar, br, cr, F3, KK1, 5, 9); > + R( cl, dl, el, al, bl, F1, K1, 3, 15 ); > + R( cr, dr, er, ar, br, F3, KK1, 10, 11); > + R( bl, cl, dl, el, al, F1, K1, 12, 7 ); > + R( br, cr, dr, er, ar, F3, KK1, 14, 7); > + R( al, bl, cl, dl, el, F1, K1, 0, 12 ); > + R( ar, br, cr, dr, er, F3, KK1, 15, 7); > + R( el, al, bl, cl, dl, F1, K1, 9, 15 ); > + R( er, ar, br, cr, dr, F3, KK1, 8, 12); > + R( dl, el, al, bl, cl, F1, K1, 5, 9 ); > + R( dr, er, ar, br, cr, F3, KK1, 12, 7); > + R( cl, dl, el, al, bl, F1, K1, 2, 11 ); > + R( cr, dr, er, ar, br, F3, KK1, 4, 6); > + R( bl, cl, dl, el, al, F1, K1, 14, 7 ); > + R( br, cr, dr, er, ar, F3, KK1, 9, 15); > + R( al, bl, cl, dl, el, F1, K1, 11, 13 ); > + R( ar, br, cr, dr, er, F3, KK1, 1, 13); > + R( el, al, bl, cl, dl, F1, K1, 8, 12 ); > + R( er, ar, br, cr, dr, F3, KK1, 2, 11); > + R( dl, el, al, bl, cl, F2, K2, 3, 11 ); > + R( dr, er, ar, br, cr, F2, KK2, 15, 9); > + R( cl, dl, el, al, bl, F2, K2, 10, 13 ); > + R( cr, dr, er, ar, br, F2, KK2, 5, 7); > + R( bl, cl, dl, el, al, F2, K2, 14, 6 ); > + R( br, cr, dr, er, ar, F2, KK2, 1, 15); > + R( al, bl, cl, dl, el, F2, K2, 4, 7 ); > + R( ar, br, cr, dr, er, F2, KK2, 3, 11); > + R( el, al, bl, cl, dl, F2, K2, 9, 14 ); > + R( er, ar, br, cr, dr, F2, KK2, 7, 8); > + R( dl, el, al, bl, cl, F2, K2, 15, 9 ); > + R( dr, er, ar, br, cr, F2, KK2, 14, 6); > + R( cl, dl, el, al, bl, F2, K2, 8, 13 ); > + R( cr, dr, er, ar, br, F2, KK2, 6, 6); > + R( bl, cl, dl, el, al, F2, K2, 1, 15 ); > + R( br, cr, dr, er, ar, F2, KK2, 9, 14); > + R( al, bl, cl, dl, el, F2, K2, 2, 14 ); > + R( ar, br, cr, dr, er, F2, KK2, 11, 12); > + R( el, al, bl, cl, dl, F2, K2, 7, 8 ); > + R( er, ar, br, cr, dr, F2, KK2, 8, 13); > + R( dl, el, al, bl, cl, F2, K2, 0, 13 ); > + R( dr, er, ar, br, cr, F2, KK2, 12, 5); > + R( cl, dl, el, al, bl, F2, K2, 6, 6 ); > + R( cr, dr, er, ar, br, F2, KK2, 2, 14); > + R( bl, cl, dl, el, al, F2, K2, 13, 5 ); > + R( br, cr, dr, er, ar, F2, KK2, 10, 13); > + R( al, bl, cl, dl, el, F2, K2, 11, 12 ); > + R( ar, br, cr, dr, er, F2, KK2, 0, 13); > + R( el, al, bl, cl, dl, F2, K2, 5, 7 ); > + R( er, ar, br, cr, dr, F2, KK2, 4, 7); > + R( dl, el, al, bl, cl, F2, K2, 12, 5 ); > + R( dr, er, ar, br, cr, F2, KK2, 13, 5); > + R( cl, dl, el, al, bl, F3, K3, 1, 11 ); > + R( cr, dr, er, ar, br, F1, KK3, 8, 15); > + R( bl, cl, dl, el, al, F3, K3, 9, 12 ); > + R( br, cr, dr, er, ar, F1, KK3, 6, 5); > + R( al, bl, cl, dl, el, F3, K3, 11, 14 ); > + R( ar, br, cr, dr, er, F1, KK3, 4, 8); > + R( el, al, bl, cl, dl, F3, K3, 10, 15 ); > + R( er, ar, br, cr, dr, F1, KK3, 1, 11); > + R( dl, el, al, bl, cl, F3, K3, 0, 14 ); > + R( dr, er, ar, br, cr, F1, KK3, 3, 14); > + R( cl, dl, el, al, bl, F3, K3, 8, 15 ); > + R( cr, dr, er, ar, br, F1, KK3, 11, 14); > + R( bl, cl, dl, el, al, F3, K3, 12, 9 ); > + R( br, cr, dr, er, ar, F1, KK3, 15, 6); > + R( al, bl, cl, dl, el, F3, K3, 4, 8 ); > + R( ar, br, cr, dr, er, F1, KK3, 0, 14); > + R( el, al, bl, cl, dl, F3, K3, 13, 9 ); > + R( er, ar, br, cr, dr, F1, KK3, 5, 6); > + R( dl, el, al, bl, cl, F3, K3, 3, 14 ); > + R( dr, er, ar, br, cr, F1, KK3, 12, 9); > + R( cl, dl, el, al, bl, F3, K3, 7, 5 ); > + R( cr, dr, er, ar, br, F1, KK3, 2, 12); > + R( bl, cl, dl, el, al, F3, K3, 15, 6 ); > + R( br, cr, dr, er, ar, F1, KK3, 13, 9); > + R( al, bl, cl, dl, el, F3, K3, 14, 8 ); > + R( ar, br, cr, dr, er, F1, KK3, 9, 12); > + R( el, al, bl, cl, dl, F3, K3, 5, 6 ); > + R( er, ar, br, cr, dr, F1, KK3, 7, 5); > + R( dl, el, al, bl, cl, F3, K3, 6, 5 ); > + R( dr, er, ar, br, cr, F1, KK3, 10, 15); > + R( cl, dl, el, al, bl, F3, K3, 2, 12 ); > + R( cr, dr, er, ar, br, F1, KK3, 14, 8); > + R( bl, cl, dl, el, al, F4, K4, 4, 9 ); > + R( br, cr, dr, er, ar, F0, KK4, 12, 8); > + R( al, bl, cl, dl, el, F4, K4, 0, 15 ); > + R( ar, br, cr, dr, er, F0, KK4, 15, 5); > + R( el, al, bl, cl, dl, F4, K4, 5, 5 ); > + R( er, ar, br, cr, dr, F0, KK4, 10, 12); > + R( dl, el, al, bl, cl, F4, K4, 9, 11 ); > + R( dr, er, ar, br, cr, F0, KK4, 4, 9); > + R( cl, dl, el, al, bl, F4, K4, 7, 6 ); > + R( cr, dr, er, ar, br, F0, KK4, 1, 12); > + R( bl, cl, dl, el, al, F4, K4, 12, 8 ); > + R( br, cr, dr, er, ar, F0, KK4, 5, 5); > + R( al, bl, cl, dl, el, F4, K4, 2, 13 ); > + R( ar, br, cr, dr, er, F0, KK4, 8, 14); > + R( el, al, bl, cl, dl, F4, K4, 10, 12 ); > + R( er, ar, br, cr, dr, F0, KK4, 7, 6); > + R( dl, el, al, bl, cl, F4, K4, 14, 5 ); > + R( dr, er, ar, br, cr, F0, KK4, 6, 8); > + R( cl, dl, el, al, bl, F4, K4, 1, 12 ); > + R( cr, dr, er, ar, br, F0, KK4, 2, 13); > + R( bl, cl, dl, el, al, F4, K4, 3, 13 ); > + R( br, cr, dr, er, ar, F0, KK4, 13, 6); > + R( al, bl, cl, dl, el, F4, K4, 8, 14 ); > + R( ar, br, cr, dr, er, F0, KK4, 14, 5); > + R( el, al, bl, cl, dl, F4, K4, 11, 11 ); > + R( er, ar, br, cr, dr, F0, KK4, 0, 15); > + R( dl, el, al, bl, cl, F4, K4, 6, 8 ); > + R( dr, er, ar, br, cr, F0, KK4, 3, 13); > + R( cl, dl, el, al, bl, F4, K4, 15, 5 ); > + R( cr, dr, er, ar, br, F0, KK4, 9, 11); > + R( bl, cl, dl, el, al, F4, K4, 13, 6 ); > + R( br, cr, dr, er, ar, F0, KK4, 11, 11); > + > + dr += cl + hd->h1; > + hd->h1 = hd->h2 + dl + er; > + hd->h2 = hd->h3 + el + ar; > + hd->h3 = hd->h4 + al + br; > + hd->h4 = hd->h0 + bl + cr; > + hd->h0 = dr; > > - return /*burn_stack*/ 108+5*sizeof(void*); > + return /*burn_stack*/ 104+5*sizeof(void*); > } > > > > ____________________________________________________________ > FREE 3D EARTH SCREENSAVER - Watch the Earth right on your desktop! > Check it out at http://www.inbox.com/earth > > > > _______________________________________________ > Gcrypt-devel mailing list > Gcrypt-devel at gnupg.org > http://lists.gnupg.org/mailman/listinfo/gcrypt-devel > From andsch at inbox.com Thu Aug 28 19:45:35 2014 From: andsch at inbox.com (And Sch) Date: Thu, 28 Aug 2014 09:45:35 -0800 Subject: [PATCH 1/1] Improved ripemd160 performance Message-ID: <0BBF38B822B.00000F33andsch@inbox.com> * cipher/rmd160.c (transform): Interleave the left and right lane rounds to introduce more instruction level parallelism. -- The benchmarks on different systems: Intel(R) Atom(TM) CPU N570 @ 1.66GHz before: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 13.07 ns/B 72.97 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 11.37 ns/B 83.84 MiB/s - c/B Intel(R) Core(TM) i5-4670 CPU @ 3.40GHz before: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 3.31 ns/B 288.0 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte RIPEMD160 | 2.08 ns/B 458.5 MiB/s - c/B Signed-off-by: Andrei Scherer --- diff -ruNp libgcrypt-1.6.2/cipher/rmd160.c libgcrypt-1.6.3/cipher/rmd160.c --- libgcrypt-1.6.2/cipher/rmd160.c 2014-08-21 07:50:39.000000000 -0500 +++ libgcrypt-1.6.3/cipher/rmd160.c 2014-08-28 12:43:17.749359346 -0500 @@ -178,8 +178,7 @@ static unsigned int transform ( void *ctx, const unsigned char *data ) { RMD160_CONTEXT *hd = ctx; - register u32 a,b,c,d,e; - u32 aa,bb,cc,dd,ee,t; + register u32 al, ar, bl, br, cl, cr, dl, dr, el, er; u32 x[16]; int i; @@ -201,196 +200,186 @@ transform ( void *ctx, const unsigned ch #define F2(x,y,z) ( ((x) | ~(y)) ^ (z) ) #define F3(x,y,z) ( ((x) & (z)) | ((y) & ~(z)) ) #define F4(x,y,z) ( (x) ^ ((y) | ~(z)) ) -#define R(a,b,c,d,e,f,k,r,s) do { t = a + f(b,c,d) + k + x[r]; \ - a = rol(t,s) + e; \ +#define R(a,b,c,d,e,f,k,r,s) do { a += f(b,c,d) + k + x[r]; \ + a = rol(a,s) + e; \ c = rol(c,10); \ } while(0) - /* left lane */ - a = hd->h0; - b = hd->h1; - c = hd->h2; - d = hd->h3; - e = hd->h4; - R( a, b, c, d, e, F0, K0, 0, 11 ); - R( e, a, b, c, d, F0, K0, 1, 14 ); - R( d, e, a, b, c, F0, K0, 2, 15 ); - R( c, d, e, a, b, F0, K0, 3, 12 ); - R( b, c, d, e, a, F0, K0, 4, 5 ); - R( a, b, c, d, e, F0, K0, 5, 8 ); - R( e, a, b, c, d, F0, K0, 6, 7 ); - R( d, e, a, b, c, F0, K0, 7, 9 ); - R( c, d, e, a, b, F0, K0, 8, 11 ); - R( b, c, d, e, a, F0, K0, 9, 13 ); - R( a, b, c, d, e, F0, K0, 10, 14 ); - R( e, a, b, c, d, F0, K0, 11, 15 ); - R( d, e, a, b, c, F0, K0, 12, 6 ); - R( c, d, e, a, b, F0, K0, 13, 7 ); - R( b, c, d, e, a, F0, K0, 14, 9 ); - R( a, b, c, d, e, F0, K0, 15, 8 ); - R( e, a, b, c, d, F1, K1, 7, 7 ); - R( d, e, a, b, c, F1, K1, 4, 6 ); - R( c, d, e, a, b, F1, K1, 13, 8 ); - R( b, c, d, e, a, F1, K1, 1, 13 ); - R( a, b, c, d, e, F1, K1, 10, 11 ); - R( e, a, b, c, d, F1, K1, 6, 9 ); - R( d, e, a, b, c, F1, K1, 15, 7 ); - R( c, d, e, a, b, F1, K1, 3, 15 ); - R( b, c, d, e, a, F1, K1, 12, 7 ); - R( a, b, c, d, e, F1, K1, 0, 12 ); - R( e, a, b, c, d, F1, K1, 9, 15 ); - R( d, e, a, b, c, F1, K1, 5, 9 ); - R( c, d, e, a, b, F1, K1, 2, 11 ); - R( b, c, d, e, a, F1, K1, 14, 7 ); - R( a, b, c, d, e, F1, K1, 11, 13 ); - R( e, a, b, c, d, F1, K1, 8, 12 ); - R( d, e, a, b, c, F2, K2, 3, 11 ); - R( c, d, e, a, b, F2, K2, 10, 13 ); - R( b, c, d, e, a, F2, K2, 14, 6 ); - R( a, b, c, d, e, F2, K2, 4, 7 ); - R( e, a, b, c, d, F2, K2, 9, 14 ); - R( d, e, a, b, c, F2, K2, 15, 9 ); - R( c, d, e, a, b, F2, K2, 8, 13 ); - R( b, c, d, e, a, F2, K2, 1, 15 ); - R( a, b, c, d, e, F2, K2, 2, 14 ); - R( e, a, b, c, d, F2, K2, 7, 8 ); - R( d, e, a, b, c, F2, K2, 0, 13 ); - R( c, d, e, a, b, F2, K2, 6, 6 ); - R( b, c, d, e, a, F2, K2, 13, 5 ); - R( a, b, c, d, e, F2, K2, 11, 12 ); - R( e, a, b, c, d, F2, K2, 5, 7 ); - R( d, e, a, b, c, F2, K2, 12, 5 ); - R( c, d, e, a, b, F3, K3, 1, 11 ); - R( b, c, d, e, a, F3, K3, 9, 12 ); - R( a, b, c, d, e, F3, K3, 11, 14 ); - R( e, a, b, c, d, F3, K3, 10, 15 ); - R( d, e, a, b, c, F3, K3, 0, 14 ); - R( c, d, e, a, b, F3, K3, 8, 15 ); - R( b, c, d, e, a, F3, K3, 12, 9 ); - R( a, b, c, d, e, F3, K3, 4, 8 ); - R( e, a, b, c, d, F3, K3, 13, 9 ); - R( d, e, a, b, c, F3, K3, 3, 14 ); - R( c, d, e, a, b, F3, K3, 7, 5 ); - R( b, c, d, e, a, F3, K3, 15, 6 ); - R( a, b, c, d, e, F3, K3, 14, 8 ); - R( e, a, b, c, d, F3, K3, 5, 6 ); - R( d, e, a, b, c, F3, K3, 6, 5 ); - R( c, d, e, a, b, F3, K3, 2, 12 ); - R( b, c, d, e, a, F4, K4, 4, 9 ); - R( a, b, c, d, e, F4, K4, 0, 15 ); - R( e, a, b, c, d, F4, K4, 5, 5 ); - R( d, e, a, b, c, F4, K4, 9, 11 ); - R( c, d, e, a, b, F4, K4, 7, 6 ); - R( b, c, d, e, a, F4, K4, 12, 8 ); - R( a, b, c, d, e, F4, K4, 2, 13 ); - R( e, a, b, c, d, F4, K4, 10, 12 ); - R( d, e, a, b, c, F4, K4, 14, 5 ); - R( c, d, e, a, b, F4, K4, 1, 12 ); - R( b, c, d, e, a, F4, K4, 3, 13 ); - R( a, b, c, d, e, F4, K4, 8, 14 ); - R( e, a, b, c, d, F4, K4, 11, 11 ); - R( d, e, a, b, c, F4, K4, 6, 8 ); - R( c, d, e, a, b, F4, K4, 15, 5 ); - R( b, c, d, e, a, F4, K4, 13, 6 ); - - aa = a; bb = b; cc = c; dd = d; ee = e; - - /* right lane */ - a = hd->h0; - b = hd->h1; - c = hd->h2; - d = hd->h3; - e = hd->h4; - R( a, b, c, d, e, F4, KK0, 5, 8); - R( e, a, b, c, d, F4, KK0, 14, 9); - R( d, e, a, b, c, F4, KK0, 7, 9); - R( c, d, e, a, b, F4, KK0, 0, 11); - R( b, c, d, e, a, F4, KK0, 9, 13); - R( a, b, c, d, e, F4, KK0, 2, 15); - R( e, a, b, c, d, F4, KK0, 11, 15); - R( d, e, a, b, c, F4, KK0, 4, 5); - R( c, d, e, a, b, F4, KK0, 13, 7); - R( b, c, d, e, a, F4, KK0, 6, 7); - R( a, b, c, d, e, F4, KK0, 15, 8); - R( e, a, b, c, d, F4, KK0, 8, 11); - R( d, e, a, b, c, F4, KK0, 1, 14); - R( c, d, e, a, b, F4, KK0, 10, 14); - R( b, c, d, e, a, F4, KK0, 3, 12); - R( a, b, c, d, e, F4, KK0, 12, 6); - R( e, a, b, c, d, F3, KK1, 6, 9); - R( d, e, a, b, c, F3, KK1, 11, 13); - R( c, d, e, a, b, F3, KK1, 3, 15); - R( b, c, d, e, a, F3, KK1, 7, 7); - R( a, b, c, d, e, F3, KK1, 0, 12); - R( e, a, b, c, d, F3, KK1, 13, 8); - R( d, e, a, b, c, F3, KK1, 5, 9); - R( c, d, e, a, b, F3, KK1, 10, 11); - R( b, c, d, e, a, F3, KK1, 14, 7); - R( a, b, c, d, e, F3, KK1, 15, 7); - R( e, a, b, c, d, F3, KK1, 8, 12); - R( d, e, a, b, c, F3, KK1, 12, 7); - R( c, d, e, a, b, F3, KK1, 4, 6); - R( b, c, d, e, a, F3, KK1, 9, 15); - R( a, b, c, d, e, F3, KK1, 1, 13); - R( e, a, b, c, d, F3, KK1, 2, 11); - R( d, e, a, b, c, F2, KK2, 15, 9); - R( c, d, e, a, b, F2, KK2, 5, 7); - R( b, c, d, e, a, F2, KK2, 1, 15); - R( a, b, c, d, e, F2, KK2, 3, 11); - R( e, a, b, c, d, F2, KK2, 7, 8); - R( d, e, a, b, c, F2, KK2, 14, 6); - R( c, d, e, a, b, F2, KK2, 6, 6); - R( b, c, d, e, a, F2, KK2, 9, 14); - R( a, b, c, d, e, F2, KK2, 11, 12); - R( e, a, b, c, d, F2, KK2, 8, 13); - R( d, e, a, b, c, F2, KK2, 12, 5); - R( c, d, e, a, b, F2, KK2, 2, 14); - R( b, c, d, e, a, F2, KK2, 10, 13); - R( a, b, c, d, e, F2, KK2, 0, 13); - R( e, a, b, c, d, F2, KK2, 4, 7); - R( d, e, a, b, c, F2, KK2, 13, 5); - R( c, d, e, a, b, F1, KK3, 8, 15); - R( b, c, d, e, a, F1, KK3, 6, 5); - R( a, b, c, d, e, F1, KK3, 4, 8); - R( e, a, b, c, d, F1, KK3, 1, 11); - R( d, e, a, b, c, F1, KK3, 3, 14); - R( c, d, e, a, b, F1, KK3, 11, 14); - R( b, c, d, e, a, F1, KK3, 15, 6); - R( a, b, c, d, e, F1, KK3, 0, 14); - R( e, a, b, c, d, F1, KK3, 5, 6); - R( d, e, a, b, c, F1, KK3, 12, 9); - R( c, d, e, a, b, F1, KK3, 2, 12); - R( b, c, d, e, a, F1, KK3, 13, 9); - R( a, b, c, d, e, F1, KK3, 9, 12); - R( e, a, b, c, d, F1, KK3, 7, 5); - R( d, e, a, b, c, F1, KK3, 10, 15); - R( c, d, e, a, b, F1, KK3, 14, 8); - R( b, c, d, e, a, F0, KK4, 12, 8); - R( a, b, c, d, e, F0, KK4, 15, 5); - R( e, a, b, c, d, F0, KK4, 10, 12); - R( d, e, a, b, c, F0, KK4, 4, 9); - R( c, d, e, a, b, F0, KK4, 1, 12); - R( b, c, d, e, a, F0, KK4, 5, 5); - R( a, b, c, d, e, F0, KK4, 8, 14); - R( e, a, b, c, d, F0, KK4, 7, 6); - R( d, e, a, b, c, F0, KK4, 6, 8); - R( c, d, e, a, b, F0, KK4, 2, 13); - R( b, c, d, e, a, F0, KK4, 13, 6); - R( a, b, c, d, e, F0, KK4, 14, 5); - R( e, a, b, c, d, F0, KK4, 0, 15); - R( d, e, a, b, c, F0, KK4, 3, 13); - R( c, d, e, a, b, F0, KK4, 9, 11); - R( b, c, d, e, a, F0, KK4, 11, 11); - - - t = hd->h1 + d + cc; - hd->h1 = hd->h2 + e + dd; - hd->h2 = hd->h3 + a + ee; - hd->h3 = hd->h4 + b + aa; - hd->h4 = hd->h0 + c + bb; - hd->h0 = t; + /* left lane and right lanes interleaved */ + al = ar = hd->h0; + bl = br = hd->h1; + cl = cr = hd->h2; + dl = dr = hd->h3; + el = er = hd->h4; + R( al, bl, cl, dl, el, F0, K0, 0, 11 ); + R( ar, br, cr, dr, er, F4, KK0, 5, 8); + R( el, al, bl, cl, dl, F0, K0, 1, 14 ); + R( er, ar, br, cr, dr, F4, KK0, 14, 9); + R( dl, el, al, bl, cl, F0, K0, 2, 15 ); + R( dr, er, ar, br, cr, F4, KK0, 7, 9); + R( cl, dl, el, al, bl, F0, K0, 3, 12 ); + R( cr, dr, er, ar, br, F4, KK0, 0, 11); + R( bl, cl, dl, el, al, F0, K0, 4, 5 ); + R( br, cr, dr, er, ar, F4, KK0, 9, 13); + R( al, bl, cl, dl, el, F0, K0, 5, 8 ); + R( ar, br, cr, dr, er, F4, KK0, 2, 15); + R( el, al, bl, cl, dl, F0, K0, 6, 7 ); + R( er, ar, br, cr, dr, F4, KK0, 11, 15); + R( dl, el, al, bl, cl, F0, K0, 7, 9 ); + R( dr, er, ar, br, cr, F4, KK0, 4, 5); + R( cl, dl, el, al, bl, F0, K0, 8, 11 ); + R( cr, dr, er, ar, br, F4, KK0, 13, 7); + R( bl, cl, dl, el, al, F0, K0, 9, 13 ); + R( br, cr, dr, er, ar, F4, KK0, 6, 7); + R( al, bl, cl, dl, el, F0, K0, 10, 14 ); + R( ar, br, cr, dr, er, F4, KK0, 15, 8); + R( el, al, bl, cl, dl, F0, K0, 11, 15 ); + R( er, ar, br, cr, dr, F4, KK0, 8, 11); + R( dl, el, al, bl, cl, F0, K0, 12, 6 ); + R( dr, er, ar, br, cr, F4, KK0, 1, 14); + R( cl, dl, el, al, bl, F0, K0, 13, 7 ); + R( cr, dr, er, ar, br, F4, KK0, 10, 14); + R( bl, cl, dl, el, al, F0, K0, 14, 9 ); + R( br, cr, dr, er, ar, F4, KK0, 3, 12); + R( al, bl, cl, dl, el, F0, K0, 15, 8 ); + R( ar, br, cr, dr, er, F4, KK0, 12, 6); + R( el, al, bl, cl, dl, F1, K1, 7, 7 ); + R( er, ar, br, cr, dr, F3, KK1, 6, 9); + R( dl, el, al, bl, cl, F1, K1, 4, 6 ); + R( dr, er, ar, br, cr, F3, KK1, 11, 13); + R( cl, dl, el, al, bl, F1, K1, 13, 8 ); + R( cr, dr, er, ar, br, F3, KK1, 3, 15); + R( bl, cl, dl, el, al, F1, K1, 1, 13 ); + R( br, cr, dr, er, ar, F3, KK1, 7, 7); + R( al, bl, cl, dl, el, F1, K1, 10, 11 ); + R( ar, br, cr, dr, er, F3, KK1, 0, 12); + R( el, al, bl, cl, dl, F1, K1, 6, 9 ); + R( er, ar, br, cr, dr, F3, KK1, 13, 8); + R( dl, el, al, bl, cl, F1, K1, 15, 7 ); + R( dr, er, ar, br, cr, F3, KK1, 5, 9); + R( cl, dl, el, al, bl, F1, K1, 3, 15 ); + R( cr, dr, er, ar, br, F3, KK1, 10, 11); + R( bl, cl, dl, el, al, F1, K1, 12, 7 ); + R( br, cr, dr, er, ar, F3, KK1, 14, 7); + R( al, bl, cl, dl, el, F1, K1, 0, 12 ); + R( ar, br, cr, dr, er, F3, KK1, 15, 7); + R( el, al, bl, cl, dl, F1, K1, 9, 15 ); + R( er, ar, br, cr, dr, F3, KK1, 8, 12); + R( dl, el, al, bl, cl, F1, K1, 5, 9 ); + R( dr, er, ar, br, cr, F3, KK1, 12, 7); + R( cl, dl, el, al, bl, F1, K1, 2, 11 ); + R( cr, dr, er, ar, br, F3, KK1, 4, 6); + R( bl, cl, dl, el, al, F1, K1, 14, 7 ); + R( br, cr, dr, er, ar, F3, KK1, 9, 15); + R( al, bl, cl, dl, el, F1, K1, 11, 13 ); + R( ar, br, cr, dr, er, F3, KK1, 1, 13); + R( el, al, bl, cl, dl, F1, K1, 8, 12 ); + R( er, ar, br, cr, dr, F3, KK1, 2, 11); + R( dl, el, al, bl, cl, F2, K2, 3, 11 ); + R( dr, er, ar, br, cr, F2, KK2, 15, 9); + R( cl, dl, el, al, bl, F2, K2, 10, 13 ); + R( cr, dr, er, ar, br, F2, KK2, 5, 7); + R( bl, cl, dl, el, al, F2, K2, 14, 6 ); + R( br, cr, dr, er, ar, F2, KK2, 1, 15); + R( al, bl, cl, dl, el, F2, K2, 4, 7 ); + R( ar, br, cr, dr, er, F2, KK2, 3, 11); + R( el, al, bl, cl, dl, F2, K2, 9, 14 ); + R( er, ar, br, cr, dr, F2, KK2, 7, 8); + R( dl, el, al, bl, cl, F2, K2, 15, 9 ); + R( dr, er, ar, br, cr, F2, KK2, 14, 6); + R( cl, dl, el, al, bl, F2, K2, 8, 13 ); + R( cr, dr, er, ar, br, F2, KK2, 6, 6); + R( bl, cl, dl, el, al, F2, K2, 1, 15 ); + R( br, cr, dr, er, ar, F2, KK2, 9, 14); + R( al, bl, cl, dl, el, F2, K2, 2, 14 ); + R( ar, br, cr, dr, er, F2, KK2, 11, 12); + R( el, al, bl, cl, dl, F2, K2, 7, 8 ); + R( er, ar, br, cr, dr, F2, KK2, 8, 13); + R( dl, el, al, bl, cl, F2, K2, 0, 13 ); + R( dr, er, ar, br, cr, F2, KK2, 12, 5); + R( cl, dl, el, al, bl, F2, K2, 6, 6 ); + R( cr, dr, er, ar, br, F2, KK2, 2, 14); + R( bl, cl, dl, el, al, F2, K2, 13, 5 ); + R( br, cr, dr, er, ar, F2, KK2, 10, 13); + R( al, bl, cl, dl, el, F2, K2, 11, 12 ); + R( ar, br, cr, dr, er, F2, KK2, 0, 13); + R( el, al, bl, cl, dl, F2, K2, 5, 7 ); + R( er, ar, br, cr, dr, F2, KK2, 4, 7); + R( dl, el, al, bl, cl, F2, K2, 12, 5 ); + R( dr, er, ar, br, cr, F2, KK2, 13, 5); + R( cl, dl, el, al, bl, F3, K3, 1, 11 ); + R( cr, dr, er, ar, br, F1, KK3, 8, 15); + R( bl, cl, dl, el, al, F3, K3, 9, 12 ); + R( br, cr, dr, er, ar, F1, KK3, 6, 5); + R( al, bl, cl, dl, el, F3, K3, 11, 14 ); + R( ar, br, cr, dr, er, F1, KK3, 4, 8); + R( el, al, bl, cl, dl, F3, K3, 10, 15 ); + R( er, ar, br, cr, dr, F1, KK3, 1, 11); + R( dl, el, al, bl, cl, F3, K3, 0, 14 ); + R( dr, er, ar, br, cr, F1, KK3, 3, 14); + R( cl, dl, el, al, bl, F3, K3, 8, 15 ); + R( cr, dr, er, ar, br, F1, KK3, 11, 14); + R( bl, cl, dl, el, al, F3, K3, 12, 9 ); + R( br, cr, dr, er, ar, F1, KK3, 15, 6); + R( al, bl, cl, dl, el, F3, K3, 4, 8 ); + R( ar, br, cr, dr, er, F1, KK3, 0, 14); + R( el, al, bl, cl, dl, F3, K3, 13, 9 ); + R( er, ar, br, cr, dr, F1, KK3, 5, 6); + R( dl, el, al, bl, cl, F3, K3, 3, 14 ); + R( dr, er, ar, br, cr, F1, KK3, 12, 9); + R( cl, dl, el, al, bl, F3, K3, 7, 5 ); + R( cr, dr, er, ar, br, F1, KK3, 2, 12); + R( bl, cl, dl, el, al, F3, K3, 15, 6 ); + R( br, cr, dr, er, ar, F1, KK3, 13, 9); + R( al, bl, cl, dl, el, F3, K3, 14, 8 ); + R( ar, br, cr, dr, er, F1, KK3, 9, 12); + R( el, al, bl, cl, dl, F3, K3, 5, 6 ); + R( er, ar, br, cr, dr, F1, KK3, 7, 5); + R( dl, el, al, bl, cl, F3, K3, 6, 5 ); + R( dr, er, ar, br, cr, F1, KK3, 10, 15); + R( cl, dl, el, al, bl, F3, K3, 2, 12 ); + R( cr, dr, er, ar, br, F1, KK3, 14, 8); + R( bl, cl, dl, el, al, F4, K4, 4, 9 ); + R( br, cr, dr, er, ar, F0, KK4, 12, 8); + R( al, bl, cl, dl, el, F4, K4, 0, 15 ); + R( ar, br, cr, dr, er, F0, KK4, 15, 5); + R( el, al, bl, cl, dl, F4, K4, 5, 5 ); + R( er, ar, br, cr, dr, F0, KK4, 10, 12); + R( dl, el, al, bl, cl, F4, K4, 9, 11 ); + R( dr, er, ar, br, cr, F0, KK4, 4, 9); + R( cl, dl, el, al, bl, F4, K4, 7, 6 ); + R( cr, dr, er, ar, br, F0, KK4, 1, 12); + R( bl, cl, dl, el, al, F4, K4, 12, 8 ); + R( br, cr, dr, er, ar, F0, KK4, 5, 5); + R( al, bl, cl, dl, el, F4, K4, 2, 13 ); + R( ar, br, cr, dr, er, F0, KK4, 8, 14); + R( el, al, bl, cl, dl, F4, K4, 10, 12 ); + R( er, ar, br, cr, dr, F0, KK4, 7, 6); + R( dl, el, al, bl, cl, F4, K4, 14, 5 ); + R( dr, er, ar, br, cr, F0, KK4, 6, 8); + R( cl, dl, el, al, bl, F4, K4, 1, 12 ); + R( cr, dr, er, ar, br, F0, KK4, 2, 13); + R( bl, cl, dl, el, al, F4, K4, 3, 13 ); + R( br, cr, dr, er, ar, F0, KK4, 13, 6); + R( al, bl, cl, dl, el, F4, K4, 8, 14 ); + R( ar, br, cr, dr, er, F0, KK4, 14, 5); + R( el, al, bl, cl, dl, F4, K4, 11, 11 ); + R( er, ar, br, cr, dr, F0, KK4, 0, 15); + R( dl, el, al, bl, cl, F4, K4, 6, 8 ); + R( dr, er, ar, br, cr, F0, KK4, 3, 13); + R( cl, dl, el, al, bl, F4, K4, 15, 5 ); + R( cr, dr, er, ar, br, F0, KK4, 9, 11); + R( bl, cl, dl, el, al, F4, K4, 13, 6 ); + R( br, cr, dr, er, ar, F0, KK4, 11, 11); + + dr += cl + hd->h1; + hd->h1 = hd->h2 + dl + er; + hd->h2 = hd->h3 + el + ar; + hd->h3 = hd->h4 + al + br; + hd->h4 = hd->h0 + bl + cr; + hd->h0 = dr; - return /*burn_stack*/ 108+5*sizeof(void*); + return /*burn_stack*/ 104+5*sizeof(void*); } ____________________________________________________________ FREE 3D MARINE AQUARIUM SCREENSAVER - Watch dolphins, sharks & orcas on your desktop! Check it out at http://www.inbox.com/marineaquarium From jussi.kivilinna at iki.fi Thu Aug 28 18:35:24 2014 From: jussi.kivilinna at iki.fi (Jussi Kivilinna) Date: Thu, 28 Aug 2014 19:35:24 +0300 Subject: [PATCH] Add new Poly1305 MAC test vectors Message-ID: <20140828163524.1520.44123.stgit@localhost6.localdomain6> * tests/basic.c (check_mac): Add new test vectors for Poly1305 MAC. -- Patch adds new test vectors for Poly1305 MAC from Internet Draft draft-irtf-cfrg-chacha20-poly1305-01. Signed-off-by: Jussi Kivilinna --- tests/basic.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/tests/basic.c b/tests/basic.c index 6d70cfd..e406db4 100644 --- a/tests/basic.c +++ b/tests/basic.c @@ -6008,6 +6008,72 @@ check_mac (void) "\xf3\x47\x7e\x7c\xd9\x54\x17\xaf\x89\xa6\xb8\x79\x4c\x31\x0c\xf0", NULL, 0, 32 }, + /* draft-irtf-cfrg-chacha20-poly1305-01 */ + /* TV#5 */ + { GCRY_MAC_POLY1305, + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", + "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + NULL, + 16, 32 }, + /* TV#6 */ + { GCRY_MAC_POLY1305, + "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", + "\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + NULL, + 16, 32 }, + /* TV#7 */ + { GCRY_MAC_POLY1305, + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xF0\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\x11\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x05\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + NULL, + 48, 32 }, + /* TV#8 */ + { GCRY_MAC_POLY1305, + "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" + "\xFB\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE\xFE" + "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01", + "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + NULL, + 48, 32 }, + /* TV#9 */ + { GCRY_MAC_POLY1305, + "\xFD\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", + "\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\xFA\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", + NULL, + 16, 32 }, + /* TV#10 */ + { GCRY_MAC_POLY1305, + "\xE3\x35\x94\xD7\x50\x5E\x43\xB9\x00\x00\x00\x00\x00\x00\x00\x00" + "\x33\x94\xD7\x50\x5E\x43\x79\xCD\x01\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x14\x00\x00\x00\x00\x00\x00\x00\x55\x00\x00\x00\x00\x00\x00\x00", + NULL, + 64, 32 }, + /* TV#11 */ + { GCRY_MAC_POLY1305, + "\xE3\x35\x94\xD7\x50\x5E\x43\xB9\x00\x00\x00\x00\x00\x00\x00\x00" + "\x33\x94\xD7\x50\x5E\x43\x79\xCD\x01\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x01\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + "\x13\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", + NULL, + 48, 32 }, /* from http://cr.yp.to/mac/poly1305-20050329.pdf */ { GCRY_MAC_POLY1305, "\xf3\xf6", From andsch at inbox.com Thu Aug 28 20:02:17 2014 From: andsch at inbox.com (And Sch) Date: Thu, 28 Aug 2014 10:02:17 -0800 Subject: [PATCH 1/1] Improved whirlpool hash performance Message-ID: <0BE490E19CE.00000F69andsch@inbox.com> * cipher/whirlpool.c (whirlpool_transform, sbox, added macro): Added macro and rearranged round function to alternate between reading to and writing from different state and key variables. Two whirlpool_context_t variables removed, two were replaced, the sizes of state and key doubled, so overall the burn stack stays the same. buffer_to_block and block_xor were combined into one operation. The sbox was converted to one large table, because it is faster than many small tables. -- Benchmark on different systems: Intel(R) Atom(TM) CPU N570 @ 1.66GHz before: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 63.40 ns/B 15.04 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 46.21 ns/B 20.64 MiB/s - c/B Intel(R) Core(TM) i5-4670 CPU @ 3.40GHz before: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 7.75 ns/B 123.0 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 6.70 ns/B 142.3 MiB/s - c/B This one actually shows greater improvement on the Atom system. Signed-off-by: Andrei Scherer --- diff -ruNp libgcrypt-1.6.2/cipher/whirlpool.c libgcrypt-1.6.3/cipher/whirlpool.c --- libgcrypt-1.6.2/cipher/whirlpool.c 2014-08-21 07:50:39.000000000 -0500 +++ libgcrypt-1.6.3/cipher/whirlpool.c 2014-08-28 12:47:04.917824140 -0500 @@ -87,6 +87,17 @@ typedef struct { for (i = 0; i < 8; i++) \ block_dst[i] ^= block_src[i]; +/* XOR lookup boxes with index SRC [(SHIFT + n) & 7] >> x. */ +#define WHIRLPOOL_XOR(src, shift) \ + C[((unsigned int)(src[ (shift) ] >> 56) ) ] ^ \ + C[((unsigned int)(src[((shift) + 7) & 7] >> 48) & 0xff) + 256 ] ^ \ + C[((unsigned int)(src[((shift) + 6) & 7] >> 40) & 0xff) + (256*2)] ^ \ + C[((unsigned int)(src[((shift) + 5) & 7] >> 32) & 0xff) + (256*3)] ^ \ + C[((unsigned int)(src[((shift) + 4) & 7] >> 24) & 0xff) + (256*4)] ^ \ + C[((unsigned int)(src[((shift) + 3) & 7] >> 16) & 0xff) + (256*5)] ^ \ + C[((unsigned int)(src[((shift) + 2) & 7] >> 8) & 0xff) + (256*6)] ^ \ + C[((unsigned int)(src[((shift) + 1) & 7] ) & 0xff) + (256*7)] \ + ? /* Round constants. */ @@ -107,7 +118,7 @@ static const u64 rc[R] = ? /* Main lookup boxes. */ -static const u64 C0[256] = +static const u64 C[8*256] = { U64_C (0x18186018c07830d8), U64_C (0x23238c2305af4626), U64_C (0xc6c63fc67ef991b8), U64_C (0xe8e887e8136fcdfb), @@ -237,10 +248,7 @@ static const u64 C0[256] = U64_C (0x98985a98b4c22d2c), U64_C (0xa4a4aaa4490e55ed), U64_C (0x2828a0285d885075), U64_C (0x5c5c6d5cda31b886), U64_C (0xf8f8c7f8933fed6b), U64_C (0x8686228644a411c2), - }; -static const u64 C1[256] = - { U64_C (0xd818186018c07830), U64_C (0x2623238c2305af46), U64_C (0xb8c6c63fc67ef991), U64_C (0xfbe8e887e8136fcd), U64_C (0xcb878726874ca113), U64_C (0x11b8b8dab8a9626d), @@ -369,10 +377,7 @@ static const u64 C1[256] = U64_C (0x2c98985a98b4c22d), U64_C (0xeda4a4aaa4490e55), U64_C (0x752828a0285d8850), U64_C (0x865c5c6d5cda31b8), U64_C (0x6bf8f8c7f8933fed), U64_C (0xc28686228644a411), - }; -static const u64 C2[256] = - { U64_C (0x30d818186018c078), U64_C (0x462623238c2305af), U64_C (0x91b8c6c63fc67ef9), U64_C (0xcdfbe8e887e8136f), U64_C (0x13cb878726874ca1), U64_C (0x6d11b8b8dab8a962), @@ -501,10 +506,7 @@ static const u64 C2[256] = U64_C (0x2d2c98985a98b4c2), U64_C (0x55eda4a4aaa4490e), U64_C (0x50752828a0285d88), U64_C (0xb8865c5c6d5cda31), U64_C (0xed6bf8f8c7f8933f), U64_C (0x11c28686228644a4), - }; -static const u64 C3[256] = - { U64_C (0x7830d818186018c0), U64_C (0xaf462623238c2305), U64_C (0xf991b8c6c63fc67e), U64_C (0x6fcdfbe8e887e813), U64_C (0xa113cb878726874c), U64_C (0x626d11b8b8dab8a9), @@ -633,10 +635,7 @@ static const u64 C3[256] = U64_C (0xc22d2c98985a98b4), U64_C (0x0e55eda4a4aaa449), U64_C (0x8850752828a0285d), U64_C (0x31b8865c5c6d5cda), U64_C (0x3fed6bf8f8c7f893), U64_C (0xa411c28686228644), - }; -static const u64 C4[256] = - { U64_C (0xc07830d818186018), U64_C (0x05af462623238c23), U64_C (0x7ef991b8c6c63fc6), U64_C (0x136fcdfbe8e887e8), U64_C (0x4ca113cb87872687), U64_C (0xa9626d11b8b8dab8), @@ -765,10 +764,7 @@ static const u64 C4[256] = U64_C (0xb4c22d2c98985a98), U64_C (0x490e55eda4a4aaa4), U64_C (0x5d8850752828a028), U64_C (0xda31b8865c5c6d5c), U64_C (0x933fed6bf8f8c7f8), U64_C (0x44a411c286862286), - }; -static const u64 C5[256] = - { U64_C (0x18c07830d8181860), U64_C (0x2305af462623238c), U64_C (0xc67ef991b8c6c63f), U64_C (0xe8136fcdfbe8e887), U64_C (0x874ca113cb878726), U64_C (0xb8a9626d11b8b8da), @@ -897,10 +893,7 @@ static const u64 C5[256] = U64_C (0x98b4c22d2c98985a), U64_C (0xa4490e55eda4a4aa), U64_C (0x285d8850752828a0), U64_C (0x5cda31b8865c5c6d), U64_C (0xf8933fed6bf8f8c7), U64_C (0x8644a411c2868622), - }; -static const u64 C6[256] = - { U64_C (0x6018c07830d81818), U64_C (0x8c2305af46262323), U64_C (0x3fc67ef991b8c6c6), U64_C (0x87e8136fcdfbe8e8), U64_C (0x26874ca113cb8787), U64_C (0xdab8a9626d11b8b8), @@ -1029,10 +1022,7 @@ static const u64 C6[256] = U64_C (0x5a98b4c22d2c9898), U64_C (0xaaa4490e55eda4a4), U64_C (0xa0285d8850752828), U64_C (0x6d5cda31b8865c5c), U64_C (0xc7f8933fed6bf8f8), U64_C (0x228644a411c28686), - }; -static const u64 C7[256] = - { U64_C (0x186018c07830d818), U64_C (0x238c2305af462623), U64_C (0xc63fc67ef991b8c6), U64_C (0xe887e8136fcdfbe8), U64_C (0x8726874ca113cb87), U64_C (0xb8dab8a9626d11b8), @@ -1163,7 +1153,6 @@ static const u64 C7[256] = U64_C (0xf8c7f8933fed6bf8), U64_C (0x86228644a411c286), }; - ? /* * Transform block. @@ -1172,97 +1161,36 @@ static unsigned int whirlpool_transform (void *ctx, const unsigned char *data) { whirlpool_context_t *context = ctx; - whirlpool_block_t data_block; - whirlpool_block_t key; - whirlpool_block_t state; - whirlpool_block_t block; + u64 key[2][BLOCK_SIZE / 8]; + u64 state[2][BLOCK_SIZE / 8]; unsigned int r; unsigned int i; - buffer_to_block (data, data_block, i); - block_copy (key, context->hash_state, i); - block_copy (state, context->hash_state, i); - block_xor (state, data_block, i); + /* buffer_to_block and block_xor at once */ + + for (i = 0; i < 8; i++) + state[0][i] = buf_get_be64((data) + i * 8) ^ context->hash_state[i]; + + block_copy (key[0], context->hash_state, i); + block_copy (context->hash_state, state[0], i); - for (r = 0; r < R; r++) + for (r = 0, i = 0; r < R; r++, i = !i) { - /* Compute round key K^r. */ + /* Compute round key K^r, and apply r-th round transformation, interleaved */ - block[0] = (C0[(key[0] >> 56) & 0xFF] ^ C1[(key[7] >> 48) & 0xFF] ^ - C2[(key[6] >> 40) & 0xFF] ^ C3[(key[5] >> 32) & 0xFF] ^ - C4[(key[4] >> 24) & 0xFF] ^ C5[(key[3] >> 16) & 0xFF] ^ - C6[(key[2] >> 8) & 0xFF] ^ C7[(key[1] >> 0) & 0xFF] ^ rc[r]); - block[1] = (C0[(key[1] >> 56) & 0xFF] ^ C1[(key[0] >> 48) & 0xFF] ^ - C2[(key[7] >> 40) & 0xFF] ^ C3[(key[6] >> 32) & 0xFF] ^ - C4[(key[5] >> 24) & 0xFF] ^ C5[(key[4] >> 16) & 0xFF] ^ - C6[(key[3] >> 8) & 0xFF] ^ C7[(key[2] >> 0) & 0xFF]); - block[2] = (C0[(key[2] >> 56) & 0xFF] ^ C1[(key[1] >> 48) & 0xFF] ^ - C2[(key[0] >> 40) & 0xFF] ^ C3[(key[7] >> 32) & 0xFF] ^ - C4[(key[6] >> 24) & 0xFF] ^ C5[(key[5] >> 16) & 0xFF] ^ - C6[(key[4] >> 8) & 0xFF] ^ C7[(key[3] >> 0) & 0xFF]); - block[3] = (C0[(key[3] >> 56) & 0xFF] ^ C1[(key[2] >> 48) & 0xFF] ^ - C2[(key[1] >> 40) & 0xFF] ^ C3[(key[0] >> 32) & 0xFF] ^ - C4[(key[7] >> 24) & 0xFF] ^ C5[(key[6] >> 16) & 0xFF] ^ - C6[(key[5] >> 8) & 0xFF] ^ C7[(key[4] >> 0) & 0xFF]); - block[4] = (C0[(key[4] >> 56) & 0xFF] ^ C1[(key[3] >> 48) & 0xFF] ^ - C2[(key[2] >> 40) & 0xFF] ^ C3[(key[1] >> 32) & 0xFF] ^ - C4[(key[0] >> 24) & 0xFF] ^ C5[(key[7] >> 16) & 0xFF] ^ - C6[(key[6] >> 8) & 0xFF] ^ C7[(key[5] >> 0) & 0xFF]); - block[5] = (C0[(key[5] >> 56) & 0xFF] ^ C1[(key[4] >> 48) & 0xFF] ^ - C2[(key[3] >> 40) & 0xFF] ^ C3[(key[2] >> 32) & 0xFF] ^ - C4[(key[1] >> 24) & 0xFF] ^ C5[(key[0] >> 16) & 0xFF] ^ - C6[(key[7] >> 8) & 0xFF] ^ C7[(key[6] >> 0) & 0xFF]); - block[6] = (C0[(key[6] >> 56) & 0xFF] ^ C1[(key[5] >> 48) & 0xFF] ^ - C2[(key[4] >> 40) & 0xFF] ^ C3[(key[3] >> 32) & 0xFF] ^ - C4[(key[2] >> 24) & 0xFF] ^ C5[(key[1] >> 16) & 0xFF] ^ - C6[(key[0] >> 8) & 0xFF] ^ C7[(key[7] >> 0) & 0xFF]); - block[7] = (C0[(key[7] >> 56) & 0xFF] ^ C1[(key[6] >> 48) & 0xFF] ^ - C2[(key[5] >> 40) & 0xFF] ^ C3[(key[4] >> 32) & 0xFF] ^ - C4[(key[3] >> 24) & 0xFF] ^ C5[(key[2] >> 16) & 0xFF] ^ - C6[(key[1] >> 8) & 0xFF] ^ C7[(key[0] >> 0) & 0xFF]); - block_copy (key, block, i); - - /* Apply r-th round transformation. */ - - block[0] = (C0[(state[0] >> 56) & 0xFF] ^ C1[(state[7] >> 48) & 0xFF] ^ - C2[(state[6] >> 40) & 0xFF] ^ C3[(state[5] >> 32) & 0xFF] ^ - C4[(state[4] >> 24) & 0xFF] ^ C5[(state[3] >> 16) & 0xFF] ^ - C6[(state[2] >> 8) & 0xFF] ^ C7[(state[1] >> 0) & 0xFF] ^ key[0]); - block[1] = (C0[(state[1] >> 56) & 0xFF] ^ C1[(state[0] >> 48) & 0xFF] ^ - C2[(state[7] >> 40) & 0xFF] ^ C3[(state[6] >> 32) & 0xFF] ^ - C4[(state[5] >> 24) & 0xFF] ^ C5[(state[4] >> 16) & 0xFF] ^ - C6[(state[3] >> 8) & 0xFF] ^ C7[(state[2] >> 0) & 0xFF] ^ key[1]); - block[2] = (C0[(state[2] >> 56) & 0xFF] ^ C1[(state[1] >> 48) & 0xFF] ^ - C2[(state[0] >> 40) & 0xFF] ^ C3[(state[7] >> 32) & 0xFF] ^ - C4[(state[6] >> 24) & 0xFF] ^ C5[(state[5] >> 16) & 0xFF] ^ - C6[(state[4] >> 8) & 0xFF] ^ C7[(state[3] >> 0) & 0xFF] ^ key[2]); - block[3] = (C0[(state[3] >> 56) & 0xFF] ^ C1[(state[2] >> 48) & 0xFF] ^ - C2[(state[1] >> 40) & 0xFF] ^ C3[(state[0] >> 32) & 0xFF] ^ - C4[(state[7] >> 24) & 0xFF] ^ C5[(state[6] >> 16) & 0xFF] ^ - C6[(state[5] >> 8) & 0xFF] ^ C7[(state[4] >> 0) & 0xFF] ^ key[3]); - block[4] = (C0[(state[4] >> 56) & 0xFF] ^ C1[(state[3] >> 48) & 0xFF] ^ - C2[(state[2] >> 40) & 0xFF] ^ C3[(state[1] >> 32) & 0xFF] ^ - C4[(state[0] >> 24) & 0xFF] ^ C5[(state[7] >> 16) & 0xFF] ^ - C6[(state[6] >> 8) & 0xFF] ^ C7[(state[5] >> 0) & 0xFF] ^ key[4]); - block[5] = (C0[(state[5] >> 56) & 0xFF] ^ C1[(state[4] >> 48) & 0xFF] ^ - C2[(state[3] >> 40) & 0xFF] ^ C3[(state[2] >> 32) & 0xFF] ^ - C4[(state[1] >> 24) & 0xFF] ^ C5[(state[0] >> 16) & 0xFF] ^ - C6[(state[7] >> 8) & 0xFF] ^ C7[(state[6] >> 0) & 0xFF] ^ key[5]); - block[6] = (C0[(state[6] >> 56) & 0xFF] ^ C1[(state[5] >> 48) & 0xFF] ^ - C2[(state[4] >> 40) & 0xFF] ^ C3[(state[3] >> 32) & 0xFF] ^ - C4[(state[2] >> 24) & 0xFF] ^ C5[(state[1] >> 16) & 0xFF] ^ - C6[(state[0] >> 8) & 0xFF] ^ C7[(state[7] >> 0) & 0xFF] ^ key[6]); - block[7] = (C0[(state[7] >> 56) & 0xFF] ^ C1[(state[6] >> 48) & 0xFF] ^ - C2[(state[5] >> 40) & 0xFF] ^ C3[(state[4] >> 32) & 0xFF] ^ - C4[(state[3] >> 24) & 0xFF] ^ C5[(state[2] >> 16) & 0xFF] ^ - C6[(state[1] >> 8) & 0xFF] ^ C7[(state[0] >> 0) & 0xFF] ^ key[7]); - block_copy (state, block, i); + state[!i][0] = WHIRLPOOL_XOR(state[i], 0) ^ (key[!i][0] = WHIRLPOOL_XOR(key[i], 0) ^ rc[r]); + state[!i][1] = WHIRLPOOL_XOR(state[i], 1) ^ (key[!i][1] = WHIRLPOOL_XOR(key[i], 1)); + state[!i][2] = WHIRLPOOL_XOR(state[i], 2) ^ (key[!i][2] = WHIRLPOOL_XOR(key[i], 2)); + state[!i][3] = WHIRLPOOL_XOR(state[i], 3) ^ (key[!i][3] = WHIRLPOOL_XOR(key[i], 3)); + state[!i][4] = WHIRLPOOL_XOR(state[i], 4) ^ (key[!i][4] = WHIRLPOOL_XOR(key[i], 4)); + state[!i][5] = WHIRLPOOL_XOR(state[i], 5) ^ (key[!i][5] = WHIRLPOOL_XOR(key[i], 5)); + state[!i][6] = WHIRLPOOL_XOR(state[i], 6) ^ (key[!i][6] = WHIRLPOOL_XOR(key[i], 6)); + state[!i][7] = WHIRLPOOL_XOR(state[i], 7) ^ (key[!i][7] = WHIRLPOOL_XOR(key[i], 7)); } /* Compression. */ - block_xor (context->hash_state, data_block, i); - block_xor (context->hash_state, state, i); + block_xor (context->hash_state, state[0], i); return /*burn_stack*/ 4 * sizeof(whirlpool_block_t) + 2 * sizeof(int) + 4 * sizeof(void*); ____________________________________________________________ FREE ONLINE PHOTOSHARING - Share your photos online with your friends and family! Visit http://www.inbox.com/photosharing to find out more! From cvs at cvs.gnupg.org Fri Aug 29 14:54:15 2014 From: cvs at cvs.gnupg.org (by Werner Koch) Date: Fri, 29 Aug 2014 14:54:15 +0200 Subject: [git] GCRYPT - branch, master, updated. libgcrypt-1.6.0-109-gdb3c028 Message-ID: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The GNU crypto library". The branch, master has been updated via db3c0286bf159568aa315d15f9708fe2de02b022 (commit) from e606d5f1bada1f2d21faeedd3fa2cf2dca7b274c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit db3c0286bf159568aa315d15f9708fe2de02b022 Author: Werner Koch Date: Fri Aug 29 14:54:11 2014 +0200 mpi: Re-indent longlong.h. -- Indenting the cpp statements should make longlong.h better readable. diff --git a/mpi/longlong.h b/mpi/longlong.h index 4f33937..db98e47 100644 --- a/mpi/longlong.h +++ b/mpi/longlong.h @@ -1,5 +1,6 @@ /* longlong.h -- definitions for mixed size 32/64 bit arithmetic. - Note: I added some stuff for use with gnupg + Note: This is the Libgcrypt version + Copyright (C) 1991, 1992, 1993, 1994, 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2011 Free Software Foundation, Inc. @@ -41,7 +42,7 @@ MA 02111-1307, USA. */ /* This is used to make sure no undesirable sharing between different libraries that use this file takes place. */ #ifndef __MPN -#define __MPN(x) __##x +# define __MPN(x) __##x #endif /* Define auxiliary asm macros. @@ -102,19 +103,22 @@ MA 02111-1307, USA. */ /* We sometimes need to clobber "cc" with gcc2, but that would not be understood by gcc1. Use cpp to avoid major code duplication. */ #if __GNUC__ < 2 -#define __CLOBBER_CC -#define __AND_CLOBBER_CC +# define __CLOBBER_CC +# define __AND_CLOBBER_CC #else /* __GNUC__ >= 2 */ -#define __CLOBBER_CC : "cc" -#define __AND_CLOBBER_CC , "cc" +# define __CLOBBER_CC : "cc" +# define __AND_CLOBBER_CC , "cc" #endif /* __GNUC__ < 2 */ +/*************************************** + **** Begin CPU Specific Versions **** + ***************************************/ /*************************************** ************** A29K ***************** ***************************************/ #if (defined (__a29k__) || defined (_AM29K)) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add %1,%4,%5\n" \ "addc %0,%2,%3" \ : "=r" ((USItype)(sh)), \ @@ -123,7 +127,7 @@ MA 02111-1307, USA. */ "rI" ((USItype)(bh)), \ "%r" ((USItype)(al)), \ "rI" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub %1,%4,%5\n" \ "subc %0,%2,%3" \ : "=r" ((USItype)(sh)), \ @@ -132,7 +136,7 @@ MA 02111-1307, USA. */ "rI" ((USItype)(bh)), \ "r" ((USItype)(al)), \ "rI" ((USItype)(bl))) -#define umul_ppmm(xh, xl, m0, m1) \ +# define umul_ppmm(xh, xl, m0, m1) \ do { \ USItype __m0 = (m0), __m1 = (m1); \ __asm__ ("multiplu %0,%1,%2" \ @@ -144,23 +148,23 @@ MA 02111-1307, USA. */ : "r" (__m0), \ "r" (__m1)); \ } while (0) -#define udiv_qrnnd(q, r, n1, n0, d) \ +# define udiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("dividu %0,%3,%4" \ : "=r" ((USItype)(q)), \ "=q" ((USItype)(r)) \ : "1" ((USItype)(n1)), \ "r" ((USItype)(n0)), \ "r" ((USItype)(d))) -#define count_leading_zeros(count, x) \ +# define count_leading_zeros(count, x) \ __asm__ ("clz %0,%1" \ : "=r" ((USItype)(count)) \ : "r" ((USItype)(x))) -#define COUNT_LEADING_ZEROS_0 32 +# define COUNT_LEADING_ZEROS_0 32 #endif /* __a29k__ */ #if defined (__alpha) && W_TYPE_SIZE == 64 -#define umul_ppmm(ph, pl, m0, m1) \ +# define umul_ppmm(ph, pl, m0, m1) \ do { \ UDItype __m0 = (m0), __m1 = (m1); \ __asm__ ("umulh %r1,%2,%0" \ @@ -169,16 +173,16 @@ MA 02111-1307, USA. */ "rI" (__m1)); \ (pl) = __m0 * __m1; \ } while (0) -#define UMUL_TIME 46 -#ifndef LONGLONG_STANDALONE -#define udiv_qrnnd(q, r, n1, n0, d) \ +# define UMUL_TIME 46 +# ifndef LONGLONG_STANDALONE +# define udiv_qrnnd(q, r, n1, n0, d) \ do { UDItype __r; \ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ (r) = __r; \ } while (0) extern UDItype __udiv_qrnnd (); -#define UDIV_TIME 220 -#endif /* LONGLONG_STANDALONE */ +# define UDIV_TIME 220 +# endif /* !LONGLONG_STANDALONE */ #endif /* __alpha */ /*************************************** @@ -187,30 +191,31 @@ extern UDItype __udiv_qrnnd (); #if defined (__arm__) && W_TYPE_SIZE == 32 && \ (!defined (__thumb__) || defined (__thumb2__)) /* The __ARM_ARCH define is provided by gcc 4.8. Construct it otherwise. */ -#ifndef __ARM_ARCH -# ifdef __ARM_ARCH_2__ -# define __ARM_ARCH 2 -# elif defined (__ARM_ARCH_3__) || defined (__ARM_ARCH_3M__) -# define __ARM_ARCH 3 -# elif defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__) -# define __ARM_ARCH 4 -# elif defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5E__) \ - || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \ - || defined(__ARM_ARCH_5TEJ__) -# define __ARM_ARCH 5 -# elif defined (__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ - || defined (__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \ - || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) -# define __ARM_ARCH 6 -# elif defined (__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ - || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \ - || defined(__ARM_ARCH_7EM__) -# define __ARM_ARCH 7 -# else +# ifndef __ARM_ARCH +# ifdef __ARM_ARCH_2__ +# define __ARM_ARCH 2 +# elif defined (__ARM_ARCH_3__) || defined (__ARM_ARCH_3M__) +# define __ARM_ARCH 3 +# elif defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__) +# define __ARM_ARCH 4 +# elif defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5E__) \ + || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \ + || defined(__ARM_ARCH_5TEJ__) +# define __ARM_ARCH 5 +# elif defined (__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ + || defined (__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \ + || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__) +# define __ARM_ARCH 6 +# elif defined (__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \ + || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \ + || defined(__ARM_ARCH_7EM__) +# define __ARM_ARCH 7 +# else /* could not detect? */ -# endif -#endif -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# endif +# endif /* !__ARM_ARCH */ + +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("adds %1, %4, %5\n" \ "adc %0, %2, %3" \ : "=r" ((sh)), \ @@ -219,7 +224,7 @@ extern UDItype __udiv_qrnnd (); "rI" ((USItype)(bh)), \ "%r" ((USItype)(al)), \ "rI" ((USItype)(bl)) __CLOBBER_CC) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subs %1, %4, %5\n" \ "sbc %0, %2, %3" \ : "=r" ((sh)), \ @@ -228,8 +233,8 @@ extern UDItype __udiv_qrnnd (); "rI" ((USItype)(bh)), \ "r" ((USItype)(al)), \ "rI" ((USItype)(bl)) __CLOBBER_CC) -#if (defined __ARM_ARCH && __ARM_ARCH <= 3) -#define umul_ppmm(xh, xl, a, b) \ +# if (defined __ARM_ARCH && __ARM_ARCH <= 3) +# define umul_ppmm(xh, xl, a, b) \ __asm__ ("@ Inlined umul_ppmm\n" \ "mov %|r0, %2, lsr #16 @ AAAA\n" \ "mov %|r2, %3, lsr #16 @ BBBB\n" \ @@ -248,30 +253,30 @@ extern UDItype __udiv_qrnnd (); : "r" ((USItype)(a)), \ "r" ((USItype)(b)) \ : "r0", "r1", "r2" __AND_CLOBBER_CC) -#else /* __ARM_ARCH >= 4 */ -#define umul_ppmm(xh, xl, a, b) \ +# else /* __ARM_ARCH >= 4 */ +# define umul_ppmm(xh, xl, a, b) \ __asm__ ("@ Inlined umul_ppmm\n" \ "umull %1, %0, %2, %3" \ : "=&r" ((xh)), \ "=r" ((xl)) \ : "r" ((USItype)(a)), \ "r" ((USItype)(b))) -#endif /* __ARM_ARCH >= 4 */ -#define UMUL_TIME 20 -#define UDIV_TIME 100 -#if (defined __ARM_ARCH && __ARM_ARCH >= 5) -#define count_leading_zeros(count, x) \ +# endif /* __ARM_ARCH >= 4 */ +# define UMUL_TIME 20 +# define UDIV_TIME 100 +# if (defined __ARM_ARCH && __ARM_ARCH >= 5) +# define count_leading_zeros(count, x) \ __asm__ ("clz %0, %1" \ : "=r" ((count)) \ : "r" ((USItype)(x))) -#endif /* __ARM_ARCH >= 5 */ +# endif /* __ARM_ARCH >= 5 */ #endif /* __arm__ */ /*************************************** ********** ARM64 / Aarch64 ********** ***************************************/ #if defined(__aarch64__) && W_TYPE_SIZE == 64 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("adds %1, %4, %5\n" \ "adc %0, %2, %3\n" \ : "=r" ((sh)), \ @@ -280,7 +285,7 @@ extern UDItype __udiv_qrnnd (); "r" ((UDItype)(bh)), \ "r" ((UDItype)(al)), \ "r" ((UDItype)(bl)) __CLOBBER_CC) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subs %1, %4, %5\n" \ "sbc %0, %2, %3\n" \ : "=r" ((sh)), \ @@ -289,7 +294,7 @@ extern UDItype __udiv_qrnnd (); "r" ((UDItype)(bh)), \ "r" ((UDItype)(al)), \ "r" ((UDItype)(bl)) __CLOBBER_CC) -#define umul_ppmm(ph, pl, m0, m1) \ +# define umul_ppmm(ph, pl, m0, m1) \ do { \ UDItype __m0 = (m0), __m1 = (m1), __ph; \ (pl) = __m0 * __m1; \ @@ -299,7 +304,7 @@ extern UDItype __udiv_qrnnd (); "r" (__m1)); \ (ph) = __ph; \ } while (0) -#define count_leading_zeros(count, x) \ +# define count_leading_zeros(count, x) \ __asm__ ("clz %0, %1\n" \ : "=r" ((count)) \ : "r" ((UDItype)(x))) @@ -309,7 +314,7 @@ extern UDItype __udiv_qrnnd (); ************** CLIPPER ************** ***************************************/ #if defined (__clipper__) && W_TYPE_SIZE == 32 -#define umul_ppmm(w1, w0, u, v) \ +# define umul_ppmm(w1, w0, u, v) \ ({union {UDItype __ll; \ struct {USItype __l, __h;} __i; \ } __xx; \ @@ -318,7 +323,7 @@ extern UDItype __udiv_qrnnd (); : "%0" ((USItype)(u)), \ "r" ((USItype)(v))); \ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) -#define smul_ppmm(w1, w0, u, v) \ +# define smul_ppmm(w1, w0, u, v) \ ({union {DItype __ll; \ struct {SItype __l, __h;} __i; \ } __xx; \ @@ -327,7 +332,7 @@ extern UDItype __udiv_qrnnd (); : "%0" ((SItype)(u)), \ "r" ((SItype)(v))); \ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) -#define __umulsidi3(u, v) \ +# define __umulsidi3(u, v) \ ({UDItype __w; \ __asm__ ("mulwux %2,%0" \ : "=r" (__w) \ @@ -341,7 +346,7 @@ extern UDItype __udiv_qrnnd (); ************** GMICRO *************** ***************************************/ #if defined (__gmicro__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add.w %5,%1\n" \ "addx %3,%0" \ : "=g" ((USItype)(sh)), \ @@ -350,7 +355,7 @@ extern UDItype __udiv_qrnnd (); "g" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ "g" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub.w %5,%1\n" \ "subx %3,%0" \ : "=g" ((USItype)(sh)), \ @@ -359,20 +364,20 @@ extern UDItype __udiv_qrnnd (); "g" ((USItype)(bh)), \ "1" ((USItype)(al)), \ "g" ((USItype)(bl))) -#define umul_ppmm(ph, pl, m0, m1) \ +# define umul_ppmm(ph, pl, m0, m1) \ __asm__ ("mulx %3,%0,%1" \ : "=g" ((USItype)(ph)), \ "=r" ((USItype)(pl)) \ : "%0" ((USItype)(m0)), \ "g" ((USItype)(m1))) -#define udiv_qrnnd(q, r, nh, nl, d) \ +# define udiv_qrnnd(q, r, nh, nl, d) \ __asm__ ("divx %4,%0,%1" \ : "=g" ((USItype)(q)), \ "=r" ((USItype)(r)) \ : "1" ((USItype)(nh)), \ "0" ((USItype)(nl)), \ "g" ((USItype)(d))) -#define count_leading_zeros(count, x) \ +# define count_leading_zeros(count, x) \ __asm__ ("bsch/1 %1,%0" \ : "=g" (count) \ : "g" ((USItype)(x)), \ @@ -384,7 +389,7 @@ extern UDItype __udiv_qrnnd (); ************** HPPA ***************** ***************************************/ #if defined (__hppa) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ (" add %4,%5,%1\n" \ " addc %2,%3,%0" \ : "=r" ((USItype)(sh)), \ @@ -393,7 +398,7 @@ extern UDItype __udiv_qrnnd (); "rM" ((USItype)(bh)), \ "%rM" ((USItype)(al)), \ "rM" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ (" sub %4,%5,%1\n" \ " subb %2,%3,%0" \ : "=r" ((USItype)(sh)), \ @@ -402,8 +407,8 @@ extern UDItype __udiv_qrnnd (); "rM" ((USItype)(bh)), \ "rM" ((USItype)(al)), \ "rM" ((USItype)(bl))) -#if defined (_PA_RISC1_1) -#define umul_ppmm(wh, wl, u, v) \ +# if defined (_PA_RISC1_1) +# define umul_ppmm(wh, wl, u, v) \ do { \ union {UDItype __ll; \ struct {USItype __h, __l;} __i; \ @@ -415,21 +420,21 @@ extern UDItype __udiv_qrnnd (); (wh) = __xx.__i.__h; \ (wl) = __xx.__i.__l; \ } while (0) -#define UMUL_TIME 8 -#define UDIV_TIME 60 -#else -#define UMUL_TIME 40 -#define UDIV_TIME 80 -#endif -#ifndef LONGLONG_STANDALONE -#define udiv_qrnnd(q, r, n1, n0, d) \ +# define UMUL_TIME 8 +# define UDIV_TIME 60 +# else +# define UMUL_TIME 40 +# define UDIV_TIME 80 +# endif +# ifndef LONGLONG_STANDALONE +# define udiv_qrnnd(q, r, n1, n0, d) \ do { USItype __r; \ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ (r) = __r; \ } while (0) extern USItype __udiv_qrnnd (); -#endif /* LONGLONG_STANDALONE */ -#define count_leading_zeros(count, x) \ +# endif /* !LONGLONG_STANDALONE */ +# define count_leading_zeros(count, x) \ do { \ USItype __tmp; \ __asm__ ( \ @@ -457,7 +462,7 @@ extern USItype __udiv_qrnnd (); ************** I370 ***************** ***************************************/ #if (defined (__i370__) || defined (__mvs__)) && W_TYPE_SIZE == 32 -#define umul_ppmm(xh, xl, m0, m1) \ +# define umul_ppmm(xh, xl, m0, m1) \ do { \ union {UDItype __ll; \ struct {USItype __h, __l;} __i; \ @@ -472,7 +477,7 @@ extern USItype __udiv_qrnnd (); (xh) += ((((SItype) __m0 >> 31) & __m1) \ + (((SItype) __m1 >> 31) & __m0)); \ } while (0) -#define smul_ppmm(xh, xl, m0, m1) \ +# define smul_ppmm(xh, xl, m0, m1) \ do { \ union {DItype __ll; \ struct {USItype __h, __l;} __i; \ @@ -484,7 +489,7 @@ extern USItype __udiv_qrnnd (); "r" (m1)); \ (xh) = __xx.__i.__h; (xl) = __xx.__i.__l; \ } while (0) -#define sdiv_qrnnd(q, r, n1, n0, d) \ +# define sdiv_qrnnd(q, r, n1, n0, d) \ do { \ union {DItype __ll; \ struct {USItype __h, __l;} __i; \ @@ -502,7 +507,7 @@ extern USItype __udiv_qrnnd (); ************** I386 ***************** ***************************************/ #if (defined (__i386__) || defined (__i486__)) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addl %5,%1\n" \ "adcl %3,%0" \ : "=r" ((sh)), \ @@ -512,7 +517,7 @@ extern USItype __udiv_qrnnd (); "%1" ((USItype)(al)), \ "g" ((USItype)(bl)) \ __CLOBBER_CC) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subl %5,%1\n" \ "sbbl %3,%0" \ : "=r" ((sh)), \ @@ -522,14 +527,14 @@ extern USItype __udiv_qrnnd (); "1" ((USItype)(al)), \ "g" ((USItype)(bl)) \ __CLOBBER_CC) -#define umul_ppmm(w1, w0, u, v) \ +# define umul_ppmm(w1, w0, u, v) \ __asm__ ("mull %3" \ : "=a" ((w0)), \ "=d" ((w1)) \ : "%0" ((USItype)(u)), \ "rm" ((USItype)(v)) \ __CLOBBER_CC) -#define udiv_qrnnd(q, r, n1, n0, d) \ +# define udiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("divl %4" \ : "=a" ((q)), \ "=d" ((r)) \ @@ -537,7 +542,7 @@ extern USItype __udiv_qrnnd (); "1" ((USItype)(n1)), \ "rm" ((USItype)(d)) \ __CLOBBER_CC) -#define count_leading_zeros(count, x) \ +# define count_leading_zeros(count, x) \ do { \ USItype __cbtmp; \ __asm__ ("bsrl %1,%0" \ @@ -545,21 +550,21 @@ extern USItype __udiv_qrnnd (); __CLOBBER_CC); \ (count) = __cbtmp ^ 31; \ } while (0) -#define count_trailing_zeros(count, x) \ +# define count_trailing_zeros(count, x) \ __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)) __CLOBBER_CC) -#ifndef UMUL_TIME -#define UMUL_TIME 40 -#endif -#ifndef UDIV_TIME -#define UDIV_TIME 40 -#endif +# ifndef UMUL_TIME +# define UMUL_TIME 40 +# endif +# ifndef UDIV_TIME +# define UDIV_TIME 40 +# endif #endif /* 80x86 */ /*************************************** *********** AMD64 / x86-64 ************ ***************************************/ #if defined(__x86_64) && W_TYPE_SIZE == 64 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addq %5,%1\n" \ "adcq %3,%0" \ : "=r" ((sh)), \ @@ -569,7 +574,7 @@ extern USItype __udiv_qrnnd (); "1" ((UDItype)(al)), \ "g" ((UDItype)(bl)) \ __CLOBBER_CC) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subq %5,%1\n" \ "sbbq %3,%0" \ : "=r" ((sh)), \ @@ -579,14 +584,14 @@ extern USItype __udiv_qrnnd (); "1" ((UDItype)(al)), \ "g" ((UDItype)(bl)) \ __CLOBBER_CC) -#define umul_ppmm(w1, w0, u, v) \ +# define umul_ppmm(w1, w0, u, v) \ __asm__ ("mulq %3" \ : "=a" ((w0)), \ "=d" ((w1)) \ : "0" ((UDItype)(u)), \ "rm" ((UDItype)(v)) \ __CLOBBER_CC) -#define udiv_qrnnd(q, r, n1, n0, d) \ +# define udiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("divq %4" \ : "=a" ((q)), \ "=d" ((r)) \ @@ -594,7 +599,7 @@ extern USItype __udiv_qrnnd (); "1" ((UDItype)(n1)), \ "rm" ((UDItype)(d)) \ __CLOBBER_CC) -#define count_leading_zeros(count, x) \ +# define count_leading_zeros(count, x) \ do { \ UDItype __cbtmp; \ __asm__ ("bsrq %1,%0" \ @@ -602,7 +607,7 @@ extern USItype __udiv_qrnnd (); __CLOBBER_CC); \ (count) = __cbtmp ^ 63; \ } while (0) -#define count_trailing_zeros(count, x) \ +# define count_trailing_zeros(count, x) \ do { \ UDItype __cbtmp; \ __asm__ ("bsfq %1,%0" \ @@ -610,12 +615,12 @@ extern USItype __udiv_qrnnd (); __CLOBBER_CC); \ (count) = __cbtmp; \ } while (0) -#ifndef UMUL_TIME -#define UMUL_TIME 40 -#endif -#ifndef UDIV_TIME -#define UDIV_TIME 40 -#endif +# ifndef UMUL_TIME +# define UMUL_TIME 40 +# endif +# ifndef UDIV_TIME +# define UDIV_TIME 40 +# endif #endif /* __x86_64 */ @@ -623,7 +628,7 @@ extern USItype __udiv_qrnnd (); ************** I860 ***************** ***************************************/ #if defined (__i860__) && W_TYPE_SIZE == 32 -#define rshift_rhlc(r,h,l,c) \ +# define rshift_rhlc(r,h,l,c) \ __asm__ ("shr %3,r0,r0\n" \ "shrd %1,%2,%0" \ "=r" (r) : "r" (h), "r" (l), "rn" (c)) @@ -633,7 +638,7 @@ extern USItype __udiv_qrnnd (); ************** I960 ***************** ***************************************/ #if defined (__i960__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("cmpo 1,0\n" \ "addc %5,%4,%1\n" \ "addc %3,%2,%0" \ @@ -643,7 +648,7 @@ extern USItype __udiv_qrnnd (); "dI" ((USItype)(bh)), \ "%dI" ((USItype)(al)), \ "dI" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("cmpo 0,0\n" \ "subc %5,%4,%1\n" \ "subc %3,%2,%0" \ @@ -653,7 +658,7 @@ extern USItype __udiv_qrnnd (); "dI" ((USItype)(bh)), \ "dI" ((USItype)(al)), \ "dI" ((USItype)(bl))) -#define umul_ppmm(w1, w0, u, v) \ +# define umul_ppmm(w1, w0, u, v) \ ({union {UDItype __ll; \ struct {USItype __l, __h;} __i; \ } __xx; \ @@ -662,14 +667,14 @@ extern USItype __udiv_qrnnd (); : "%dI" ((USItype)(u)), \ "dI" ((USItype)(v))); \ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) -#define __umulsidi3(u, v) \ +# define __umulsidi3(u, v) \ ({UDItype __w; \ __asm__ ("emul %2,%1,%0" \ : "=d" (__w) \ : "%dI" ((USItype)(u)), \ "dI" ((USItype)(v))); \ __w; }) -#define udiv_qrnnd(q, r, nh, nl, d) \ +# define udiv_qrnnd(q, r, nh, nl, d) \ do { \ union {UDItype __ll; \ struct {USItype __l, __h;} __i; \ @@ -681,7 +686,7 @@ extern USItype __udiv_qrnnd (); "dI" ((USItype)(d))); \ (r) = __rq.__i.__l; (q) = __rq.__i.__h; \ } while (0) -#define count_leading_zeros(count, x) \ +# define count_leading_zeros(count, x) \ do { \ USItype __cbtmp; \ __asm__ ("scanbit %1,%0" \ @@ -689,9 +694,9 @@ extern USItype __udiv_qrnnd (); : "r" ((USItype)(x))); \ (count) = __cbtmp ^ 31; \ } while (0) -#define COUNT_LEADING_ZEROS_0 (-32) /* sic */ -#if defined (__i960mx) /* what is the proper symbol to test??? */ -#define rshift_rhlc(r,h,l,c) \ +# define COUNT_LEADING_ZEROS_0 (-32) /* sic */ +# if defined (__i960mx) /* what is the proper symbol to test??? */ +# define rshift_rhlc(r,h,l,c) \ do { \ union {UDItype __ll; \ struct {USItype __l, __h;} __i; \ @@ -700,15 +705,16 @@ extern USItype __udiv_qrnnd (); __asm__ ("shre %2,%1,%0" \ : "=d" (r) : "dI" (__nn.__ll), "dI" (c)); \ } -#endif /* i960mx */ +# endif /* i960mx */ #endif /* i960 */ /*************************************** ************** 68000 **************** ***************************************/ -#if (defined (__mc68000__) || defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +#if (defined (__mc68000__) || defined (__mc68020__) \ + || defined (__NeXT__) || defined(mc68020)) && W_TYPE_SIZE == 32 +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add%.l %5,%1\n" \ "addx%.l %3,%0" \ : "=d" ((USItype)(sh)), \ @@ -717,7 +723,7 @@ extern USItype __udiv_qrnnd (); "d" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ "g" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub%.l %5,%1\n" \ "subx%.l %3,%0" \ : "=d" ((USItype)(sh)), \ @@ -726,36 +732,36 @@ extern USItype __udiv_qrnnd (); "d" ((USItype)(bh)), \ "1" ((USItype)(al)), \ "g" ((USItype)(bl))) -#if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) -#define umul_ppmm(w1, w0, u, v) \ +# if (defined (__mc68020__) || defined (__NeXT__) || defined(mc68020)) +# define umul_ppmm(w1, w0, u, v) \ __asm__ ("mulu%.l %3,%1:%0" \ : "=d" ((USItype)(w0)), \ "=d" ((USItype)(w1)) \ : "%0" ((USItype)(u)), \ "dmi" ((USItype)(v))) -#define UMUL_TIME 45 -#define udiv_qrnnd(q, r, n1, n0, d) \ +# define UMUL_TIME 45 +# define udiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("divu%.l %4,%1:%0" \ : "=d" ((USItype)(q)), \ "=d" ((USItype)(r)) \ : "0" ((USItype)(n0)), \ "1" ((USItype)(n1)), \ "dmi" ((USItype)(d))) -#define UDIV_TIME 90 -#define sdiv_qrnnd(q, r, n1, n0, d) \ +# define UDIV_TIME 90 +# define sdiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("divs%.l %4,%1:%0" \ : "=d" ((USItype)(q)), \ "=d" ((USItype)(r)) \ : "0" ((USItype)(n0)), \ "1" ((USItype)(n1)), \ "dmi" ((USItype)(d))) -#define count_leading_zeros(count, x) \ +# define count_leading_zeros(count, x) \ __asm__ ("bfffo %1{%b2:%b2},%0" \ : "=d" ((USItype)(count)) \ : "od" ((USItype)(x)), "n" (0)) -#define COUNT_LEADING_ZEROS_0 32 -#else /* not mc68020 */ -#define umul_ppmm(xh, xl, a, b) \ +# define COUNT_LEADING_ZEROS_0 32 +# else /* not mc68020 */ +# define umul_ppmm(xh, xl, a, b) \ do { USItype __umul_tmp1, __umul_tmp2; \ __asm__ ("| Inlined umul_ppmm \n" \ " move%.l %5,%3 \n" \ @@ -783,9 +789,9 @@ extern USItype __udiv_qrnnd (); "=d" (__umul_tmp1), "=&d" (__umul_tmp2) \ : "%2" ((USItype)(a)), "d" ((USItype)(b))); \ } while (0) -#define UMUL_TIME 100 -#define UDIV_TIME 400 -#endif /* not mc68020 */ +# define UMUL_TIME 100 +# define UDIV_TIME 400 +# endif /* not mc68020 */ #endif /* mc68000 */ @@ -793,7 +799,7 @@ extern USItype __udiv_qrnnd (); ************** 88000 **************** ***************************************/ #if defined (__m88000__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addu.co %1,%r4,%r5\n" \ "addu.ci %0,%r2,%r3" \ : "=r" ((USItype)(sh)), \ @@ -802,7 +808,7 @@ extern USItype __udiv_qrnnd (); "rJ" ((USItype)(bh)), \ "%rJ" ((USItype)(al)), \ "rJ" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subu.co %1,%r4,%r5\n" \ "subu.ci %0,%r2,%r3" \ : "=r" ((USItype)(sh)), \ @@ -811,7 +817,7 @@ extern USItype __udiv_qrnnd (); "rJ" ((USItype)(bh)), \ "rJ" ((USItype)(al)), \ "rJ" ((USItype)(bl))) -#define count_leading_zeros(count, x) \ +# define count_leading_zeros(count, x) \ do { \ USItype __cbtmp; \ __asm__ ("ff1 %0,%1" \ @@ -819,9 +825,9 @@ extern USItype __udiv_qrnnd (); : "r" ((USItype)(x))); \ (count) = __cbtmp ^ 31; \ } while (0) -#define COUNT_LEADING_ZEROS_0 63 /* sic */ -#if defined (__m88110__) -#define umul_ppmm(wh, wl, u, v) \ +# define COUNT_LEADING_ZEROS_0 63 /* sic */ +# if defined (__m88110__) +# define umul_ppmm(wh, wl, u, v) \ do { \ union {UDItype __ll; \ struct {USItype __h, __l;} __i; \ @@ -830,7 +836,7 @@ extern USItype __udiv_qrnnd (); (wh) = __x.__i.__h; \ (wl) = __x.__i.__l; \ } while (0) -#define udiv_qrnnd(q, r, n1, n0, d) \ +# define udiv_qrnnd(q, r, n1, n0, d) \ ({union {UDItype __ll; \ struct {USItype __h, __l;} __i; \ } __x, __q; \ @@ -838,36 +844,36 @@ extern USItype __udiv_qrnnd (); __asm__ ("divu.d %0,%1,%2" \ : "=r" (__q.__ll) : "r" (__x.__ll), "r" (d)); \ (r) = (n0) - __q.__l * (d); (q) = __q.__l; }) -#define UMUL_TIME 5 -#define UDIV_TIME 25 -#else -#define UMUL_TIME 17 -#define UDIV_TIME 150 -#endif /* __m88110__ */ +# define UMUL_TIME 5 +# define UDIV_TIME 25 +# else +# define UMUL_TIME 17 +# define UDIV_TIME 150 +# endif /* __m88110__ */ #endif /* __m88000__ */ /*************************************** ************** MIPS ***************** ***************************************/ #if defined (__mips__) && W_TYPE_SIZE == 32 -#if defined (__clang__) || (__GNUC__ >= 5) || (__GNUC__ == 4 && \ +# if defined (__clang__) || (__GNUC__ >= 5) || (__GNUC__ == 4 && \ __GNUC_MINOR__ >= 4) -#define umul_ppmm(w1, w0, u, v) \ +# define umul_ppmm(w1, w0, u, v) \ do { \ UDItype _r; \ _r = (UDItype) u * v; \ (w1) = _r >> 32; \ (w0) = (USItype) _r; \ } while (0) -#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 -#define umul_ppmm(w1, w0, u, v) \ +# elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +# define umul_ppmm(w1, w0, u, v) \ __asm__ ("multu %2,%3" \ : "=l" ((USItype)(w0)), \ "=h" ((USItype)(w1)) \ : "d" ((USItype)(u)), \ "d" ((USItype)(v))) -#else -#define umul_ppmm(w1, w0, u, v) \ +# else +# define umul_ppmm(w1, w0, u, v) \ __asm__ ("multu %2,%3 \n" \ "mflo %0 \n" \ "mfhi %1" \ @@ -875,33 +881,33 @@ extern USItype __udiv_qrnnd (); "=d" ((USItype)(w1)) \ : "d" ((USItype)(u)), \ "d" ((USItype)(v))) -#endif -#define UMUL_TIME 10 -#define UDIV_TIME 100 +# endif +# define UMUL_TIME 10 +# define UDIV_TIME 100 #endif /* __mips__ */ /*************************************** ************** MIPS/64 ************** ***************************************/ #if (defined (__mips) && __mips >= 3) && W_TYPE_SIZE == 64 -#if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) +# if (__GNUC__ >= 5) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4) typedef unsigned int UTItype __attribute__ ((mode (TI))); -#define umul_ppmm(w1, w0, u, v) \ +# define umul_ppmm(w1, w0, u, v) \ do { \ UTItype _r; \ _r = (UTItype) u * v; \ (w1) = _r >> 64; \ (w0) = (UDItype) _r; \ } while (0) -#elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 -#define umul_ppmm(w1, w0, u, v) \ +# elif __GNUC__ > 2 || __GNUC_MINOR__ >= 7 +# define umul_ppmm(w1, w0, u, v) \ __asm__ ("dmultu %2,%3" \ : "=l" ((UDItype)(w0)), \ "=h" ((UDItype)(w1)) \ : "d" ((UDItype)(u)), \ "d" ((UDItype)(v))) -#else -#define umul_ppmm(w1, w0, u, v) \ +# else +# define umul_ppmm(w1, w0, u, v) \ __asm__ ("dmultu %2,%3 \n" \ "mflo %0 \n" \ "mfhi %1" \ @@ -909,9 +915,9 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "=d" ((UDItype)(w1)) \ : "d" ((UDItype)(u)), \ "d" ((UDItype)(v))) -#endif -#define UMUL_TIME 20 -#define UDIV_TIME 140 +# endif +# define UMUL_TIME 20 +# define UDIV_TIME 140 #endif /* __mips__ */ @@ -919,7 +925,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); ************** 32000 **************** ***************************************/ #if defined (__ns32000__) && W_TYPE_SIZE == 32 -#define umul_ppmm(w1, w0, u, v) \ +# define umul_ppmm(w1, w0, u, v) \ ({union {UDItype __ll; \ struct {USItype __l, __h;} __i; \ } __xx; \ @@ -928,14 +934,14 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); : "%0" ((USItype)(u)), \ "g" ((USItype)(v))); \ (w1) = __xx.__i.__h; (w0) = __xx.__i.__l;}) -#define __umulsidi3(u, v) \ +# define __umulsidi3(u, v) \ ({UDItype __w; \ __asm__ ("meid %2,%0" \ : "=g" (__w) \ : "%0" ((USItype)(u)), \ "g" ((USItype)(v))); \ __w; }) -#define udiv_qrnnd(q, r, n1, n0, d) \ +# define udiv_qrnnd(q, r, n1, n0, d) \ ({union {UDItype __ll; \ struct {USItype __l, __h;} __i; \ } __xx; \ @@ -945,7 +951,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); : "0" (__xx.__ll), \ "g" ((USItype)(d))); \ (r) = __xx.__i.__l; (q) = __xx.__i.__h; }) -#define count_trailing_zeros(count,x) \ +# define count_trailing_zeros(count,x) \ do { __asm__ ("ffsd %2,%0" \ : "=r" ((USItype) (count)) \ @@ -959,7 +965,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); ************** PPC ****************** ***************************************/ #if (defined (_ARCH_PPC) || defined (_IBMR2)) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ do { \ if (__builtin_constant_p (bh) && (bh) == 0) \ __asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \ @@ -984,7 +990,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "%r" ((USItype)(al)), \ "rI" ((USItype)(bl))); \ } while (0) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ do { \ if (__builtin_constant_p (ah) && (ah) == 0) \ __asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \ @@ -1023,13 +1029,13 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "rI" ((USItype)(al)), \ "r" ((USItype)(bl))); \ } while (0) -#define count_leading_zeros(count, x) \ +# define count_leading_zeros(count, x) \ __asm__ ("{cntlz|cntlzw} %0,%1" \ : "=r" ((count)) \ : "r" ((USItype)(x))) -#define COUNT_LEADING_ZEROS_0 32 -#if defined (_ARCH_PPC) -#define umul_ppmm(ph, pl, m0, m1) \ +# define COUNT_LEADING_ZEROS_0 32 +# if defined (_ARCH_PPC) +# define umul_ppmm(ph, pl, m0, m1) \ do { \ USItype __m0 = (m0), __m1 = (m1); \ __asm__ ("mulhwu %0,%1,%2" \ @@ -1038,8 +1044,8 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "r" (__m1)); \ (pl) = __m0 * __m1; \ } while (0) -#define UMUL_TIME 15 -#define smul_ppmm(ph, pl, m0, m1) \ +# define UMUL_TIME 15 +# define smul_ppmm(ph, pl, m0, m1) \ do { \ SItype __m0 = (m0), __m1 = (m1); \ __asm__ ("mulhw %0,%1,%2" \ @@ -1048,10 +1054,10 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "r" (__m1)); \ (pl) = __m0 * __m1; \ } while (0) -#define SMUL_TIME 14 -#define UDIV_TIME 120 -#else -#define umul_ppmm(xh, xl, m0, m1) \ +# define SMUL_TIME 14 +# define UDIV_TIME 120 +# else +# define umul_ppmm(xh, xl, m0, m1) \ do { \ USItype __m0 = (m0), __m1 = (m1); \ __asm__ ("mul %0,%2,%3" \ @@ -1062,20 +1068,20 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); (xh) += ((((SItype) __m0 >> 31) & __m1) \ + (((SItype) __m1 >> 31) & __m0)); \ } while (0) -#define UMUL_TIME 8 -#define smul_ppmm(xh, xl, m0, m1) \ +# define UMUL_TIME 8 +# define smul_ppmm(xh, xl, m0, m1) \ __asm__ ("mul %0,%2,%3" \ : "=r" ((SItype)(xh)), \ "=q" ((SItype)(xl)) \ : "r" (m0), \ "r" (m1)) -#define SMUL_TIME 4 -#define sdiv_qrnnd(q, r, nh, nl, d) \ +# define SMUL_TIME 4 +# define sdiv_qrnnd(q, r, nh, nl, d) \ __asm__ ("div %0,%2,%4" \ : "=r" ((SItype)(q)), "=q" ((SItype)(r)) \ : "r" ((SItype)(nh)), "1" ((SItype)(nl)), "r" ((SItype)(d))) -#define UDIV_TIME 100 -#endif +# define UDIV_TIME 100 +# endif #endif /* Power architecture variants. */ /* Powerpc 64 bit support taken from gmp-4.1.2. */ @@ -1140,7 +1146,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); ************** PYR ****************** ***************************************/ #if defined (__pyr__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addw %5,%1 \n" \ "addwc %3,%0" \ : "=r" ((USItype)(sh)), \ @@ -1149,7 +1155,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "g" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ "g" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subw %5,%1 \n" \ "subwb %3,%0" \ : "=r" ((USItype)(sh)), \ @@ -1159,7 +1165,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "1" ((USItype)(al)), \ "g" ((USItype)(bl))) /* This insn works on Pyramids with AP, XP, or MI CPUs, but not with SP. */ -#define umul_ppmm(w1, w0, u, v) \ +# define umul_ppmm(w1, w0, u, v) \ ({union {UDItype __ll; \ struct {USItype __h, __l;} __i; \ } __xx; \ @@ -1176,7 +1182,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); ************** RT/ROMP ************** ***************************************/ #if defined (__ibm032__) /* RT/ROMP */ && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("a %1,%5 \n" \ "ae %0,%3" \ : "=r" ((USItype)(sh)), \ @@ -1185,7 +1191,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "r" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ "r" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("s %1,%5\n" \ "se %0,%3" \ : "=r" ((USItype)(sh)), \ @@ -1194,7 +1200,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "r" ((USItype)(bh)), \ "1" ((USItype)(al)), \ "r" ((USItype)(bl))) -#define umul_ppmm(ph, pl, m0, m1) \ +# define umul_ppmm(ph, pl, m0, m1) \ do { \ USItype __m0 = (m0), __m1 = (m1); \ __asm__ ( \ @@ -1226,9 +1232,9 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); (ph) += ((((SItype) __m0 >> 31) & __m1) \ + (((SItype) __m1 >> 31) & __m0)); \ } while (0) -#define UMUL_TIME 20 -#define UDIV_TIME 200 -#define count_leading_zeros(count, x) \ +# define UMUL_TIME 20 +# define UDIV_TIME 200 +# define count_leading_zeros(count, x) \ do { \ if ((x) >= 0x10000) \ __asm__ ("clz %0,%1" \ @@ -1250,7 +1256,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); ***************************************/ #if (defined (__sh2__) || defined(__sh3__) || defined(__SH4__) ) \ && W_TYPE_SIZE == 32 -#define umul_ppmm(w1, w0, u, v) \ +# define umul_ppmm(w1, w0, u, v) \ __asm__ ( \ "dmulu.l %2,%3\n" \ "sts macl,%1\n" \ @@ -1260,14 +1266,14 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); : "r" ((USItype)(u)), \ "r" ((USItype)(v)) \ : "macl", "mach") -#define UMUL_TIME 5 +# define UMUL_TIME 5 #endif /*************************************** ************** SPARC **************** ***************************************/ #if defined (__sparc__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addcc %r4,%5,%1\n" \ "addx %r2,%3,%0" \ : "=r" ((USItype)(sh)), \ @@ -1277,7 +1283,7 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "%rJ" ((USItype)(al)), \ "rI" ((USItype)(bl)) \ __CLOBBER_CC) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subcc %r4,%5,%1\n" \ "subx %r2,%3,%0" \ : "=r" ((USItype)(sh)), \ @@ -1287,20 +1293,20 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "rJ" ((USItype)(al)), \ "rI" ((USItype)(bl)) \ __CLOBBER_CC) -#if defined (__sparc_v8__) +# if defined (__sparc_v8__) /* Don't match immediate range because, 1) it is not often useful, 2) the 'I' flag thinks of the range as a 13 bit signed interval, while we want to match a 13 bit interval, sign extended to 32 bits, but INTERPRETED AS UNSIGNED. */ -#define umul_ppmm(w1, w0, u, v) \ +# define umul_ppmm(w1, w0, u, v) \ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ : "=r" ((USItype)(w1)), \ "=r" ((USItype)(w0)) \ : "r" ((USItype)(u)), \ "r" ((USItype)(v))) -#define UMUL_TIME 5 -#ifndef SUPERSPARC /* SuperSPARC's udiv only handles 53 bit dividends */ -#define udiv_qrnnd(q, r, n1, n0, d) \ +# define UMUL_TIME 5 +# ifndef SUPERSPARC /* SuperSPARC's udiv only handles 53 bit dividends */ +# define udiv_qrnnd(q, r, n1, n0, d) \ do { \ USItype __q; \ __asm__ ("mov %1,%%y;nop;nop;nop;udiv %2,%3,%0" \ @@ -1311,20 +1317,20 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); (r) = (n0) - __q * (d); \ (q) = __q; \ } while (0) -#define UDIV_TIME 25 -#endif /* SUPERSPARC */ -#else /* ! __sparc_v8__ */ -#if defined (__sparclite__) +# define UDIV_TIME 25 +# endif /*!SUPERSPARC */ +# else /* ! __sparc_v8__ */ +# if defined (__sparclite__) /* This has hardware multiply but not divide. It also has two additional instructions scan (ffs from high bit) and divscc. */ -#define umul_ppmm(w1, w0, u, v) \ +# define umul_ppmm(w1, w0, u, v) \ __asm__ ("umul %2,%3,%1;rd %%y,%0" \ : "=r" ((USItype)(w1)), \ "=r" ((USItype)(w0)) \ : "r" ((USItype)(u)), \ "r" ((USItype)(v))) -#define UMUL_TIME 5 -#define udiv_qrnnd(q, r, n1, n0, d) \ +# define UMUL_TIME 5 +# define udiv_qrnnd(q, r, n1, n0, d) \ __asm__ ("! Inlined udiv_qrnnd \n" \ " wr %%g0,%2,%%y ! Not a delayed write for sparclite \n" \ " tst %%g0 \n" \ @@ -1370,19 +1376,19 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); "r" ((USItype)(n0)), \ "rI" ((USItype)(d)) \ : "%g1" __AND_CLOBBER_CC) -#define UDIV_TIME 37 -#define count_leading_zeros(count, x) \ +# define UDIV_TIME 37 +# define count_leading_zeros(count, x) \ __asm__ ("scan %1,0,%0" \ : "=r" ((USItype)(x)) \ : "r" ((USItype)(count))) /* Early sparclites return 63 for an argument of 0, but they warn that future implementations might change this. Therefore, leave COUNT_LEADING_ZEROS_0 undefined. */ -#endif /* __sparclite__ */ -#endif /* __sparc_v8__ */ +# endif /* !__sparclite__ */ +# endif /* !__sparc_v8__ */ /* Default to sparc v7 versions of umul_ppmm and udiv_qrnnd. */ -#ifndef umul_ppmm -#define umul_ppmm(w1, w0, u, v) \ +# ifndef umul_ppmm +# define umul_ppmm(w1, w0, u, v) \ __asm__ ("! Inlined umul_ppmm \n" \ " wr %%g0,%2,%%y ! SPARC has 0-3 delay insn after a wr \n" \ " sra %3,31,%%g2 ! Don't move this insn \n" \ @@ -1428,19 +1434,19 @@ typedef unsigned int UTItype __attribute__ ((mode (TI))); : "%rI" ((USItype)(u)), \ "r" ((USItype)(v)) \ : "%g1", "%g2" __AND_CLOBBER_CC) -#define UMUL_TIME 39 /* 39 instructions */ -#endif -#ifndef udiv_qrnnd -#ifndef LONGLONG_STANDALONE -#define udiv_qrnnd(q, r, n1, n0, d) \ +# define UMUL_TIME 39 /* 39 instructions */ +# endif /* umul_ppmm */ +# ifndef udiv_qrnnd +# ifndef LONGLONG_STANDALONE +# define udiv_qrnnd(q, r, n1, n0, d) \ do { USItype __r; \ (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ (r) = __r; \ } while (0) extern USItype __udiv_qrnnd (); -#define UDIV_TIME 140 -#endif /* LONGLONG_STANDALONE */ -#endif /* udiv_qrnnd */ +# define UDIV_TIME 140 +# endif /* LONGLONG_STANDALONE */ +# endif /* udiv_qrnnd */ #endif /* __sparc__ */ @@ -1448,7 +1454,7 @@ extern USItype __udiv_qrnnd (); ************** VAX ****************** ***************************************/ #if defined (__vax__) && W_TYPE_SIZE == 32 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("addl2 %5,%1\n" \ "adwc %3,%0" \ : "=g" ((USItype)(sh)), \ @@ -1457,7 +1463,7 @@ extern USItype __udiv_qrnnd (); "g" ((USItype)(bh)), \ "%1" ((USItype)(al)), \ "g" ((USItype)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("subl2 %5,%1\n" \ "sbwc %3,%0" \ : "=g" ((USItype)(sh)), \ @@ -1466,7 +1472,7 @@ extern USItype __udiv_qrnnd (); "g" ((USItype)(bh)), \ "1" ((USItype)(al)), \ "g" ((USItype)(bl))) -#define umul_ppmm(xh, xl, m0, m1) \ +# define umul_ppmm(xh, xl, m0, m1) \ do { \ union {UDItype __ll; \ struct {USItype __l, __h;} __i; \ @@ -1480,7 +1486,7 @@ extern USItype __udiv_qrnnd (); (xh) += ((((SItype) __m0 >> 31) & __m1) \ + (((SItype) __m1 >> 31) & __m0)); \ } while (0) -#define sdiv_qrnnd(q, r, n1, n0, d) \ +# define sdiv_qrnnd(q, r, n1, n0, d) \ do { \ union {DItype __ll; \ struct {SItype __l, __h;} __i; \ @@ -1497,7 +1503,7 @@ extern USItype __udiv_qrnnd (); ************** Z8000 **************** ***************************************/ #if defined (__z8000__) && W_TYPE_SIZE == 16 -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ __asm__ ("add %H1,%H5\n\tadc %H0,%H3" \ : "=r" ((unsigned int)(sh)), \ "=&r" ((unsigned int)(sl)) \ @@ -1505,7 +1511,7 @@ extern USItype __udiv_qrnnd (); "r" ((unsigned int)(bh)), \ "%1" ((unsigned int)(al)), \ "rQR" ((unsigned int)(bl))) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ __asm__ ("sub %H1,%H5\n\tsbc %H0,%H3" \ : "=r" ((unsigned int)(sh)), \ "=&r" ((unsigned int)(sl)) \ @@ -1513,7 +1519,7 @@ extern USItype __udiv_qrnnd (); "r" ((unsigned int)(bh)), \ "1" ((unsigned int)(al)), \ "rQR" ((unsigned int)(bl))) -#define umul_ppmm(xh, xl, m0, m1) \ +# define umul_ppmm(xh, xl, m0, m1) \ do { \ union {long int __ll; \ struct {unsigned int __h, __l;} __i; \ @@ -1530,6 +1536,11 @@ extern USItype __udiv_qrnnd (); } while (0) #endif /* __z8000__ */ + +/*************************************** + ***** End CPU Specific Versions ***** + ***************************************/ + #endif /* __GNUC__ */ #endif /* !__riscos__ */ @@ -1538,7 +1549,7 @@ extern USItype __udiv_qrnnd (); *********** Generic Versions ******** ***************************************/ #if !defined (umul_ppmm) && defined (__umulsidi3) -#define umul_ppmm(ph, pl, m0, m1) \ +# define umul_ppmm(ph, pl, m0, m1) \ { \ UDWtype __ll = __umulsidi3 (m0, m1); \ ph = (UWtype) (__ll >> W_TYPE_SIZE); \ @@ -1547,7 +1558,7 @@ extern USItype __udiv_qrnnd (); #endif #if !defined (__umulsidi3) -#define __umulsidi3(u, v) \ +# define __umulsidi3(u, v) \ ({UWtype __hi, __lo; \ umul_ppmm (__hi, __lo, u, v); \ ((UDWtype) __hi << W_TYPE_SIZE) | __lo; }) @@ -1556,7 +1567,7 @@ extern USItype __udiv_qrnnd (); /* If this machine has no inline assembler, use C macros. */ #if !defined (add_ssaaaa) -#define add_ssaaaa(sh, sl, ah, al, bh, bl) \ +# define add_ssaaaa(sh, sl, ah, al, bh, bl) \ do { \ UWtype __x; \ __x = (al) + (bl); \ @@ -1566,7 +1577,7 @@ extern USItype __udiv_qrnnd (); #endif #if !defined (sub_ddmmss) -#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ +# define sub_ddmmss(sh, sl, ah, al, bh, bl) \ do { \ UWtype __x; \ __x = (al) - (bl); \ @@ -1576,7 +1587,7 @@ extern USItype __udiv_qrnnd (); #endif #if !defined (umul_ppmm) -#define umul_ppmm(w1, w0, u, v) \ +# define umul_ppmm(w1, w0, u, v) \ do { \ UWtype __x0, __x1, __x2, __x3; \ UHWtype __ul, __vl, __uh, __vh; \ @@ -1603,7 +1614,7 @@ extern USItype __udiv_qrnnd (); #endif #if !defined (umul_ppmm) -#define smul_ppmm(w1, w0, u, v) \ +# define smul_ppmm(w1, w0, u, v) \ do { \ UWtype __w1; \ UWtype __m0 = (u), __m1 = (v); \ @@ -1653,7 +1664,7 @@ extern USItype __udiv_qrnnd (); /* If the processor has no udiv_qrnnd but sdiv_qrnnd, go through __udiv_w_sdiv (defined in libgcc or elsewhere). */ #if !defined (udiv_qrnnd) && defined (sdiv_qrnnd) -#define udiv_qrnnd(q, r, nh, nl, d) \ +# define udiv_qrnnd(q, r, nh, nl, d) \ do { \ UWtype __r; \ (q) = __MPN(udiv_w_sdiv) (&__r, nh, nl, d); \ @@ -1663,18 +1674,18 @@ extern USItype __udiv_qrnnd (); /* If udiv_qrnnd was not defined for this processor, use __udiv_qrnnd_c. */ #if !defined (udiv_qrnnd) -#define UDIV_NEEDS_NORMALIZATION 1 -#define udiv_qrnnd __udiv_qrnnd_c +# define UDIV_NEEDS_NORMALIZATION 1 +# define udiv_qrnnd __udiv_qrnnd_c #endif #if !defined (count_leading_zeros) extern -#ifdef __STDC__ +# ifdef __STDC__ const -#endif +# endif unsigned char _gcry_clz_tab[]; -#define MPI_INTERNAL_NEED_CLZ_TAB 1 -#define count_leading_zeros(count, x) \ +# define MPI_INTERNAL_NEED_CLZ_TAB 1 +# define count_leading_zeros(count, x) \ do { \ UWtype __xr = (x); \ UWtype __a; \ @@ -1695,21 +1706,25 @@ unsigned char _gcry_clz_tab[]; (count) = W_TYPE_SIZE - (_gcry_clz_tab[__xr >> __a] + __a); \ } while (0) /* This version gives a well-defined value for zero. */ -#define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE -#endif +# define COUNT_LEADING_ZEROS_0 W_TYPE_SIZE +#endif /* !count_leading_zeros */ #if !defined (count_trailing_zeros) /* Define count_trailing_zeros using count_leading_zeros. The latter might be defined in asm, but if it is not, the C version above is good enough. */ -#define count_trailing_zeros(count, x) \ +# define count_trailing_zeros(count, x) \ do { \ UWtype __ctz_x = (x); \ UWtype __ctz_c; \ count_leading_zeros (__ctz_c, __ctz_x & -__ctz_x); \ (count) = W_TYPE_SIZE - 1 - __ctz_c; \ } while (0) -#endif +#endif /* !count_trailing_zeros */ #ifndef UDIV_NEEDS_NORMALIZATION -#define UDIV_NEEDS_NORMALIZATION 0 +# define UDIV_NEEDS_NORMALIZATION 0 #endif + +/*************************************** + ****** longlong.h ends here ********* + ***************************************/ ----------------------------------------------------------------------- Summary of changes: mpi/longlong.h | 513 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 264 insertions(+), 249 deletions(-) hooks/post-receive -- The GNU crypto library http://git.gnupg.org _______________________________________________ Gnupg-commits mailing list Gnupg-commits at gnupg.org http://lists.gnupg.org/mailman/listinfo/gnupg-commits From andsch at inbox.com Fri Aug 29 17:45:23 2014 From: andsch at inbox.com (And Sch) Date: Fri, 29 Aug 2014 07:45:23 -0800 Subject: [PATCH 1/1] whirlpool hash amd64 assembly Message-ID: <1745308C116.00000937andsch@inbox.com> * cipher/whirlpool.c (whirlpool_transform, sbox, added macros): Added macros to support little endian AMD64 assembly implementation. Added prototype for assembly function and wrapped transform function in macro. * cipher/whirlpool-amd64.S (_gcry_whirlpool_transform_amd64): Originally generated by gcc with optimization options, I've cleaned it up a bit. * configure: Added build option for AMD64 assembly implementation. * configure.ac: Added build option for AMD64 assembly implementation. -- Benchmark on different systems: Intel(R) Atom(TM) CPU N570 @ 1.66GHz before: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 63.40 ns/B 15.04 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 29.29 ns/B 32.56 MiB/s - c/B Intel(R) Core(TM) i5-4670 CPU @ 3.40GHz before: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 7.75 ns/B 123.0 MiB/s - c/B after: Hash: | nanosecs/byte mebibytes/sec cycles/byte WHIRLPOOL | 5.91 ns/B 161.3 MiB/s - c/B That is more than twice as fast as the original on the Atom system. I tried to find a way to use macros to sort out parts of the loop, but any change in the order of the instructions slows it down a lot. There are also only 7 registers available at one time in most parts of the loop, so that makes macros and rearrangements even more difficult. I used a little endian version of the last patch I posted and gcc -funroll-loops to generate this assembly. I've looked through it and tried to organize it as best I can. Suggestions on how to clean it up further would be helpful. Signed-off-by: Andrei Scherer --- diff -ruNp libgcrypt-1.6.2/cipher/whirlpool-amd64.S libgcrypt-1.6.3/cipher/whirlpool-amd64.S --- libgcrypt-1.6.2/cipher/whirlpool-amd64.S 1969-12-31 18:00:00.000000000 -0600 +++ libgcrypt-1.6.3/cipher/whirlpool-amd64.S 2014-08-28 20:06:34.691538742 -0500 @@ -0,0 +1,1068 @@ +.p2align 4,,15 +.globl _gcry_whirlpool_transform_amd64 +.type _gcry_whirlpool_transform_amd64, @function +_gcry_whirlpool_transform_amd64: + .cfi_startproc + pushq %r15 + .cfi_def_cfa_offset 16 + .cfi_offset 15, -16 + pushq %r14 + .cfi_def_cfa_offset 24 + .cfi_offset 14, -24 + pushq %r13 + .cfi_def_cfa_offset 32 + .cfi_offset 13, -32 + pushq %r12 + .cfi_def_cfa_offset 40 + .cfi_offset 12, -40 + pushq %rbp + .cfi_def_cfa_offset 48 + .cfi_offset 6, -48 + pushq %rbx + .cfi_def_cfa_offset 56 + .cfi_offset 3, -56 + subq $152, %rsp + .cfi_def_cfa_offset 208 + + /* load hash (%rdi) */ + /* store hash (%rdi) into key -(%rsp) */ + /* xor block (%rsi) with hash (%rdi) */ + /* store result into state +(%rsp) */ + movq (%rdi), %r15 + movq %r15, -112(%rsp) + xorq (%rsi), %r15 + movq %r15, 16(%rsp) + + movq 8(%rdi), %r13 + movq %r13, -104(%rsp) + xorq 8(%rsi), %r13 + movq %r13, 24(%rsp) + + movq 16(%rdi), %rbp + movq %rbp, -96(%rsp) + xorq 16(%rsi), %rbp + movq %rbp, 32(%rsp) + + movq 24(%rdi), %r11 + movq %r11, -88(%rsp) + xorq 24(%rsi), %r11 + movq %r11, 40(%rsp) + + movq 32(%rdi), %r10 + movq %r10, -80(%rsp) + xorq 32(%rsi), %r10 + movq %r10, 48(%rsp) + + movq 40(%rdi), %rcx + movq %rcx, -72(%rsp) + xorq 40(%rsi), %rcx + movq %rcx, 56(%rsp) + + movq 48(%rdi), %rdx + movq %rdx, -64(%rsp) + xorq 48(%rsi), %rdx + movq %rdx, 64(%rsp) + + movq 56(%rdi), %rax + movq %rax, -56(%rsp) + xorq 56(%rsi), %rax + movq %rax, 72(%rsp) + + /* store result into hash (%rdi) */ + movq %r15, (%rdi) + movq %r13, 8(%rdi) + movq %rbp, 16(%rdi) + movq %r11, 24(%rdi) + movq %r10, 32(%rdi) + movq %rcx, 40(%rdi) + movq %rdx, 48(%rdi) + movq %rax, 56(%rdi) + + /* load first rc address */ + leaq rc(%rip), %r12 + + /* load last rc address */ + leaq 80+rc(%rip), %rbp + + /* load sbox address*/ + leaq sbox(%rip), %r8 + + /* zero alternator */ + xorl %r10d, %r10d + +.p2align 4,,10 +.p2align 3 +.Lroundloop: + /* save and flip alternator */ + movl %r10d, %edx + xorl $1, %r10d + salq $6, %rdx + + /* 0 state, key */ + /* load state +(%rsp) */ + /* load and xor sboxes (%r8) together */ + /* load key -(%rsp) */ + /* load and xor sboxes (%r8) together */ + movzbl 31(%rsp,%rdx), %ebx + movzbl 16(%rsp,%rdx), %ecx + movzbl 73(%rsp,%rdx), %eax + movzbl 66(%rsp,%rdx), %r9d + movq 14336(%r8,%rbx,8), %r11 + movzbl -97(%rsp,%rdx), %ebx + movzbl 59(%rsp,%rdx), %esi + movzbl 52(%rsp,%rdx), %r15d + xorq (%r8,%rcx,8), %r11 + movzbl -112(%rsp,%rdx), %ecx + movzbl 45(%rsp,%rdx), %r14d + movzbl 38(%rsp,%rdx), %r13d + xorq 2048(%r8,%rax,8), %r11 + movq 14336(%r8,%rbx,8), %rax + movzbl -90(%rsp,%rdx), %ebx + xorq 4096(%r8,%r9,8), %r11 + xorq (%r8,%rcx,8), %rax + movzbl -55(%rsp,%rdx), %r9d + xorq 6144(%r8,%rsi,8), %r11 + movzbl -62(%rsp,%rdx), %esi + xorq 2048(%r8,%r9,8), %rax + xorq 8192(%r8,%r15,8), %r11 + movzbl -69(%rsp,%rdx), %r15d + xorq 4096(%r8,%rsi,8), %rax + xorq 10240(%r8,%r14,8), %r11 + movzbl -76(%rsp,%rdx), %r14d + xorq 6144(%r8,%r15,8), %rax + xorq 12288(%r8,%r13,8), %r11 + movzbl -83(%rsp,%rdx), %r13d + xorq 8192(%r8,%r14,8), %rax + xorq 10240(%r8,%r13,8), %rax + xorq 12288(%r8,%rbx,8), %rax + + /* xor rc with key */ + xorq (%r12), %rax + + /* xor key with state */ + xorq %rax, %r11 + + /* this alternator is left unflipped */ + /* movsxd in intel syntax */ + movslq %r10d, %rcx + salq $6, %rcx + + /* store key */ + movq %rax, -112(%rsp,%rcx) + + /* store state */ + movq %r11, 16(%rsp,%rcx) + + /* 1 state, key */ + /* load state +(%rsp) */ + /* load and xor sboxes (%r8) together */ + /* load key -(%rsp) */ + /* load and xor sboxes (%r8) together */ + movzbl 39(%rsp,%rdx), %eax + movzbl 24(%rsp,%rdx), %r11d + movzbl 17(%rsp,%rdx), %esi + movzbl 74(%rsp,%rdx), %r15d + movq 14336(%r8,%rax,8), %r9 + movzbl 67(%rsp,%rdx), %r14d + movzbl 60(%rsp,%rdx), %r13d + movzbl 53(%rsp,%rdx), %ebx + xorq (%r8,%r11,8), %r9 + movzbl -89(%rsp,%rdx), %r11d + movzbl 46(%rsp,%rdx), %eax + xorq 2048(%r8,%rsi,8), %r9 + movzbl -104(%rsp,%rdx), %esi + xorq 4096(%r8,%r15,8), %r9 + movq 14336(%r8,%r11,8), %r15 + movzbl -75(%rsp,%rdx), %r11d + xorq 6144(%r8,%r14,8), %r9 + xorq (%r8,%rsi,8), %r15 + movzbl -111(%rsp,%rdx), %r14d + movzbl -82(%rsp,%rdx), %esi + xorq 8192(%r8,%r13,8), %r9 + movzbl -54(%rsp,%rdx), %r13d + xorq 2048(%r8,%r14,8), %r15 + xorq 10240(%r8,%rbx,8), %r9 + movzbl -61(%rsp,%rdx), %ebx + xorq 4096(%r8,%r13,8), %r15 + xorq 12288(%r8,%rax,8), %r9 + movzbl -68(%rsp,%rdx), %eax + xorq 6144(%r8,%rbx,8), %r15 + xorq 8192(%r8,%rax,8), %r15 + xorq 10240(%r8,%r11,8), %r15 + xorq 12288(%r8,%rsi,8), %r15 + + /* xor key with state */ + xorq %r15, %r9 + + /* store key */ + movq %r15, -104(%rsp,%rcx) + + /* store state */ + movq %r9, 24(%rsp,%rcx) + + /* 2 state, key */ + /* load state +(%rsp) */ + /* load and xor sboxes (%r8) together */ + /* load key -(%rsp) */ + /* load and xor sboxes (%r8) together */ + movzbl 47(%rsp,%rdx), %r9d + movzbl 32(%rsp,%rdx), %r15d + movzbl 25(%rsp,%rdx), %r13d + movzbl 18(%rsp,%rdx), %ebx + movq 14336(%r8,%r9,8), %r14 + movzbl 75(%rsp,%rdx), %eax + movzbl 68(%rsp,%rdx), %r11d + movzbl 61(%rsp,%rdx), %esi + xorq (%r8,%r15,8), %r14 + movzbl -81(%rsp,%rdx), %r15d + movzbl 54(%rsp,%rdx), %r9d + xorq 2048(%r8,%r13,8), %r14 + movzbl -96(%rsp,%rdx), %r13d + xorq 4096(%r8,%rbx,8), %r14 + movzbl -103(%rsp,%rdx), %ebx + xorq 6144(%r8,%rax,8), %r14 + movq 14336(%r8,%r15,8), %rax + movzbl -67(%rsp,%rdx), %r15d + xorq 8192(%r8,%r11,8), %r14 + xorq (%r8,%r13,8), %rax + movzbl -110(%rsp,%rdx), %r11d + movzbl -74(%rsp,%rdx), %r13d + xorq 10240(%r8,%rsi,8), %r14 + xorq 2048(%r8,%rbx,8), %rax + movzbl -53(%rsp,%rdx), %esi + xorq 12288(%r8,%r9,8), %r14 + xorq 4096(%r8,%r11,8), %rax + movzbl -60(%rsp,%rdx), %r9d + xorq 6144(%r8,%rsi,8), %rax + xorq 8192(%r8,%r9,8), %rax + xorq 10240(%r8,%r15,8), %rax + xorq 12288(%r8,%r13,8), %rax + + /* xor key with state */ + xorq %rax, %r14 + + /* store key */ + movq %rax, -96(%rsp,%rcx) + + /* store state */ + movq %r14, 32(%rsp,%rcx) + + /* 3 state, key */ + /* load state +(%rsp) */ + /* load and xor sboxes (%r8) together */ + /* load key -(%rsp) */ + /* load and xor sboxes (%r8) together */ + movzbl 55(%rsp,%rdx), %r14d + movzbl 40(%rsp,%rdx), %eax + movzbl 33(%rsp,%rdx), %ebx + movzbl 26(%rsp,%rdx), %r11d + movq 14336(%r8,%r14,8), %rsi + movzbl 19(%rsp,%rdx), %r9d + movzbl 76(%rsp,%rdx), %r15d + movzbl 69(%rsp,%rdx), %r13d + xorq (%r8,%rax,8), %rsi + movzbl -73(%rsp,%rdx), %eax + movzbl 62(%rsp,%rdx), %r14d + xorq 2048(%r8,%rbx,8), %rsi + movzbl -88(%rsp,%rdx), %ebx + xorq 4096(%r8,%r11,8), %rsi + movq 14336(%r8,%rax,8), %r11 + movzbl -59(%rsp,%rdx), %eax + xorq 6144(%r8,%r9,8), %rsi + xorq (%r8,%rbx,8), %r11 + movzbl -95(%rsp,%rdx), %r9d + movzbl -66(%rsp,%rdx), %ebx + xorq 8192(%r8,%r15,8), %rsi + movzbl -102(%rsp,%rdx), %r15d + xorq 2048(%r8,%r9,8), %r11 + xorq 10240(%r8,%r13,8), %rsi + movzbl -109(%rsp,%rdx), %r13d + xorq 4096(%r8,%r15,8), %r11 + xorq 12288(%r8,%r14,8), %rsi + movzbl -52(%rsp,%rdx), %r14d + xorq 6144(%r8,%r13,8), %r11 + xorq 8192(%r8,%r14,8), %r11 + xorq 10240(%r8,%rax,8), %r11 + xorq 12288(%r8,%rbx,8), %r11 + + /* xor key with state */ + xorq %r11, %rsi + + /* store key */ + movq %r11, -88(%rsp,%rcx) + + /* store state */ + movq %rsi, 40(%rsp,%rcx) + + /* 4 state, key */ + /* load state +(%rsp) */ + /* load and xor sboxes (%r8) together */ + /* load key -(%rsp) */ + /* load and xor sboxes (%r8) together */ + movzbl 63(%rsp,%rdx), %esi + movzbl 48(%rsp,%rdx), %r11d + movzbl 41(%rsp,%rdx), %r15d + movzbl 34(%rsp,%rdx), %r13d + movq 14336(%r8,%rsi,8), %r9 + movzbl 27(%rsp,%rdx), %r14d + movzbl 20(%rsp,%rdx), %eax + movzbl 77(%rsp,%rdx), %ebx + xorq (%r8,%r11,8), %r9 + movzbl -65(%rsp,%rdx), %r11d + movzbl 70(%rsp,%rdx), %esi + xorq 2048(%r8,%r15,8), %r9 + movzbl -80(%rsp,%rdx), %r15d + xorq 4096(%r8,%r13,8), %r9 + movq 14336(%r8,%r11,8), %r13 + movzbl -51(%rsp,%rdx), %r11d + xorq 6144(%r8,%r14,8), %r9 + xorq (%r8,%r15,8), %r13 + movzbl -87(%rsp,%rdx), %r14d + movzbl -58(%rsp,%rdx), %r15d + xorq 8192(%r8,%rax,8), %r9 + movzbl -94(%rsp,%rdx), %eax + xorq 2048(%r8,%r14,8), %r13 + xorq 10240(%r8,%rbx,8), %r9 + movzbl -101(%rsp,%rdx), %ebx + xorq 4096(%r8,%rax,8), %r13 + xorq 12288(%r8,%rsi,8), %r9 + movzbl -108(%rsp,%rdx), %esi + xorq 6144(%r8,%rbx,8), %r13 + xorq 8192(%r8,%rsi,8), %r13 + xorq 10240(%r8,%r11,8), %r13 + xorq 12288(%r8,%r15,8), %r13 + + /* xor key with state */ + xorq %r13, %r9 + + /* store key */ + movq %r13, -80(%rsp,%rcx) + + /* store state */ + movq %r9, 48(%rsp,%rcx) + + /* 5 state, key */ + /* load state +(%rsp) */ + /* load and xor sboxes (%r8) together */ + /* load key -(%rsp) */ + /* load and xor sboxes (%r8) together */ + movzbl 71(%rsp,%rdx), %r9d + movzbl 56(%rsp,%rdx), %r13d + movzbl 49(%rsp,%rdx), %eax + movzbl 42(%rsp,%rdx), %ebx + movq 14336(%r8,%r9,8), %r14 + movzbl 35(%rsp,%rdx), %esi + movzbl 28(%rsp,%rdx), %r11d + movzbl 21(%rsp,%rdx), %r15d + xorq (%r8,%r13,8), %r14 + movzbl -57(%rsp,%rdx), %r13d + movzbl 78(%rsp,%rdx), %r9d + xorq 2048(%r8,%rax,8), %r14 + movzbl -72(%rsp,%rdx), %eax + xorq 4096(%r8,%rbx,8), %r14 + movzbl -79(%rsp,%rdx), %ebx + xorq 6144(%r8,%rsi,8), %r14 + movq 14336(%r8,%r13,8), %rsi + movzbl -107(%rsp,%rdx), %r13d + xorq 8192(%r8,%r11,8), %r14 + xorq (%r8,%rax,8), %rsi + movzbl -86(%rsp,%rdx), %r11d + movzbl -50(%rsp,%rdx), %eax + xorq 10240(%r8,%r15,8), %r14 + xorq 2048(%r8,%rbx,8), %rsi + movzbl -93(%rsp,%rdx), %r15d + xorq 12288(%r8,%r9,8), %r14 + xorq 4096(%r8,%r11,8), %rsi + movzbl -100(%rsp,%rdx), %r9d + xorq 6144(%r8,%r15,8), %rsi + xorq 8192(%r8,%r9,8), %rsi + xorq 10240(%r8,%r13,8), %rsi + xorq 12288(%r8,%rax,8), %rsi + + /* xor key with state */ + xorq %rsi, %r14 + + /* store key */ + movq %rsi, -72(%rsp,%rcx) + + /* store state */ + movq %r14, 56(%rsp,%rcx) + + /* 6 state, key */ + /* load state +(%rsp) */ + /* load and xor sboxes (%r8) together */ + /* load key -(%rsp) */ + /* load and xor sboxes (%r8) together */ + movzbl 79(%rsp,%rdx), %r14d + movzbl 64(%rsp,%rdx), %ebx + movzbl 57(%rsp,%rdx), %r11d + movzbl 50(%rsp,%rdx), %r15d + movq 14336(%r8,%r14,8), %rsi + movzbl 43(%rsp,%rdx), %r9d + movzbl 36(%rsp,%rdx), %r13d + movzbl 29(%rsp,%rdx), %eax + xorq (%r8,%rbx,8), %rsi + movzbl -64(%rsp,%rdx), %ebx + movzbl 22(%rsp,%rdx), %r14d + xorq 2048(%r8,%r11,8), %rsi + movzbl -49(%rsp,%rdx), %r11d + xorq 4096(%r8,%r15,8), %rsi + movq 14336(%r8,%r11,8), %r15 + movzbl -99(%rsp,%rdx), %r11d + xorq 6144(%r8,%r9,8), %rsi + movzbl -71(%rsp,%rdx), %r9d + xorq 8192(%r8,%r13,8), %rsi + movzbl -78(%rsp,%rdx), %r13d + xorq 10240(%r8,%rax,8), %rsi + xorq (%r8,%rbx,8), %r15 + movzbl -85(%rsp,%rdx), %eax + movzbl -106(%rsp,%rdx), %ebx + xorq 12288(%r8,%r14,8), %rsi + xorq 2048(%r8,%r9,8), %r15 + movzbl -92(%rsp,%rdx), %r14d + xorq 4096(%r8,%r13,8), %r15 + xorq 6144(%r8,%rax,8), %r15 + xorq 8192(%r8,%r14,8), %r15 + xorq 10240(%r8,%r11,8), %r15 + xorq 12288(%r8,%rbx,8), %r15 + + /* xor key with state */ + xorq %r15, %rsi + + /* store key */ + movq %r15, -64(%rsp,%rcx) + + /* store state */ + movq %rsi, 64(%rsp,%rcx) + + /* 7 state, key */ + /* load state +(%rsp) */ + /* load and xor sboxes (%r8) together */ + /* load key -(%rsp) */ + /* load and xor sboxes (%r8) together */ + movzbl 23(%rsp,%rdx), %esi + movzbl 72(%rsp,%rdx), %r15d + movzbl 65(%rsp,%rdx), %r13d + movzbl 58(%rsp,%rdx), %eax + movq 14336(%r8,%rsi,8), %r9 + movzbl 51(%rsp,%rdx), %r14d + movzbl 44(%rsp,%rdx), %r11d + movzbl 37(%rsp,%rdx), %ebx + xorq (%r8,%r15,8), %r9 + movzbl -105(%rsp,%rdx), %r15d + movzbl 30(%rsp,%rdx), %esi + xorq 2048(%r8,%r13,8), %r9 + movzbl -56(%rsp,%rdx), %r13d + xorq 4096(%r8,%rax,8), %r9 + movzbl -63(%rsp,%rdx), %eax + xorq 6144(%r8,%r14,8), %r9 + movq 14336(%r8,%r15,8), %r14 + movzbl -91(%rsp,%rdx), %r15d + xorq 8192(%r8,%r11,8), %r9 + xorq (%r8,%r13,8), %r14 + movzbl -70(%rsp,%rdx), %r11d + xorq 10240(%r8,%rbx,8), %r9 + xorq 2048(%r8,%rax,8), %r14 + movzbl -77(%rsp,%rdx), %ebx + xorq 12288(%r8,%rsi,8), %r9 + xorq 4096(%r8,%r11,8), %r14 + movzbl -84(%rsp,%rdx), %esi + movzbl -98(%rsp,%rdx), %edx + xorq 6144(%r8,%rbx,8), %r14 + xorq 8192(%r8,%rsi,8), %r14 + xorq 10240(%r8,%r15,8), %r14 + xorq 12288(%r8,%rdx,8), %r14 + + /* xor key with state */ + xorq %r14, %r9 + + /* store key */ + movq %r14, -56(%rsp,%rcx) + + /* store state */ + movq %r9, 72(%rsp,%rcx) + + /* increment and compare rc addresses */ + addq $8, %r12 + cmpq %rbp, %r12 + jne .Lroundloop + + /* load state +(%rsp) */ + /* xor state +(%rsp) with hash (%rdi) */ + movq 16(%rsp), %r12 + xorq %r12, (%rdi) + movq 24(%rsp), %rbp + xorq %rbp, 8(%rdi) + movq 64(%rsp), %r13 + xorq %r13, 48(%rdi) + movq 72(%rsp), %r14 + xorq %r14, 56(%rdi) + movq 32(%rsp), %r10 + xorq %r10, 16(%rdi) + movq 40(%rsp), %r8 + xorq %r8, 24(%rdi) + movq 48(%rsp), %rcx + xorq %rcx, 32(%rdi) + movq 56(%rsp), %r9 + xorq %r9, 40(%rdi) + + addq $152, %rsp + .cfi_def_cfa_offset 56 + popq %rbx + .cfi_def_cfa_offset 48 + popq %rbp + .cfi_def_cfa_offset 40 + popq %r12 + .cfi_def_cfa_offset 32 + popq %r13 + .cfi_def_cfa_offset 24 + popq %r14 + .cfi_def_cfa_offset 16 + popq %r15 + .cfi_def_cfa_offset 8 + + /* burn_stack */ + movl $(4 * 64 + 2 * 4), %eax + + ret + .cfi_endproc +.section .rodata +.align 32 +.type rc, @object +.size rc, 80 +/* round constants in little endian */ +rc: + .quad 0x4f01b887e8c62318 + .quad 0x52916f79f5d2a636 + .quad 0x357b0ca38e9bbc60 + .quad 0x57fe4b2ec2d7e01d + .quad 0xda4af09fe5377715 + .quad 0x856ba0b10a29c958 + .quad 0x67053ecbf4105dbd + .quad 0xd8957da78b4127e4 + .quad 0x9e4717dd667ceefb + .quad 0x33835aad07bf2dca +.align 32 +.type sbox, @object +.size sbox, 16384 +/* rotated sboxes in little endian */ +sbox: + .quad 0xd83078c018601818, 0x2646af05238c2323, 0xb891f97ec63fc6c6, 0xfbcd6f13e887e8e8 + .quad 0xcb13a14c87268787, 0x116d62a9b8dab8b8, 0x0902050801040101, 0x0d9e6e424f214f4f + .quad 0x9b6ceead36d83636, 0xff510459a6a2a6a6, 0x0cb9bdded26fd2d2, 0x0ef706fbf5f3f5f5 + .quad 0x96f280ef79f97979, 0x30dece5f6fa16f6f, 0x6d3feffc917e9191, 0xf8a407aa52555252 + .quad 0x47c0fd27609d6060, 0x35657689bccabcbc, 0x372bcdac9b569b9b, 0x8a018c048e028e8e + .quad 0xd25b1571a3b6a3a3, 0x6c183c600c300c0c, 0x84f68aff7bf17b7b, 0x806ae1b535d43535 + .quad 0xf53a69e81d741d1d, 0xb3dd4753e0a7e0e0, 0x21b3acf6d77bd7d7, 0x9c99ed5ec22fc2c2 + .quad 0x435c966d2eb82e2e, 0x29967a624b314b4b, 0x5de121a3fedffefe, 0xd5ae168257415757 + .quad 0xbd2a41a815541515, 0xe8eeb69f77c17777, 0x926eeba537dc3737, 0x9ed7567be5b3e5e5 + .quad 0x1323d98c9f469f9f, 0x23fd17d3f0e7f0f0, 0x20947f6a4a354a4a, 0x44a9959eda4fdada + .quad 0xa2b025fa587d5858, 0xcf8fca06c903c9c9, 0x7c528d5529a42929, 0x5a1422500a280a0a + .quad 0x507f4fe1b1feb1b1, 0xc95d1a69a0baa0a0, 0x14d6da7f6bb16b6b, 0xd917ab5c852e8585 + .quad 0x3c677381bdcebdbd, 0x8fba34d25d695d5d, 0x9020508010401010, 0x07f503f3f4f7f4f4 + .quad 0xdd8bc016cb0bcbcb, 0xd37cc6ed3ef83e3e, 0x2d0a112805140505, 0x78cee61f67816767 + .quad 0x97d55373e4b7e4e4, 0x024ebb25279c2727, 0x7382583241194141, 0xa70b9d2c8b168b8b + .quad 0xf6530151a7a6a7a7, 0xb2fa94cf7de97d7d, 0x4937fbdc956e9595, 0x56ad9f8ed847d8d8 + .quad 0x70eb308bfbcbfbfb, 0xcdc17123ee9feeee, 0xbbf891c77ced7c7c, 0x71cce31766856666 + .quad 0x7ba78ea6dd53dddd, 0xaf2e4bb8175c1717, 0x458e460247014747, 0x1a21dc849e429e9e + .quad 0xd489c51eca0fcaca, 0x585a99752db42d2d, 0x2e637991bfc6bfbf, 0x3f0e1b38071c0707 + .quad 0xac472301ad8eadad, 0xb0b42fea5a755a5a, 0xef1bb56c83368383, 0xb666ff8533cc3333 + .quad 0x5cc6f23f63916363, 0x12040a1002080202, 0x93493839aa92aaaa, 0xdee2a8af71d97171 + .quad 0xc68dcf0ec807c8c8, 0xd1327dc819641919, 0x3b92707249394949, 0x5faf9a86d943d9d9 + .quad 0x31f91dc3f2eff2f2, 0xa8db484be3abe3e3, 0xb9b62ae25b715b5b, 0xbc0d9234881a8888 + .quad 0x3e29c8a49a529a9a, 0x0b4cbe2d26982626, 0xbf64fa8d32c83232, 0x597d4ae9b0fab0b0 + .quad 0xf2cf6a1be983e9e9, 0x771e33780f3c0f0f, 0x33b7a6e6d573d5d5, 0xf41dba74803a8080 + .quad 0x27617c99bec2bebe, 0xeb87de26cd13cdcd, 0x8968e4bd34d03434, 0x3290757a483d4848 + .quad 0x54e324abffdbffff, 0x8df48ff77af57a7a, 0x643deaf4907a9090, 0x9dbe3ec25f615f5f + .quad 0x3d40a01d20802020, 0x0fd0d56768bd6868, 0xca3472d01a681a1a, 0xb7412c19ae82aeae + .quad 0x7d755ec9b4eab4b4, 0xcea8199a544d5454, 0x7f3be5ec93769393, 0x2f44aa0d22882222 + .quad 0x63c8e907648d6464, 0x2aff12dbf1e3f1f1, 0xcce6a2bf73d17373, 0x82245a9012481212 + .quad 0x7a805d3a401d4040, 0x4810284008200808, 0x959be856c32bc3c3, 0xdfc57b33ec97ecec + .quad 0x4dab9096db4bdbdb, 0xc05f1f61a1bea1a1, 0x9107831c8d0e8d8d, 0xc87ac9f53df43d3d + .quad 0x5b33f1cc97669797, 0x0000000000000000, 0xf983d436cf1bcfcf, 0x6e5687452bac2b2b + .quad 0xe1ecb39776c57676, 0xe619b06482328282, 0x28b1a9fed67fd6d6, 0xc33677d81b6c1b1b + .quad 0x74775bc1b5eeb5b5, 0xbe432911af86afaf, 0x1dd4df776ab56a6a, 0xeaa00dba505d5050 + .quad 0x578a4c1245094545, 0x38fb18cbf3ebf3f3, 0xad60f09d30c03030, 0xc4c3742bef9befef + .quad 0xda7ec3e53ffc3f3f, 0xc7aa1c9255495555, 0xdb591079a2b2a2a2, 0xe9c96503ea8feaea + .quad 0x6acaec0f65896565, 0x036968b9bad2baba, 0x4a5e93652fbc2f2f, 0x8e9de74ec027c0c0 + .quad 0x60a181bede5fdede, 0xfc386ce01c701c1c, 0x46e72ebbfdd3fdfd, 0x1f9a64524d294d4d + .quad 0x7639e0e492729292, 0xfaeabc8f75c97575, 0x360c1e3006180606, 0xae0998248a128a8a + .quad 0x4b7940f9b2f2b2b2, 0x85d15963e6bfe6e6, 0x7e1c36700e380e0e, 0xe73e63f81f7c1f1f + .quad 0x55c4f73762956262, 0x3ab5a3eed477d4d4, 0x814d3229a89aa8a8, 0x5231f4c496629696 + .quad 0x62ef3a9bf9c3f9f9, 0xa397f666c533c5c5, 0x104ab13525942525, 0xabb220f259795959 + .quad 0xd015ae54842a8484, 0xc5e4a7b772d57272, 0xec72ddd539e43939, 0x1698615a4c2d4c4c + .quad 0x94bc3bca5e655e5e, 0x9ff085e778fd7878, 0xe570d8dd38e03838, 0x980586148c0a8c8c + .quad 0x17bfb2c6d163d1d1, 0xe4570b41a5aea5a5, 0xa1d94d43e2afe2e2, 0x4ec2f82f61996161 + .quad 0x427b45f1b3f6b3b3, 0x3442a51521842121, 0x0825d6949c4a9c9c, 0xee3c66f01e781e1e + .quad 0x6186522243114343, 0xb193fc76c73bc7c7, 0x4fe52bb3fcd7fcfc, 0x2408142004100404 + .quad 0xe3a208b251595151, 0x252fc7bc995e9999, 0x22dac44f6da96d6d, 0x651a39680d340d0d + .quad 0x79e93583facffafa, 0x69a384b6df5bdfdf, 0xa9fc9bd77ee57e7e, 0x1948b43d24902424 + .quad 0xfe76d7c53bec3b3b, 0x9a4b3d31ab96abab, 0xf081d13ece1fcece, 0x9922558811441111 + .quad 0x8303890c8f068f8f, 0x049c6b4a4e254e4e, 0x667351d1b7e6b7b7, 0xe0cb600beb8bebeb + .quad 0xc178ccfd3cf03c3c, 0xfd1fbf7c813e8181, 0x4035fed4946a9494, 0x1cf30cebf7fbf7f7 + .quad 0x186f67a1b9deb9b9, 0x8b265f98134c1313, 0x51589c7d2cb02c2c, 0x05bbb8d6d36bd3d3 + .quad 0x8cd35c6be7bbe7e7, 0x39dccb576ea56e6e, 0xaa95f36ec437c4c4, 0x1b060f18030c0303 + .quad 0xdcac138a56455656, 0x5e88491a440d4444, 0xa0fe9edf7fe17f7f, 0x884f3721a99ea9a9 + .quad 0x6754824d2aa82a2a, 0x0a6b6db1bbd6bbbb, 0x879fe246c123c1c1, 0xf1a602a253515353 + .quad 0x72a58baedc57dcdc, 0x531627580b2c0b0b, 0x0127d39c9d4e9d9d, 0x2bd8c1476cad6c6c + .quad 0xa462f59531c43131, 0xf3e8b98774cd7474, 0x15f109e3f6fff6f6, 0x4c8c430a46054646 + .quad 0xa5452609ac8aacac, 0xb50f973c891e8989, 0xb42844a014501414, 0xbadf425be1a3e1e1 + .quad 0xa62c4eb016581616, 0xf774d2cd3ae83a3a, 0x06d2d06f69b96969, 0x41122d4809240909 + .quad 0xd7e0ada770dd7070, 0x6f7154d9b6e2b6b6, 0x1ebdb7ced067d0d0, 0xd6c77e3bed93eded + .quad 0xe285db2ecc17cccc, 0x6884572a42154242, 0x2c2dc2b4985a9898, 0xed550e49a4aaa4a4 + .quad 0x7550885d28a02828, 0x86b831da5c6d5c5c, 0x6bed3f93f8c7f8f8, 0xc211a44486228686 + + .quad 0x3078c018601818d8, 0x46af05238c232326, 0x91f97ec63fc6c6b8, 0xcd6f13e887e8e8fb + .quad 0x13a14c87268787cb, 0x6d62a9b8dab8b811, 0x0205080104010109, 0x9e6e424f214f4f0d + .quad 0x6ceead36d836369b, 0x510459a6a2a6a6ff, 0xb9bdded26fd2d20c, 0xf706fbf5f3f5f50e + .quad 0xf280ef79f9797996, 0xdece5f6fa16f6f30, 0x3feffc917e91916d, 0xa407aa52555252f8 + .quad 0xc0fd27609d606047, 0x657689bccabcbc35, 0x2bcdac9b569b9b37, 0x018c048e028e8e8a + .quad 0x5b1571a3b6a3a3d2, 0x183c600c300c0c6c, 0xf68aff7bf17b7b84, 0x6ae1b535d4353580 + .quad 0x3a69e81d741d1df5, 0xdd4753e0a7e0e0b3, 0xb3acf6d77bd7d721, 0x99ed5ec22fc2c29c + .quad 0x5c966d2eb82e2e43, 0x967a624b314b4b29, 0xe121a3fedffefe5d, 0xae168257415757d5 + .quad 0x2a41a815541515bd, 0xeeb69f77c17777e8, 0x6eeba537dc373792, 0xd7567be5b3e5e59e + .quad 0x23d98c9f469f9f13, 0xfd17d3f0e7f0f023, 0x947f6a4a354a4a20, 0xa9959eda4fdada44 + .quad 0xb025fa587d5858a2, 0x8fca06c903c9c9cf, 0x528d5529a429297c, 0x1422500a280a0a5a + .quad 0x7f4fe1b1feb1b150, 0x5d1a69a0baa0a0c9, 0xd6da7f6bb16b6b14, 0x17ab5c852e8585d9 + .quad 0x677381bdcebdbd3c, 0xba34d25d695d5d8f, 0x2050801040101090, 0xf503f3f4f7f4f407 + .quad 0x8bc016cb0bcbcbdd, 0x7cc6ed3ef83e3ed3, 0x0a1128051405052d, 0xcee61f6781676778 + .quad 0xd55373e4b7e4e497, 0x4ebb25279c272702, 0x8258324119414173, 0x0b9d2c8b168b8ba7 + .quad 0x530151a7a6a7a7f6, 0xfa94cf7de97d7db2, 0x37fbdc956e959549, 0xad9f8ed847d8d856 + .quad 0xeb308bfbcbfbfb70, 0xc17123ee9feeeecd, 0xf891c77ced7c7cbb, 0xcce3176685666671 + .quad 0xa78ea6dd53dddd7b, 0x2e4bb8175c1717af, 0x8e46024701474745, 0x21dc849e429e9e1a + .quad 0x89c51eca0fcacad4, 0x5a99752db42d2d58, 0x637991bfc6bfbf2e, 0x0e1b38071c07073f + .quad 0x472301ad8eadadac, 0xb42fea5a755a5ab0, 0x1bb56c83368383ef, 0x66ff8533cc3333b6 + .quad 0xc6f23f639163635c, 0x040a100208020212, 0x493839aa92aaaa93, 0xe2a8af71d97171de + .quad 0x8dcf0ec807c8c8c6, 0x327dc819641919d1, 0x927072493949493b, 0xaf9a86d943d9d95f + .quad 0xf91dc3f2eff2f231, 0xdb484be3abe3e3a8, 0xb62ae25b715b5bb9, 0x0d9234881a8888bc + .quad 0x29c8a49a529a9a3e, 0x4cbe2d269826260b, 0x64fa8d32c83232bf, 0x7d4ae9b0fab0b059 + .quad 0xcf6a1be983e9e9f2, 0x1e33780f3c0f0f77, 0xb7a6e6d573d5d533, 0x1dba74803a8080f4 + .quad 0x617c99bec2bebe27, 0x87de26cd13cdcdeb, 0x68e4bd34d0343489, 0x90757a483d484832 + .quad 0xe324abffdbffff54, 0xf48ff77af57a7a8d, 0x3deaf4907a909064, 0xbe3ec25f615f5f9d + .quad 0x40a01d208020203d, 0xd0d56768bd68680f, 0x3472d01a681a1aca, 0x412c19ae82aeaeb7 + .quad 0x755ec9b4eab4b47d, 0xa8199a544d5454ce, 0x3be5ec937693937f, 0x44aa0d228822222f + .quad 0xc8e907648d646463, 0xff12dbf1e3f1f12a, 0xe6a2bf73d17373cc, 0x245a901248121282 + .quad 0x805d3a401d40407a, 0x1028400820080848, 0x9be856c32bc3c395, 0xc57b33ec97ececdf + .quad 0xab9096db4bdbdb4d, 0x5f1f61a1bea1a1c0, 0x07831c8d0e8d8d91, 0x7ac9f53df43d3dc8 + .quad 0x33f1cc976697975b, 0x0000000000000000, 0x83d436cf1bcfcff9, 0x5687452bac2b2b6e + .quad 0xecb39776c57676e1, 0x19b06482328282e6, 0xb1a9fed67fd6d628, 0x3677d81b6c1b1bc3 + .quad 0x775bc1b5eeb5b574, 0x432911af86afafbe, 0xd4df776ab56a6a1d, 0xa00dba505d5050ea + .quad 0x8a4c124509454557, 0xfb18cbf3ebf3f338, 0x60f09d30c03030ad, 0xc3742bef9befefc4 + .quad 0x7ec3e53ffc3f3fda, 0xaa1c9255495555c7, 0x591079a2b2a2a2db, 0xc96503ea8feaeae9 + .quad 0xcaec0f658965656a, 0x6968b9bad2baba03, 0x5e93652fbc2f2f4a, 0x9de74ec027c0c08e + .quad 0xa181bede5fdede60, 0x386ce01c701c1cfc, 0xe72ebbfdd3fdfd46, 0x9a64524d294d4d1f + .quad 0x39e0e49272929276, 0xeabc8f75c97575fa, 0x0c1e300618060636, 0x0998248a128a8aae + .quad 0x7940f9b2f2b2b24b, 0xd15963e6bfe6e685, 0x1c36700e380e0e7e, 0x3e63f81f7c1f1fe7 + .quad 0xc4f7376295626255, 0xb5a3eed477d4d43a, 0x4d3229a89aa8a881, 0x31f4c49662969652 + .quad 0xef3a9bf9c3f9f962, 0x97f666c533c5c5a3, 0x4ab1352594252510, 0xb220f259795959ab + .quad 0x15ae54842a8484d0, 0xe4a7b772d57272c5, 0x72ddd539e43939ec, 0x98615a4c2d4c4c16 + .quad 0xbc3bca5e655e5e94, 0xf085e778fd78789f, 0x70d8dd38e03838e5, 0x0586148c0a8c8c98 + .quad 0xbfb2c6d163d1d117, 0x570b41a5aea5a5e4, 0xd94d43e2afe2e2a1, 0xc2f82f619961614e + .quad 0x7b45f1b3f6b3b342, 0x42a5152184212134, 0x25d6949c4a9c9c08, 0x3c66f01e781e1eee + .quad 0x8652224311434361, 0x93fc76c73bc7c7b1, 0xe52bb3fcd7fcfc4f, 0x0814200410040424 + .quad 0xa208b251595151e3, 0x2fc7bc995e999925, 0xdac44f6da96d6d22, 0x1a39680d340d0d65 + .quad 0xe93583facffafa79, 0xa384b6df5bdfdf69, 0xfc9bd77ee57e7ea9, 0x48b43d2490242419 + .quad 0x76d7c53bec3b3bfe, 0x4b3d31ab96abab9a, 0x81d13ece1fcecef0, 0x2255881144111199 + .quad 0x03890c8f068f8f83, 0x9c6b4a4e254e4e04, 0x7351d1b7e6b7b766, 0xcb600beb8bebebe0 + .quad 0x78ccfd3cf03c3cc1, 0x1fbf7c813e8181fd, 0x35fed4946a949440, 0xf30cebf7fbf7f71c + .quad 0x6f67a1b9deb9b918, 0x265f98134c13138b, 0x589c7d2cb02c2c51, 0xbbb8d6d36bd3d305 + .quad 0xd35c6be7bbe7e78c, 0xdccb576ea56e6e39, 0x95f36ec437c4c4aa, 0x060f18030c03031b + .quad 0xac138a56455656dc, 0x88491a440d44445e, 0xfe9edf7fe17f7fa0, 0x4f3721a99ea9a988 + .quad 0x54824d2aa82a2a67, 0x6b6db1bbd6bbbb0a, 0x9fe246c123c1c187, 0xa602a253515353f1 + .quad 0xa58baedc57dcdc72, 0x1627580b2c0b0b53, 0x27d39c9d4e9d9d01, 0xd8c1476cad6c6c2b + .quad 0x62f59531c43131a4, 0xe8b98774cd7474f3, 0xf109e3f6fff6f615, 0x8c430a460546464c + .quad 0x452609ac8aacaca5, 0x0f973c891e8989b5, 0x2844a014501414b4, 0xdf425be1a3e1e1ba + .quad 0x2c4eb016581616a6, 0x74d2cd3ae83a3af7, 0xd2d06f69b9696906, 0x122d480924090941 + .quad 0xe0ada770dd7070d7, 0x7154d9b6e2b6b66f, 0xbdb7ced067d0d01e, 0xc77e3bed93ededd6 + .quad 0x85db2ecc17cccce2, 0x84572a4215424268, 0x2dc2b4985a98982c, 0x550e49a4aaa4a4ed + .quad 0x50885d28a0282875, 0xb831da5c6d5c5c86, 0xed3f93f8c7f8f86b, 0x11a44486228686c2 + + .quad 0x78c018601818d830, 0xaf05238c23232646, 0xf97ec63fc6c6b891, 0x6f13e887e8e8fbcd + .quad 0xa14c87268787cb13, 0x62a9b8dab8b8116d, 0x0508010401010902, 0x6e424f214f4f0d9e + .quad 0xeead36d836369b6c, 0x0459a6a2a6a6ff51, 0xbdded26fd2d20cb9, 0x06fbf5f3f5f50ef7 + .quad 0x80ef79f9797996f2, 0xce5f6fa16f6f30de, 0xeffc917e91916d3f, 0x07aa52555252f8a4 + .quad 0xfd27609d606047c0, 0x7689bccabcbc3565, 0xcdac9b569b9b372b, 0x8c048e028e8e8a01 + .quad 0x1571a3b6a3a3d25b, 0x3c600c300c0c6c18, 0x8aff7bf17b7b84f6, 0xe1b535d43535806a + .quad 0x69e81d741d1df53a, 0x4753e0a7e0e0b3dd, 0xacf6d77bd7d721b3, 0xed5ec22fc2c29c99 + .quad 0x966d2eb82e2e435c, 0x7a624b314b4b2996, 0x21a3fedffefe5de1, 0x168257415757d5ae + .quad 0x41a815541515bd2a, 0xb69f77c17777e8ee, 0xeba537dc3737926e, 0x567be5b3e5e59ed7 + .quad 0xd98c9f469f9f1323, 0x17d3f0e7f0f023fd, 0x7f6a4a354a4a2094, 0x959eda4fdada44a9 + .quad 0x25fa587d5858a2b0, 0xca06c903c9c9cf8f, 0x8d5529a429297c52, 0x22500a280a0a5a14 + .quad 0x4fe1b1feb1b1507f, 0x1a69a0baa0a0c95d, 0xda7f6bb16b6b14d6, 0xab5c852e8585d917 + .quad 0x7381bdcebdbd3c67, 0x34d25d695d5d8fba, 0x5080104010109020, 0x03f3f4f7f4f407f5 + .quad 0xc016cb0bcbcbdd8b, 0xc6ed3ef83e3ed37c, 0x1128051405052d0a, 0xe61f6781676778ce + .quad 0x5373e4b7e4e497d5, 0xbb25279c2727024e, 0x5832411941417382, 0x9d2c8b168b8ba70b + .quad 0x0151a7a6a7a7f653, 0x94cf7de97d7db2fa, 0xfbdc956e95954937, 0x9f8ed847d8d856ad + .quad 0x308bfbcbfbfb70eb, 0x7123ee9feeeecdc1, 0x91c77ced7c7cbbf8, 0xe3176685666671cc + .quad 0x8ea6dd53dddd7ba7, 0x4bb8175c1717af2e, 0x460247014747458e, 0xdc849e429e9e1a21 + .quad 0xc51eca0fcacad489, 0x99752db42d2d585a, 0x7991bfc6bfbf2e63, 0x1b38071c07073f0e + .quad 0x2301ad8eadadac47, 0x2fea5a755a5ab0b4, 0xb56c83368383ef1b, 0xff8533cc3333b666 + .quad 0xf23f639163635cc6, 0x0a10020802021204, 0x3839aa92aaaa9349, 0xa8af71d97171dee2 + .quad 0xcf0ec807c8c8c68d, 0x7dc819641919d132, 0x7072493949493b92, 0x9a86d943d9d95faf + .quad 0x1dc3f2eff2f231f9, 0x484be3abe3e3a8db, 0x2ae25b715b5bb9b6, 0x9234881a8888bc0d + .quad 0xc8a49a529a9a3e29, 0xbe2d269826260b4c, 0xfa8d32c83232bf64, 0x4ae9b0fab0b0597d + .quad 0x6a1be983e9e9f2cf, 0x33780f3c0f0f771e, 0xa6e6d573d5d533b7, 0xba74803a8080f41d + .quad 0x7c99bec2bebe2761, 0xde26cd13cdcdeb87, 0xe4bd34d034348968, 0x757a483d48483290 + .quad 0x24abffdbffff54e3, 0x8ff77af57a7a8df4, 0xeaf4907a9090643d, 0x3ec25f615f5f9dbe + .quad 0xa01d208020203d40, 0xd56768bd68680fd0, 0x72d01a681a1aca34, 0x2c19ae82aeaeb741 + .quad 0x5ec9b4eab4b47d75, 0x199a544d5454cea8, 0xe5ec937693937f3b, 0xaa0d228822222f44 + .quad 0xe907648d646463c8, 0x12dbf1e3f1f12aff, 0xa2bf73d17373cce6, 0x5a90124812128224 + .quad 0x5d3a401d40407a80, 0x2840082008084810, 0xe856c32bc3c3959b, 0x7b33ec97ececdfc5 + .quad 0x9096db4bdbdb4dab, 0x1f61a1bea1a1c05f, 0x831c8d0e8d8d9107, 0xc9f53df43d3dc87a + .quad 0xf1cc976697975b33, 0x0000000000000000, 0xd436cf1bcfcff983, 0x87452bac2b2b6e56 + .quad 0xb39776c57676e1ec, 0xb06482328282e619, 0xa9fed67fd6d628b1, 0x77d81b6c1b1bc336 + .quad 0x5bc1b5eeb5b57477, 0x2911af86afafbe43, 0xdf776ab56a6a1dd4, 0x0dba505d5050eaa0 + .quad 0x4c1245094545578a, 0x18cbf3ebf3f338fb, 0xf09d30c03030ad60, 0x742bef9befefc4c3 + .quad 0xc3e53ffc3f3fda7e, 0x1c9255495555c7aa, 0x1079a2b2a2a2db59, 0x6503ea8feaeae9c9 + .quad 0xec0f658965656aca, 0x68b9bad2baba0369, 0x93652fbc2f2f4a5e, 0xe74ec027c0c08e9d + .quad 0x81bede5fdede60a1, 0x6ce01c701c1cfc38, 0x2ebbfdd3fdfd46e7, 0x64524d294d4d1f9a + .quad 0xe0e4927292927639, 0xbc8f75c97575faea, 0x1e3006180606360c, 0x98248a128a8aae09 + .quad 0x40f9b2f2b2b24b79, 0x5963e6bfe6e685d1, 0x36700e380e0e7e1c, 0x63f81f7c1f1fe73e + .quad 0xf7376295626255c4, 0xa3eed477d4d43ab5, 0x3229a89aa8a8814d, 0xf4c4966296965231 + .quad 0x3a9bf9c3f9f962ef, 0xf666c533c5c5a397, 0xb13525942525104a, 0x20f259795959abb2 + .quad 0xae54842a8484d015, 0xa7b772d57272c5e4, 0xddd539e43939ec72, 0x615a4c2d4c4c1698 + .quad 0x3bca5e655e5e94bc, 0x85e778fd78789ff0, 0xd8dd38e03838e570, 0x86148c0a8c8c9805 + .quad 0xb2c6d163d1d117bf, 0x0b41a5aea5a5e457, 0x4d43e2afe2e2a1d9, 0xf82f619961614ec2 + .quad 0x45f1b3f6b3b3427b, 0xa515218421213442, 0xd6949c4a9c9c0825, 0x66f01e781e1eee3c + .quad 0x5222431143436186, 0xfc76c73bc7c7b193, 0x2bb3fcd7fcfc4fe5, 0x1420041004042408 + .quad 0x08b251595151e3a2, 0xc7bc995e9999252f, 0xc44f6da96d6d22da, 0x39680d340d0d651a + .quad 0x3583facffafa79e9, 0x84b6df5bdfdf69a3, 0x9bd77ee57e7ea9fc, 0xb43d249024241948 + .quad 0xd7c53bec3b3bfe76, 0x3d31ab96abab9a4b, 0xd13ece1fcecef081, 0x5588114411119922 + .quad 0x890c8f068f8f8303, 0x6b4a4e254e4e049c, 0x51d1b7e6b7b76673, 0x600beb8bebebe0cb + .quad 0xccfd3cf03c3cc178, 0xbf7c813e8181fd1f, 0xfed4946a94944035, 0x0cebf7fbf7f71cf3 + .quad 0x67a1b9deb9b9186f, 0x5f98134c13138b26, 0x9c7d2cb02c2c5158, 0xb8d6d36bd3d305bb + .quad 0x5c6be7bbe7e78cd3, 0xcb576ea56e6e39dc, 0xf36ec437c4c4aa95, 0x0f18030c03031b06 + .quad 0x138a56455656dcac, 0x491a440d44445e88, 0x9edf7fe17f7fa0fe, 0x3721a99ea9a9884f + .quad 0x824d2aa82a2a6754, 0x6db1bbd6bbbb0a6b, 0xe246c123c1c1879f, 0x02a253515353f1a6 + .quad 0x8baedc57dcdc72a5, 0x27580b2c0b0b5316, 0xd39c9d4e9d9d0127, 0xc1476cad6c6c2bd8 + .quad 0xf59531c43131a462, 0xb98774cd7474f3e8, 0x09e3f6fff6f615f1, 0x430a460546464c8c + .quad 0x2609ac8aacaca545, 0x973c891e8989b50f, 0x44a014501414b428, 0x425be1a3e1e1badf + .quad 0x4eb016581616a62c, 0xd2cd3ae83a3af774, 0xd06f69b9696906d2, 0x2d48092409094112 + .quad 0xada770dd7070d7e0, 0x54d9b6e2b6b66f71, 0xb7ced067d0d01ebd, 0x7e3bed93ededd6c7 + .quad 0xdb2ecc17cccce285, 0x572a421542426884, 0xc2b4985a98982c2d, 0x0e49a4aaa4a4ed55 + .quad 0x885d28a028287550, 0x31da5c6d5c5c86b8, 0x3f93f8c7f8f86bed, 0xa44486228686c211 + + .quad 0xc018601818d83078, 0x05238c23232646af, 0x7ec63fc6c6b891f9, 0x13e887e8e8fbcd6f + .quad 0x4c87268787cb13a1, 0xa9b8dab8b8116d62, 0x0801040101090205, 0x424f214f4f0d9e6e + .quad 0xad36d836369b6cee, 0x59a6a2a6a6ff5104, 0xded26fd2d20cb9bd, 0xfbf5f3f5f50ef706 + .quad 0xef79f9797996f280, 0x5f6fa16f6f30dece, 0xfc917e91916d3fef, 0xaa52555252f8a407 + .quad 0x27609d606047c0fd, 0x89bccabcbc356576, 0xac9b569b9b372bcd, 0x048e028e8e8a018c + .quad 0x71a3b6a3a3d25b15, 0x600c300c0c6c183c, 0xff7bf17b7b84f68a, 0xb535d43535806ae1 + .quad 0xe81d741d1df53a69, 0x53e0a7e0e0b3dd47, 0xf6d77bd7d721b3ac, 0x5ec22fc2c29c99ed + .quad 0x6d2eb82e2e435c96, 0x624b314b4b29967a, 0xa3fedffefe5de121, 0x8257415757d5ae16 + .quad 0xa815541515bd2a41, 0x9f77c17777e8eeb6, 0xa537dc3737926eeb, 0x7be5b3e5e59ed756 + .quad 0x8c9f469f9f1323d9, 0xd3f0e7f0f023fd17, 0x6a4a354a4a20947f, 0x9eda4fdada44a995 + .quad 0xfa587d5858a2b025, 0x06c903c9c9cf8fca, 0x5529a429297c528d, 0x500a280a0a5a1422 + .quad 0xe1b1feb1b1507f4f, 0x69a0baa0a0c95d1a, 0x7f6bb16b6b14d6da, 0x5c852e8585d917ab + .quad 0x81bdcebdbd3c6773, 0xd25d695d5d8fba34, 0x8010401010902050, 0xf3f4f7f4f407f503 + .quad 0x16cb0bcbcbdd8bc0, 0xed3ef83e3ed37cc6, 0x28051405052d0a11, 0x1f6781676778cee6 + .quad 0x73e4b7e4e497d553, 0x25279c2727024ebb, 0x3241194141738258, 0x2c8b168b8ba70b9d + .quad 0x51a7a6a7a7f65301, 0xcf7de97d7db2fa94, 0xdc956e95954937fb, 0x8ed847d8d856ad9f + .quad 0x8bfbcbfbfb70eb30, 0x23ee9feeeecdc171, 0xc77ced7c7cbbf891, 0x176685666671cce3 + .quad 0xa6dd53dddd7ba78e, 0xb8175c1717af2e4b, 0x0247014747458e46, 0x849e429e9e1a21dc + .quad 0x1eca0fcacad489c5, 0x752db42d2d585a99, 0x91bfc6bfbf2e6379, 0x38071c07073f0e1b + .quad 0x01ad8eadadac4723, 0xea5a755a5ab0b42f, 0x6c83368383ef1bb5, 0x8533cc3333b666ff + .quad 0x3f639163635cc6f2, 0x100208020212040a, 0x39aa92aaaa934938, 0xaf71d97171dee2a8 + .quad 0x0ec807c8c8c68dcf, 0xc819641919d1327d, 0x72493949493b9270, 0x86d943d9d95faf9a + .quad 0xc3f2eff2f231f91d, 0x4be3abe3e3a8db48, 0xe25b715b5bb9b62a, 0x34881a8888bc0d92 + .quad 0xa49a529a9a3e29c8, 0x2d269826260b4cbe, 0x8d32c83232bf64fa, 0xe9b0fab0b0597d4a + .quad 0x1be983e9e9f2cf6a, 0x780f3c0f0f771e33, 0xe6d573d5d533b7a6, 0x74803a8080f41dba + .quad 0x99bec2bebe27617c, 0x26cd13cdcdeb87de, 0xbd34d034348968e4, 0x7a483d4848329075 + .quad 0xabffdbffff54e324, 0xf77af57a7a8df48f, 0xf4907a9090643dea, 0xc25f615f5f9dbe3e + .quad 0x1d208020203d40a0, 0x6768bd68680fd0d5, 0xd01a681a1aca3472, 0x19ae82aeaeb7412c + .quad 0xc9b4eab4b47d755e, 0x9a544d5454cea819, 0xec937693937f3be5, 0x0d228822222f44aa + .quad 0x07648d646463c8e9, 0xdbf1e3f1f12aff12, 0xbf73d17373cce6a2, 0x901248121282245a + .quad 0x3a401d40407a805d, 0x4008200808481028, 0x56c32bc3c3959be8, 0x33ec97ececdfc57b + .quad 0x96db4bdbdb4dab90, 0x61a1bea1a1c05f1f, 0x1c8d0e8d8d910783, 0xf53df43d3dc87ac9 + .quad 0xcc976697975b33f1, 0x0000000000000000, 0x36cf1bcfcff983d4, 0x452bac2b2b6e5687 + .quad 0x9776c57676e1ecb3, 0x6482328282e619b0, 0xfed67fd6d628b1a9, 0xd81b6c1b1bc33677 + .quad 0xc1b5eeb5b574775b, 0x11af86afafbe4329, 0x776ab56a6a1dd4df, 0xba505d5050eaa00d + .quad 0x1245094545578a4c, 0xcbf3ebf3f338fb18, 0x9d30c03030ad60f0, 0x2bef9befefc4c374 + .quad 0xe53ffc3f3fda7ec3, 0x9255495555c7aa1c, 0x79a2b2a2a2db5910, 0x03ea8feaeae9c965 + .quad 0x0f658965656acaec, 0xb9bad2baba036968, 0x652fbc2f2f4a5e93, 0x4ec027c0c08e9de7 + .quad 0xbede5fdede60a181, 0xe01c701c1cfc386c, 0xbbfdd3fdfd46e72e, 0x524d294d4d1f9a64 + .quad 0xe4927292927639e0, 0x8f75c97575faeabc, 0x3006180606360c1e, 0x248a128a8aae0998 + .quad 0xf9b2f2b2b24b7940, 0x63e6bfe6e685d159, 0x700e380e0e7e1c36, 0xf81f7c1f1fe73e63 + .quad 0x376295626255c4f7, 0xeed477d4d43ab5a3, 0x29a89aa8a8814d32, 0xc4966296965231f4 + .quad 0x9bf9c3f9f962ef3a, 0x66c533c5c5a397f6, 0x3525942525104ab1, 0xf259795959abb220 + .quad 0x54842a8484d015ae, 0xb772d57272c5e4a7, 0xd539e43939ec72dd, 0x5a4c2d4c4c169861 + .quad 0xca5e655e5e94bc3b, 0xe778fd78789ff085, 0xdd38e03838e570d8, 0x148c0a8c8c980586 + .quad 0xc6d163d1d117bfb2, 0x41a5aea5a5e4570b, 0x43e2afe2e2a1d94d, 0x2f619961614ec2f8 + .quad 0xf1b3f6b3b3427b45, 0x15218421213442a5, 0x949c4a9c9c0825d6, 0xf01e781e1eee3c66 + .quad 0x2243114343618652, 0x76c73bc7c7b193fc, 0xb3fcd7fcfc4fe52b, 0x2004100404240814 + .quad 0xb251595151e3a208, 0xbc995e9999252fc7, 0x4f6da96d6d22dac4, 0x680d340d0d651a39 + .quad 0x83facffafa79e935, 0xb6df5bdfdf69a384, 0xd77ee57e7ea9fc9b, 0x3d249024241948b4 + .quad 0xc53bec3b3bfe76d7, 0x31ab96abab9a4b3d, 0x3ece1fcecef081d1, 0x8811441111992255 + .quad 0x0c8f068f8f830389, 0x4a4e254e4e049c6b, 0xd1b7e6b7b7667351, 0x0beb8bebebe0cb60 + .quad 0xfd3cf03c3cc178cc, 0x7c813e8181fd1fbf, 0xd4946a94944035fe, 0xebf7fbf7f71cf30c + .quad 0xa1b9deb9b9186f67, 0x98134c13138b265f, 0x7d2cb02c2c51589c, 0xd6d36bd3d305bbb8 + .quad 0x6be7bbe7e78cd35c, 0x576ea56e6e39dccb, 0x6ec437c4c4aa95f3, 0x18030c03031b060f + .quad 0x8a56455656dcac13, 0x1a440d44445e8849, 0xdf7fe17f7fa0fe9e, 0x21a99ea9a9884f37 + .quad 0x4d2aa82a2a675482, 0xb1bbd6bbbb0a6b6d, 0x46c123c1c1879fe2, 0xa253515353f1a602 + .quad 0xaedc57dcdc72a58b, 0x580b2c0b0b531627, 0x9c9d4e9d9d0127d3, 0x476cad6c6c2bd8c1 + .quad 0x9531c43131a462f5, 0x8774cd7474f3e8b9, 0xe3f6fff6f615f109, 0x0a460546464c8c43 + .quad 0x09ac8aacaca54526, 0x3c891e8989b50f97, 0xa014501414b42844, 0x5be1a3e1e1badf42 + .quad 0xb016581616a62c4e, 0xcd3ae83a3af774d2, 0x6f69b9696906d2d0, 0x480924090941122d + .quad 0xa770dd7070d7e0ad, 0xd9b6e2b6b66f7154, 0xced067d0d01ebdb7, 0x3bed93ededd6c77e + .quad 0x2ecc17cccce285db, 0x2a42154242688457, 0xb4985a98982c2dc2, 0x49a4aaa4a4ed550e + .quad 0x5d28a02828755088, 0xda5c6d5c5c86b831, 0x93f8c7f8f86bed3f, 0x4486228686c211a4 + + .quad 0x18601818d83078c0, 0x238c23232646af05, 0xc63fc6c6b891f97e, 0xe887e8e8fbcd6f13 + .quad 0x87268787cb13a14c, 0xb8dab8b8116d62a9, 0x0104010109020508, 0x4f214f4f0d9e6e42 + .quad 0x36d836369b6ceead, 0xa6a2a6a6ff510459, 0xd26fd2d20cb9bdde, 0xf5f3f5f50ef706fb + .quad 0x79f9797996f280ef, 0x6fa16f6f30dece5f, 0x917e91916d3feffc, 0x52555252f8a407aa + .quad 0x609d606047c0fd27, 0xbccabcbc35657689, 0x9b569b9b372bcdac, 0x8e028e8e8a018c04 + .quad 0xa3b6a3a3d25b1571, 0x0c300c0c6c183c60, 0x7bf17b7b84f68aff, 0x35d43535806ae1b5 + .quad 0x1d741d1df53a69e8, 0xe0a7e0e0b3dd4753, 0xd77bd7d721b3acf6, 0xc22fc2c29c99ed5e + .quad 0x2eb82e2e435c966d, 0x4b314b4b29967a62, 0xfedffefe5de121a3, 0x57415757d5ae1682 + .quad 0x15541515bd2a41a8, 0x77c17777e8eeb69f, 0x37dc3737926eeba5, 0xe5b3e5e59ed7567b + .quad 0x9f469f9f1323d98c, 0xf0e7f0f023fd17d3, 0x4a354a4a20947f6a, 0xda4fdada44a9959e + .quad 0x587d5858a2b025fa, 0xc903c9c9cf8fca06, 0x29a429297c528d55, 0x0a280a0a5a142250 + .quad 0xb1feb1b1507f4fe1, 0xa0baa0a0c95d1a69, 0x6bb16b6b14d6da7f, 0x852e8585d917ab5c + .quad 0xbdcebdbd3c677381, 0x5d695d5d8fba34d2, 0x1040101090205080, 0xf4f7f4f407f503f3 + .quad 0xcb0bcbcbdd8bc016, 0x3ef83e3ed37cc6ed, 0x051405052d0a1128, 0x6781676778cee61f + .quad 0xe4b7e4e497d55373, 0x279c2727024ebb25, 0x4119414173825832, 0x8b168b8ba70b9d2c + .quad 0xa7a6a7a7f6530151, 0x7de97d7db2fa94cf, 0x956e95954937fbdc, 0xd847d8d856ad9f8e + .quad 0xfbcbfbfb70eb308b, 0xee9feeeecdc17123, 0x7ced7c7cbbf891c7, 0x6685666671cce317 + .quad 0xdd53dddd7ba78ea6, 0x175c1717af2e4bb8, 0x47014747458e4602, 0x9e429e9e1a21dc84 + .quad 0xca0fcacad489c51e, 0x2db42d2d585a9975, 0xbfc6bfbf2e637991, 0x071c07073f0e1b38 + .quad 0xad8eadadac472301, 0x5a755a5ab0b42fea, 0x83368383ef1bb56c, 0x33cc3333b666ff85 + .quad 0x639163635cc6f23f, 0x0208020212040a10, 0xaa92aaaa93493839, 0x71d97171dee2a8af + .quad 0xc807c8c8c68dcf0e, 0x19641919d1327dc8, 0x493949493b927072, 0xd943d9d95faf9a86 + .quad 0xf2eff2f231f91dc3, 0xe3abe3e3a8db484b, 0x5b715b5bb9b62ae2, 0x881a8888bc0d9234 + .quad 0x9a529a9a3e29c8a4, 0x269826260b4cbe2d, 0x32c83232bf64fa8d, 0xb0fab0b0597d4ae9 + .quad 0xe983e9e9f2cf6a1b, 0x0f3c0f0f771e3378, 0xd573d5d533b7a6e6, 0x803a8080f41dba74 + .quad 0xbec2bebe27617c99, 0xcd13cdcdeb87de26, 0x34d034348968e4bd, 0x483d48483290757a + .quad 0xffdbffff54e324ab, 0x7af57a7a8df48ff7, 0x907a9090643deaf4, 0x5f615f5f9dbe3ec2 + .quad 0x208020203d40a01d, 0x68bd68680fd0d567, 0x1a681a1aca3472d0, 0xae82aeaeb7412c19 + .quad 0xb4eab4b47d755ec9, 0x544d5454cea8199a, 0x937693937f3be5ec, 0x228822222f44aa0d + .quad 0x648d646463c8e907, 0xf1e3f1f12aff12db, 0x73d17373cce6a2bf, 0x1248121282245a90 + .quad 0x401d40407a805d3a, 0x0820080848102840, 0xc32bc3c3959be856, 0xec97ececdfc57b33 + .quad 0xdb4bdbdb4dab9096, 0xa1bea1a1c05f1f61, 0x8d0e8d8d9107831c, 0x3df43d3dc87ac9f5 + .quad 0x976697975b33f1cc, 0x0000000000000000, 0xcf1bcfcff983d436, 0x2bac2b2b6e568745 + .quad 0x76c57676e1ecb397, 0x82328282e619b064, 0xd67fd6d628b1a9fe, 0x1b6c1b1bc33677d8 + .quad 0xb5eeb5b574775bc1, 0xaf86afafbe432911, 0x6ab56a6a1dd4df77, 0x505d5050eaa00dba + .quad 0x45094545578a4c12, 0xf3ebf3f338fb18cb, 0x30c03030ad60f09d, 0xef9befefc4c3742b + .quad 0x3ffc3f3fda7ec3e5, 0x55495555c7aa1c92, 0xa2b2a2a2db591079, 0xea8feaeae9c96503 + .quad 0x658965656acaec0f, 0xbad2baba036968b9, 0x2fbc2f2f4a5e9365, 0xc027c0c08e9de74e + .quad 0xde5fdede60a181be, 0x1c701c1cfc386ce0, 0xfdd3fdfd46e72ebb, 0x4d294d4d1f9a6452 + .quad 0x927292927639e0e4, 0x75c97575faeabc8f, 0x06180606360c1e30, 0x8a128a8aae099824 + .quad 0xb2f2b2b24b7940f9, 0xe6bfe6e685d15963, 0x0e380e0e7e1c3670, 0x1f7c1f1fe73e63f8 + .quad 0x6295626255c4f737, 0xd477d4d43ab5a3ee, 0xa89aa8a8814d3229, 0x966296965231f4c4 + .quad 0xf9c3f9f962ef3a9b, 0xc533c5c5a397f666, 0x25942525104ab135, 0x59795959abb220f2 + .quad 0x842a8484d015ae54, 0x72d57272c5e4a7b7, 0x39e43939ec72ddd5, 0x4c2d4c4c1698615a + .quad 0x5e655e5e94bc3bca, 0x78fd78789ff085e7, 0x38e03838e570d8dd, 0x8c0a8c8c98058614 + .quad 0xd163d1d117bfb2c6, 0xa5aea5a5e4570b41, 0xe2afe2e2a1d94d43, 0x619961614ec2f82f + .quad 0xb3f6b3b3427b45f1, 0x218421213442a515, 0x9c4a9c9c0825d694, 0x1e781e1eee3c66f0 + .quad 0x4311434361865222, 0xc73bc7c7b193fc76, 0xfcd7fcfc4fe52bb3, 0x0410040424081420 + .quad 0x51595151e3a208b2, 0x995e9999252fc7bc, 0x6da96d6d22dac44f, 0x0d340d0d651a3968 + .quad 0xfacffafa79e93583, 0xdf5bdfdf69a384b6, 0x7ee57e7ea9fc9bd7, 0x249024241948b43d + .quad 0x3bec3b3bfe76d7c5, 0xab96abab9a4b3d31, 0xce1fcecef081d13e, 0x1144111199225588 + .quad 0x8f068f8f8303890c, 0x4e254e4e049c6b4a, 0xb7e6b7b7667351d1, 0xeb8bebebe0cb600b + .quad 0x3cf03c3cc178ccfd, 0x813e8181fd1fbf7c, 0x946a94944035fed4, 0xf7fbf7f71cf30ceb + .quad 0xb9deb9b9186f67a1, 0x134c13138b265f98, 0x2cb02c2c51589c7d, 0xd36bd3d305bbb8d6 + .quad 0xe7bbe7e78cd35c6b, 0x6ea56e6e39dccb57, 0xc437c4c4aa95f36e, 0x030c03031b060f18 + .quad 0x56455656dcac138a, 0x440d44445e88491a, 0x7fe17f7fa0fe9edf, 0xa99ea9a9884f3721 + .quad 0x2aa82a2a6754824d, 0xbbd6bbbb0a6b6db1, 0xc123c1c1879fe246, 0x53515353f1a602a2 + .quad 0xdc57dcdc72a58bae, 0x0b2c0b0b53162758, 0x9d4e9d9d0127d39c, 0x6cad6c6c2bd8c147 + .quad 0x31c43131a462f595, 0x74cd7474f3e8b987, 0xf6fff6f615f109e3, 0x460546464c8c430a + .quad 0xac8aacaca5452609, 0x891e8989b50f973c, 0x14501414b42844a0, 0xe1a3e1e1badf425b + .quad 0x16581616a62c4eb0, 0x3ae83a3af774d2cd, 0x69b9696906d2d06f, 0x0924090941122d48 + .quad 0x70dd7070d7e0ada7, 0xb6e2b6b66f7154d9, 0xd067d0d01ebdb7ce, 0xed93ededd6c77e3b + .quad 0xcc17cccce285db2e, 0x421542426884572a, 0x985a98982c2dc2b4, 0xa4aaa4a4ed550e49 + .quad 0x28a028287550885d, 0x5c6d5c5c86b831da, 0xf8c7f8f86bed3f93, 0x86228686c211a444 + + .quad 0x601818d83078c018, 0x8c23232646af0523, 0x3fc6c6b891f97ec6, 0x87e8e8fbcd6f13e8 + .quad 0x268787cb13a14c87, 0xdab8b8116d62a9b8, 0x0401010902050801, 0x214f4f0d9e6e424f + .quad 0xd836369b6ceead36, 0xa2a6a6ff510459a6, 0x6fd2d20cb9bdded2, 0xf3f5f50ef706fbf5 + .quad 0xf9797996f280ef79, 0xa16f6f30dece5f6f, 0x7e91916d3feffc91, 0x555252f8a407aa52 + .quad 0x9d606047c0fd2760, 0xcabcbc35657689bc, 0x569b9b372bcdac9b, 0x028e8e8a018c048e + .quad 0xb6a3a3d25b1571a3, 0x300c0c6c183c600c, 0xf17b7b84f68aff7b, 0xd43535806ae1b535 + .quad 0x741d1df53a69e81d, 0xa7e0e0b3dd4753e0, 0x7bd7d721b3acf6d7, 0x2fc2c29c99ed5ec2 + .quad 0xb82e2e435c966d2e, 0x314b4b29967a624b, 0xdffefe5de121a3fe, 0x415757d5ae168257 + .quad 0x541515bd2a41a815, 0xc17777e8eeb69f77, 0xdc3737926eeba537, 0xb3e5e59ed7567be5 + .quad 0x469f9f1323d98c9f, 0xe7f0f023fd17d3f0, 0x354a4a20947f6a4a, 0x4fdada44a9959eda + .quad 0x7d5858a2b025fa58, 0x03c9c9cf8fca06c9, 0xa429297c528d5529, 0x280a0a5a1422500a + .quad 0xfeb1b1507f4fe1b1, 0xbaa0a0c95d1a69a0, 0xb16b6b14d6da7f6b, 0x2e8585d917ab5c85 + .quad 0xcebdbd3c677381bd, 0x695d5d8fba34d25d, 0x4010109020508010, 0xf7f4f407f503f3f4 + .quad 0x0bcbcbdd8bc016cb, 0xf83e3ed37cc6ed3e, 0x1405052d0a112805, 0x81676778cee61f67 + .quad 0xb7e4e497d55373e4, 0x9c2727024ebb2527, 0x1941417382583241, 0x168b8ba70b9d2c8b + .quad 0xa6a7a7f6530151a7, 0xe97d7db2fa94cf7d, 0x6e95954937fbdc95, 0x47d8d856ad9f8ed8 + .quad 0xcbfbfb70eb308bfb, 0x9feeeecdc17123ee, 0xed7c7cbbf891c77c, 0x85666671cce31766 + .quad 0x53dddd7ba78ea6dd, 0x5c1717af2e4bb817, 0x014747458e460247, 0x429e9e1a21dc849e + .quad 0x0fcacad489c51eca, 0xb42d2d585a99752d, 0xc6bfbf2e637991bf, 0x1c07073f0e1b3807 + .quad 0x8eadadac472301ad, 0x755a5ab0b42fea5a, 0x368383ef1bb56c83, 0xcc3333b666ff8533 + .quad 0x9163635cc6f23f63, 0x08020212040a1002, 0x92aaaa93493839aa, 0xd97171dee2a8af71 + .quad 0x07c8c8c68dcf0ec8, 0x641919d1327dc819, 0x3949493b92707249, 0x43d9d95faf9a86d9 + .quad 0xeff2f231f91dc3f2, 0xabe3e3a8db484be3, 0x715b5bb9b62ae25b, 0x1a8888bc0d923488 + .quad 0x529a9a3e29c8a49a, 0x9826260b4cbe2d26, 0xc83232bf64fa8d32, 0xfab0b0597d4ae9b0 + .quad 0x83e9e9f2cf6a1be9, 0x3c0f0f771e33780f, 0x73d5d533b7a6e6d5, 0x3a8080f41dba7480 + .quad 0xc2bebe27617c99be, 0x13cdcdeb87de26cd, 0xd034348968e4bd34, 0x3d48483290757a48 + .quad 0xdbffff54e324abff, 0xf57a7a8df48ff77a, 0x7a9090643deaf490, 0x615f5f9dbe3ec25f + .quad 0x8020203d40a01d20, 0xbd68680fd0d56768, 0x681a1aca3472d01a, 0x82aeaeb7412c19ae + .quad 0xeab4b47d755ec9b4, 0x4d5454cea8199a54, 0x7693937f3be5ec93, 0x8822222f44aa0d22 + .quad 0x8d646463c8e90764, 0xe3f1f12aff12dbf1, 0xd17373cce6a2bf73, 0x48121282245a9012 + .quad 0x1d40407a805d3a40, 0x2008084810284008, 0x2bc3c3959be856c3, 0x97ececdfc57b33ec + .quad 0x4bdbdb4dab9096db, 0xbea1a1c05f1f61a1, 0x0e8d8d9107831c8d, 0xf43d3dc87ac9f53d + .quad 0x6697975b33f1cc97, 0x0000000000000000, 0x1bcfcff983d436cf, 0xac2b2b6e5687452b + .quad 0xc57676e1ecb39776, 0x328282e619b06482, 0x7fd6d628b1a9fed6, 0x6c1b1bc33677d81b + .quad 0xeeb5b574775bc1b5, 0x86afafbe432911af, 0xb56a6a1dd4df776a, 0x5d5050eaa00dba50 + .quad 0x094545578a4c1245, 0xebf3f338fb18cbf3, 0xc03030ad60f09d30, 0x9befefc4c3742bef + .quad 0xfc3f3fda7ec3e53f, 0x495555c7aa1c9255, 0xb2a2a2db591079a2, 0x8feaeae9c96503ea + .quad 0x8965656acaec0f65, 0xd2baba036968b9ba, 0xbc2f2f4a5e93652f, 0x27c0c08e9de74ec0 + .quad 0x5fdede60a181bede, 0x701c1cfc386ce01c, 0xd3fdfd46e72ebbfd, 0x294d4d1f9a64524d + .quad 0x7292927639e0e492, 0xc97575faeabc8f75, 0x180606360c1e3006, 0x128a8aae0998248a + .quad 0xf2b2b24b7940f9b2, 0xbfe6e685d15963e6, 0x380e0e7e1c36700e, 0x7c1f1fe73e63f81f + .quad 0x95626255c4f73762, 0x77d4d43ab5a3eed4, 0x9aa8a8814d3229a8, 0x6296965231f4c496 + .quad 0xc3f9f962ef3a9bf9, 0x33c5c5a397f666c5, 0x942525104ab13525, 0x795959abb220f259 + .quad 0x2a8484d015ae5484, 0xd57272c5e4a7b772, 0xe43939ec72ddd539, 0x2d4c4c1698615a4c + .quad 0x655e5e94bc3bca5e, 0xfd78789ff085e778, 0xe03838e570d8dd38, 0x0a8c8c980586148c + .quad 0x63d1d117bfb2c6d1, 0xaea5a5e4570b41a5, 0xafe2e2a1d94d43e2, 0x9961614ec2f82f61 + .quad 0xf6b3b3427b45f1b3, 0x8421213442a51521, 0x4a9c9c0825d6949c, 0x781e1eee3c66f01e + .quad 0x1143436186522243, 0x3bc7c7b193fc76c7, 0xd7fcfc4fe52bb3fc, 0x1004042408142004 + .quad 0x595151e3a208b251, 0x5e9999252fc7bc99, 0xa96d6d22dac44f6d, 0x340d0d651a39680d + .quad 0xcffafa79e93583fa, 0x5bdfdf69a384b6df, 0xe57e7ea9fc9bd77e, 0x9024241948b43d24 + .quad 0xec3b3bfe76d7c53b, 0x96abab9a4b3d31ab, 0x1fcecef081d13ece, 0x4411119922558811 + .quad 0x068f8f8303890c8f, 0x254e4e049c6b4a4e, 0xe6b7b7667351d1b7, 0x8bebebe0cb600beb + .quad 0xf03c3cc178ccfd3c, 0x3e8181fd1fbf7c81, 0x6a94944035fed494, 0xfbf7f71cf30cebf7 + .quad 0xdeb9b9186f67a1b9, 0x4c13138b265f9813, 0xb02c2c51589c7d2c, 0x6bd3d305bbb8d6d3 + .quad 0xbbe7e78cd35c6be7, 0xa56e6e39dccb576e, 0x37c4c4aa95f36ec4, 0x0c03031b060f1803 + .quad 0x455656dcac138a56, 0x0d44445e88491a44, 0xe17f7fa0fe9edf7f, 0x9ea9a9884f3721a9 + .quad 0xa82a2a6754824d2a, 0xd6bbbb0a6b6db1bb, 0x23c1c1879fe246c1, 0x515353f1a602a253 + .quad 0x57dcdc72a58baedc, 0x2c0b0b531627580b, 0x4e9d9d0127d39c9d, 0xad6c6c2bd8c1476c + .quad 0xc43131a462f59531, 0xcd7474f3e8b98774, 0xfff6f615f109e3f6, 0x0546464c8c430a46 + .quad 0x8aacaca5452609ac, 0x1e8989b50f973c89, 0x501414b42844a014, 0xa3e1e1badf425be1 + .quad 0x581616a62c4eb016, 0xe83a3af774d2cd3a, 0xb9696906d2d06f69, 0x24090941122d4809 + .quad 0xdd7070d7e0ada770, 0xe2b6b66f7154d9b6, 0x67d0d01ebdb7ced0, 0x93ededd6c77e3bed + .quad 0x17cccce285db2ecc, 0x1542426884572a42, 0x5a98982c2dc2b498, 0xaaa4a4ed550e49a4 + .quad 0xa028287550885d28, 0x6d5c5c86b831da5c, 0xc7f8f86bed3f93f8, 0x228686c211a44486 + + .quad 0x1818d83078c01860, 0x23232646af05238c, 0xc6c6b891f97ec63f, 0xe8e8fbcd6f13e887 + .quad 0x8787cb13a14c8726, 0xb8b8116d62a9b8da, 0x0101090205080104, 0x4f4f0d9e6e424f21 + .quad 0x36369b6ceead36d8, 0xa6a6ff510459a6a2, 0xd2d20cb9bdded26f, 0xf5f50ef706fbf5f3 + .quad 0x797996f280ef79f9, 0x6f6f30dece5f6fa1, 0x91916d3feffc917e, 0x5252f8a407aa5255 + .quad 0x606047c0fd27609d, 0xbcbc35657689bcca, 0x9b9b372bcdac9b56, 0x8e8e8a018c048e02 + .quad 0xa3a3d25b1571a3b6, 0x0c0c6c183c600c30, 0x7b7b84f68aff7bf1, 0x3535806ae1b535d4 + .quad 0x1d1df53a69e81d74, 0xe0e0b3dd4753e0a7, 0xd7d721b3acf6d77b, 0xc2c29c99ed5ec22f + .quad 0x2e2e435c966d2eb8, 0x4b4b29967a624b31, 0xfefe5de121a3fedf, 0x5757d5ae16825741 + .quad 0x1515bd2a41a81554, 0x7777e8eeb69f77c1, 0x3737926eeba537dc, 0xe5e59ed7567be5b3 + .quad 0x9f9f1323d98c9f46, 0xf0f023fd17d3f0e7, 0x4a4a20947f6a4a35, 0xdada44a9959eda4f + .quad 0x5858a2b025fa587d, 0xc9c9cf8fca06c903, 0x29297c528d5529a4, 0x0a0a5a1422500a28 + .quad 0xb1b1507f4fe1b1fe, 0xa0a0c95d1a69a0ba, 0x6b6b14d6da7f6bb1, 0x8585d917ab5c852e + .quad 0xbdbd3c677381bdce, 0x5d5d8fba34d25d69, 0x1010902050801040, 0xf4f407f503f3f4f7 + .quad 0xcbcbdd8bc016cb0b, 0x3e3ed37cc6ed3ef8, 0x05052d0a11280514, 0x676778cee61f6781 + .quad 0xe4e497d55373e4b7, 0x2727024ebb25279c, 0x4141738258324119, 0x8b8ba70b9d2c8b16 + .quad 0xa7a7f6530151a7a6, 0x7d7db2fa94cf7de9, 0x95954937fbdc956e, 0xd8d856ad9f8ed847 + .quad 0xfbfb70eb308bfbcb, 0xeeeecdc17123ee9f, 0x7c7cbbf891c77ced, 0x666671cce3176685 + .quad 0xdddd7ba78ea6dd53, 0x1717af2e4bb8175c, 0x4747458e46024701, 0x9e9e1a21dc849e42 + .quad 0xcacad489c51eca0f, 0x2d2d585a99752db4, 0xbfbf2e637991bfc6, 0x07073f0e1b38071c + .quad 0xadadac472301ad8e, 0x5a5ab0b42fea5a75, 0x8383ef1bb56c8336, 0x3333b666ff8533cc + .quad 0x63635cc6f23f6391, 0x020212040a100208, 0xaaaa93493839aa92, 0x7171dee2a8af71d9 + .quad 0xc8c8c68dcf0ec807, 0x1919d1327dc81964, 0x49493b9270724939, 0xd9d95faf9a86d943 + .quad 0xf2f231f91dc3f2ef, 0xe3e3a8db484be3ab, 0x5b5bb9b62ae25b71, 0x8888bc0d9234881a + .quad 0x9a9a3e29c8a49a52, 0x26260b4cbe2d2698, 0x3232bf64fa8d32c8, 0xb0b0597d4ae9b0fa + .quad 0xe9e9f2cf6a1be983, 0x0f0f771e33780f3c, 0xd5d533b7a6e6d573, 0x8080f41dba74803a + .quad 0xbebe27617c99bec2, 0xcdcdeb87de26cd13, 0x34348968e4bd34d0, 0x48483290757a483d + .quad 0xffff54e324abffdb, 0x7a7a8df48ff77af5, 0x9090643deaf4907a, 0x5f5f9dbe3ec25f61 + .quad 0x20203d40a01d2080, 0x68680fd0d56768bd, 0x1a1aca3472d01a68, 0xaeaeb7412c19ae82 + .quad 0xb4b47d755ec9b4ea, 0x5454cea8199a544d, 0x93937f3be5ec9376, 0x22222f44aa0d2288 + .quad 0x646463c8e907648d, 0xf1f12aff12dbf1e3, 0x7373cce6a2bf73d1, 0x121282245a901248 + .quad 0x40407a805d3a401d, 0x0808481028400820, 0xc3c3959be856c32b, 0xececdfc57b33ec97 + .quad 0xdbdb4dab9096db4b, 0xa1a1c05f1f61a1be, 0x8d8d9107831c8d0e, 0x3d3dc87ac9f53df4 + .quad 0x97975b33f1cc9766, 0x0000000000000000, 0xcfcff983d436cf1b, 0x2b2b6e5687452bac + .quad 0x7676e1ecb39776c5, 0x8282e619b0648232, 0xd6d628b1a9fed67f, 0x1b1bc33677d81b6c + .quad 0xb5b574775bc1b5ee, 0xafafbe432911af86, 0x6a6a1dd4df776ab5, 0x5050eaa00dba505d + .quad 0x4545578a4c124509, 0xf3f338fb18cbf3eb, 0x3030ad60f09d30c0, 0xefefc4c3742bef9b + .quad 0x3f3fda7ec3e53ffc, 0x5555c7aa1c925549, 0xa2a2db591079a2b2, 0xeaeae9c96503ea8f + .quad 0x65656acaec0f6589, 0xbaba036968b9bad2, 0x2f2f4a5e93652fbc, 0xc0c08e9de74ec027 + .quad 0xdede60a181bede5f, 0x1c1cfc386ce01c70, 0xfdfd46e72ebbfdd3, 0x4d4d1f9a64524d29 + .quad 0x92927639e0e49272, 0x7575faeabc8f75c9, 0x0606360c1e300618, 0x8a8aae0998248a12 + .quad 0xb2b24b7940f9b2f2, 0xe6e685d15963e6bf, 0x0e0e7e1c36700e38, 0x1f1fe73e63f81f7c + .quad 0x626255c4f7376295, 0xd4d43ab5a3eed477, 0xa8a8814d3229a89a, 0x96965231f4c49662 + .quad 0xf9f962ef3a9bf9c3, 0xc5c5a397f666c533, 0x2525104ab1352594, 0x5959abb220f25979 + .quad 0x8484d015ae54842a, 0x7272c5e4a7b772d5, 0x3939ec72ddd539e4, 0x4c4c1698615a4c2d + .quad 0x5e5e94bc3bca5e65, 0x78789ff085e778fd, 0x3838e570d8dd38e0, 0x8c8c980586148c0a + .quad 0xd1d117bfb2c6d163, 0xa5a5e4570b41a5ae, 0xe2e2a1d94d43e2af, 0x61614ec2f82f6199 + .quad 0xb3b3427b45f1b3f6, 0x21213442a5152184, 0x9c9c0825d6949c4a, 0x1e1eee3c66f01e78 + .quad 0x4343618652224311, 0xc7c7b193fc76c73b, 0xfcfc4fe52bb3fcd7, 0x0404240814200410 + .quad 0x5151e3a208b25159, 0x9999252fc7bc995e, 0x6d6d22dac44f6da9, 0x0d0d651a39680d34 + .quad 0xfafa79e93583facf, 0xdfdf69a384b6df5b, 0x7e7ea9fc9bd77ee5, 0x24241948b43d2490 + .quad 0x3b3bfe76d7c53bec, 0xabab9a4b3d31ab96, 0xcecef081d13ece1f, 0x1111992255881144 + .quad 0x8f8f8303890c8f06, 0x4e4e049c6b4a4e25, 0xb7b7667351d1b7e6, 0xebebe0cb600beb8b + .quad 0x3c3cc178ccfd3cf0, 0x8181fd1fbf7c813e, 0x94944035fed4946a, 0xf7f71cf30cebf7fb + .quad 0xb9b9186f67a1b9de, 0x13138b265f98134c, 0x2c2c51589c7d2cb0, 0xd3d305bbb8d6d36b + .quad 0xe7e78cd35c6be7bb, 0x6e6e39dccb576ea5, 0xc4c4aa95f36ec437, 0x03031b060f18030c + .quad 0x5656dcac138a5645, 0x44445e88491a440d, 0x7f7fa0fe9edf7fe1, 0xa9a9884f3721a99e + .quad 0x2a2a6754824d2aa8, 0xbbbb0a6b6db1bbd6, 0xc1c1879fe246c123, 0x5353f1a602a25351 + .quad 0xdcdc72a58baedc57, 0x0b0b531627580b2c, 0x9d9d0127d39c9d4e, 0x6c6c2bd8c1476cad + .quad 0x3131a462f59531c4, 0x7474f3e8b98774cd, 0xf6f615f109e3f6ff, 0x46464c8c430a4605 + .quad 0xacaca5452609ac8a, 0x8989b50f973c891e, 0x1414b42844a01450, 0xe1e1badf425be1a3 + .quad 0x1616a62c4eb01658, 0x3a3af774d2cd3ae8, 0x696906d2d06f69b9, 0x090941122d480924 + .quad 0x7070d7e0ada770dd, 0xb6b66f7154d9b6e2, 0xd0d01ebdb7ced067, 0xededd6c77e3bed93 + .quad 0xcccce285db2ecc17, 0x42426884572a4215, 0x98982c2dc2b4985a, 0xa4a4ed550e49a4aa + .quad 0x28287550885d28a0, 0x5c5c86b831da5c6d, 0xf8f86bed3f93f8c7, 0x8686c211a4448622 + + .quad 0x18d83078c0186018, 0x232646af05238c23, 0xc6b891f97ec63fc6, 0xe8fbcd6f13e887e8 + .quad 0x87cb13a14c872687, 0xb8116d62a9b8dab8, 0x0109020508010401, 0x4f0d9e6e424f214f + .quad 0x369b6ceead36d836, 0xa6ff510459a6a2a6, 0xd20cb9bdded26fd2, 0xf50ef706fbf5f3f5 + .quad 0x7996f280ef79f979, 0x6f30dece5f6fa16f, 0x916d3feffc917e91, 0x52f8a407aa525552 + .quad 0x6047c0fd27609d60, 0xbc35657689bccabc, 0x9b372bcdac9b569b, 0x8e8a018c048e028e + .quad 0xa3d25b1571a3b6a3, 0x0c6c183c600c300c, 0x7b84f68aff7bf17b, 0x35806ae1b535d435 + .quad 0x1df53a69e81d741d, 0xe0b3dd4753e0a7e0, 0xd721b3acf6d77bd7, 0xc29c99ed5ec22fc2 + .quad 0x2e435c966d2eb82e, 0x4b29967a624b314b, 0xfe5de121a3fedffe, 0x57d5ae1682574157 + .quad 0x15bd2a41a8155415, 0x77e8eeb69f77c177, 0x37926eeba537dc37, 0xe59ed7567be5b3e5 + .quad 0x9f1323d98c9f469f, 0xf023fd17d3f0e7f0, 0x4a20947f6a4a354a, 0xda44a9959eda4fda + .quad 0x58a2b025fa587d58, 0xc9cf8fca06c903c9, 0x297c528d5529a429, 0x0a5a1422500a280a + .quad 0xb1507f4fe1b1feb1, 0xa0c95d1a69a0baa0, 0x6b14d6da7f6bb16b, 0x85d917ab5c852e85 + .quad 0xbd3c677381bdcebd, 0x5d8fba34d25d695d, 0x1090205080104010, 0xf407f503f3f4f7f4 + .quad 0xcbdd8bc016cb0bcb, 0x3ed37cc6ed3ef83e, 0x052d0a1128051405, 0x6778cee61f678167 + .quad 0xe497d55373e4b7e4, 0x27024ebb25279c27, 0x4173825832411941, 0x8ba70b9d2c8b168b + .quad 0xa7f6530151a7a6a7, 0x7db2fa94cf7de97d, 0x954937fbdc956e95, 0xd856ad9f8ed847d8 + .quad 0xfb70eb308bfbcbfb, 0xeecdc17123ee9fee, 0x7cbbf891c77ced7c, 0x6671cce317668566 + .quad 0xdd7ba78ea6dd53dd, 0x17af2e4bb8175c17, 0x47458e4602470147, 0x9e1a21dc849e429e + .quad 0xcad489c51eca0fca, 0x2d585a99752db42d, 0xbf2e637991bfc6bf, 0x073f0e1b38071c07 + .quad 0xadac472301ad8ead, 0x5ab0b42fea5a755a, 0x83ef1bb56c833683, 0x33b666ff8533cc33 + .quad 0x635cc6f23f639163, 0x0212040a10020802, 0xaa93493839aa92aa, 0x71dee2a8af71d971 + .quad 0xc8c68dcf0ec807c8, 0x19d1327dc8196419, 0x493b927072493949, 0xd95faf9a86d943d9 + .quad 0xf231f91dc3f2eff2, 0xe3a8db484be3abe3, 0x5bb9b62ae25b715b, 0x88bc0d9234881a88 + .quad 0x9a3e29c8a49a529a, 0x260b4cbe2d269826, 0x32bf64fa8d32c832, 0xb0597d4ae9b0fab0 + .quad 0xe9f2cf6a1be983e9, 0x0f771e33780f3c0f, 0xd533b7a6e6d573d5, 0x80f41dba74803a80 + .quad 0xbe27617c99bec2be, 0xcdeb87de26cd13cd, 0x348968e4bd34d034, 0x483290757a483d48 + .quad 0xff54e324abffdbff, 0x7a8df48ff77af57a, 0x90643deaf4907a90, 0x5f9dbe3ec25f615f + .quad 0x203d40a01d208020, 0x680fd0d56768bd68, 0x1aca3472d01a681a, 0xaeb7412c19ae82ae + .quad 0xb47d755ec9b4eab4, 0x54cea8199a544d54, 0x937f3be5ec937693, 0x222f44aa0d228822 + .quad 0x6463c8e907648d64, 0xf12aff12dbf1e3f1, 0x73cce6a2bf73d173, 0x1282245a90124812 + .quad 0x407a805d3a401d40, 0x0848102840082008, 0xc3959be856c32bc3, 0xecdfc57b33ec97ec + .quad 0xdb4dab9096db4bdb, 0xa1c05f1f61a1bea1, 0x8d9107831c8d0e8d, 0x3dc87ac9f53df43d + .quad 0x975b33f1cc976697, 0x0000000000000000, 0xcff983d436cf1bcf, 0x2b6e5687452bac2b + .quad 0x76e1ecb39776c576, 0x82e619b064823282, 0xd628b1a9fed67fd6, 0x1bc33677d81b6c1b + .quad 0xb574775bc1b5eeb5, 0xafbe432911af86af, 0x6a1dd4df776ab56a, 0x50eaa00dba505d50 + .quad 0x45578a4c12450945, 0xf338fb18cbf3ebf3, 0x30ad60f09d30c030, 0xefc4c3742bef9bef + .quad 0x3fda7ec3e53ffc3f, 0x55c7aa1c92554955, 0xa2db591079a2b2a2, 0xeae9c96503ea8fea + .quad 0x656acaec0f658965, 0xba036968b9bad2ba, 0x2f4a5e93652fbc2f, 0xc08e9de74ec027c0 + .quad 0xde60a181bede5fde, 0x1cfc386ce01c701c, 0xfd46e72ebbfdd3fd, 0x4d1f9a64524d294d + .quad 0x927639e0e4927292, 0x75faeabc8f75c975, 0x06360c1e30061806, 0x8aae0998248a128a + .quad 0xb24b7940f9b2f2b2, 0xe685d15963e6bfe6, 0x0e7e1c36700e380e, 0x1fe73e63f81f7c1f + .quad 0x6255c4f737629562, 0xd43ab5a3eed477d4, 0xa8814d3229a89aa8, 0x965231f4c4966296 + .quad 0xf962ef3a9bf9c3f9, 0xc5a397f666c533c5, 0x25104ab135259425, 0x59abb220f2597959 + .quad 0x84d015ae54842a84, 0x72c5e4a7b772d572, 0x39ec72ddd539e439, 0x4c1698615a4c2d4c + .quad 0x5e94bc3bca5e655e, 0x789ff085e778fd78, 0x38e570d8dd38e038, 0x8c980586148c0a8c + .quad 0xd117bfb2c6d163d1, 0xa5e4570b41a5aea5, 0xe2a1d94d43e2afe2, 0x614ec2f82f619961 + .quad 0xb3427b45f1b3f6b3, 0x213442a515218421, 0x9c0825d6949c4a9c, 0x1eee3c66f01e781e + .quad 0x4361865222431143, 0xc7b193fc76c73bc7, 0xfc4fe52bb3fcd7fc, 0x0424081420041004 + .quad 0x51e3a208b2515951, 0x99252fc7bc995e99, 0x6d22dac44f6da96d, 0x0d651a39680d340d + .quad 0xfa79e93583facffa, 0xdf69a384b6df5bdf, 0x7ea9fc9bd77ee57e, 0x241948b43d249024 + .quad 0x3bfe76d7c53bec3b, 0xab9a4b3d31ab96ab, 0xcef081d13ece1fce, 0x1199225588114411 + .quad 0x8f8303890c8f068f, 0x4e049c6b4a4e254e, 0xb7667351d1b7e6b7, 0xebe0cb600beb8beb + .quad 0x3cc178ccfd3cf03c, 0x81fd1fbf7c813e81, 0x944035fed4946a94, 0xf71cf30cebf7fbf7 + .quad 0xb9186f67a1b9deb9, 0x138b265f98134c13, 0x2c51589c7d2cb02c, 0xd305bbb8d6d36bd3 + .quad 0xe78cd35c6be7bbe7, 0x6e39dccb576ea56e, 0xc4aa95f36ec437c4, 0x031b060f18030c03 + .quad 0x56dcac138a564556, 0x445e88491a440d44, 0x7fa0fe9edf7fe17f, 0xa9884f3721a99ea9 + .quad 0x2a6754824d2aa82a, 0xbb0a6b6db1bbd6bb, 0xc1879fe246c123c1, 0x53f1a602a2535153 + .quad 0xdc72a58baedc57dc, 0x0b531627580b2c0b, 0x9d0127d39c9d4e9d, 0x6c2bd8c1476cad6c + .quad 0x31a462f59531c431, 0x74f3e8b98774cd74, 0xf615f109e3f6fff6, 0x464c8c430a460546 + .quad 0xaca5452609ac8aac, 0x89b50f973c891e89, 0x14b42844a0145014, 0xe1badf425be1a3e1 + .quad 0x16a62c4eb0165816, 0x3af774d2cd3ae83a, 0x6906d2d06f69b969, 0x0941122d48092409 + .quad 0x70d7e0ada770dd70, 0xb66f7154d9b6e2b6, 0xd01ebdb7ced067d0, 0xedd6c77e3bed93ed + .quad 0xcce285db2ecc17cc, 0x426884572a421542, 0x982c2dc2b4985a98, 0xa4ed550e49a4aaa4 + .quad 0x287550885d28a028, 0x5c86b831da5c6d5c, 0xf86bed3f93f8c7f8, 0x86c211a444862286 diff -ruNp libgcrypt-1.6.2/cipher/whirlpool.c libgcrypt-1.6.3/cipher/whirlpool.c --- libgcrypt-1.6.2/cipher/whirlpool.c 2014-08-21 07:50:39.000000000 -0500 +++ libgcrypt-1.6.3/cipher/whirlpool.c 2014-08-28 20:40:19.695123491 -0500 @@ -46,7 +46,11 @@ /* Number of rounds. */ #define R 10 - +/* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */ +#undef USE_AMD64_ASM +#if defined(__x86_64__) && defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) +# define USE_AMD64_ASM 1 +#endif /* Types. */ typedef u64 whirlpool_block_t[BLOCK_SIZE / 8]; @@ -73,9 +77,14 @@ typedef struct { /* Convert the block BLOCK into a buffer BUFFER, using I as counter. */ +#ifdef USE_AMD64_ASM #define block_to_buffer(buffer, block, i) \ for (i = 0; i < 8; i++) \ + buf_put_le64((buffer) + i * 8, (block)[i]); +#else + for (i = 0; i < 8; i++) \ buf_put_be64((buffer) + i * 8, (block)[i]); +#endif /* Copy the block BLOCK_SRC to BLOCK_DST, using I as counter. */ #define block_copy(block_dst, block_src, i) \ @@ -1164,7 +1173,19 @@ static const u64 C7[256] = }; -? +#ifdef USE_AMD64_ASM +/* Assembly implementation of Whirlpool */ +unsigned int +_gcry_whirlpool_transform_amd64 (void *state, const unsigned char *data); + +static unsigned int +whirlpool_transform (void *ctx, const unsigned char *data) +{ + whirlpool_context_t *context = ctx; + return _gcry_whirlpool_transform_amd64 (context->hash_state, data) + + 4 * sizeof(void*); +} +#else /*!USE_AMD64_ASM*/ /* * Transform block. */ @@ -1267,7 +1288,7 @@ whirlpool_transform (void *ctx, const un return /*burn_stack*/ 4 * sizeof(whirlpool_block_t) + 2 * sizeof(int) + 4 * sizeof(void*); } - +#endif /*!USE_AMD64_ASM*/ static void whirlpool_init (void *ctx, unsigned int flags) diff -ruNp libgcrypt-1.6.2/configure libgcrypt-1.6.3/configure --- libgcrypt-1.6.2/configure 2014-08-21 08:14:09.000000000 -0500 +++ libgcrypt-1.6.3/configure 2014-08-28 20:04:11.750250587 -0500 @@ -18033,6 +18033,13 @@ if test "$found" = "1" ; then $as_echo "#define USE_WHIRLPOOL 1" >>confdefs.h + + case "${host}" in + x86_64-*-*) + # Build with the assembly implementation + GCRYPT_DIGESTS="$GCRYPT_DIGESTS whirlpool-amd64.lo" + ;; + esac fi # rmd160 and sha1 should be included always. diff -ruNp libgcrypt-1.6.2/configure.ac libgcrypt-1.6.3/configure.ac --- libgcrypt-1.6.2/configure.ac 2014-08-21 08:03:35.000000000 -0500 +++ libgcrypt-1.6.3/configure.ac 2014-08-28 20:04:11.751250575 -0500 @@ -1866,6 +1866,13 @@ LIST_MEMBER(whirlpool, $enabled_digests) if test "$found" = "1" ; then GCRYPT_DIGESTS="$GCRYPT_DIGESTS whirlpool.lo" AC_DEFINE(USE_WHIRLPOOL, 1, [Defined if this module should be included]) + + case "${host}" in + x86_64-*-*) + # Build with the assembly implementation + GCRYPT_DIGESTS="$GCRYPT_DIGESTS whirlpool-amd64.lo" + ;; + esac fi # rmd160 and sha1 should be included always. ____________________________________________________________ Can't remember your password? Do you need a strong and secure password? Use Password manager! It stores your passwords & protects your account. Check it out at http://mysecurelogon.com/password-manager